1. opensymphony
  2. osworkflow

Commits

hani  committed bfcedb2

Initial import from SourceForge

  • Participants
  • Parent commits c1e5e63
  • Branches default

Comments (0)

Files changed (4)

File src/java/com/opensymphony/workflow/JoinNodes.java

View file
+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.workflow;
+
+import com.opensymphony.workflow.spi.Step;
+
+import java.util.*;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision: 1.1.1.1 $
+ */
+public class JoinNodes {
+    //~ Instance fields ////////////////////////////////////////////////////////
+
+    private Collection steps;
+    private DummyStep dummy = new DummyStep();
+
+    //~ Constructors ///////////////////////////////////////////////////////////
+
+    public JoinNodes(Collection steps) {
+        this.steps = steps;
+    }
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public Step getStep(int stepId) {
+        for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+            Step step = (Step) iterator.next();
+
+            if (step.getStepId() == stepId) {
+                return step;
+            }
+        }
+
+        // no match, not ready to join ...
+        // ... so return a dummy step that is always false
+        return dummy;
+    }
+
+    //~ Inner Classes //////////////////////////////////////////////////////////
+
+    public class DummyStep implements Step {
+        public int getActionId() {
+            return -1;
+        }
+
+        public String getCaller() {
+            return null;
+        }
+
+        public Date getDueDate() {
+            return null;
+        }
+
+        public long getEntryId() {
+            return -1;
+        }
+
+        public Date getFinishDate() {
+            return null;
+        }
+
+        public long getId() {
+            return -1;
+        }
+
+        public String getOwner() {
+            return null;
+        }
+
+        public long[] getPreviousStepIds() {
+            return new long[0];
+        }
+
+        public Date getStartDate() {
+            return null;
+        }
+
+        public String getStatus() {
+            return null;
+        }
+
+        public int getStepId() {
+            return -1;
+        }
+    }
+}

File src/java/com/opensymphony/workflow/spi/Step.java

View file
+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.workflow.spi;
+
+import java.util.Date;
+
+
+/**
+ * Interface for a step associated with a workflow instance.
+ *
+ * @author <a href="mailto:plightbo@hotmail.com">Pat Lightbody</a>
+ */
+public interface Step {
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns the ID of the action associated with this step,
+     * or 0 if there is no action associated.
+     */
+    public int getActionId();
+
+    public String getCaller();
+
+    /**
+     * Returns an optional date signifying when this step must be finished.
+     */
+    public Date getDueDate();
+
+    /**
+     * Returns the unique ID of the workflow entry.
+     */
+    public long getEntryId();
+
+    /**
+     * Returns the date this step was finished, or null if it isn't finished.
+     */
+    public Date getFinishDate();
+
+    /**
+     * Returns the unique ID of this step.
+     */
+    public long getId();
+
+    /**
+     * Returns the owner of this step, or null if there is no owner.
+     */
+    public String getOwner();
+
+    /**
+     * Returns the unique ID of the previous step, or 0 if this is the first step.
+     */
+    public long[] getPreviousStepIds();
+
+    /**
+     * Returns the date that this step was created.
+     */
+    public Date getStartDate();
+
+    /**
+     * Returns the status of this step.
+     */
+    public String getStatus();
+
+    /**
+     * Returns the ID of the step in the workflow definition.
+     */
+    public int getStepId();
+}

File src/java/com/opensymphony/workflow/spi/memory/MemoryWorkflowStore.java

View file
+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.workflow.spi.memory;
+
+import com.opensymphony.module.propertyset.*;
+
+import com.opensymphony.util.DataUtil;
+import com.opensymphony.util.TextUtils;
+
+import com.opensymphony.workflow.query.WorkflowQuery;
+import com.opensymphony.workflow.spi.*;
+
+import java.util.*;
+
+
+/**
+ * Simple memory implementation.
+ *
+ * @author <a href="mailto:plightbo@hotmail.com">Pat Lightbody</a>
+ */
+public class MemoryWorkflowStore implements WorkflowStore {
+    //~ Static fields/initializers /////////////////////////////////////////////
+
+    private static HashMap entryCache = new HashMap();
+    private static HashMap currentStepsCache = new HashMap();
+    private static HashMap historyStepsCache = new HashMap();
+    private static HashMap propertySetCache = new HashMap();
+    private static long globalEntryId = 1;
+    private static long globalStepId = 1;
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public PropertySet getPropertySet(long entryId) {
+        PropertySet ps = (PropertySet) propertySetCache.get(new Long(entryId));
+
+        if (ps == null) {
+            ps = PropertySetManager.getInstance("memory", null);
+            propertySetCache.put(new Long(entryId), ps);
+        }
+
+        return ps;
+    }
+
+    public Step createCurrentStep(long entryId, int stepId, String owner, Date startDate, Date dueDate, String status, long[] previousIds) {
+        long id = globalStepId++;
+        SimpleStep step = new SimpleStep(id, entryId, stepId, 0, owner, startDate, dueDate, null, status, previousIds, null);
+
+        List currentSteps = (List) currentStepsCache.get(new Long(entryId));
+
+        if (currentSteps == null) {
+            currentSteps = new ArrayList();
+            currentStepsCache.put(new Long(entryId), currentSteps);
+        }
+
+        currentSteps.add(step);
+
+        return step;
+    }
+
+    public WorkflowEntry createEntry(String workflowName) {
+        long id = globalEntryId++;
+        SimpleWorkflowEntry entry = new SimpleWorkflowEntry(id, workflowName, false);
+        entryCache.put(new Long(id), entry);
+
+        return entry;
+    }
+
+    public List findCurrentSteps(long entryId) {
+        List currentSteps = (List) currentStepsCache.get(new Long(entryId));
+
+        if (currentSteps == null) {
+            currentSteps = new ArrayList();
+            currentStepsCache.put(new Long(entryId), currentSteps);
+        }
+
+        return currentSteps;
+    }
+
+    public WorkflowEntry findEntry(long entryId) {
+        return (WorkflowEntry) entryCache.get(new Long(entryId));
+    }
+
+    public List findHistorySteps(long entryId) {
+        List historySteps = (List) historyStepsCache.get(new Long(entryId));
+
+        if (historySteps == null) {
+            historySteps = new ArrayList();
+            historyStepsCache.put(new Long(entryId), historySteps);
+        }
+
+        return historySteps;
+    }
+
+    public void init(Map props) {
+    }
+
+    public Step markFinished(Step step, int actionId, Date finishDate, String status, String caller) {
+        List currentSteps = (List) currentStepsCache.get(new Long(step.getEntryId()));
+
+        for (Iterator iterator = currentSteps.iterator(); iterator.hasNext();) {
+            SimpleStep theStep = (SimpleStep) iterator.next();
+
+            if (theStep.getId() == step.getId()) {
+                theStep.setStatus(status);
+                theStep.setActionId(actionId);
+                theStep.setFinishDate(finishDate);
+                theStep.setCaller(caller);
+
+                return theStep;
+            }
+        }
+
+        return null;
+    }
+
+    public void moveToHistory(Step step) {
+        List currentSteps = (List) currentStepsCache.get(new Long(step.getEntryId()));
+
+        List historySteps = (List) historyStepsCache.get(new Long(step.getEntryId()));
+
+        if (historySteps == null) {
+            historySteps = new ArrayList();
+            historyStepsCache.put(new Long(step.getEntryId()), historySteps);
+        }
+
+        SimpleStep simpleStep = (SimpleStep) step;
+
+        for (Iterator iterator = currentSteps.iterator(); iterator.hasNext();) {
+            Step currentStep = (Step) iterator.next();
+
+            if (simpleStep.getId() == currentStep.getId()) {
+                iterator.remove();
+                historySteps.add(simpleStep);
+
+                break;
+            }
+        }
+    }
+
+    public List query(WorkflowQuery query) {
+        ArrayList results = new ArrayList();
+
+        for (Iterator iterator = entryCache.entrySet().iterator();
+                iterator.hasNext();) {
+            Map.Entry mapEntry = (Map.Entry) iterator.next();
+            Long entryId = (Long) mapEntry.getKey();
+
+            if (query(entryId, query)) {
+                results.add(entryId);
+            }
+        }
+
+        return results;
+    }
+
+    private boolean query(Long entryId, WorkflowQuery query) {
+        if (query.getLeft() == null) {
+            return queryBasic(entryId, query);
+        } else {
+            int operator = query.getOperator();
+            WorkflowQuery left = query.getLeft();
+            WorkflowQuery right = query.getRight();
+
+            switch (operator) {
+            case WorkflowQuery.AND:
+                return query(entryId, left) && query(entryId, right);
+
+            case WorkflowQuery.OR:
+                return query(entryId, left) || query(entryId, right);
+
+            case WorkflowQuery.XOR:
+                return query(entryId, left) ^ query(entryId, right);
+            }
+        }
+
+        return false;
+    }
+
+    private boolean queryBasic(Long entryId, WorkflowQuery query) {
+        // the query object is a comparison
+        Object value = query.getValue();
+        int operator = query.getOperator();
+        int field = query.getField();
+        int type = query.getType();
+
+        switch (operator) {
+        case WorkflowQuery.EQUALS:
+            return queryEquals(entryId, field, type, value);
+
+        case WorkflowQuery.NOT_EQUALS:
+            return queryNotEquals(entryId, field, type, value);
+
+        case WorkflowQuery.GT:
+            return queryGreaterThan(entryId, field, type, value);
+
+        case WorkflowQuery.LT:
+            return queryLessThan(entryId, field, type, value);
+        }
+
+        return false;
+    }
+
+    private boolean queryEquals(Long entryId, int field, int type, Object value) {
+        List steps = null;
+
+        if (type == WorkflowQuery.CURRENT) {
+            steps = (List) currentStepsCache.get(entryId);
+        } else {
+            steps = (List) historyStepsCache.get(entryId);
+        }
+
+        switch (field) {
+        case WorkflowQuery.ACTION:
+
+            long actionId = DataUtil.getLong((Long) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getActionId() == actionId) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.CALLER:
+
+            String caller = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getCaller()).equals(caller)) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.FINISH_DATE:
+
+            Date finishDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (finishDate.equals(step.getFinishDate())) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.OWNER:
+
+            String owner = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getOwner()).equals(owner)) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.START_DATE:
+
+            Date startDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (startDate.equals(step.getStartDate())) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STEP:
+
+            int stepId = DataUtil.getInt((Integer) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (stepId == step.getStepId()) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STATUS:
+
+            String status = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getStatus()).equals(status)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        return false;
+    }
+
+    private boolean queryGreaterThan(Long entryId, int field, int type, Object value) {
+        List steps = null;
+
+        if (type == WorkflowQuery.CURRENT) {
+            steps = (List) currentStepsCache.get(entryId);
+        } else {
+            steps = (List) historyStepsCache.get(entryId);
+        }
+
+        switch (field) {
+        case WorkflowQuery.ACTION:
+
+            long actionId = DataUtil.getLong((Long) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getActionId() > actionId) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.CALLER:
+
+            String caller = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getCaller()).compareTo(caller) > 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.FINISH_DATE:
+
+            Date finishDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getFinishDate().compareTo(finishDate) > 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.OWNER:
+
+            String owner = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getOwner()).compareTo(owner) > 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.START_DATE:
+
+            Date startDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getStartDate().compareTo(startDate) > 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STEP:
+
+            int stepId = DataUtil.getInt((Integer) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getStepId() > stepId) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STATUS:
+
+            String status = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getStatus()).compareTo(status) > 0) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        return false;
+    }
+
+    private boolean queryLessThan(Long entryId, int field, int type, Object value) {
+        List steps = null;
+
+        if (type == WorkflowQuery.CURRENT) {
+            steps = (List) currentStepsCache.get(entryId);
+        } else {
+            steps = (List) historyStepsCache.get(entryId);
+        }
+
+        switch (field) {
+        case WorkflowQuery.ACTION:
+
+            long actionId = DataUtil.getLong((Long) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getActionId() < actionId) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.CALLER:
+
+            String caller = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getCaller()).compareTo(caller) < 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.FINISH_DATE:
+
+            Date finishDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getFinishDate().compareTo(finishDate) < 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.OWNER:
+
+            String owner = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getOwner()).compareTo(owner) < 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.START_DATE:
+
+            Date startDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getStartDate().compareTo(startDate) < 0) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STEP:
+
+            int stepId = DataUtil.getInt((Integer) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getStepId() < stepId) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STATUS:
+
+            String status = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (TextUtils.noNull(step.getStatus()).compareTo(status) < 0) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        return false;
+    }
+
+    private boolean queryNotEquals(Long entryId, int field, int type, Object value) {
+        List steps = null;
+
+        if (type == WorkflowQuery.CURRENT) {
+            steps = (List) currentStepsCache.get(entryId);
+        } else {
+            steps = (List) historyStepsCache.get(entryId);
+        }
+
+        switch (field) {
+        case WorkflowQuery.ACTION:
+
+            long actionId = DataUtil.getLong((Long) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (step.getActionId() != actionId) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.CALLER:
+
+            String caller = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (!TextUtils.noNull(step.getCaller()).equals(caller)) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.FINISH_DATE:
+
+            Date finishDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (!finishDate.equals(step.getFinishDate())) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.OWNER:
+
+            String owner = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (!TextUtils.noNull(step.getOwner()).equals(owner)) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.START_DATE:
+
+            Date startDate = (Date) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (!startDate.equals(step.getStartDate())) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STEP:
+
+            int stepId = DataUtil.getInt((Integer) value);
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (stepId != step.getStepId()) {
+                    return true;
+                }
+            }
+
+            return false;
+
+        case WorkflowQuery.STATUS:
+
+            String status = (String) value;
+
+            for (Iterator iterator = steps.iterator(); iterator.hasNext();) {
+                SimpleStep step = (SimpleStep) iterator.next();
+
+                if (!TextUtils.noNull(step.getStatus()).equals(status)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        return false;
+    }
+}

File src/java/com/opensymphony/workflow/spi/memory/SerializableWorkflowStore.java

View file
+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.workflow.spi.memory;
+
+import com.opensymphony.module.propertyset.PropertySet;
+import com.opensymphony.module.propertyset.PropertySetManager;
+
+import com.opensymphony.workflow.query.WorkflowQuery;
+import com.opensymphony.workflow.spi.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * Simple flat file implementation.
+ *
+ * Following properties are <b>required</b>:
+ * <ul>
+ * <li><b>storeFile</b> - the absolute path to the store file
+ (<i>ex:c:\workflow.store</i>)</li>
+ * </ul>
+ *
+ * @author <a href="mailto:gbort@msn.com">Guillaume Bort</a>
+ */
+public class SerializableWorkflowStore extends MemoryWorkflowStore {
+    //~ Static fields/initializers /////////////////////////////////////////////
+
+    protected static final Log log = LogFactory.getLog(SerializableWorkflowStore.class);
+    static String storeFile;
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public PropertySet getPropertySet(long entryId) {
+        PropertySet ps = (PropertySet) SerializableCache.getInstance().propertySetCache.get(new Long(entryId));
+
+        if (ps == null) {
+            ps = PropertySetManager.getInstance("serializable", null);
+            SerializableCache.getInstance().propertySetCache.put(new Long(entryId), ps);
+        }
+
+        return ps;
+    }
+
+    public Step createCurrentStep(long entryId, int stepId, String owner, Date startDate, Date dueDate, String status, long[] previousIds) {
+        long id = SerializableCache.getInstance().globalStepId++;
+        SimpleStep step = new SimpleStep(id, entryId, stepId, 0, owner, startDate, dueDate, null, status, previousIds, null);
+
+        List currentSteps = (List) SerializableCache.getInstance().currentStepsCache.get(new Long(entryId));
+
+        if (currentSteps == null) {
+            currentSteps = new ArrayList();
+            SerializableCache.getInstance().currentStepsCache.put(new Long(entryId), currentSteps);
+        }
+
+        currentSteps.add(step);
+        SerializableCache.getInstance().store();
+
+        return step;
+    }
+
+    public WorkflowEntry createEntry(String workflowName) {
+        long id = SerializableCache.getInstance().globalEntryId++;
+        SimpleWorkflowEntry entry = new SimpleWorkflowEntry(id, workflowName, false);
+        SerializableCache.getInstance().entryCache.put(new Long(id), entry);
+        SerializableCache.getInstance().store();
+
+        return entry;
+    }
+
+    public List findCurrentSteps(long entryId) {
+        List currentSteps = (List) SerializableCache.getInstance().currentStepsCache.get(new Long(entryId));
+
+        if (currentSteps == null) {
+            currentSteps = new ArrayList();
+            SerializableCache.getInstance().currentStepsCache.put(new Long(entryId), currentSteps);
+        }
+
+        return currentSteps;
+    }
+
+    public WorkflowEntry findEntry(long entryId) {
+        return (WorkflowEntry) SerializableCache.getInstance().entryCache.get(new Long(entryId));
+    }
+
+    public List findHistorySteps(long entryId) {
+        List historySteps = (List) SerializableCache.getInstance().historyStepsCache.get(new Long(entryId));
+
+        if (historySteps == null) {
+            historySteps = new ArrayList();
+            SerializableCache.getInstance().historyStepsCache.put(new Long(entryId), historySteps);
+        }
+
+        return historySteps;
+    }
+
+    public void init(Map props) {
+        storeFile = (String) props.get("storeFile");
+
+        // check whether the file denoted by the storeFile property is a normal file.
+        if (!new File(storeFile).isFile()) {
+            log.fatal("storePath property should indicate a normal file");
+        }
+
+        // check wheter the directory containing the storeFile exist
+        if (!new File(storeFile).getParentFile().exists()) {
+            log.fatal("directory " + new File(storeFile).getParent() + " not found");
+        }
+    }
+
+    public Step markFinished(Step step, int actionId, Date finishDate, String status, String caller) {
+        List currentSteps = (List) SerializableCache.getInstance().currentStepsCache.get(new Long(step.getEntryId()));
+
+        for (Iterator iterator = currentSteps.iterator(); iterator.hasNext();) {
+            SimpleStep theStep = (SimpleStep) iterator.next();
+
+            if (theStep.getId() == step.getId()) {
+                theStep.setStatus(status);
+                theStep.setActionId(actionId);
+                theStep.setFinishDate(finishDate);
+                theStep.setCaller(caller);
+
+                return theStep;
+            }
+        }
+
+        SerializableCache.getInstance().store();
+
+        return null;
+    }
+
+    public void moveToHistory(Step step) {
+        List currentSteps = (List) SerializableCache.getInstance().currentStepsCache.get(new Long(step.getEntryId()));
+
+        List historySteps = (List) SerializableCache.getInstance().historyStepsCache.get(new Long(step.getEntryId()));
+
+        if (historySteps == null) {
+            historySteps = new ArrayList();
+            SerializableCache.getInstance().historyStepsCache.put(new Long(step.getEntryId()), historySteps);
+        }
+
+        SimpleStep simpleStep = (SimpleStep) step;
+
+        for (Iterator iterator = currentSteps.iterator(); iterator.hasNext();) {
+            Step currentStep = (Step) iterator.next();
+
+            if (simpleStep.getId() == currentStep.getId()) {
+                iterator.remove();
+                historySteps.add(simpleStep);
+
+                break;
+            }
+        }
+
+        SerializableCache.getInstance().store();
+    }
+}
+
+
+class SerializableCache implements Serializable {
+    //~ Static fields/initializers /////////////////////////////////////////////
+
+    private static transient SerializableCache instance;
+
+    //~ Instance fields ////////////////////////////////////////////////////////
+
+    HashMap currentStepsCache;
+    HashMap entryCache;
+    HashMap historyStepsCache;
+    HashMap propertySetCache;
+    long globalEntryId = 1;
+    long globalStepId = 1;
+
+    //~ Constructors ///////////////////////////////////////////////////////////
+
+    private SerializableCache() {
+        entryCache = new HashMap();
+        currentStepsCache = new HashMap();
+        historyStepsCache = new HashMap();
+        propertySetCache = new HashMap();
+    }
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public List query(WorkflowQuery query) {
+        // not implemented
+        return Collections.EMPTY_LIST;
+    }
+
+    static SerializableCache getInstance() {
+        if (instance == null) {
+            instance = load();
+        }
+
+        return instance;
+    }
+
+    static SerializableCache load() {
+        try {
+            FileInputStream fis = new FileInputStream(new File(SerializableWorkflowStore.storeFile));
+            ObjectInputStream ois = new ObjectInputStream(fis);
+            SerializableCache o = (SerializableCache) ois.readObject();
+            fis.close();
+
+            return o;
+        } catch (Exception e) {
+            SerializableWorkflowStore.log.fatal("cannot store in file " + SerializableWorkflowStore.storeFile + ". Create a new blank store.");
+        }
+
+        return new SerializableCache();
+    }
+
+    static void store() {
+        try {
+            FileOutputStream fos = new FileOutputStream(new File(SerializableWorkflowStore.storeFile));
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+            oos.writeObject(getInstance());
+            fos.close();
+        } catch (Exception e) {
+            SerializableWorkflowStore.log.fatal("cannot store in file " + SerializableWorkflowStore.storeFile + ".");
+        }
+    }
+}