KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > infoglue > cms > util > workflow > WorkflowFacade


1 /* ===============================================================================
2 *
3 * Part of the InfoGlue Content Management Platform (www.infoglue.org)
4 *
5 * ===============================================================================
6 *
7 * Copyright (C)
8 *
9 * This program is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License version 2, as published by the
11 * Free Software Foundation. See the file LICENSE.html for more information.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
19 * Place, Suite 330 / Boston, MA 02111-1307 / USA.
20 *
21 * ===============================================================================
22 */

23
24 package org.infoglue.cms.util.workflow;
25
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Set JavaDoc;
34
35 import net.sf.hibernate.HibernateException;
36 import net.sf.hibernate.SessionFactory;
37 import net.sf.hibernate.cfg.Configuration;
38
39 import org.apache.log4j.Logger;
40 import org.infoglue.cms.entities.mydesktop.WorkflowActionVO;
41 import org.infoglue.cms.entities.mydesktop.WorkflowStepVO;
42 import org.infoglue.cms.entities.mydesktop.WorkflowVO;
43 import org.infoglue.cms.exception.SystemException;
44 import org.infoglue.cms.security.InfoGluePrincipal;
45 import org.infoglue.deliver.util.CacheController;
46
47 import com.opensymphony.module.propertyset.PropertySet;
48 import com.opensymphony.workflow.AbstractWorkflow;
49 import com.opensymphony.workflow.InvalidActionException;
50 import com.opensymphony.workflow.WorkflowException;
51 import com.opensymphony.workflow.basic.BasicWorkflow;
52 import com.opensymphony.workflow.loader.ActionDescriptor;
53 import com.opensymphony.workflow.loader.StepDescriptor;
54 import com.opensymphony.workflow.loader.WorkflowDescriptor;
55 import com.opensymphony.workflow.query.Expression;
56 import com.opensymphony.workflow.query.FieldExpression;
57 import com.opensymphony.workflow.query.NestedExpression;
58 import com.opensymphony.workflow.query.WorkflowExpressionQuery;
59 import com.opensymphony.workflow.spi.Step;
60 import com.opensymphony.workflow.spi.WorkflowEntry;
61
62 /**
63  * A facade to OSWorkflow that gives us a place to cache workflow data as we need it while interacting with it.
64  * This class has kind of a strange interface due to the idiosyncracies of the OSWorkflow, particularly
65  * the Workflow interface. The idea is to encapsulate the interactions with OSWorkflow and eliminate the
66  * need to pass a Workflow reference and the workflow ID all over the place when extracting data from OSWorkflow
67  * @author <a HREF="mailto:jedprentice@gmail.com">Jed Prentice</a>
68  * @version $Revision: 1.32 $ $Date: 2006/09/22 12:15:30 $
69  */

70 public class WorkflowFacade
71 {
72     /**
73      * If the following attribute is specified in the workflow meta attributes,
74      * The title will be fetch from the propertyset associated with the workflow, using the meta value as a key.
75      */

76     private static final String JavaDoc WORKFLOW_TITLE_EXTENSION_META_ATTRIBUTE = "org.infoglue.title";
77     
78     /**
79      * If the following attribute is specified in the workflow meta attributes,
80      * then all actions will have access to a DatabaseSession instance controlled by this class.
81      */

82     private static final String JavaDoc WORKFLOW_DATABASE_EXTENSION_META_ATTRIBUTE = "org.infoglue.database";
83     
84     
85     private final static Logger logger = Logger.getLogger(WorkflowFacade.class.getName());
86
87     private static SessionFactory hibernateSessionFactory;
88
89     static
90     {
91         try
92         {
93             hibernateSessionFactory = new Configuration().configure().buildSessionFactory();
94         }
95         catch (HibernateException e)
96         {
97             e.printStackTrace();
98             throw new ExceptionInInitializerError JavaDoc(e);
99         }
100     }
101     
102     /**
103      * Keep track of the workflows that is currently executing.
104      */

105     private static final Collection JavaDoc currentWorkflows = new ArrayList JavaDoc();
106
107     private final AbstractWorkflow workflow;
108     private long workflowId;
109
110     private WorkflowDescriptor workflowDescriptor;
111
112     /**
113      * Constructs a WorkflowFacade with the given owner.
114      *
115      * @param owner the owner of the workflow.
116      */

117     public WorkflowFacade(final Owner owner)
118     {
119         workflow = new InfoGlueBasicWorkflow(owner.getIdentifier());
120         //workflow = new BasicWorkflow(owner.getIdentifier());
121
workflow.getConfiguration().getPersistenceArgs().put("sessionFactory", hibernateSessionFactory);
122     }
123     
124     /**
125      * Constructs a WorkflowFacade with the given user principal
126      * @param userPrincipal an InfoGluePrincipal representing a system user
127      */

128     public WorkflowFacade(InfoGluePrincipal userPrincipal)
129     {
130         this(OwnerFactory.create(userPrincipal));
131     }
132
133     /**
134      * Constructs a WorkflowFacade with the given user principal representing an initialized instance of the workflow
135      * with the given name. "Initialized" in this context means that the initial action has been executed and we have
136      * the workflow ID.
137      * @param userPrincipal an InfoGluePrincipal representing a system user
138      * @param name the name of the workflow to create
139      * @param initialAction the ID of the initial action to perform to get the workflow started.
140      */

141     public WorkflowFacade(InfoGluePrincipal userPrincipal, String JavaDoc name, int initialAction) throws SystemException
142     {
143         this(userPrincipal, name, initialAction, new HashMap JavaDoc());
144     }
145
146     /**
147      * Constructs a WorkflowFacade with the given user principal representing an initialized instance of the workflow
148      * with the given name. "Initialized" in this context means that the initial action has been executed and we have
149      * the workflow ID.
150      * @param userPrincipal an InfoGluePrincipal representing a system user
151      * @param name the name of the workflow to create
152      * @param initialAction the ID of the initial action to perform to get the workflow started.
153      * @param inputs a map of inputs to use to initialize the workflow.
154      */

155     public WorkflowFacade(InfoGluePrincipal userPrincipal, String JavaDoc name, int initialAction, Map JavaDoc inputs) throws SystemException
156     {
157         this(userPrincipal);
158         initialize(name, initialAction, inputs);
159     }
160
161     /**
162      * Constructs a WorkflowFacade for a user with the given workflow ID.
163      * @param userPrincipal an InfoGluePrincipal representing a system user
164      * @param workflowId the ID representing an instance of the desired workflow
165      */

166     public WorkflowFacade(InfoGluePrincipal userPrincipal, long workflowId)
167     {
168         this(userPrincipal);
169         setWorkflowIdAndDescriptor(workflowId);
170     }
171
172     /**
173      * Sets the workflow ID to the given value, and caches the associated workflow descriptor
174      * @param workflowId the desired workflow ID
175      */

176     private void setWorkflowIdAndDescriptor(long workflowId)
177     {
178         this.workflowId = workflowId;
179         String JavaDoc key = "workflowName_" + workflowId;
180         String JavaDoc workflowName = (String JavaDoc)CacheController.getCachedObject("workflowNameCache", key);
181         if(workflowName == null)
182         {
183             workflowName = workflow.getWorkflowName(workflowId);
184             CacheController.cacheObject("workflowNameCache", key, workflowName);
185         }
186             
187         workflowDescriptor = workflow.getWorkflowDescriptor(workflowName);
188     }
189
190     /**
191      * Returns the workflow ID
192      * @return the workflow ID
193      */

194     public long getWorkflowId()
195     {
196         return workflowId;
197     }
198
199     /**
200      * Initializes the workflow, setting workflowId as a side-effect.
201      * @param name the name of the workflow to initialize
202      * @param initialAction the ID of the initial action to perform to get the workflow started.
203      * @param inputs a map of inputs to use to initialize the workflow.
204      * @throws SystemException if a workflow error occurs.
205      */

206     private void initialize(String JavaDoc name, int initialAction, Map JavaDoc inputs) throws SystemException
207     {
208         try
209         {
210             if(useDatabaseExtension(workflow.getWorkflowDescriptor(name)))
211             {
212                 setWorkflowIdAndDescriptor(doExtendedInitialize(name, initialAction, inputs));
213             }
214             else
215             {
216                 setWorkflowIdAndDescriptor(workflow.initialize(name, initialAction, inputs));
217             }
218         }
219         catch (Exception JavaDoc e)
220         {
221             throw new SystemException(e);
222         }
223     }
224
225     /**
226      * Initializes the workflow.
227      * A <code>DatabaseSession</code> object whose lifecycle is handled by this method is inserted into the <code>inputs</code>.
228      *
229      * @param name the name of the workflow to initialize
230      * @param initialAction the ID of the initial action to perform to get the workflow started.
231      * @param inputs a map of inputs to use to initialize the workflow.
232      * @throws SystemException if a workflow error occurs.
233      */

234     private long doExtendedInitialize(final String JavaDoc name, final int initialAction, final Map JavaDoc inputs) throws WorkflowException
235     {
236         long result = 0;
237         final DatabaseSession db = new DatabaseSession();
238         try
239         {
240             final Map JavaDoc copy = new HashMap JavaDoc();
241             copy.putAll(inputs);
242             copy.put(workflow.getWorkflowDescriptor(name).getMetaAttributes().get(WORKFLOW_DATABASE_EXTENSION_META_ATTRIBUTE), db);
243             result = workflow.initialize(name, initialAction, copy);
244         }
245         catch(Exception JavaDoc e)
246         {
247             e.printStackTrace();
248             if(db != null)
249             {
250                 db.setRollbackOnly();
251             }
252             throw (e instanceof WorkflowException) ? (WorkflowException) e : new WorkflowException(e);
253         }
254         finally
255         {
256             db.releaseDB();
257         }
258         return result;
259     }
260     
261     /**
262      * Performs an action using the given inputs
263      * @param actionId the ID of the action to perform
264      * @param inputs a map of inputs to the action
265      * @throws WorkflowException if a workflow error occurs, or if the underlying workflow is not active
266      */

267     public void doAction(int actionId, Map JavaDoc inputs) throws WorkflowException
268     {
269         final Long JavaDoc id = new Long JavaDoc(workflowId);
270         synchronized(currentWorkflows)
271         {
272             if(!isActive())
273             {
274                 throw new InvalidActionException("Workflow " + workflowId + " is no longer active");
275             }
276             if(currentWorkflows.contains(id))
277             {
278                 throw new WorkflowException("The selected workflow is executing...");
279             }
280             currentWorkflows.add(id);
281         }
282         
283         try
284         {
285             if(useDatabaseExtension(workflowDescriptor))
286             {
287                 doExtendedAction(actionId, inputs);
288             }
289             else
290             {
291                 workflow.doAction(workflowId, actionId, inputs);
292             }
293         }
294         finally
295         {
296             synchronized(currentWorkflows)
297             {
298                 currentWorkflows.remove(id);
299             }
300         }
301     }
302
303     /**
304      * Performs an action using the given inputs.
305      * A <code>DatabaseSession</code> object whose lifecycle is handled by this method is inserted into the <code>inputs</code>.
306      *
307      * @param actionId the ID of the action to perform
308      * @param inputs a map of inputs to the action
309      * @throws WorkflowException if a workflow error occurs, or if the underlying workflow is not active
310      */

311     private void doExtendedAction(final int actionId, final Map JavaDoc inputs) throws WorkflowException
312     {
313         final DatabaseSession db = new DatabaseSession();
314         try
315         {
316             final Map JavaDoc copy = new HashMap JavaDoc();
317             copy.putAll(inputs);
318             copy.put(workflowDescriptor.getMetaAttributes().get(WORKFLOW_DATABASE_EXTENSION_META_ATTRIBUTE), db);
319             workflow.doAction(workflowId, actionId, copy);
320         }
321         catch(Exception JavaDoc e)
322         {
323             e.printStackTrace();
324             if(db != null)
325             {
326                 db.setRollbackOnly();
327             }
328             throw (e instanceof WorkflowException) ? (WorkflowException) e : new WorkflowException(e);
329         }
330         finally
331         {
332             db.releaseDB();
333         }
334     }
335
336     /**
337      * Returns the property set associated with the underlying workflow
338      * @return the property set associated with the underlying workflow
339      */

340     public PropertySet getPropertySet()
341     {
342         return workflow.getPropertySet(workflowId);
343     }
344
345     /**
346      * Returns the state of the underlying workflow entry
347      * @return the state of the underlying workflow entry
348      */

349     private int getEntryState()
350     {
351         return workflow.getEntryState(workflowId);
352     }
353
354     /**
355      * Indicates whether the underlying workflow is active.
356      *
357      * @return true if the underlying workflow's state is WorkflowEntry.ACTIVATED, otherwise returns false.
358      */

359     public boolean isActive()
360     {
361         return getEntryState() == WorkflowEntry.ACTIVATED;
362     }
363
364     /**
365      * Indicates whether the underlying workflow is finished.
366      *
367      * @return true if the underlying workflow's state is WorkflowEntry.KILLED or WorkflowEntry.COMPLETED, otherwise returns false.
368      */

369     public boolean isFinished()
370     {
371         int state = getEntryState();
372         return state == WorkflowEntry.KILLED || state == WorkflowEntry.COMPLETED;
373     }
374     
375     /**
376      * Returns a list of all declared workflows, i.e., workflows defined in workflows.xml
377      * @return a list WorkflowVOs representing all declared workflows
378      */

379     public List JavaDoc getDeclaredWorkflows()
380     {
381         String JavaDoc[] workflowNames = workflow.getWorkflowNames();
382         List JavaDoc availableWorkflows = new ArrayList JavaDoc();
383
384         for (int i = 0; i < workflowNames.length; i++)
385         {
386             try
387             {
388                 availableWorkflows.add(createWorkflowVO(workflowNames[i]));
389             }
390             catch(Exception JavaDoc e)
391             {
392                 logger.error("The workflow " + workflowNames[i] + " could not be instantiated:" + e.getMessage(), e);
393             }
394         }
395         
396         return availableWorkflows;
397     }
398
399     /**
400      * Returns a list of all active workflows.
401      *
402      * @return a list of WorkflowVOs representing all active workflows
403      * @throws SystemException if an error occurs finding the active workflows
404      */

405     public List JavaDoc getActiveWorkflows() throws SystemException
406     {
407         List JavaDoc workflowVOs = new ArrayList JavaDoc();
408
409         for (Iterator JavaDoc workflows = findActiveWorkflows().iterator(); workflows.hasNext();)
410         {
411             setWorkflowIdAndDescriptor(((Long JavaDoc)workflows.next()).longValue());
412             logger.info("workflowId:" + workflowId);
413             workflowVOs.add(createWorkflowVO());
414         }
415
416         return workflowVOs;
417     }
418     
419     /**
420      * Returns a list of workflows owned by the specified principal. If the principal is
421      * an administrator, all active workflows are returned.
422      *
423      * @param principal the principal.
424      * @return the workflows owned by the specified principal.
425      */

426     
427     public List JavaDoc getMyActiveWorkflows(final InfoGluePrincipal principal) throws SystemException
428     {
429         String JavaDoc key = "myWorkflows_" + principal.getName();
430         List JavaDoc workflows = (List JavaDoc)CacheController.getCachedObject("myActiveWorkflows", key);
431         if(workflows == null)
432         {
433             if(principal.getIsAdministrator())
434             {
435                 workflows = getActiveWorkflows();
436             }
437             
438             Collection JavaDoc owners = OwnerFactory.createAll(principal);
439             Expression[] expressions = new Expression[owners.size()];
440             
441             Iterator JavaDoc ownersIterator = owners.iterator();
442             int i = 0;
443             while(ownersIterator.hasNext())
444             {
445                 Owner owner = (Owner)ownersIterator.next();
446                 Expression expression = new FieldExpression(FieldExpression.OWNER, FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, owner.getIdentifier());
447                 expressions[i] = expression;
448                 i++;
449             }
450             
451             final Set JavaDoc workflowVOs = new HashSet JavaDoc();
452             workflowVOs.addAll(createWorkflowsForOwner(expressions));
453
454             /*
455             final Set workflowVOs = new HashSet();
456             for(final Iterator owners = OwnerFactory.createAll(principal).iterator(); owners.hasNext(); )
457             {
458                 final Owner owner = (Owner) owners.next();
459                 workflowVOs.addAll(createWorkflowsForOwner(owner));
460             }
461             */

462             
463             workflows = new ArrayList JavaDoc(workflowVOs);
464             CacheController.cacheObject("myActiveWorkflows", key, workflows);
465         }
466         
467         return workflows;
468     }
469     
470     /**
471      * Creates value object for all workflows having the specified owner.
472      *
473      * @param owner the owner.
474      * @return the value objects.
475      * @throws SystemException if an error occurs when creating the value objects.
476      */

477     private final Set JavaDoc createWorkflowsForOwner(final Owner owner) throws SystemException
478     {
479         final Set JavaDoc workflowVOs = new HashSet JavaDoc();
480         List JavaDoc workflows = findWorkflows(owner);
481         Iterator JavaDoc workflowsIterator = workflows.iterator();
482         while (workflowsIterator.hasNext())
483         {
484             setWorkflowIdAndDescriptor(((Long JavaDoc)workflowsIterator.next()).longValue());
485             workflowVOs.add(createWorkflowVO());
486         }
487         return workflowVOs;
488     }
489
490     /**
491      * Creates value object for all workflows having the specified owner.
492      *
493      * @param owner the owner.
494      * @return the value objects.
495      * @throws SystemException if an error occurs when creating the value objects.
496      */

497     private final Set JavaDoc createWorkflowsForOwner(final Expression[] expressions) throws SystemException
498     {
499         final Set JavaDoc workflowVOs = new HashSet JavaDoc();
500         List JavaDoc workflows = findWorkflows(expressions);
501         Iterator JavaDoc workflowsIterator = workflows.iterator();
502         while (workflowsIterator.hasNext())
503         {
504             setWorkflowIdAndDescriptor(((Long JavaDoc)workflowsIterator.next()).longValue());
505             workflowVOs.add(createWorkflowVO());
506         }
507         return workflowVOs;
508     }
509
510     /**
511      * Finds all active workflows
512      * @return A list of workflowIds representing workflows that match the hard-wored query expression.
513      * @throws SystemException if a workflow error occurs during the search
514      */

515     private List JavaDoc findActiveWorkflows() throws SystemException
516     {
517         try
518         {
519             return workflow.query(new WorkflowExpressionQuery(new FieldExpression(FieldExpression.STATE,
520                         FieldExpression.ENTRY, FieldExpression.EQUALS, new Integer JavaDoc(WorkflowEntry.ACTIVATED))));
521         }
522         catch (WorkflowException e)
523         {
524             throw new SystemException(e);
525         }
526     }
527
528     /**
529      * Finds all workflows for the specified owner.
530      *
531      * @param owner the owner.
532      * @return The active workflows owned by the specified owner.
533      * @throws SystemException
534      */

535     private List JavaDoc findWorkflows(final Owner owner) throws SystemException
536     {
537         try
538         {
539             List JavaDoc workflows = workflow.query(new WorkflowExpressionQuery(new FieldExpression(FieldExpression.OWNER,
540                     FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, owner.getIdentifier())));
541
542             return workflows;
543         }
544         catch (WorkflowException e)
545         {
546             throw new SystemException(e);
547         }
548     }
549
550     /**
551      * Finds all workflows for the specified owner.
552      *
553      * @param owner the owner.
554      * @return The active workflows owned by the specified owner.
555      * @throws SystemException
556      */

557     private List JavaDoc findWorkflows(final Expression[] expressions) throws SystemException
558     {
559         try
560         {
561             List JavaDoc workflows = workflow.query(new WorkflowExpressionQuery(new NestedExpression(expressions, NestedExpression.OR)));
562
563             //List workflows = workflow.query(new WorkflowExpressionQuery(new FieldExpression(FieldExpression.OWNER, FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, owner.getIdentifier())));
564
return workflows;
565         }
566         catch (WorkflowException e)
567         {
568             throw new SystemException(e);
569         }
570     }
571
572     /**
573      * Returns all current steps for the workflow, i.e., steps that could be performed in the workflow's current state
574      * Steps are filtered according to ownership; if a step has an owner, it is only included if the ownser matches
575      * the caller or if the current user is an administrator.
576      * @return a list of WorkflowStepVOs representing the current steps of the workflow with workflowId
577      */

578     public List JavaDoc getCurrentSteps()
579     {
580         return getCurrentSteps(null);
581     }
582     
583     public List JavaDoc getCurrentSteps(final WorkflowVO workflowVO)
584     {
585         return createStepVOs(workflowVO, workflow.getCurrentSteps(workflowId));
586     }
587
588     /**
589      * Returns all history steps for the workflow, i.e., all the steps that have already been performed.
590      * @return a list of WorkflowStepVOs representing all history steps for the workflow with workflowId
591      */

592     public List JavaDoc getHistorySteps()
593     {
594         return getHistorySteps(null);
595     }
596     
597     public List JavaDoc getHistorySteps(final WorkflowVO workflowVO)
598     {
599         return createStepVOs(workflowVO, workflow.getHistorySteps(workflowId));
600     }
601
602     /**
603      * Returns all steps for a workflow definition. These are the steps declared in the workfow descriptor; there is
604      * no knowledge of current or history steps at this point.
605      * @return a list of WorkflowStepVOs representing all steps in the workflow.
606      */

607     public List JavaDoc getDeclaredSteps()
608     {
609         return getDeclaredSteps(workflowDescriptor);
610     }
611
612     /**
613      * Creates a list of WorkflowStepVOs from the given list of steps
614      * @param steps a list of Steps
615      * @return a list of WorkflowStepVOs corresponding to all steps that pass the filter
616      */

617     private List JavaDoc createStepVOs(final WorkflowVO workflowVO, final List JavaDoc steps)
618     {
619         List JavaDoc stepVOs = new ArrayList JavaDoc();
620         for (Iterator JavaDoc i = steps.iterator(); i.hasNext();)
621         {
622             Step step = null;
623             try
624             {
625                 step = (Step)i.next();
626                 stepVOs.add(createStepVO(workflowVO, step));
627             }
628             catch(Exception JavaDoc e)
629             {
630                 logger.warn("There was an invalid step:" + workflowVO, e);
631             }
632         }
633         
634         return stepVOs;
635     }
636
637     /**
638      * Returns all steps for a workflow definition. These are the steps declared in the workfow descriptor; there is
639      * no knowledge of current or history steps at this point.
640      * @param descriptor a workflow descriptor from which to get current steps
641      * @return a list of WorkflowStepVOs representing all steps in the workflow.
642      */

643     private List JavaDoc getDeclaredSteps(WorkflowDescriptor descriptor)
644     {
645         List JavaDoc steps = new ArrayList JavaDoc();
646         for (Iterator JavaDoc i = descriptor.getSteps().iterator(); i.hasNext();)
647             steps.add(createStepVO((StepDescriptor)i.next()));
648
649         return steps;
650     }
651
652     /**
653      * Returns a list of initial actions for the workflow
654      * @return a list of WorkflowActionVOs representing the global actions for the workflow with workflowId
655      */

656     private List JavaDoc getInitialActions()
657     {
658         return createActionVOs(workflowDescriptor.getInitialActions());
659     }
660
661     /**
662      * Returns a list of global actions for the workflow
663      * @return a list of WorkflowActionVOs representing the global actions for the workflow with workflowId
664      */

665     private List JavaDoc getGlobalActions()
666     {
667         return createActionVOs(workflowDescriptor.getGlobalActions());
668     }
669
670     /**
671      * Creates a list of WorkflowActionVOs from a list of action descriptors
672      * @param actionDescriptors a list of ActionDescriptors
673      * @return a list of WorkflowActionVOs representing actionDescriptors
674      */

675     private List JavaDoc createActionVOs(List JavaDoc actionDescriptors)
676     {
677         List JavaDoc actions = new ArrayList JavaDoc();
678         for (Iterator JavaDoc i = actionDescriptors.iterator(); i.hasNext();)
679             actions.add(createActionVO((ActionDescriptor)i.next()));
680
681         return actions;
682
683     }
684
685     /**
686      * Creates a new WorkflowVO. This represents a pretty complete workflow; you get all the current steps, history
687      * steps, available actions, and global actions.
688      * @return a WorkflowVO representing workflow, with workflowId
689      */

690     public WorkflowVO createWorkflowVO()
691     {
692         WorkflowVO workflowVO = new WorkflowVO(new Long JavaDoc(workflowId), workflow.getWorkflowName(workflowId));
693         if(workflowDescriptor != null)
694         {
695             if(useTitleExtension(workflowDescriptor))
696                 workflowVO.setTitle(getWorkflowTitle());
697         }
698         
699         workflowVO.setCurrentSteps(getCurrentSteps(workflowVO));
700         workflowVO.setHistorySteps(getHistorySteps(workflowVO));
701         workflowVO.setInitialActions(getInitialActions());
702         workflowVO.setGlobalActions(getGlobalActions());
703
704         return workflowVO;
705     }
706
707     /**
708      * Returns the title of the workflow instance.
709      *
710      * @return the title of the workflow instance.
711      */

712     private String JavaDoc getWorkflowTitle()
713     {
714         if(!workflowDescriptor.getMetaAttributes().containsKey(WORKFLOW_TITLE_EXTENSION_META_ATTRIBUTE))
715         {
716             return null;
717         }
718         
719         final String JavaDoc key = (String JavaDoc) workflowDescriptor.getMetaAttributes().get(WORKFLOW_TITLE_EXTENSION_META_ATTRIBUTE);
720         final PropertySet ps = getPropertySet();
721         return ps.exists(key) ? ps.getString(key) : null;
722     }
723     
724     /**
725      * Creates a new WorkflowVO from workflow with the given name. The resulting workflow VO contains only a
726      * minimal amount of data because we don't have the workflow ID. Basically all you get is all the steps.
727      * @param name the name of the desired workflow
728      * @return a new WorkflowVO representing workflow
729      */

730     private WorkflowVO createWorkflowVO(String JavaDoc name)
731     {
732         WorkflowVO workflowVO = new WorkflowVO(null, name);
733         try
734         {
735             workflowVO.setDeclaredSteps(getDeclaredSteps(workflow.getWorkflowDescriptor(name)));
736         }
737         catch(Exception JavaDoc e)
738         {
739             workflowVO.setStatus(WorkflowVO.STATUS_NOT_OK);
740             workflowVO.setStatusMessage("Error in workflow:" + e.getMessage());
741             
742             logger.error("Could not read workflow:" + e.getMessage(), e);
743         }
744         
745         return workflowVO;
746     }
747
748     /**
749      * Creates a WorkflowStepVO from the given step
750      * @param step the desired step
751      * @return a new WorkflowStepVO representing step.
752      */

753     private WorkflowStepVO createStepVO(final WorkflowVO workflowVO, final Step step) throws Exception JavaDoc
754     {
755         logger.info("step:" + step + ':' + step.getId());
756         logger.info("Owner:" + step.getOwner());
757
758         WorkflowStepVO stepVO = new WorkflowStepVO(workflowVO);
759         stepVO.setId(new Integer JavaDoc((int)step.getId()));// Hope it doesn't get too big; we are stuck with int thanks to BaseEntityVO
760
stepVO.setStepId(new Integer JavaDoc(step.getStepId()));
761         stepVO.setWorkflowId(new Long JavaDoc(workflowId));
762         stepVO.setStatus(step.getStatus());
763         stepVO.setStartDate(step.getStartDate());
764         stepVO.setFinishDate(step.getFinishDate());
765         stepVO.setOwner(step.getOwner());
766         stepVO.setCaller(step.getCaller());
767
768         StepDescriptor stepDescriptor = workflowDescriptor.getStep(step.getStepId());
769         if(stepDescriptor != null)
770         {
771             stepVO.setName(stepDescriptor.getName());
772             for (Iterator JavaDoc i = stepDescriptor.getActions().iterator(); i.hasNext();)
773                 stepVO.addAction(createActionVO((ActionDescriptor)i.next()));
774         }
775         else
776         {
777             throw new SystemException("No stepDescriptor found for " + step);
778         }
779         
780         return stepVO;
781     }
782
783     /**
784      * Creates a WorkflowStepVO from a step descriptor. Some of the step data, e.g., status, startDate,
785      * finishDate, etc. cannot be populated here because the step descriptor does not know about these things.
786      * @param stepDescriptor a step descriptor
787      * @return a WorkflowStepVO representing stepDescriptor
788      */

789     private WorkflowStepVO createStepVO(StepDescriptor stepDescriptor)
790     {
791         WorkflowStepVO step = new WorkflowStepVO();
792         step.setStepId(new Integer JavaDoc(stepDescriptor.getId()));
793         step.setName(stepDescriptor.getName());
794         step.setStatus("Not started");
795
796         for (Iterator JavaDoc i = stepDescriptor.getActions().iterator(); i.hasNext();)
797             step.addAction(createActionVO((ActionDescriptor)i.next()));
798
799         return step;
800     }
801
802     /**
803      * Creates a WorkflowActionVO for the given action descriptor
804      * @param actionDescriptor an action descriptor
805      * @return a WorkflowActionVO representing actionDescriptor
806      */

807     private WorkflowActionVO createActionVO(ActionDescriptor actionDescriptor)
808     {
809         logger.info("Action:" + actionDescriptor.getId() + ':' + actionDescriptor.getName()
810                     + ':' + actionDescriptor.getParent().getClass());
811
812         WorkflowActionVO actionVO = new WorkflowActionVO(new Integer JavaDoc(actionDescriptor.getId()));
813         actionVO.setWorkflowId(new Long JavaDoc(workflowId));
814         actionVO.setName(actionDescriptor.getName());
815         actionVO.setView(actionDescriptor.getView());
816         actionVO.setAutoExecute(actionDescriptor.getAutoExecute());
817         actionVO.setMetaAttributes(actionDescriptor.getMetaAttributes());
818         return actionVO;
819     }
820     
821     /**
822      * Checks if the title extension should be used.
823      *
824      * @return true if the extension should be used, false otherwise.
825      */

826     private boolean useTitleExtension(final WorkflowDescriptor descriptor)
827     {
828         return descriptor.getMetaAttributes().containsKey(WORKFLOW_TITLE_EXTENSION_META_ATTRIBUTE);
829     }
830
831     /**
832      * Checks if the database extension should be used.
833      *
834      * @return true if the extension should be used, false otherwise.
835      */

836     private boolean useDatabaseExtension(final WorkflowDescriptor descriptor)
837     {
838         return descriptor.getMetaAttributes().containsKey(WORKFLOW_DATABASE_EXTENSION_META_ATTRIBUTE);
839     }
840 }
841
Popular Tags