KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > jawe > WorkflowManager


1 /* WorkflowManager.java
2  *
3  * Authors:
4  * Stefanovic Nenad chupo@iis.ns.ac.yu
5  * Bojanic Sasa sasaboy@neobee.net
6  * Puskas Vladimir vpuskas@eunet.yu
7  * Pilipovic Goran zboniek@uns.ac.yu
8  * Harald Meister harald.meister@abacus.ch
9  *
10  */

11
12 package org.enhydra.jawe;
13
14 import org.enhydra.jawe.PackageEditor;
15 import org.enhydra.jawe.graph.*;
16 import org.enhydra.jawe.xml.*;
17 import org.enhydra.jawe.xml.elements.Activities;
18 import org.enhydra.jawe.xml.elements.ActivitySet;
19 import org.enhydra.jawe.xml.elements.ActivitySets;
20 import org.enhydra.jawe.xml.elements.Join;
21 import org.enhydra.jawe.xml.elements.Package;
22 import org.enhydra.jawe.xml.elements.Participants;
23 import org.enhydra.jawe.xml.elements.Performer;
24 import org.enhydra.jawe.xml.elements.Split;
25 import org.enhydra.jawe.xml.elements.Transitions;
26 import org.enhydra.jawe.xml.elements.WorkflowProcess;
27 import org.enhydra.jawe.xml.elements.WorkflowProcesses;
28
29 import org.jgraph.graph.*;
30 import org.jgraph.*;
31
32 import java.util.*;
33 import java.awt.*;
34 import java.awt.geom.Point2D JavaDoc;
35 import java.awt.geom.Rectangle2D JavaDoc;
36 import javax.swing.*;
37 import javax.swing.tree.*;
38
39 import java.io.*;
40
41 /**
42  * Class intended to serve as a control center for creation, removal,
43  * resizing and changing position of Participants as well as for
44  * doing the same things with Activity objects and Transitions. Class
45  * manages this actions in such a way that undoing of operations are
46  * possible. It incorporates multiple view and model changes into one
47  * by doing them virtually, and after all changes are done, in interaction
48  * with JaWEGraphModel class applies this changes so that undo is possible.
49  * Instance of this class is joined to to all objects of classes derived
50  * from AbstractGraph class (PackageGraph, ProcessGraph and BlockActivityGraph).
51  * <p> This class also handles the relationships between visual and logical
52  * representation of workflow graph.
53  * <p> When reading a package from an XML file, this class creates imported
54  * objects and establishes relationship between graph objects (classes within
55  * jawe and jawe.graph package) and 'graph logic' objects (
56  * classes within jawe.xml package).
57  */

58 public class WorkflowManager implements Serializable {
59
60    /** Graph reference */
61    private transient AbstractGraph graph;
62
63    /**
64     * Offset for drawing - no meaning (it was used in previous versions)
65     */

66    private int horizontalOffset=0;
67
68    // some default values for setting participants and activity sizes
69
/** Variable that holds width of process */
70    private static final int defProcessWidth=JaWEConfig.getInstance().getProcessWidth();
71    /** Variable that holds height of process */
72    private static final int defProcessHeight=JaWEConfig.getInstance().getProcessHeight();
73    /** Variable that holds minimum width for any participant */
74    private static final int minParWidth=JaWEConfig.getInstance().getMinParticipantWidth();
75    /** Variable that holds minimum height for any participant */
76    private static final int minParHeight=JaWEConfig.getInstance().getMinParticipantHeight();
77    /** Variable that holds the width for participant name section*/
78    private static final int defParNameWidth=JaWEConfig.getInstance().getParticipantNameWidth();
79    /** Variable that holds width of activities */
80    private static final int defActivityWidth=JaWEConfig.getInstance().getActivityWidth();
81    /** Variable that holds height of activities */
82    private static final int defActivityHeight=JaWEConfig.getInstance().getActivityHeight();
83
84    private boolean creatingGraph=false;
85
86    /**
87     * Creates new workflow manager for given graph.
88     * @param g The graph that manager manages.
89     */

90    public WorkflowManager (AbstractGraph g) {
91       this.graph=g;
92    }
93
94    /** Returns the graph which is managed. */
95    public AbstractGraph getGraph () {
96       return graph;
97    }
98
99    /**
100     * Returns the object representing the main element of XML file that
101     * defines the workflow model logic.
102     */

103    public Package JavaDoc getXMLPackage () {
104       return graph.getXMLPackage();
105    }
106
107    /**
108     * Returns the graph model - the model that represents the graph view.
109     * (See JGraph documentation).
110     */

111    public JaWEGraphModel graphModel () {
112       return (JaWEGraphModel)graph.getModel();
113    }
114
115    /**
116     * Creates graph representation of given workflow process. It creates a graph
117     * entities (participants, activities, transitions) and associates
118     * the workflow logic to it. The graph entities are inserted according
119     * to the data that <tt>wp</tt> object holds (the data from XML file).
120     * <p>This is used when reading a workflow definition from an XML file.
121     * @param wp Object that mapps the logic of WorkflowProcess element
122     * of XML - defines a particular Workflow process.
123     */

124    public void createWorkflowGraph (WorkflowProcess wp) {
125       creatingGraph=true;
126       // checks if it is graph made by JaWE
127
boolean isMine=true;
128       if (!getXMLPackage().isMadeByJaWE()) {
129          isMine=false;
130       }
131       //********* the creation other is very important and shouldn't be changed
132
//System.out.println("Creating graph for WP "+wp+" and VO="+getVisualOwner());
133

134       java.util.List JavaDoc entitiesToInsert=wp.getEntitiesToInsert(getVisualOwner());
135
136       //System.out.println("Entities to insert="+entitiesToInsert);
137
// show Participants
138
createGraphParticipants(wp,entitiesToInsert);
139
140       // showing Activities
141
createGraphActivitiesAndBlockActivities(wp,entitiesToInsert,isMine);
142
143       // show transitions
144
createGraphTransitions(wp,entitiesToInsert,isMine);
145
146       // show start
147
if (JaWEConfig.getInstance().getUseBubblesStatus()) {
148          createGraphStarts(wp,isMine,false);
149
150          // show ends
151
createGraphEnds(wp,isMine,false);
152       }
153
154       // if workflow model is not created by JaWE, perform some
155
// kind of layout, and create start and end objects
156
if (!isMine) {
157          layoutActivities();
158          ProcessEditor pe=(ProcessEditor)graph.getEditor();
159          Set startDescs=Utils.getStartDescriptions(pe);
160          Set endDescs=Utils.getEndDescriptions(pe);
161          XMLComplexElement vo=getVisualOwner();
162          if (vo instanceof WorkflowProcess) {
163             ((WorkflowProcess)vo).setStartDescriptions(startDescs);
164             ((WorkflowProcess)vo).setEndDescriptions(endDescs);
165          } else {
166             ((org.enhydra.jawe.xml.elements.Activity)vo).
167                setStartDescriptions(startDescs);
168             ((org.enhydra.jawe.xml.elements.Activity)vo).
169                setEndDescriptions(endDescs);
170          }
171       }
172       creatingGraph=false;
173       try {
174          Dimension prefSize=new Dimension(getRootParticipantWidth(null,null)+50,
175                                           getNewRootParYPos(null,null)+50);
176          graph.setPreferredSize(prefSize);
177       } catch (Exception JavaDoc ex) {}
178    }
179
180    /**
181     * Returns the object (part of mapped XML logic) that is represented by
182     * the graph managed by WorklowManager. That object can be instance
183     * of the Package, WorkflowProcess or ...xml.elements.BlockActivity class,
184     * and is held as a property of the manager's graph object.
185     * @return The object (representing XML logic) that is represented
186     * by this manager's graph.
187     */

188    public XMLComplexElement getVisualOwner () {
189       if (graph instanceof BlockActivityGraph) {
190          return (org.enhydra.jawe.xml.elements.Activity)
191             ((BlockActivityGraph)graph).getMyBlockActivity().getUserObject();
192       } else if (graph instanceof ProcessGraph) {
193          return (WorkflowProcess)graph.getPropertyObject();
194       } else {
195          return (Package JavaDoc)graph.getPropertyObject();
196       }
197    }
198
199    /**
200     * Returns the (XML logic) Activities object, that holds all
201     * (XML logic) Activity objects which graphical representation
202     * is managed by this workflow manager. That could be activites
203     * belonging directly to the WorkflowProcess, or activities
204     * belonging to the BlockActivity element. If this is a manager
205     * of Package graph, <tt>null</tt> is returned.
206     */

207    private Activities getActivitiesCollection () {
208       Activities acts;
209       XMLComplexElement myOwner=getVisualOwner();
210       if (myOwner instanceof WorkflowProcess) {
211          acts=(Activities)myOwner.get("Activities");
212       } else {
213          BlockActivity ba=((BlockActivityGraph)graph).getMyBlockActivity();
214          ActivitySet as=getBlockActivitySet(ba);
215          acts=(Activities)as.get("Activities");
216       }
217       return acts;
218    }
219
220    /**
221     * Returns the (XML logic) Transitions object, that holds all
222     * (XML logic) Transition objects which graphical representation
223     * is managed by this workflow manager. That could be transitions
224     * belonging directly to the WorkflowProcess, or transitions
225     * belonging to the BlockActivity element. If this is a manager
226     * of Package graph, <tt>null</tt> is returned.
227     */

228    public Transitions getTransitionsCollection () {
229       Transitions trans;
230       XMLComplexElement myOwner=getVisualOwner();
231       if (myOwner instanceof WorkflowProcess) {
232          trans=(Transitions)myOwner.get("Transitions");
233       } else {
234          BlockActivity ba=((BlockActivityGraph)graph).getMyBlockActivity();
235          ActivitySet as=getBlockActivitySet(ba);
236          trans=(Transitions)as.get("Transitions");
237       }
238       return trans;
239    }
240
241    /**
242     * Returns the (XML logic) ActivitySet object that is associated
243     * to the given graph's object logic.
244     */

245    private ActivitySet getBlockActivitySet (BlockActivity ba) {
246       try {
247          String JavaDoc ID=ba.getBlockID();
248          ActivitySet as=((ActivitySets)getWorkflowProcess().
249                             get("ActivitySets")).getActivitySet(ID);
250          return as;
251       } catch (Exception JavaDoc ex) {
252          return null;
253       }
254    }
255
256    /**
257     * Returns the (XML logic) WorkflowProcess object that is
258     * represented by the manager's graph, or (if the graph
259     * represents the (XML logic) BlockActivity content) the
260     * WorkflowProcess object that holds BlockActivity represented
261     * by manager's graph. If graph represents (XML logic) Package
262     * object, <tt>null</tt> is returned.
263     */

264    private WorkflowProcess getWorkflowProcess () {
265       if (graph.getPropertyObject() instanceof WorkflowProcess) {
266          return (WorkflowProcess)graph.getPropertyObject();
267       } else {
268          return null;
269       }
270    }
271
272    /**
273     * Inserts new process cell into (graph) model and creates
274     * new (XML logic) WorkflowProcess object. Depending on
275     * <tt>updateCollection</tt> parameter, it calls the method
276     * that updates the collection of existing WorkflowProcess
277     * objects (it is set to <tt>true</tt> when user inserts the
278     * new WorkflowProcess into the Package graph, and to <tt>false</tt>
279     * during importing from XML).
280     * @param p The position within the graph where
281     * the process cell should be inserted.
282     * @param updateCollection <tt>true</tt> if collection of
283     * WorkflowProcess objects should be
284     * updated (user inserts object), and
285     * <tt>false</tt> if not (XML file is
286     * importing, and objects are constructed
287     * depending on data held within the file).
288     * @return The created graph object.
289     */

290    public org.enhydra.jawe.graph.Process insertProcess (Point p,boolean updateCollection) {
291       Point realP=(Point)graph.fromScreen(new Point(p));//HM, JGraph3.4.1
292
int ulx=realP.x;
293       int uly=realP.y;
294       Rectangle bounds=new Rectangle(ulx,uly,defProcessWidth,defProcessHeight);
295
296       Map viewMap = new Hashtable();
297       Map map = GraphConstants.createMap();
298
299       org.enhydra.jawe.graph.Process pr =
300          new org.enhydra.jawe.graph.Process((PackageEditor)getGraph().getEditor());
301       WorkflowProcess wp=new WorkflowProcess((WorkflowProcesses)getXMLPackage().
302                                                 get("WorkflowProcesses"),getXMLPackage());
303       wp.get("Name").setValue(ResourceManager.getLanguageDependentString("ProcessKey"));
304       pr.setUserObject(wp);
305
306       GraphConstants.setBounds(map,bounds);
307       GraphConstants.setOpaque(map,true);
308       GraphConstants.setBorderColor(map,Color.darkGray);
309       GraphConstants.setFont(map,GraphConstants.defaultFont.deriveFont(JaWEConfig.getInstance().getFontSize()));
310
311       viewMap.put(pr,map);
312       Object JavaDoc[] insert = new Object JavaDoc[]{pr};
313       // makes all changes (if there was any) - to model and to view
314
String JavaDoc actionName=
315          ResourceManager.getLanguageDependentString("MessageInsertingProcessIntoPackage");
316       graphModel().insertAndEdit(insert,viewMap,null,null,null,actionName);
317
318       if (updateCollection) {
319          refreshCollections (insert,true);
320       }
321
322       return pr;
323    }
324
325    /**
326     * Inserts cells <b>insert</b> into model. First, the parent of cells is
327     * searched, and when found, put into ParentMap object (they are not
328     * inserted into model at ones). After that model's view is arranged
329     * (Participants are moved and translated along with it's children cells)
330     * to suite to the new model state - this is done "virtually" which
331     * means that changes are not directly applied to view until all
332     * changes are made. At the end, all changes are applied to model and view.
333     * Such procedure enables compound undo support.
334     * <BR> This method is called when pasting cells into model.
335     * @see #updateModelAndArrangeParticipants
336     */

337    public void insertCellsAndArrangeParticipants (Object JavaDoc[] insert,Map viewMap, ConnectionSet cs) {
338       if(JaWEGraphModel.getRootParticipants(graphModel()) != null) {
339          updateModelAndArrangeParticipants(insert,null,null,viewMap,
340                                            ResourceManager.getLanguageDependentString("MessageDuplicatingObject"),true,cs);
341       }
342       else {
343          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
344                                        ResourceManager.getLanguageDependentString(
345                                           "WarningCannotInsertObjectsOutsideParticipant"),
346                                        JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
347       }
348    }
349
350    /**
351     * Moves cells given in a <b>propertyMap</b> to new location (also
352     * given in <b>propertyMap</b>. First, the parent of cells is
353     * searched, and when found, put into ParentMap object (the model
354     * is not changed at ones). After that model's view is arranged
355     * (Participants are moved and translated along with it's children cells)
356     * to suite to the new model state - this is done "virtually" which
357     * means that changes are not directly applied to view until all
358     * changes are made. At the end, all changes are applied to model and view.
359     * Such procedure enables compound undo support.
360     * <BR> This method is called when moving cells along participants.
361     * @see #updateModelAndArrangeParticipants
362     */

363    public void moveCellsAndArrangeParticipants (Map propertyMap) {
364       updateModelAndArrangeParticipants(null,propertyMap,null,null,
365                                         ResourceManager.getLanguageDependentString("MessageMovingObjects"),false,null);
366    }
367
368    /**
369     * Inserts new Subflow cell at position <b>p</b> into model. First, the
370     * parent of new Subflow is searched, and when found, put into ParentMap
371     * object (it is not inserted into model at ones). After that model's view
372     * is arranged (Participants are moved and translated along with it's children
373     * cells) to suite to the new model state - this is done "virtually" which
374     * means that changes are not directly applied to view until all changes are
375     * made. At the end, all changes are applied to model and view.
376     * Such procedure enables compound undo support.
377     * <BR> This method is called when user inserts new Subflow into graph.
378     * @see #updateModelAndArrangeParticipants
379     */

380    public void insertSubflowAndArrangeParticipants (Point p) {
381       Set rootParticipants=JaWEGraphModel.getRootParticipants(graphModel());
382       if(rootParticipants != null && rootParticipants.size()>0) {
383          Map viewMap = new Hashtable();
384          Subflow sbf=createSubflow(p,viewMap);
385          //updateModelAndArrangeParticipants(new Object[] {sbf},viewMap,null,null,
386
updateModelAndArrangeParticipants(new Object JavaDoc[] {sbf},null,null,viewMap,
387                                            ResourceManager.getLanguageDependentString("MessageInsertingSubflowActivity"),
388                                            true,null);
389       }
390       else {
391          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
392                                        ResourceManager.getLanguageDependentString(
393                                           "WarningCannotInsertSubflowActivityOutsideParticipant"),
394                                        JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
395       }
396    }
397
398    /**
399     * Inserts new BlockActivity cell at position <b>p</b> into model. First, the
400     * parent of new BlockActivity is searched, and when found, put into ParentMap
401     * object (it is not inserted into model at ones). After that model's view
402     * is arranged (Participants are moved and translated along with it's children
403     * cells) to suite to the new model state - this is done "virtually" which
404     * means that changes are not directly applied to view until all changes are
405     * made. At the end, all changes are applied to model and view.
406     * Such procedure enables compound undo support.
407     * <BR> This method is called when user inserts new BlockActivity into graph.
408     * @see #updateModelAndArrangeParticipants
409     */

410    public void insertBlockActivityAndArrangeParticipants (Point p) {
411       Set rootParticipants=JaWEGraphModel.getRootParticipants(graphModel());
412       if(rootParticipants != null && rootParticipants.size()>0) {
413          Map viewMap = new Hashtable();
414          BlockActivity bla=createBlockActivity(p,viewMap);
415          //updateModelAndArrangeParticipants(new Object[] {bla},viewMap,null,null,
416
updateModelAndArrangeParticipants(new Object JavaDoc[] {bla},null,null,viewMap,
417                                            ResourceManager.getLanguageDependentString("MessageInsertingBlockActivity"),
418                                            true,null);
419       }
420       else {
421          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
422                                        ResourceManager.getLanguageDependentString(
423                                           "WarningCannotInsertBlockActivityOutsideParticipant"),
424                                        JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
425       }
426    }
427
428    /**
429     * Inserts new Start activity cell at position <b>p</b> into model. First,
430     * the parent of new Activity is searched, and when found, put into ParentMap
431     * object (it is not inserted into model at ones). After that model's view
432     * is arranged (Participants are moved and translated along with it's children
433     * cells) to suite to the new model state - this is done "virtually" which
434     * means that changes are not directly applied to view until all changes are
435     * made. At the end, all changes are applied to model and view.
436     * Such procedure enables compound undo support.
437     * <BR> This method is called when user inserts new Start into graph.
438     * @see #updateModelAndArrangeParticipants
439     */

440    public void insertStartAndArrangeParticipants (Point p) {
441       Set rootParticipants=JaWEGraphModel.getRootParticipants(graphModel());
442       if(rootParticipants != null && rootParticipants.size()>0) {
443          Map viewMap = new Hashtable();
444          Start s=createStart(p,viewMap);
445          //updateModelAndArrangeParticipants(new Object[] {s},viewMap,null,null,
446
updateModelAndArrangeParticipants(new Object JavaDoc[] {s},null,null,viewMap,
447                                            ResourceManager.getLanguageDependentString("MessageInsertingStart"),
448                                            true,null);
449       }
450       else {
451          String JavaDoc msg=ResourceManager.getLanguageDependentString(
452             "WarningCannotInsertStartOutsideParticipant");
453          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
454                                        msg,JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
455       }
456    }
457
458    /**
459     * Inserts new End activity cell at position <b>p</b> into model. First, the
460     * parent of new Activity is searched, and when found, put into ParentMap
461     * object (it is not inserted into model at ones). After that model's view
462     * is arranged (Participants are moved and translated along with it's children
463     * cells) to suite to the new model state - this is done "virtually" which
464     * means that changes are not directly applied to view until all changes are
465     * made. At the end, all changes are applied to model and view.
466     * Such procedure enables compound undo support.
467     * <BR> This method is called when user inserts new End into graph.
468     * @see #updateModelAndArrangeParticipants
469     */

470    public void insertEndAndArrangeParticipants (Point p) {
471       Set rootParticipants=JaWEGraphModel.getRootParticipants(graphModel());
472       if(rootParticipants != null && rootParticipants.size()>0) {
473          Map viewMap = new Hashtable();
474          Activity e=createEnd(p,viewMap);
475          //updateModelAndArrangeParticipants(new Object[] {e},viewMap,null,null,
476
updateModelAndArrangeParticipants(new Object JavaDoc[] {e},null,null,viewMap,
477                                            ResourceManager.getLanguageDependentString("MessageInsertingEnd"),
478                                            true,null);
479       }
480       else {
481          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
482                                        ResourceManager.getLanguageDependentString(
483                                           "WarningCannotInsertEndOutsideParticipant"),
484                                        JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
485       }
486    }
487
488    /**
489     * Inserts new Activity cell at position <b>p</b> into model. First, the
490     * parent of new Activity is searched, and when found, put into ParentMap
491     * object (it is not inserted into model at ones). After that model's view
492     * is arranged (Participants are moved and translated along with it's children
493     * cells) to suite to the new model state - this is done "virtually" which
494     * means that changes are not directly applied to view until all changes are
495     * made. At the end, all changes are applied to model and view.
496     * Such procedure enables compound undo support.
497     * <BR> This method is called when user inserts new generic activity into graph.
498     * @see #updateModelAndArrangeParticipants
499     */

500    public void insertActivityAndArrangeParticipants (Point p) {
501       Set rootParticipants=JaWEGraphModel.getRootParticipants(graphModel());
502       if(rootParticipants != null && rootParticipants.size()>0) {
503          Map viewMap = new Hashtable();
504          Activity act=createActivity(p,viewMap);
505          //updateModelAndArrangeParticipants(new Object[] {act},viewMap,null,null,
506
updateModelAndArrangeParticipants(new Object JavaDoc[] {act},null,null,viewMap,
507                                            ResourceManager.getLanguageDependentString("MessageInsertingGenericActivity"),
508                                            true,null);
509       }
510       else {
511          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
512                                        ResourceManager.getLanguageDependentString(
513                                           "WarningCannotInsertGenericActivityOutsideParticipant"),
514                                        JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
515       }
516    }
517
518    /**
519     * Inserts new Route activity cell at position <b>p</b> into model. First, the
520     * parent of new Activity is searched, and when found, put into ParentMap
521     * object (it is not inserted into model at ones). After that model's view
522     * is arranged (Participants are moved and translated along with it's children
523     * cells) to suite to the new model state - this is done "virtually" which
524     * means that changes are not directly applied to view until all changes are
525     * made. At the end, all changes are applied to model and view.
526     * Such procedure enables compound undo support.
527     * <BR> This method is called when user inserts new Route activity into graph.
528     * @see #updateModelAndArrangeParticipants
529     */

530    public void insertRouteAndArrangeParticipants (Point p) {
531       Set rootParticipants=JaWEGraphModel.getRootParticipants(graphModel());
532       if(rootParticipants != null && rootParticipants.size()>0) {
533          Map viewMap = new Hashtable();
534          Route r=createRoute(p,viewMap);
535          //updateModelAndArrangeParticipants(new Object[] {r},viewMap,null,null,
536
updateModelAndArrangeParticipants(new Object JavaDoc[] {r},null,null,viewMap,
537                                            ResourceManager.getLanguageDependentString("MessageInsertingRouteActivity"),
538                                            true,null);
539       }
540       else {
541          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
542                                        ResourceManager.getLanguageDependentString(
543                                           "WarningCannotInsertRouteActivityOutsideParticipant"),
544                                        JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
545       }
546    }
547
548    /**
549     * Inserts new Participant cell at position <b>p</b> into model. First, the
550     * parent of new Participant is searched, and if found, put into ParentMap
551     * (it is not inserted into model at ones). If parent participant isn't
552     * found -> root participant will be inserted. After that model's view
553     * is arranged (Participants are moved and translated along with it's children
554     * cells) to suite to the new model state - this is done "virtually" which
555     * means that changes are not directly applied to view until all changes are
556     * made. At the end, all changes are applied to model and view.
557     * Such procedure enables compound undo support.
558     * <BR> This method is called when inserting new Participant into model.
559     * <BR> If <tt>parUO</tt> is <tt>null</tt>, the new object is inserted
560     * into XML logic, and if not, the predefined XML object is used.
561     * @param p The position of participant within the graph.
562     * @param parUO The XML logic object that holds the data for participant
563     * to be inserted and that will be held as a property of
564     * the graph object.
565     */

566    public Participant insertParticipantAndArrangeParticipants (Point p,
567                                                                org.enhydra.jawe.xml.elements.Participant parUO) {
568
569       ToolTipManager.sharedInstance().setEnabled(false);
570
571       Participant par=null;
572
573       Map viewMap=new HashMap();
574       ParentMap parentMap=null;
575       Map propertyMap=null;
576
577       // get the topmost participant at the location where
578
// user want to insert participant
579
Object JavaDoc cell=((ProcessGraph)graph).
580          getFirstParticipantForLocation(p.x,p.y);
581
582       // if there is no cell at the mouse position,
583
// add new participant below existing ones
584
if (cell==null) {
585          par=createParticipant(
586             new Rectangle(horizontalOffset,getNewRootParYPos(null,null),
587                           getRootParticipantWidth(null,null),minParHeight),
588             viewMap);
589          propertyMap=new HashMap(viewMap);
590          // otherwise, display an warning message that
591
// participant can't be inserted here
592
} else {
593          JOptionPane.showMessageDialog(graph.getEditor().getWindow(),
594                                        ResourceManager.getLanguageDependentString(
595                                           "WarningParticipantCannotHaveParticipants"),
596                                        JaWE.getAppTitle(),JOptionPane.WARNING_MESSAGE);
597          return null;
598       }
599
600       Participants wfp =(Participants)getWorkflowProcess().get("Participants");
601       // if user inserts an existing (logical) participant into graph
602
if (parUO!=null) {
603          Object JavaDoc[] insert = new Object JavaDoc[]{par};
604          // graphModel().insertAndEdit(insert,null,propertyMap,parentMap,viewMap,
605
graphModel().insertAndEdit(insert,propertyMap,null,parentMap,null,
606                                     ResourceManager.getLanguageDependentString("MessageInsertingParticipant"));
607          par.setUserObject(parUO);
608          // notifies participants user object that one of it's graph
609
// presentation is added
610
// ADDED 19.02.03 - conditional graph reference adding, only
611
// if this is not external model graph
612
if (!getXMLPackage().isReadOnly()) {
613             parUO.graphReferenceAdded();
614          }
615          // if user creates new (logical) participant by selecting
616
// it from the toolbox toolbar
617
} else {
618          parUO=(org.enhydra.jawe.xml.elements.Participant)
619             wfp.generateNewElement();
620          // show dialog for entering initial participant data
621
Window w=graph.getEditor().getWindow();
622          XMLElementDialog de=new XMLElementDialog((JDialog)w,
623                                                   ResourceManager.getLanguageDependentString("DialogNewParticipant"));
624
625          de.editXMLElement(parUO.getPanel(),true,false);
626          // if cancel hasn't been pressed
627
if (!de.isCanceled()) {
628             Object JavaDoc[] insert = new Object JavaDoc[]{par};
629             //graphModel().insertAndEdit(insert,null,propertyMap,parentMap,viewMap,
630
graphModel().insertAndEdit(insert,propertyMap,null,parentMap,null,
631                                        ResourceManager.getLanguageDependentString("MessageInsertingParticipant"));
632             par.setUserObject(parUO);
633             // notifies participants user object that one of it's graph
634
// presentation is added
635
// ADDED 19.02.03 - conditional graph reference adding, only
636
// if this is not external model graph
637
if (!getXMLPackage().isReadOnly()) {
638                parUO.graphReferenceAdded();
639             }
640             // adds object to the collection
641
wfp.add(parUO);
642          }
643       }
644
645       if (JaWEConfig.getInstance().getTooltipStatus()) {
646          ToolTipManager.sharedInstance().setEnabled(true);
647       }
648
649       if (!creatingGraph) {
650          try {
651             Dimension prefSize=new Dimension(getRootParticipantWidth(propertyMap,parentMap)+50,
652                                              getNewRootParYPos(propertyMap,parentMap)+50);
653             graph.setPreferredSize(prefSize);
654          } catch (Exception JavaDoc ex) {}
655       }
656
657       return par;
658    }
659
660    /**
661     * Called when user wants to insert an existing (logical) participant
662     * into graph. Participant is inserted below all already inserted
663     * participants.
664     * @return <tt>true</tt> if participant is successfully inserted into
665     * graph, <tt>false</tt> otherwise.
666     */

667    public boolean showNode (org.enhydra.jawe.xml.elements.Participant parUO) {
668       if (parUO==null) return false;
669
670       Point ofInsert = new Point(10,Integer.MAX_VALUE);
671       Object JavaDoc graphObj = getGraphObjectForXMLParticipant(parUO);
672       // if participant is already inserted into graph, just return true
673
if (null != graphObj) {
674          return true;
675       }
676
677       Object JavaDoc ins=insertParticipantAndArrangeParticipants(ofInsert,parUO);
678
679       if (ins==null) {
680          return false;
681       } else {
682          return true;
683       }
684    }
685
686    /**
687     * Called when user wants to remove an existing (logical) participant
688     * from the graph. The participant can be removed only if there are
689     * no activities that it is responsible for (activity graph objects
690     * that lies inside the participant graph object).
691     */

692    public void hideNode(org.enhydra.jawe.xml.elements.Participant parUO) {
693       Participant p=getGraphObjectForXMLParticipant(parUO);
694       if (p!=null && !p.hasAnyActivity()) {
695          removeCellsAndArrangeParticipants(new Object JavaDoc[]{p});
696       }
697    }
698
699    /**
700     * Returns the graph object representing given (XML logic) Participant
701     * object.
702     * @param source The (XML logic) Participant object which graph
703     * object should be returned by this method.
704     * @return The graph object for given XML logic object if it is
705     * inserted into graph, <tt>null</tt> otherwise.
706     */

707    private Participant getGraphObjectForXMLParticipant(
708       org.enhydra.jawe.xml.elements.Participant source) {
709
710       Set graphParts=JaWEGraphModel.getAllParticipantsInModel(graphModel());
711       if (graphParts!=null) {
712          Participant graphPart;
713          Iterator it=graphParts.iterator();
714          while (it.hasNext()) {
715             graphPart=(Participant)it.next();
716             if (graphPart.getUserObject()==source) {
717                return graphPart;
718             }
719          }
720       }
721       return null;
722    }
723
724
725    /**
726     * Inserts new Transition cell, between points <b>start</b> and <b>end</b>,
727     * connected to the ports <b>source</b> and <b>target</b> into model.
728     * <BR> This method is called when inserting new Transition into graph.
729     * Depending on <tt>updateCollection</tt> parameter, it calls the method
730     * that updates the collection of existing Transition objects
731     * (it is set to <tt>true</tt> when user inserts the new Transition into
732     * the Process or BlockActivity graph, and to <tt>false</tt>
733     * during importing from XML).
734     * @param start The position of start point of transition
735     * within the graph.
736     * @param end The position of end point of transition
737     * within the graph.
738     * @param source The source port of transition's graph object.
739     * @param target The target port of transition's graph object.
740     * @param updateCollection <tt>true</tt> if collection of
741     * Transition objects should be
742     * updated (user inserts object), and
743     * <tt>false</tt> if not (XML file is
744     * importing, and objects are constructed
745     * depending on data held within the file).
746     * @return The created transition's graph object.
747     */

748    public Transition insertTransition (Point start,Point end,PortView source,
749                                        PortView target,boolean isRouting,boolean updateCollection) {
750
751       Point p = (Point)graph.fromScreen(new Point(start));//HM, JGraph3.4.1
752
Point p2 = (Point)graph.fromScreen(new Point(end));//HM, JGraph3.4.1
753
ArrayList list = new ArrayList();
754
755       // creating line style
756
Map map = GraphConstants.createMap();
757       if (source.equals(target)) {
758          GraphConstants.setLineStyle(map,GraphConstants.STYLE_BEZIER);
759          list.add(p);
760          if (updateCollection) {
761             list.add(new Point(p.x-50,p.y-75));
762             list.add(new Point(p.x+50,p.y-75));
763          }
764          list.add(p2);
765       } else {
766          list.add(p);
767          list.add(p2);
768       }
769       GraphConstants.setPoints(map,list);
770       if (isRouting) {
771          GraphConstants.setRouting(map, GraphConstants.ROUTING_SIMPLE);
772       }
773       //GraphConstants.setLineColor(map,Utils.getColor(JaWEConfig.getInstance().getTransitionColor()));
774
GraphConstants.setLineEnd(map,GraphConstants.ARROW_TECHNICAL);
775       GraphConstants.setEndFill(map,true);
776       GraphConstants.setEndSize(map,10);
777       GraphConstants.setFont(map,GraphConstants.defaultFont.deriveFont(JaWEConfig.getInstance().getFontSize()));
778
779       Map viewMap = new Hashtable();
780       Transition transition = new Transition();
781
782       viewMap.put(transition,map);
783
784       Object JavaDoc[] insert = new Object JavaDoc[]{transition};
785       ConnectionSet cs = new ConnectionSet();
786
787       cs.connect(transition,source.getCell(),target.getCell());
788
789       org.enhydra.jawe.xml.elements.Transition uo=null;
790       Transitions ts=getTransitionsCollection();
791       uo=new org.enhydra.jawe.xml.elements.Transition(ts);
792       //uo.get("Name").setValue(ResourceManager.getLanguageDependentString("TransitionKey"));
793
transition.setUserObject(uo);
794
795       //cs.connect(transition,source.getCell(),true);
796
//cs.connect(transition,target.getCell(),false);
797
String JavaDoc undoMsg=ResourceManager.getLanguageDependentString("MessageInsertingTransition");
798       // graphModel().insertAndEdit(insert,cs,null,null,viewMap,undoMsg);
799
graphModel().insertAndEdit(insert,viewMap,cs,null,null,undoMsg);
800       Activity s=null;
801       Activity t=null;
802       try {
803          s=transition.getSourceActivity();
804       } catch (Exception JavaDoc ex) {
805       }
806       try {
807          t=transition.getTargetActivity();
808       } catch (Exception JavaDoc ex) {
809       }
810
811       // must set source and target activity objects after inserting into model
812
org.enhydra.jawe.xml.elements.Activity sourceAct=null;
813       //System.out.println("s-"+s+", t="+t);
814
if (s!=null && t!=null && !(s instanceof Start) && !(t instanceof End)) {
815          try {
816             sourceAct=(org.enhydra.jawe.xml.elements.Activity)
817                s.getPropertyObject();
818             uo.setFrom(sourceAct);
819          } catch (Exception JavaDoc e) {}
820          try {
821             uo.setTo(t.getPropertyObject());
822          } catch (Exception JavaDoc e) {}
823       }
824
825       // refreshes collection of transitions within workflow process
826
if (updateCollection) {
827          refreshCollections (insert,true);
828       }
829
830       return transition;
831    }
832
833    /**
834   &