Anonymous avatar Anonymous committed 4dff80e

Support for persistance of the WF descriptor on relational DB using hibernate

Comments (0)

Files changed (2)

src/java/com/opensymphony/workflow/loader/SpringHibernateWorkflowFactory.java

+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+/*
+ * Created on 30-nov-2005
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package com.opensymphony.workflow.loader;
+
+import com.opensymphony.workflow.FactoryException;
+import com.opensymphony.workflow.InvalidWorkflowDescriptorException;
+
+import net.sf.hibernate.HibernateException;
+import net.sf.hibernate.Session;
+import net.sf.hibernate.SessionFactory;
+
+import org.springframework.dao.DataAccessException;
+
+import org.springframework.orm.hibernate.HibernateCallback;
+import org.springframework.orm.hibernate.HibernateTemplate;
+
+import java.sql.SQLException;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SpringHibernateWorkflowFactory extends AbstractWorkflowFactory {
+    //~ Static fields/initializers /////////////////////////////////////////////
+
+    private static boolean forceReload;
+
+    //~ Instance fields ////////////////////////////////////////////////////////
+
+    private Map workflows;
+    private SessionFactory sessionFactory;
+    private boolean reload = false;
+    private boolean validate = false;
+
+    //~ Constructors ///////////////////////////////////////////////////////////
+
+    public SpringHibernateWorkflowFactory() {
+        super();
+    }
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public void setLayout(String workflowName, Object layout) {
+    }
+
+    public Object getLayout(String workflowName) {
+        return null;
+    }
+
+    public boolean isModifiable(String name) {
+        return true;
+    }
+
+    public String getName() {
+        return "";
+    }
+
+    public void setReload(boolean reload) {
+        this.reload = reload;
+    }
+
+    public void setSessionFactory(SessionFactory sessionFactory) {
+        this.sessionFactory = sessionFactory;
+    }
+
+    public void setValidate(boolean validate) {
+        this.validate = validate;
+    }
+
+    public WorkflowDescriptor getWorkflow(String name, boolean validate) throws FactoryException {
+        if (!workflows.containsKey(name)) {
+            throw new FactoryException("Unknown workflow name \"" + name + '\"');
+        }
+
+        if (reload || forceReload) {
+            forceReload = false;
+            loadWorkflow(name, validate);
+        }
+
+        return (WorkflowDescriptor) workflows.get(name);
+    }
+
+    public String[] getWorkflowNames() throws FactoryException {
+        int i = 0;
+        String[] res = new String[workflows.keySet().size()];
+        Iterator it = workflows.keySet().iterator();
+
+        while (it.hasNext()) {
+            res[i++] = (String) it.next();
+        }
+
+        return res;
+    }
+
+    public void createWorkflow(String name) {
+    }
+
+    public static void forceReload() {
+        forceReload = true;
+    }
+
+    public void initDone() throws FactoryException {
+        try {
+            workflows = new HashMap();
+
+            List workflowNames = new HibernateTemplate(sessionFactory).find("select wfn.workflowName from WorkflowName wfn");
+
+            for (Iterator iter = workflowNames.iterator(); iter.hasNext();) {
+                String wfn = iter.next().toString();
+                loadWorkflow(wfn, validate);
+            }
+        } catch (Exception e) {
+            throw new FactoryException(e);
+        }
+    }
+
+    public boolean removeWorkflow(String name) throws FactoryException {
+        final HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
+        WorkflowName wfn = (WorkflowName) hibernateTemplate.load(WorkflowName.class, name);
+
+        if (wfn != null) {
+            hibernateTemplate.delete(wfn);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public void renameWorkflow(String oldName, String newName) {
+        final HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
+        WorkflowName wfn = (WorkflowName) hibernateTemplate.load(WorkflowName.class, oldName);
+        wfn.setWorkflowName(newName);
+    }
+
+    public void save() {
+    }
+
+    public boolean saveWorkflow(String name, WorkflowDescriptor descriptor, boolean replace) throws FactoryException {
+        WorkflowName wfn = new WorkflowName();
+        wfn.setWorkflowName(name);
+        wfn.setWorkflowDescriptor(descriptor);
+
+        final HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
+        hibernateTemplate.saveOrUpdate(wfn);
+
+        initDone();
+
+        return false;
+    }
+
+    private synchronized void loadWorkflow(final String workflowName, final boolean validate) throws FactoryException {
+        try {
+            new HibernateTemplate(sessionFactory).execute(new HibernateCallback() {
+                    public Object doInHibernate(Session session) throws HibernateException, SQLException {
+                        try {
+                            WorkflowName wfn = (WorkflowName) session.load(WorkflowName.class, workflowName);
+
+                            if (validate) {
+                                wfn.getWorkflowDescriptor().validate();
+                            }
+
+                            workflows.put(wfn.getWorkflowName(), wfn.getWorkflowDescriptor());
+
+                            return null;
+                        } catch (InvalidWorkflowDescriptorException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                });
+        } catch (Exception e) {
+            throw new FactoryException(e);
+        }
+    }
+}

src/java/com/opensymphony/workflow/loader/WorkflowDescriptor.hbm.xml

+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+	"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+	"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
+<!-- com.opensymphony.workflow.loader.ResultDescriptor already added -->
+<hibernate-mapping default-cascade="all">
+	<!-- com.opensymphony.workflow.loader.Workflows -->
+	<class name="com.opensymphony.workflow.loader.WorkflowName" >
+		<id name="workflowName" unsaved-value="any">
+			<generator class="assigned"/>
+		</id>
+		<many-to-one name="workflowDescriptor" cascade="save-update" />
+	</class>
+
+	<!-- com.opensymphony.workflow.loader.AbstractDescriptor root -->
+	<class name="com.opensymphony.workflow.loader.AbstractDescriptor" >
+		<id name="entityId" unsaved-value="0">
+			<generator class="native"/>
+		</id>
+		
+		<!-- discriminator column="class"/-->
+		<property name="id" column="id" />
+		<many-to-one name="parent" class="com.opensymphony.workflow.loader.AbstractDescriptor" cascade="none"/>
+		<!-- com.opensymphony.workflow.loader.ActionDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.ActionDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="view" column="viewProperty" />
+			<property name="name" column="name"/>
+			<property name="finish" column="finish"/>
+			<property name="autoExecute" column="autoExecute" />
+			<property name="common" column="common"/>
+			<many-to-one name="restriction" />
+			<many-to-one name="unconditionalResult"/>
+			<list name="conditionalResults" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentActionDescr"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ConditionalResultDescriptor" />					
+			</list>			
+			<list name="validators" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentActionDescr"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ValidatorDescriptor" />					
+			</list>			
+			<list name="postFunctions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentActionDescrPost"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.FunctionDescriptor" />					
+			</list>			
+			<list name="preFunctions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentActionDescrPre"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.FunctionDescriptor" />					
+			</list>						
+			<map name="metaAttributes" table="actionMetaAttributes" lazy="false" >
+				<key column="entityCode"/>
+				<index column="keyName" type ="string"/>
+				<element column="value" type="com.opensymphony.workflow.loader.NotNullStringType" length="4000"/>
+			</map>
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.ResultDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.ResultDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="owner" />
+			<property name="oldStatus" access="field"/>
+			<property name="displayName" access="field"/>
+			<property name="status"/>
+			<property name="split"/>
+			<property name="step" />
+			<property name="join" column="join_id" />
+			<list name="postFunctions" lazy="false" cascade="all-delete-orphan" access="field">
+				<key column="parentResultDescrPost"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.FunctionDescriptor" />					
+			</list>			
+			<list name="preFunctions" lazy="false" cascade="all-delete-orphan" access="field">
+				<key column="parentResultDescrPre"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.FunctionDescriptor" />					
+			</list>						
+			<!-- com.opensymphony.workflow.loader.ConditionalResultDescriptor -->
+			<joined-subclass name="com.opensymphony.workflow.loader.ConditionalResultDescriptor">
+				<key column="conditionalResultDescriptorId"/>
+				<list name="conditions" lazy="false" access="field" cascade="all-delete-orphan">
+					<key column="parentConditionalResultDesc"/>
+					<index column="listOrder"/>
+					<one-to-many class="com.opensymphony.workflow.loader.ConditionsDescriptor" />					
+				</list>
+			</joined-subclass>
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.ConditionDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.ConditionDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="name" column="name" />
+			<property name="type" column="type" />
+			<property name="negate" column="negate" />
+			<map name="args" table="conditionsargs" lazy="false" access="field">
+				<key column="entityCode"/>
+				<index column="name" type ="string"/>
+				<element column="value" type="com.opensymphony.workflow.loader.NotNullStringType" length="4000"/>
+			</map>			
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.ConditionsDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.ConditionsDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="type" column="type" />
+			
+			<list name="conditions" lazy="false" cascade="all-delete-orphan">
+				<key column="parentConditionsDescriptor"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.AbstractDescriptor" />					
+			</list>
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.FunctionDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.FunctionDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="name" column="name" />
+			<property name="type" column="type" />
+			<map name="args" table="functionsargs" lazy="false" access="field">
+				<key column="entityCode"/>
+				<index column="name" type ="string"/>
+				<element column="value" type="com.opensymphony.workflow.loader.NotNullStringType" length="4000"/>
+			</map>			
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.JoinDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.JoinDescriptor">
+			<key column="abstractDescriptorId"/>
+			<many-to-one name="result" column="result" class="com.opensymphony.workflow.loader.ResultDescriptor"/>
+			<list name="conditions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentJoinDescriptor"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ConditionsDescriptor" />					
+			</list>			
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.PermissionDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.PermissionDescriptor">
+			<key column="abstractDescriptorId"/>
+			<many-to-one name="restriction" class="com.opensymphony.workflow.loader.RestrictionDescriptor" />
+			<property name="name" column="name" />
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.RegisterDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.RegisterDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="type" column="type" />
+			<property name="variableName" column="variableName" />
+			<map name="args" table="registersargs" lazy="false" access="field">
+				<key column="entityCode"/>
+				<index column="name" type ="string"/>
+				<element column="value" type="com.opensymphony.workflow.loader.NotNullStringType" length="4000"/>
+			</map>			
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.RestrictionDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.RestrictionDescriptor">
+			<key column="abstractDescriptorId"/>
+			<list name="conditions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentRestrictionDescriptor"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ConditionsDescriptor" />					
+			</list>			
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.SplitDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.SplitDescriptor">
+			<key column="abstractDescriptorId"/>
+			<list name="results" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentSplitDescriptor"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ResultDescriptor" />					
+			</list>			
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.StepDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.StepDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="name" />
+			<property name="hasActions" access="field" />
+			<list name="actions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentStepDescriptor"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ActionDescriptor" />					
+			</list>			
+			<list name="permissions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentStepDescriptor"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.PermissionDescriptor" />					
+			</list>			
+			<list name="commonActions" table="commonactions2step" lazy="false" access="field">
+				<key column="parentStepDescriptor"/>
+				<index column="listOrder"/>
+				<element column="value" type="integer"/>
+			</list>			
+			<list name="postFunctions" lazy="false" cascade="all-delete-orphan">
+				<key column="parentStepDescriptorPost"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.FunctionDescriptor" />					
+			</list>			
+			<list name="preFunctions" lazy="false" cascade="all-delete-orphan">
+				<key column="parentStepDescriptorPre"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.FunctionDescriptor" />					
+			</list>			
+			<map name="metaAttributes" table="stepMetaAttributes" lazy="false" >
+				<key column="entityCode"/>
+				<index column="keyName" type ="string"/>
+				<element column="value" type="com.opensymphony.workflow.loader.NotNullStringType" length="4000"/>
+			</map>
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.ValidatorDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.ValidatorDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="name" column="name" />
+			<property name="type" column="type" />
+			<map name="args" table="validatorsargs" lazy="false" access="field">
+				<key column="entityCode"/>
+				<index column="name" type ="string"/>
+				<element column="value" type="com.opensymphony.workflow.loader.NotNullStringType" length="4000"/>
+			</map>			
+		</joined-subclass>
+		<!-- com.opensymphony.workflow.loader.WorkflowDescriptor -->
+		<joined-subclass name="com.opensymphony.workflow.loader.WorkflowDescriptor">
+			<key column="abstractDescriptorId"/>
+			<property name="name" />
+			<many-to-one name="globalConditions" class="com.opensymphony.workflow.loader.ConditionsDescriptor" access="field"/>
+			<list name="commonActionsList" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescrCommonList"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ActionDescriptor" />					
+			</list>			
+			<list name="globalActions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescGlobal"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ActionDescriptor" />					
+			</list>			
+			<list name="initialActions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescrInitial"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ActionDescriptor" />					
+			</list>			
+			<list name="joins" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescr"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.JoinDescriptor" />					
+			</list>			
+			<list name="registers" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescr"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.RegisterDescriptor" />
+			</list>			
+			<list name="splits" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescr"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.SplitDescriptor" />					
+			</list>			
+			<list name="steps" lazy="false" outer-join="true" batch-size="10" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescr"/>
+				<index column="listOrder"/>
+				<one-to-many class="com.opensymphony.workflow.loader.StepDescriptor" />					
+			</list>			
+			<map name="commonActions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescrCommonMap"/>
+				<index column="id" type="integer"/>
+				<one-to-many class="com.opensymphony.workflow.loader.ActionDescriptor" />					
+			</map>			
+			<map name="metaAttributes" table="workflowMetaAttributes" lazy="false" access="field">
+				<key column="entityCode"/>
+				<index column="keyName" type ="string"/>
+				<element column="value" type="com.opensymphony.workflow.loader.NotNullStringType" length="4000"/>
+			</map>
+			<map name="timerFunctions" lazy="false" access="field" cascade="all-delete-orphan">
+				<key column="parentWorkflowDescr"/>
+				<index column="id" type="integer"/>
+				<one-to-many class="com.opensymphony.workflow.loader.FunctionDescriptor" />					
+			</map>						
+		</joined-subclass>
+	</class>
+</hibernate-mapping>
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.