⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 historymanager.java

📁 dspace 用j2ee架构的一个数字图书馆.开源程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * HistoryManager.java * * Version: $Revision: 1.11 $ * * Date: $Date: 2005/04/20 14:23:44 $ * * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts * Institute of Technology.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Hewlett-Packard Company nor the name of the * Massachusetts Institute of Technology nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */package org.dspace.history;import java.io.BufferedReader;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.io.StringReader;import java.io.StringWriter;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Timestamp;import java.text.NumberFormat;import java.util.LinkedList;import java.util.List;import org.apache.log4j.Logger;import org.dspace.content.Bitstream;import org.dspace.content.Collection;import org.dspace.content.Community;import org.dspace.content.DCValue;import org.dspace.content.Item;import org.dspace.content.ItemIterator;import org.dspace.content.WorkspaceItem;import org.dspace.core.ConfigurationManager;import org.dspace.core.Context;import org.dspace.core.Utils;import org.dspace.eperson.EPerson;import org.dspace.storage.rdbms.DatabaseManager;import org.dspace.storage.rdbms.TableRow;import org.dspace.workflow.WorkflowItem;import com.hp.hpl.mesa.rdf.jena.mem.ModelMem;import com.hp.hpl.mesa.rdf.jena.model.Model;import com.hp.hpl.mesa.rdf.jena.model.Property;import com.hp.hpl.mesa.rdf.jena.model.RDFException;import com.hp.hpl.mesa.rdf.jena.model.Resource;/** * Records information about changes in DSpace. The information about changes is * written out in RDF format to one or more files in the directory given by the * configuration property <em>history.dir</em>. *  * @author Peter Breton * @version $Revision: 1.11 $ */public class HistoryManager{    // Action constants    public static final int NONE = 0;    public static final int CREATE = 1;    public static final int MODIFY = 2;    public static final int REMOVE = 3;    private static final String uriPrefixConfig = ConfigurationManager            .getProperty("history.uri.prefix");    /** URI prefix */    private static final String uriPrefix = (uriPrefixConfig != null) ? uriPrefixConfig            : "http://www.dspace.org";    /** Handle prefix */    private static String handlePrefix = ConfigurationManager            .getProperty("handle.prefix");    /** log4j category */    private static Logger log = Logger.getLogger(HistoryManager.class);    /** Directory for history serialization */    private static String historyDirectory = ConfigurationManager            .getProperty("history.dir");    // These settings control the way an identifier is hashed into    // directory and file names    // FIXME: This is basically stolen from the bitstore code, and thus    // could be factored out into a common location    private static int digitsPerLevel = 2;    private static int directoryLevels = 3;    /** Identifier for the generator */    private static final String ID = new StringBuffer().append(            HistoryManager.class.getName()).append(" ").append(            "$Revision: 1.11 $").toString();    /**     * Private Constructor     */    private HistoryManager()    {    }    /**     * Save history information about this object. Errors are simply logged.     *      * @param context     *            The current DSpace context     * @param obj     *            The object to record History information about     * @param flag     *            One of CREATE, MODIFY or REMOVE.     * @param user     *            The user who performed the action that is being recorded     * @param tool     *            A description of the tool that was used to effect the action.     */    public static void saveHistory(Context context, Object obj, int flag,            EPerson user, String tool)    {        try        {            createHarmonyData(context, obj, flag, user, tool);        }        catch (Exception e)        {            if (log.isDebugEnabled())            {                log.debug("Exception while saving history", e);            }        }    }    /**     * Create Harmony data which describes the event.     *      * @param context     *            The current DSpace context     * @param obj     *            The object to record History information about     * @param flag     *            One of CREATE, MODIFY or REMOVE.     * @param user     *            The user who performed the action that is being recorded     * @param tool     *            A description of the tool that was used to effect the action.     */    private static void createHarmonyData(Context context, Object historyObj,            int flag, EPerson theUser, String theTool) throws SQLException,            RDFException, IOException    {        String id = (flag == REMOVE) ? getUniqueId(historyObj) : doSerialize(                context, historyObj);        // Figure out the tool used        if (theTool == null)        {            theTool = getTool();        }        String eventId = getUniqueId(getShortName(historyObj), flag);        // Previous state (as far as History is concerned). It's possible,        // of course, that changes were made without telling History!        String inputStateId = (flag == CREATE) ? null : findPreviousState(id);        // Create a model        Model model = new ModelMem();        // A table row and id for the new state        Integer stateId = null;        TableRow row = null;        if (flag != REMOVE)        {            row = DatabaseManager.create(context, "HistoryState");            stateId = new Integer(row.getIntColumn("history_state_id"));        }        // This is the object that we're making statements about....        Resource obj = model.createResource(id);        // This is the event        Resource event = model.createResource(eventId);        //  States        Resource outputState = (flag == REMOVE) ? null : model                .createResource(stateId.toString());        Resource inputState = (flag == CREATE) ? null : model                .createResource(inputStateId);        //  FIXME The action (also typed??)        Resource action = model.createResource(getUniqueId("action", NONE));        //  The user        Resource user = (theUser != null) ? model                .createResource(getUniqueId(theUser)) : null;        // These verbs are essentially constant        Property atTime = model.createProperty(getHarmonyId("atTime"));        Property hasInput = model.createProperty(getHarmonyId("hasInput"));        Property hasOutput = model.createProperty(getHarmonyId("hasOutput"));        Property inState = model.createProperty(getHarmonyId("inState"));        //Property contains = model.createProperty(getHarmonyId("contains"));        Property hasAction = model.createProperty(getHarmonyId("hasAction"));        Property usesTool = model.createProperty(getHarmonyId("usesTool"));        Property hasAgent = model.createProperty(getHarmonyId("hasAgent"));        Property operation = null;        // Choose the correct operation        if (flag == CREATE)        {            operation = model.createProperty(getHarmonyId("creates"));        }        else if (flag == REMOVE)        {            operation = model.createProperty(getHarmonyId("destroys"));        }        else if (flag == MODIFY)        {            operation = model.createProperty(getHarmonyId("transforms"));        }        else        {            throw new IllegalArgumentException("Unknown value for flag: "                    + flag);        }        // Creation events do not have input states, but everything        // else does        if (flag != CREATE)        {            model.add(event, hasInput, inputState);        }        // Removal events do not have output states, nor is the object        // in a state upon completion        if (flag != REMOVE)        {            model.add(event, hasOutput, outputState);            model.add(obj, inState, outputState);            //model.add(outputState, contains, obj);        }        // Time that this event occurred        model.add(event, atTime, (new java.util.Date().toString()));        model.add(action, operation, obj);        model.add(event, hasAction, action);        model.add(action, usesTool, theTool);        if (theUser != null)        {            model.add(action, hasAgent, user);        }        else        {            model.add(action, hasAgent, model.createLiteral("Unknown User"));        }        //  FIXME Strictly speaking, this is NOT a property of the        //  object itself, but of the resulting serialization!        Property generatorId = model.createProperty(uriPrefix + "/generator");        model.add(event, generatorId, ID);        List dbobjs = new LinkedList();        if (flag != REMOVE)        {            row.setColumn("history_state_id", stateId.intValue());            row.setColumn("object_id", id);            DatabaseManager.update(context, row);        }        StringWriter swdata = new StringWriter();        model.write(swdata);        swdata.close();        String data = swdata.toString();        TableRow h = DatabaseManager.create(context, "History");        int hid = h.getIntColumn("history_id");        File file = forId(hid, true);        FileWriter fw = new FileWriter(file);        fw.write(data);        fw.close();        h.setColumn("creation_date", nowAsTimeStamp());        h.setColumn("checksum", Utils.getMD5(data));        DatabaseManager.update(context, h);    }    ////////////////////////////////////////    // Unique ids    ////////////////////////////////////////    /**     * Return a unique id for an object.     *      * @param obj     *            The object to return an id for     * @return A unique id for the object.     */    private static String getUniqueId(Object obj)    {        if (obj == null)        {            return null;        }        int id = -1;        //  FIXME This would be easier there were a ContentObject        //  interface/base class        if (obj instanceof Community)        {            id = ((Community) obj).getID();        }        else if (obj instanceof Collection)        {            id = ((Collection) obj).getID();        }        else if (obj instanceof Item)        {            id = ((Item) obj).getID();        }        else if (obj instanceof EPerson)        {            id = ((EPerson) obj).getID();        }        else if (obj instanceof WorkspaceItem)        {            id = ((WorkspaceItem) obj).getID();        }        else if (obj instanceof WorkflowItem)        {            id = ((WorkflowItem) obj).getID();        }        return getUniqueIdInternal(uriPrefix, handlePrefix, getShortName(obj),                Integer.toString(id));    }    /**     * Return a unique id corresponding to a Harmony object.     *      * @param name     *            The name of a Harmony object (action, event, etc)     * @param flag     *            One of CREATE, MODIFY, REMOVE     * @return A unique id     */    private static String getUniqueId(String name, int flag)    {        String objname = new StringBuffer("harmony").append("/").append(name)                .append((flag == CREATE) ? "create" : "").append(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -