0001: package org.enhydra.jawe.components.graph;
0002:
0003: import java.awt.Dimension;
0004: import java.awt.Point;
0005: import java.awt.Rectangle;
0006: import java.awt.geom.Point2D;
0007: import java.awt.geom.Rectangle2D;
0008: import java.io.Serializable;
0009: import java.util.ArrayList;
0010: import java.util.Arrays;
0011: import java.util.Collections;
0012: import java.util.HashMap;
0013: import java.util.HashSet;
0014: import java.util.Iterator;
0015: import java.util.List;
0016: import java.util.Map;
0017: import java.util.Set;
0018:
0019: import javax.swing.SwingUtilities;
0020: import javax.swing.tree.DefaultMutableTreeNode;
0021:
0022: import org.enhydra.jawe.JaWEManager;
0023: import org.enhydra.jawe.base.controller.JaWEController;
0024: import org.enhydra.shark.xpdl.XMLCollectionElement;
0025: import org.enhydra.shark.xpdl.XMLElement;
0026: import org.enhydra.shark.xpdl.XMLUtil;
0027: import org.enhydra.shark.xpdl.XPDLConstants;
0028: import org.enhydra.shark.xpdl.elements.Activities;
0029: import org.enhydra.shark.xpdl.elements.Activity;
0030: import org.enhydra.shark.xpdl.elements.ActivitySet;
0031: import org.enhydra.shark.xpdl.elements.ExtendedAttribute;
0032: import org.enhydra.shark.xpdl.elements.Participant;
0033: import org.enhydra.shark.xpdl.elements.Transition;
0034: import org.enhydra.shark.xpdl.elements.Transitions;
0035: import org.enhydra.shark.xpdl.elements.WorkflowProcess;
0036: import org.jgraph.graph.AttributeMap;
0037: import org.jgraph.graph.CellView;
0038: import org.jgraph.graph.ConnectionSet;
0039: import org.jgraph.graph.DefaultGraphCell;
0040: import org.jgraph.graph.Edge;
0041: import org.jgraph.graph.GraphConstants;
0042: import org.jgraph.graph.ParentMap;
0043: import org.jgraph.graph.Port;
0044:
0045: /**
0046: * Class intended to serve as a control center for creation, removal, resizing
0047: * and changing position of Participants as well as for doing the same things
0048: * with Activity objects and Transitions. Class manages this actions in such a
0049: * way that undoing of operations are possible. It incorporates multiple view
0050: * and model changes into one by doing them virtually, and after all changes are
0051: * done, in interaction with JaWEGraphModel class applies this changes so that
0052: * undo is possible. Instance of this class is joined to to all objects of
0053: * classes derived from Graph class.
0054: * <p>
0055: * This class also handles the relationships between visual and logical
0056: * representation of workflow graph.
0057: * <p>
0058: * When reading a package from an XML file, this class creates imported objects
0059: * and establishes relationship between graph objects (classes within jawe and
0060: * jawe.graph package) and 'graph logic' objects ( classes within jawe.xml
0061: * package).
0062: *
0063: * @author Sasa Bojanic
0064: * @author Miroslav Popov
0065: */
0066: public class GraphManager implements Serializable {
0067:
0068: /** Graph reference */
0069: private transient Graph graph;
0070:
0071: /**
0072: * Offset for drawing - no meaning (it was used in previous versions)
0073: */
0074: private int horizontalOffset = 0;
0075:
0076: private int verticalOffset = 0;
0077:
0078: // some default values for setting participants and activity sizes
0079: // /** Variable that holds width of process */
0080: // private static final int defProcessWidth = JaWEConfig.getInstance().getProcessWidth();
0081: //
0082: // /** Variable that holds height of process */
0083: // private static final int defProcessHeight = JaWEConfig.getInstance().getProcessHeight();
0084:
0085: /*
0086: * horozontal paritcipant minParWidth
0087: * +===========================================+ + | + + | + minParHeight + | +
0088: * +===========================================+ vertical participant
0089: * minParHeight +++++++ = = =------ = = = = = = = minParWidht = = = = = = = = = = = =
0090: * +++++++
0091: */
0092: /** Variable that holds minimum width for any participant */
0093: private static int minParWidth;
0094:
0095: /** Variable that holds minimum height for any participant */
0096: private static int minParHeight;
0097:
0098: /** Variable that holds the width for participant name section */
0099: private static int defParNameWidth;
0100:
0101: /** Variable that holds width of activities */
0102: private static int defActivityWidth;
0103:
0104: /** Variable that holds height of activities */
0105: private static int defActivityHeight;
0106:
0107: private boolean creatingGraph = false;
0108:
0109: protected boolean pLoaded = false;
0110:
0111: public void init() {
0112: if (!pLoaded) {
0113:
0114: defActivityWidth = GraphUtilities.getGraphController()
0115: .getGraphSettings().getActivityWidth();
0116: defActivityHeight = GraphUtilities.getGraphController()
0117: .getGraphSettings().getActivityHeight();
0118: minParWidth = GraphUtilities.getGraphController()
0119: .getGraphSettings().getMinParWidth();
0120: minParHeight = GraphUtilities.getGraphController()
0121: .getGraphSettings().getMinParHeight();
0122: defParNameWidth = GraphUtilities.getGraphController()
0123: .getGraphSettings().getParticipantNameWidth();
0124:
0125: pLoaded = true;
0126: }
0127: }
0128:
0129: /**
0130: * Creates new workflow manager for given graph.
0131: *
0132: * @param g
0133: * The graph that manager manages.
0134: */
0135: public GraphManager(Graph g) {
0136: this .graph = g;
0137: init();
0138: }
0139:
0140: /** Returns the graph which is managed. */
0141: public Graph getGraph() {
0142: return graph;
0143: }
0144:
0145: public GraphController getGraphController() {
0146: return graph.getGraphController();
0147: }
0148:
0149: /**
0150: * Returns the graph model - the model that represents the graph view. (See
0151: * JGraph documentation).
0152: */
0153: public JaWEGraphModel graphModel() {
0154: return (JaWEGraphModel) graph.getModel();
0155: }
0156:
0157: /**
0158: * Creates graph representation of given workflow process. It creates a graph
0159: * entities (participants, activities, transitions) and associates the
0160: * workflow logic to it. The graph entities are inserted according to the
0161: * data that <tt>wp</tt> object holds (the data from XML file).
0162: * <p>
0163: * This is used when reading a workflow definition from an XML file.
0164: *
0165: * @param wpOrAs
0166: * Object that mapps the logic of WorkflowProcess element of XML -
0167: * defines a particular Workflow process.
0168: */
0169: public void createWorkflowGraph(XMLCollectionElement wpOrAs) {
0170: creatingGraph = true;
0171: // checks if it is graph made by JaWE
0172:
0173: //********* the creation other is very important and shouldn't be changed
0174: //System.out.println("Creating graph for WP "+wp+" and
0175: // VO="+getVisualOwner());
0176:
0177: List participantsToInsert = GraphUtilities
0178: .gatherParticipants(wpOrAs);
0179:
0180: // show Participants and their activities
0181: Iterator it = participantsToInsert.iterator();
0182: while (it.hasNext()) {
0183: ParticipantInfo pi = (ParticipantInfo) it.next();
0184: // GraphParticipantInterface gpar = insertParticipantAndArrangeParticipants(pi.getParticipant());
0185: insertParticipantAndArrangeParticipants(pi.getParticipant());
0186: // System.out.println("Participant " + gpar + " inserted for xpdl par " + pi.getParticipant().getId());
0187: Iterator acts = pi.getActivities().iterator();
0188: while (acts.hasNext()) {
0189: Activity act = (Activity) acts.next();
0190: insertActivity(act);
0191: }
0192: }
0193:
0194: // show transitions
0195: // System.out.println("Inserting transitions for " + getXPDLOwner().getId());
0196: it = ((Transitions) wpOrAs.get("Transitions")).toElements()
0197: .iterator();
0198: while (it.hasNext()) {
0199: Transition tra = (Transition) it.next();
0200: insertTransition(tra);
0201: }
0202:
0203: // show starts/ends
0204: if (GraphUtilities.getGraphController().getGraphSettings()
0205: .shouldUseBubbles()) {
0206: // show starts
0207: List starteas = GraphUtilities
0208: .getStartOrEndExtendedAttributes(getXPDLOwner(),
0209: true);
0210: if (starteas.size() > 0) {
0211: it = starteas.iterator();
0212: ExtendedAttribute ea;
0213: while (it.hasNext()) {
0214: ea = (ExtendedAttribute) it.next();
0215: insertStart(ea);
0216: }
0217: }
0218:
0219: // show ends
0220: List endeas = GraphUtilities
0221: .getStartOrEndExtendedAttributes(getXPDLOwner(),
0222: false);
0223: if (endeas.size() > 0) {
0224: it = endeas.iterator();
0225: ExtendedAttribute ea;
0226: while (it.hasNext()) {
0227: ea = (ExtendedAttribute) it.next();
0228: insertEnd(ea);
0229: }
0230: }
0231: } else {
0232: if (!wpOrAs.isReadOnly()) {
0233: List eas = GraphUtilities
0234: .getStartOrEndExtendedAttributes(wpOrAs, true);
0235: eas
0236: .addAll(GraphUtilities
0237: .getStartOrEndExtendedAttributes(
0238: wpOrAs, false));
0239: XMLUtil.getWorkflowProcess(wpOrAs)
0240: .getExtendedAttributes().removeAll(eas);
0241: }
0242: }
0243:
0244: creatingGraph = false;
0245: try {
0246: graph.setPreferredSize(getGraphsPreferredSize());
0247: } catch (Exception ex) {
0248: }
0249: }
0250:
0251: /**
0252: * Returns the object (part of mapped XML logic) that is represented by the
0253: * graph managed by WorklowManager. That object can be instance of the
0254: * Package, WorkflowProcess or ...xml.elements.BlockActivity class, and is
0255: * held as a property of the manager's graph object.
0256: *
0257: * @return The object (representing XML logic) that is represented by this
0258: * manager's graph.
0259: */
0260: public XMLCollectionElement getXPDLOwner() {
0261: return graph.getXPDLObject();
0262: }
0263:
0264: /**
0265: * Returns the (XML logic) WorkflowProcess object that is represented by the
0266: * manager's graph, or (if the graph represents the (XML logic) BlockActivity
0267: * content) the WorkflowProcess object that holds BlockActivity represented
0268: * by manager's graph. If graph represents (XML logic) Package object,
0269: * <tt>null</tt> is returned.
0270: */
0271: private WorkflowProcess getWorkflowProcess() {
0272: return graph.getWorkflowProcess();
0273: }
0274:
0275: public List getDisplayedParticipants() {
0276: List dps = new ArrayList();
0277: List graphParts = JaWEGraphModel
0278: .getAllParticipantsInModel(graphModel());
0279: if (graphParts != null) {
0280: GraphParticipantInterface graphPart;
0281: Iterator it = graphParts.iterator();
0282: while (it.hasNext()) {
0283: graphPart = (GraphParticipantInterface) it.next();
0284: dps.add(graphPart.getPropertyObject());
0285: }
0286: }
0287: return dps;
0288: }
0289:
0290: public boolean doesRootParticipantExist() {
0291: Set rootParticipants = JaWEGraphModel
0292: .getRootParticipants(graphModel());
0293: if (rootParticipants != null && rootParticipants.size() > 0) {
0294: return true;
0295: }
0296: return false;
0297: }
0298:
0299: public String getParticipantId(Point pos) {
0300: GraphParticipantInterface gpar = findParentActivityParticipantForLocation(
0301: pos, null, null);
0302: if (gpar != null) {
0303: return gpar.getPropertyObject().get("Id").toValue();
0304: }
0305: return "";
0306: }
0307:
0308: // ----------------------- Activity handling
0309: public GraphActivityInterface insertActivity(Activity xpdla) {
0310: // System.out.println("Inserting activity "+xpdla+", id=" + xpdla.getId() + ", name=" + xpdla.getName() + ", parId="
0311: // + GraphUtilities.getParticipantId(xpdla));
0312: Map viewMap = new HashMap();
0313:
0314: GraphParticipantInterface gpar = getGraphParticipant(GraphUtilities
0315: .getParticipantId(xpdla));
0316: // if (gpar==null) {
0317: // Point p=JaWEEAHandler.getOffsetPoint(xpdla);
0318: // gpar=findParentActivityParticipantForLocation(p,null,null);
0319: // }
0320: // System.out.println("Inserting act "+xpdla.getId()+" par="+gpar);
0321: Point p = getBounds(gpar, null).getBounds().getLocation();
0322: GraphActivityInterface gact = getGraphController()
0323: .getGraphObjectFactory().createActivity(viewMap, xpdla,
0324: p);
0325: //updateModelAndArrangeParticipants(new Object[] {act},viewMap,null,null,
0326: updateModelAndArrangeParticipants(new Object[] { gact }, null,
0327: null, viewMap, getGraphController().getSettings()
0328: .getLanguageDependentString(
0329: "MessageInsertingGenericActivity"),
0330: null, true);
0331: return gact;
0332: }
0333:
0334: public void removeActivity(Activity xpdla) {
0335: GraphActivityInterface gact = getGraphActivity(xpdla);
0336: Set edges = gact.getPort().getEdges();
0337: Iterator it = edges.iterator();
0338: Set toRem = new HashSet();
0339: while (it.hasNext()) {
0340: GraphTransitionInterface gt = (GraphTransitionInterface) it
0341: .next();
0342: toRem.add(gt);
0343: }
0344: toRem.add(gact);
0345: Object[] remove = toRem.toArray();
0346: graphModel().removeAndEdit(
0347: remove,
0348: null,
0349: getGraphController().getSettings()
0350: .getLanguageDependentString(
0351: "MessageRemovingObjects"));
0352:
0353: Map propertyMap = new HashMap();
0354: ParentMap parentMap = new JaWEParentMap();
0355: arrangeParticipants(propertyMap, parentMap);
0356: updateModelAndArrangeParticipants(new Object[] {}, propertyMap,
0357: parentMap, new HashMap(), "an", null, true);
0358:
0359: }
0360:
0361: public void arrangeActivityPosition(Activity act) {
0362: // System.out.println("Searching graph act for id "+act.getId());
0363: GraphActivityInterface gact = getGraphActivity(act.getId());
0364: // System.out.println("agact "+gact);
0365: GraphParticipantInterface newPar = getGraphParticipant(GraphUtilities
0366: .getParticipantId(act));
0367: // System.out.println("newpar "+newPar);
0368: GraphParticipantInterface oldPar = (GraphParticipantInterface) gact
0369: .getParent();
0370: // System.out.println("odlpar "+oldPar);
0371: //if (newPar==null || oldPar==null) return; // can happen when participant Id is updated
0372: ParentMap parentMap = new JaWEParentMap();
0373: if (!newPar.equals(oldPar)) {
0374: parentMap.addEntry(gact, newPar);
0375: }
0376:
0377: Map propertyMap = new HashMap();
0378: Point actRealPos = getRealPosition(gact, newPar);
0379: // GraphParticipantViewInterface gpvi=(GraphParticipantViewInterface)getView(newPar);
0380: // Rectangle parBounds=getBounds(newPar, propertyMap);
0381: // if (actRealPos.x>parBounds.width) {
0382: //// gpvi.
0383: // resizeAllParticipantsHorizontally(propertyMap, parentMap);
0384: // }
0385:
0386: changeBounds(gact, propertyMap, new Rectangle(actRealPos,
0387: new Dimension(defActivityWidth, defActivityHeight)));
0388: if (!newPar.equals(oldPar)) {
0389: if (isGraphRotated()) {
0390: arrangeParticipantHorizontally(newPar, propertyMap,
0391: parentMap);
0392: if (oldPar != null) {
0393: arrangeParticipantHorizontally(oldPar, propertyMap,
0394: parentMap);
0395: }
0396: } else {
0397: arrangeParticipantVertically(newPar, propertyMap,
0398: parentMap);
0399: if (oldPar != null) {
0400: arrangeParticipantVertically(oldPar, propertyMap,
0401: parentMap);
0402: }
0403: }
0404: }
0405: updateModelAndArrangeParticipants(null, propertyMap, parentMap,
0406: null, getGraphController().getSettings()
0407: .getLanguageDependentString(
0408: "MessageMovingObjects"), null, true);
0409:
0410: }
0411:
0412: // --------------------- transition handling
0413: public GraphTransitionInterface insertTransition(Transition xpdltra) {
0414: Map viewMap = new HashMap();
0415: // System.out.println("Inserting xpdltra " + xpdltra.getId() + ", F=" + xpdltra.getFrom() + ", T=" + xpdltra.getTo());
0416: List breakPoints = GraphUtilities.getBreakpoints(xpdltra);
0417: GraphActivityInterface source = getGraphActivity(xpdltra
0418: .getFrom());
0419: GraphActivityInterface target = getGraphActivity(xpdltra
0420: .getTo());
0421: if (source == null || target == null)
0422: return null;
0423: Point p11 = getCenter(source);
0424: Point p21 = getCenter(target);
0425: Point p = (Point) graph.fromScreen(new Point(p11));
0426: Point p2 = (Point) graph.fromScreen(new Point(p21));
0427: List points = new ArrayList();
0428: points.add(p);
0429: points.addAll(breakPoints);
0430: points.add(p2);
0431:
0432: GraphTransitionInterface gtra = getGraphController()
0433: .getGraphObjectFactory().createTransition(points,
0434: viewMap, xpdltra);
0435: // System.out.println("\ngTra11="+getView(gtra).getBounds());
0436: Object[] insert = new Object[] { gtra };
0437: ConnectionSet cs = new ConnectionSet();
0438:
0439: cs.connect(gtra, source.getPort(), target.getPort());
0440:
0441: //cs.connect(transition,source.getCell(),true);
0442: //cs.connect(transition,target.getCell(),false);
0443: String undoMsg = getGraphController().getSettings()
0444: .getLanguageDependentString(
0445: "MessageInsertingTransition");
0446: // graphModel().insertAndEdit(insert,cs,null,null,viewMap,undoMsg);
0447:
0448: graphModel().insertAndEdit(insert, viewMap, cs, null, null,
0449: undoMsg);
0450:
0451: return gtra;
0452: }
0453:
0454: public void removeTransition(Transition xpdltra) {
0455: //System.out.println("Graphmanager->removing transition "+xpdltra.getId());
0456: GraphTransitionInterface gtra = getGraphTransition(xpdltra);
0457: //System.out.println(" found graph transition "+gtra);
0458: removeTransition(gtra);
0459: }
0460:
0461: public void updateTransition(Transition xpdltra) {
0462: GraphTransitionInterface gtra = getGraphTransition(xpdltra);
0463: if (gtra == null) {
0464: gtra = insertTransition(xpdltra);
0465: } else {
0466: GraphActivityInterface s1 = gtra.getSourceActivity();
0467: GraphActivityInterface t1 = gtra.getTargetActivity();
0468:
0469: if (s1 == null || t1 == null) {
0470: removeTransition(gtra);
0471: gtra = insertTransition(xpdltra);
0472: return;
0473: }
0474:
0475: if (!s1.getPropertyObject().get("Id").toValue().equals(
0476: xpdltra.getFrom())
0477: || !t1.getPropertyObject().get("Id").toValue()
0478: .equals(xpdltra.getTo())) {
0479: removeTransition(gtra);
0480: gtra = insertTransition(xpdltra);
0481: return;
0482: }
0483:
0484: Map propertyMap = new HashMap();
0485:
0486: // breakpoints
0487: updateBreakPoints(gtra, propertyMap);
0488:
0489: // style
0490: updateStyle(gtra, propertyMap);
0491:
0492: ((JaWEGraphModel) graph.getModel()).insertAndEdit(null,
0493: propertyMap, null, null, null, "");
0494:
0495: }
0496: }
0497:
0498: public void updateBreakPoints(GraphTransitionInterface gtra,
0499: Map propertyMap) {
0500: List bps = GraphUtilities.getBreakpoints((Transition) gtra
0501: .getUserObject());
0502: GraphTransitionViewInterface gtraview = (GraphTransitionViewInterface) getView(gtra);
0503: if (gtraview == null)
0504: return;
0505: AttributeMap map = (AttributeMap) propertyMap.get(gtra);
0506: if (map == null) {
0507: map = new AttributeMap(gtra.getAttributes());
0508: propertyMap.put(gtra, map);
0509: }
0510: int pcnt = gtraview.getPointCount();
0511: Point2D ps = gtraview.getPoint(0);
0512: Point2D pt = gtraview.getPoint(pcnt - 1);
0513: List points = new ArrayList();
0514: points.add(ps);
0515: points.addAll(bps);
0516: points.add(pt);
0517: //JaWEManager.getInstance().getLoggingManager().debug("Updating breakpoints for transition: "+points);
0518: GraphConstants.setPoints(map, points);
0519: }
0520:
0521: public List addOrRemoveBreakPoint(GraphTransitionInterface gtra,
0522: Point p, boolean toAdd) {
0523: CellView view = graph.getGraphLayoutCache().getMapping(gtra,
0524: false);
0525: GraphTransitionViewInterface tv = (GraphTransitionViewInterface) view;
0526: if (toAdd) {
0527: tv.addPoint(graph, p);
0528: } else {
0529: tv.removePoint(graph, p);
0530: }
0531: int noOfPoints = tv.getPointCount();
0532: List pnts = new ArrayList();
0533: for (int i = 1; i < noOfPoints - 1; i++) {
0534: pnts.add(new Point((int) tv.getPoint(i).getX(), (int) tv
0535: .getPoint(i).getY()));//HM, JGraph3.4.1
0536: }
0537: //JaWEManager.getInstance().getLoggingManager().debug("Adding/removing breakpoint for transition: "+pnts);
0538: return pnts;
0539: }
0540:
0541: public void updateStyle(GraphTransitionInterface gtra) {
0542: Map propertyMap = new HashMap();
0543: updateStyle(gtra, propertyMap);
0544: String undoMsg = getGraphController().getSettings()
0545: .getLanguageDependentString(
0546: "MessageSettingTransitionTypeToNoRouting");
0547: ((JaWEGraphModel) graph.getModel()).insertAndEdit(null,
0548: propertyMap, null, null, null, undoMsg);
0549: }
0550:
0551: protected void updateStyle(GraphTransitionInterface gtra,
0552: Map propertyMap) {
0553: String style = GraphUtilities.getStyle((Transition) gtra
0554: .getUserObject());
0555: AttributeMap map = (AttributeMap) propertyMap.get(gtra);
0556: if (map == null) {
0557: map = new AttributeMap(gtra.getAttributes());
0558: propertyMap.put(gtra, map);
0559: }
0560:
0561: if (style
0562: .equals(GraphEAConstants.EA_JAWE_GRAPH_TRANSITION_STYLE_VALUE_NO_ROUTING_BEZIER)) {
0563: GraphConstants.setRouting(map, new NoRouting());
0564: GraphConstants.setLineStyle(map,
0565: GraphConstants.STYLE_BEZIER);
0566: } else if (style
0567: .equals(GraphEAConstants.EA_JAWE_GRAPH_TRANSITION_STYLE_VALUE_NO_ROUTING_SPLINE)) {
0568: GraphConstants.setRouting(map, new NoRouting());
0569: GraphConstants.setLineStyle(map,
0570: GraphConstants.STYLE_SPLINE);
0571: } else if (style
0572: .equals(GraphEAConstants.EA_JAWE_GRAPH_TRANSITION_STYLE_VALUE_SIMPLE_ROUTING_BEZIER)) {
0573: GraphConstants.setRouting(map,
0574: GraphConstants.ROUTING_SIMPLE);
0575: GraphConstants.setLineStyle(map,
0576: GraphConstants.STYLE_BEZIER);
0577: } else if (style
0578: .equals(GraphEAConstants.EA_JAWE_GRAPH_TRANSITION_STYLE_VALUE_SIMPLE_ROUTING_ORTHOGONAL)) {
0579: GraphConstants.setRouting(map,
0580: GraphConstants.ROUTING_SIMPLE);
0581: GraphConstants.setLineStyle(map,
0582: GraphConstants.STYLE_ORTHOGONAL);
0583: } else if (style
0584: .equals(GraphEAConstants.EA_JAWE_GRAPH_TRANSITION_STYLE_VALUE_SIMPLE_ROUTING_SPLINE)) {
0585: GraphConstants.setRouting(map,
0586: GraphConstants.ROUTING_SIMPLE);
0587: GraphConstants.setLineStyle(map,
0588: GraphConstants.STYLE_SPLINE);
0589: } else {
0590: GraphConstants.setRouting(map, new NoRouting());
0591: GraphConstants.setLineStyle(map,
0592: GraphConstants.STYLE_ORTHOGONAL);
0593: }
0594:
0595: }
0596:
0597: protected void removeTransition(GraphTransitionInterface gtra) {
0598: if (gtra == null)
0599: return;
0600: // System.out.println("\ngTra11="+getView(gtra).getBounds());
0601: Object[] remove = new Object[] { gtra };
0602: //cs.connect(transition,source.getCell(),true);
0603: //cs.connect(transition,target.getCell(),false);
0604: graphModel().removeAndEdit(
0605: remove,
0606: null,
0607: getGraphController().getSettings()
0608: .getLanguageDependentString(
0609: "MessageRemovingObjects"));
0610:
0611: Map propertyMap = new HashMap();
0612: ParentMap parentMap = new JaWEParentMap();
0613: arrangeParticipants(propertyMap, parentMap);
0614: updateModelAndArrangeParticipants(new Object[] {}, propertyMap,
0615: parentMap, new HashMap(), "an", null, true);
0616:
0617: }
0618:
0619: // --------------------- start/end bubble handling
0620: public GraphActivityInterface insertStart(ExtendedAttribute sea) {
0621: Map viewMap = new HashMap();
0622: StartEndDescription sd = new StartEndDescription(sea);
0623: GraphParticipantInterface gpar = getGraphParticipant(sd
0624: .getParticipantId());
0625: Point p = getBounds(gpar, null).getBounds().getLocation();
0626: GraphBubbleActivityInterface gact = getGraphController()
0627: .getGraphObjectFactory().createStart(viewMap, sea, p);
0628: updateModelAndArrangeParticipants(new Object[] { gact }, null,
0629: null, viewMap, getGraphController().getSettings()
0630: .getLanguageDependentString(
0631: "MessageInsertingGenericActivity"),
0632: null, true);
0633: connectStartOrEndBubble(gact, sd.getActId());
0634: return gact;
0635: }
0636:
0637: public GraphActivityInterface insertEnd(ExtendedAttribute eea) {
0638: Map viewMap = new HashMap();
0639: StartEndDescription ed = new StartEndDescription(eea);
0640: GraphParticipantInterface gpar = getGraphParticipant(ed
0641: .getParticipantId());
0642: // System.err.println("Par for id "+ed.getParticipantId()+" is "+gpar);
0643: Point p = getBounds(gpar, null).getBounds().getLocation();
0644: GraphBubbleActivityInterface gact = getGraphController()
0645: .getGraphObjectFactory().createEnd(viewMap, eea, p);
0646: updateModelAndArrangeParticipants(new Object[] { gact }, null,
0647: null, viewMap, getGraphController().getSettings()
0648: .getLanguageDependentString(
0649: "MessageInsertingGenericActivity"),
0650: null, true);
0651: connectStartOrEndBubble(gact, ed.getActId());
0652: return gact;
0653: }
0654:
0655: public void removeBubble(ExtendedAttribute ea) {
0656: // System.err.println("REMOVVING BUBBLE " + ea.getVValue());
0657: GraphBubbleActivityInterface gact = getBubble(ea);
0658: if (gact == null)
0659: return;
0660: Set edges = gact.getPort().getEdges();
0661: Object[] remove;
0662: if (edges != null && edges.size() > 0) {
0663: remove = new Object[] { gact, edges.toArray()[0] };
0664: } else {
0665: remove = new Object[] { gact };
0666: }
0667:
0668: graphModel().removeAndEdit(
0669: remove,
0670: null,
0671: getGraphController().getSettings()
0672: .getLanguageDependentString(
0673: "MessageRemovingObjects"));
0674:
0675: Map propertyMap = new HashMap();
0676: ParentMap parentMap = new JaWEParentMap();
0677: arrangeParticipants(propertyMap, parentMap);
0678: updateModelAndArrangeParticipants(new Object[] {}, propertyMap,
0679: parentMap, new HashMap(), "an", null, true);
0680:
0681: }
0682:
0683: public GraphTransitionInterface connectStartOrEndBubble(
0684: GraphBubbleActivityInterface startOrEnd, String actId) {
0685: if (actId == null)
0686: return null;
0687:
0688: Map viewMap = new HashMap();
0689:
0690: StartEndDescription sed = startOrEnd.getStartEndDescription();
0691: GraphActivityInterface source = startOrEnd;
0692: GraphActivityInterface target = getGraphActivity(actId);
0693:
0694: if (source == null || target == null)
0695: return null;
0696:
0697: if (!sed.isStart()) {
0698: source = target;
0699: target = startOrEnd;
0700: }
0701: Point p11 = getCenter(source);
0702: Point p21 = getCenter(target);
0703: Point p = (Point) graph.fromScreen(new Point(p11));
0704: Point p2 = (Point) graph.fromScreen(new Point(p21));
0705: List points = new ArrayList();
0706: points.add(p);
0707: points.add(p2);
0708:
0709: GraphTransitionInterface gtra = getGraphController()
0710: .getGraphObjectFactory().createBubbleTransition(points,
0711: viewMap, sed.getTransitionStyle());
0712: // System.out.println("\ngTra11="+getView(gtra).getBounds());
0713: Object[] insert = new Object[] { gtra };
0714: ConnectionSet cs = new ConnectionSet();
0715:
0716: cs.connect(gtra, source.getPort(), target.getPort());
0717:
0718: //cs.connect(transition,source.getCell(),true);
0719: //cs.connect(transition,target.getCell(),false);
0720: String undoMsg = getGraphController().getSettings()
0721: .getLanguageDependentString(
0722: "MessageInsertingTransition");
0723: // graphModel().insertAndEdit(insert,cs,null,null,viewMap,undoMsg);
0724:
0725: graphModel().insertAndEdit(insert, viewMap, cs, null, null,
0726: undoMsg);
0727:
0728: return gtra;
0729: }
0730:
0731: public void updateBubble(ExtendedAttribute ea) {
0732: GraphBubbleActivityInterface gact = getBubble(ea);
0733: if (gact == null) {
0734: return;
0735: }
0736: StartEndDescription sed = gact.getStartEndDescription();
0737: String connectingActivityId = sed.getActId();
0738: GraphActivityInterface connAct = null;
0739: Set cas = null;
0740: if (gact.isStart()) {
0741: cas = gact.getReferencedActivities();
0742: } else {
0743: cas = gact.getReferencingActivities();
0744: }
0745: if (cas.size() > 0) {
0746: connAct = (GraphActivityInterface) cas.toArray()[0];
0747: }
0748: boolean disconnect = false;
0749: boolean connect = false;
0750: if (connectingActivityId == null) {
0751: if (connAct != null) {
0752: disconnect = true;
0753: }
0754: } else {
0755: if (connAct == null) {
0756: connect = true;
0757: } else {
0758: if (!connAct.getPropertyObject().get("Id").toValue()
0759: .equals(connectingActivityId)) {
0760: disconnect = true;
0761: connect = true;
0762: }
0763: }
0764: }
0765: if (disconnect) {
0766: Set edges = gact.getPort().getEdges();
0767: removeTransition((GraphTransitionInterface) edges.toArray()[0]);
0768: }
0769: if (connect) {
0770: connectStartOrEndBubble(gact, connectingActivityId);
0771: }
0772:
0773: GraphParticipantInterface oldPar = (GraphParticipantInterface) gact
0774: .getParent();
0775: GraphParticipantInterface newPar = getGraphParticipant(sed
0776: .getParticipantId());
0777:
0778: if (newPar == null || oldPar == null) {
0779: Thread.dumpStack();
0780: return; // can happen when participant Id is updated
0781: }
0782: ParentMap parentMap = new JaWEParentMap();
0783: if (!newPar.equals(oldPar)) {
0784: parentMap.addEntry(gact, newPar);
0785: }
0786:
0787: Map propertyMap = new HashMap();
0788: changeBounds(gact, propertyMap, new Rectangle(getRealPosition(
0789: gact, newPar), new Dimension(defActivityHeight / 5 * 3,
0790: defActivityHeight / 5 * 3)));
0791:
0792: if (!newPar.equals(oldPar)) {
0793: if (isGraphRotated()) {
0794: arrangeParticipantHorizontally(newPar, propertyMap,
0795: parentMap);
0796: if (oldPar != null) {
0797: arrangeParticipantHorizontally(oldPar, propertyMap,
0798: parentMap);
0799: }
0800: } else {
0801: arrangeParticipantVertically(newPar, propertyMap,
0802: parentMap);
0803: if (oldPar != null) {
0804: arrangeParticipantVertically(oldPar, propertyMap,
0805: parentMap);
0806: }
0807: }
0808: }
0809:
0810: updateModelAndArrangeParticipants(null, propertyMap, parentMap,
0811: null, getGraphController().getSettings()
0812: .getLanguageDependentString(
0813: "MessageMovingObjects"), null, true);
0814:
0815: }
0816:
0817: public void arrangeBubblePosition(ExtendedAttribute ea,
0818: GraphParticipantInterface newPar) {
0819: GraphBubbleActivityInterface gact = getBubble(ea);
0820: // System.out.println("bubble "+gact);
0821: // System.out.println("newpar "+newPar);
0822: GraphParticipantInterface oldPar = (GraphParticipantInterface) gact
0823: .getParent();
0824: // System.out.println("odlpar "+oldPar);
0825: if (newPar == null || oldPar == null)
0826: return; // can happen when participant Id is updated
0827: ParentMap parentMap = new JaWEParentMap();
0828: if (!newPar.equals(oldPar)) {
0829: parentMap.addEntry(gact, newPar);
0830: }
0831:
0832: Map propertyMap = new HashMap();
0833: changeBounds(gact, propertyMap, new Rectangle(getRealPosition(
0834: gact, newPar), new Dimension(defActivityHeight / 5 * 3,
0835: defActivityHeight / 5 * 3)));
0836: updateModelAndArrangeParticipants(null, propertyMap, parentMap,
0837: null, getGraphController().getSettings()
0838: .getLanguageDependentString(
0839: "MessageMovingObjects"), null, true);
0840:
0841: }
0842:
0843: // ----------------------- participant handling
0844:
0845: /**
0846: * Inserts new Participant cell into model. First, the
0847: * parent of new Participant is searched, and if found, put into ParentMap
0848: * (it is not inserted into model at ones). If parent participant isn't found ->
0849: * root participant will be inserted. After that model's view is arranged
0850: * (Participants are moved and translated along with it's children cells) to
0851: * suite to the new model state - this is done "virtually" which means that
0852: * changes are not directly applied to view until all changes are made. At
0853: * the end, all changes are applied to model and view. Such procedure enables
0854: * compound undo support. <BR>
0855: * This method is called when inserting new Participant into model.
0856: *
0857: */
0858: public GraphParticipantInterface insertParticipantAndArrangeParticipants(
0859: Participant par) {
0860:
0861: Map viewMap = new HashMap();
0862: ParentMap parentMap = null;
0863: Map propertyMap = null;
0864:
0865: // get the topmost participant at the location where
0866: // user want to insert participant
0867: Rectangle bounds = null;
0868: //System.err.println("Inserting participant "+par.getId()+", isGR="+isGraphRotated());
0869: if (isGraphRotated()) {
0870: bounds = new Rectangle(getNewRootParXPos(null, null),
0871: verticalOffset, minParHeight,
0872: getRootParticipantHeight(null, null));
0873: } else {
0874: bounds = new Rectangle(horizontalOffset, getNewRootParYPos(
0875: null, null), getRootParticipantWidth(null, null),
0876: minParHeight);
0877: }
0878: GraphParticipantInterface gpar = getGraphController()
0879: .getGraphObjectFactory().createParticipant(bounds,
0880: viewMap, par);
0881:
0882: propertyMap = new HashMap(viewMap);
0883:
0884: Object[] insert = new Object[] { gpar };
0885: // graphModel().insertAndEdit(insert,null,propertyMap,parentMap,viewMap,
0886: graphModel().insertAndEdit(
0887: insert,
0888: propertyMap,
0889: null,
0890: parentMap,
0891: null,
0892: getGraphController().getSettings()
0893: .getLanguageDependentString(
0894: "MessageInsertingParticipant"));
0895:
0896: if (!creatingGraph) {
0897: try {
0898: graph.setPreferredSize(getGraphsPreferredSize());
0899: } catch (Exception ex) {
0900: }
0901: }
0902:
0903: return gpar;
0904: }
0905:
0906: /**
0907: * Removes cells <b>cellsToDelete </b> from model. This means that given
0908: * cells and all of their descendants as well as all transitions that
0909: * connects given cells, will be removed from model. First, all remained
0910: * participants are moved and resized according to participants that are
0911: * beeing removed and ParentMap for all removed cells is created (all these
0912: * things are made "virtually" - not applied to model and view). After that
0913: * model's new view is arranged (Participants are moved and translated (along
0914: * with it's children cells) according to the remained children - this is
0915: * also done "virtually". At the end, all changes are applied to model and
0916: * view. Such procedure enables compound undo support. <BR>
0917: * This method is called when deleting or cutting cells from graph.
0918: */
0919: public void removeCellsAndArrangeParticipants(Object[] cellsToDelete) {
0920: Set participantsToArrange = new HashSet();
0921: Map propertyMap = new HashMap();
0922: ParentMap parentMap = new JaWEParentMap();
0923:
0924: Set ports = new HashSet();
0925: // begining arrangement of parent of cells that will be deleted
0926: if (cellsToDelete != null && cellsToDelete.length > 0) {
0927: for (int i = 0; i < cellsToDelete.length; i++) {
0928: if (cellsToDelete[i] instanceof GraphParticipantInterface) {
0929: GraphParticipantInterface par = (GraphParticipantInterface) cellsToDelete[i];
0930:
0931: // getting bounds of rectangle
0932: Rectangle2D r = getBounds(par, propertyMap);//HM, JGraph3.4.1
0933: int yPos = r.getBounds().y + r.getBounds().height
0934: - 1;//HM,
0935: int xPos = r.getBounds().x + r.getBounds().width
0936: - 1;//HM,
0937: // JGraph3.4.1
0938:
0939: // resize all parent participants (reduce their sizes) if needed,
0940: // and
0941: // also if needed, translate up all participants under yPos
0942: GraphParticipantInterface ppar = (GraphParticipantInterface) par
0943: .getParent();
0944: if (ppar != null) {
0945: // resizing and translating is needed only if "first" parent
0946: // has other children except one that is beeing removed
0947: // or if its height can be reduced
0948: if (ppar.getChildCount() > 1
0949: || getParticipantHeight(ppar,
0950: propertyMap) > minParHeight) {
0951: // gets all parents and resizes it
0952: Object[] allParents = ppar.getPath();
0953: // calculates resize value
0954: int resizeValue = r.getBounds().height;//HM, JGraph3.4.1
0955: int pHeight = getParticipantHeight(ppar,
0956: propertyMap);
0957: // do not allow to resize participant under it's minimal
0958: // height
0959: if (pHeight - r.getBounds().height < minParHeight) {//HM,
0960: // JGraph3.4.1
0961: resizeValue = pHeight - minParHeight;
0962: }
0963: resize(allParents, propertyMap, 0,
0964: -resizeValue);
0965: // translate up all participants under yPos
0966: translateVertically(propertyMap, null,
0967: yPos, -resizeValue);
0968: }
0969: }
0970: // if participant is root there is a need of translating
0971: // participants under it
0972: else {
0973: // translate up all participants under yPos
0974: if (!isGraphRotated()) {
0975: translateVertically(propertyMap, null,
0976: yPos, -r.getBounds().height);//HM,
0977: // JGraph3.4.1
0978: } else {
0979: // JGraph3.4.1
0980: translateHorizontally(propertyMap, null,
0981: xPos, -r.getBounds().width);
0982: }
0983: }
0984: // if some port is originally set to be deleted it must be
0985: // removed
0986: } else if (cellsToDelete[i] instanceof Port) {
0987: ports.add(cellsToDelete[i]);
0988: }
0989: }
0990:
0991: // removing ports if they were somehow selected
0992: Set ctd = new HashSet(Arrays.asList(cellsToDelete));
0993: ctd.removeAll(ports);
0994: if (ctd.size() == 0)
0995: return;
0996: cellsToDelete = ctd.toArray();
0997:
0998: // after previous, participant's are transleted and resized to certain
0999: // extent,
1000: // now final resizing and translation takes place (translation and
1001: // resizing
1002: // that calculates minimal possible height and width of participants
1003: // according
1004: // to the activities that are contained within participant after
1005: // deletion)
1006:
1007: // All cells in model to be deleted
1008: List cellsToDel = JaWEGraphModel.getDescendantList(
1009: graphModel(), cellsToDelete);
1010: // getting transitions(edges) which are connected to the cellsForDel ->
1011: // also has to be deleted
1012: List edges = JaWEGraphModel.getEdges(graphModel(),
1013: cellsToDel.toArray());
1014:
1015: // putting all items for deletation (edges and cells) together - thats
1016: // ALL FOR DELETION
1017: cellsToDel.addAll(edges);
1018:
1019: // Separate cells and edges
1020: Set allEdgesToDelete = new HashSet();
1021: Set allCellsToDelete = new HashSet();
1022: Iterator it = cellsToDel.iterator();
1023: while (it.hasNext()) {
1024: Object cell = it.next();
1025: if (cell instanceof Edge) {
1026: allEdgesToDelete.add(cell);
1027: } else if (!(cell instanceof Port)) {
1028: allCellsToDelete.add(cell);
1029: }
1030: }
1031:
1032: // working resize and translation only with cells (edges doesn't count)
1033: cellsToDelete = allCellsToDelete.toArray();
1034:
1035: for (int i = 0; i < cellsToDelete.length; i++) {
1036: // adding parent of removing Activity cell (if there is one and if
1037: // it is Participant) into array for arranging participants, and
1038: // creating
1039: // entry in parentMap -> this will be of use after basic resizing
1040: // and translating operations
1041: Object parent = ((DefaultMutableTreeNode) cellsToDelete[i])
1042: .getParent();
1043: if ((parent != null)
1044: && (parent instanceof GraphParticipantInterface)) {
1045: if (cellsToDelete[i] instanceof GraphActivityInterface) {
1046: participantsToArrange.add(parent);
1047: }
1048: }
1049: parentMap.addEntry(cellsToDelete[i], null);
1050: }
1051:
1052: // resizing remained participants
1053: if (!isGraphRotated()) {
1054: resizeAllParticipantsHorizontally(propertyMap,
1055: parentMap);
1056: arrangeParticipantsVertically(participantsToArrange
1057: .toArray(), propertyMap, parentMap);
1058: } else {
1059: resizeAllParticipantsVertically(propertyMap, parentMap);
1060: arrangeParticipantsHorizontally(participantsToArrange
1061: .toArray(), propertyMap, parentMap);
1062: }
1063:
1064: graphModel().removeAndEdit(
1065: cellsToDel.toArray(),
1066: propertyMap,
1067: getGraphController().getSettings()
1068: .getLanguageDependentString(
1069: "MessageRemovingObjects"));
1070:
1071: }
1072:
1073: try {
1074: graph.setPreferredSize(getGraphsPreferredSize());
1075: } catch (Exception ex) {
1076: }
1077: }
1078:
1079: /**
1080: * Returns horizontal offset for inserting participants.
1081: */
1082: public int getHorizontalOffset() {
1083: return horizontalOffset;
1084: }
1085:
1086: /**
1087: * Returns the point within the graph where the upper-left corner of given
1088: * graph activity is placed. The point origin is the upper-left corner of
1089: * participant graph object that holds given activity.
1090: */
1091: public Point getOffset(GraphActivityInterface a, Map propertyMap) {
1092: if (a != null) {
1093: GraphParticipantInterface par = (GraphParticipantInterface) a
1094: .getParent();
1095: if (par != null) {
1096: Rectangle2D rpar = getBounds(par, propertyMap);//HM, JGraph3.4.1
1097: Rectangle2D ract = getBounds(a, propertyMap);//HM, JGraph3.4.1
1098: int yOff = ract.getBounds().y - rpar.getBounds().y;//HM,
1099: // JGraph3.4.1
1100: int xOff = ract.getBounds().x - rpar.getBounds().x;//HM,
1101: // JGraph3.4.1
1102: return new Point(xOff, yOff);
1103: }
1104: }
1105: return new Point(0, 0);
1106: }
1107:
1108: public Point getOffset(Point actPoint) {
1109: if (actPoint != null) {
1110: GraphParticipantInterface par = findParentActivityParticipantForLocation(
1111: actPoint, null, null);
1112: // System.err.println("Handling relative offset for point "+actPoint+", found par="+par);
1113: if (par != null) {
1114: Rectangle2D rpar = getBounds(par, new HashMap());//HM, JGraph3.4.1
1115: int yOff = actPoint.y - rpar.getBounds().y;//HM, JGraph3.4.1
1116: int xOff = actPoint.x - rpar.getBounds().x;//HM, JGraph3.4.1
1117: // System.err.println(" ..........par bounds "+rpar+", offset="+new Point(xOff,yOff));
1118: return new Point(xOff, yOff);
1119: }
1120: }
1121: return new Point(0, 0);
1122: }
1123:
1124: public Point getRealPosition(GraphActivityInterface a,
1125: GraphParticipantInterface gpar) {
1126: if (a != null) {
1127: if (gpar != null) {
1128: CellView view = getView(gpar);
1129: Rectangle2D rpar = view.getBounds();
1130: Point aoffset = a.getOffset();
1131: int y = aoffset.y + rpar.getBounds().y;
1132: int x = aoffset.x + rpar.getBounds().x;
1133: // System.out.println("NP1="+new Point(x,y));
1134: //
1135: // if (y>rpar.getHeight()) y=(int)rpar.getHeight()-defActivityHeight-5;
1136: // if (x>rpar.getWidth()) x=(int)rpar.getWidth()-defActivityWidth-10;
1137: Point p = new Point(x, y);
1138: // System.out.println("NP2="+p);
1139: return p;
1140: }
1141: }
1142: return new Point(0, 0);
1143: }
1144:
1145: /**
1146: * Inserts new activities into model, changes positions and sizes of
1147: * participants due to a insertion of new activities or due to a moving of
1148: * activities. Also, finds and changes parent's of inserted/changed-position
1149: * activities. This method is called when inserting new activities, when
1150: * pasting activities, and when moving activities. All changes to the model
1151: * and to the view are at first made virtually (to the parentMap and to the
1152: * propertyMap) and when all is done, method insertAndEdit of PEGraphModel
1153: * class is called to actually make changes. The updateCollection parameter
1154: * is used when some objects are inserted into model, to update collection of
1155: * XML elements.
1156: *
1157: * @param arrangeParticipants
1158: * TODO
1159: */
1160: protected void updateModelAndArrangeParticipants(Object[] insert,
1161: Map propertyMap, ParentMap parentMap, Map viewMap,
1162: String actionName, ConnectionSet cs,
1163: boolean arrangeParticipants) {
1164:
1165: if (propertyMap == null && viewMap == null)
1166: return;
1167: if (propertyMap == null) {
1168: propertyMap = new HashMap(viewMap);
1169: }
1170: if (parentMap == null) {
1171: parentMap = new JaWEParentMap();
1172: }
1173:
1174: if (arrangeParticipants) {
1175: arrangeParticipants(propertyMap, parentMap);
1176: } else {
1177: arrangeParticipantRelationsOnly(propertyMap, parentMap);
1178: }
1179: // extracting viewMap elements out of propertyMap (if any), applying
1180: // change to viewMap element bounds (this must be done, because user
1181: // could press mouse when inserting or pasting activities at the
1182: // forbiden position so position of activity is changed during
1183: // updateActivityParent method) and applying change to model and view
1184:
1185: // if (viewMap != null) { Iterator it = viewMap.keySet().iterator(); while
1186: // (it.hasNext()) { Object cell=it.next();
1187: // // removing entry for cell that is contained within viewMap
1188: // Map mapP=(Map)propertyMap.remove(cell);
1189: // // apply position changes to corresponding viewMap element
1190: // Map mapV=(Map)viewMap.get(cell);
1191: // if (!(cell instanceof Port)) {
1192: // Rectangle2D r=GraphConstants.getBounds(mapP);
1193: // GraphConstants.setBounds(mapV,r);
1194: // }
1195: // }
1196: // }
1197:
1198: if (insert != null
1199: && ((JaWEParentMap) parentMap).entryCount() != insert.length) {
1200: //return; //HM: enable Transition-copy/paste
1201: }
1202:
1203: // makes all changes (if there was any) - to model and to view
1204: //graphModel().insertAndEdit(insert,null,propertyMap,parentMap,viewMap,actionName);
1205: graphModel().insertAndEdit(insert, propertyMap, cs, parentMap,
1206: null, actionName);
1207:
1208: Dimension prefSize = null;
1209: if (!creatingGraph) {
1210: try {
1211: prefSize = getGraphsPreferredSize();
1212: } catch (Exception ex) {
1213: }
1214: }
1215:
1216: if (!creatingGraph && prefSize != null) {
1217: try {
1218: graph.setPreferredSize(prefSize);
1219: } catch (Exception ex) {
1220: }
1221: }
1222: }
1223:
1224: /**
1225: * Arranges participants according to the given property and parent maps.
1226: */
1227: protected void arrangeParticipants(Map propertyMap,
1228: ParentMap parentMap) {
1229: Set parsToArrange = new HashSet();
1230: // going through given propertyMap keys, and if key is
1231: // activity->updating it's parent if needed.
1232: // WARNING: must extract keys and put it in a array because
1233: // propertyMap changes -> ConcurrentModificationException
1234: // can happend
1235: Object[] cellsToManage = propertyMap.keySet().toArray();
1236: for (int i = 0; i < cellsToManage.length; i++) {
1237: Object cell = cellsToManage[i];
1238: if (cell instanceof GraphActivityInterface) {
1239: Set oldAndNewParentPar = updateActivityParent(
1240: (GraphActivityInterface) cell, propertyMap,
1241: parentMap);
1242: parsToArrange.addAll(oldAndNewParentPar);
1243: }
1244: }
1245:
1246: if (isGraphRotated()) {
1247: arrangeParticipantsHorizontally(parsToArrange.toArray(),
1248: propertyMap, parentMap);
1249: resizeAllParticipantsVertically(propertyMap, parentMap);
1250: } else {
1251: // arrange participants vertically
1252: arrangeParticipantsVertically(parsToArrange.toArray(),
1253: propertyMap, parentMap);
1254: resizeAllParticipantsHorizontally(propertyMap, parentMap);
1255: }
1256: }
1257:
1258: protected void arrangeParticipantRelationsOnly(Map propertyMap,
1259: ParentMap parentMap) {
1260: Set parsToArrange = new HashSet();
1261: // going through given propertyMap keys, and if key is
1262: // activity->updating it's parent if needed.
1263: // WARNING: must extract keys and put it in a array because
1264: // propertyMap changes -> ConcurrentModificationException
1265: // can happend
1266: Object[] cellsToManage = propertyMap.keySet().toArray();
1267: for (int i = 0; i < cellsToManage.length; i++) {
1268: Object cell = cellsToManage[i];
1269: if (cell instanceof GraphActivityInterface) {
1270: Set oldAndNewParentPar = updateActivityParent(
1271: (GraphActivityInterface) cell, propertyMap,
1272: parentMap);
1273: parsToArrange.addAll(oldAndNewParentPar);
1274: }
1275: }
1276: }
1277:
1278: /**
1279: * Determines old and new participant for activity, adjusts activities
1280: * position if needed and properly changes parent of activity (adds entry
1281: * into the parentMap).
1282: */
1283: protected Set updateActivityParent(GraphActivityInterface ac,
1284: Map propertyMap, ParentMap parentMap) {
1285: // must return old and new participant to the caller method
1286: Set oldAndNewPar = new HashSet();
1287: // old and new parent participant of given activity
1288: GraphParticipantInterface oldPar = (GraphParticipantInterface) ac
1289: .getParent();
1290:
1291: // adds oldPar to the set to be returned
1292: if (oldPar != null) {
1293: oldAndNewPar.add(oldPar);
1294: }
1295:
1296: GraphParticipantInterface newPar = null;
1297: // taking position elements of Activity
1298: // taking bounding rectangle
1299: Rectangle2D acRect = getBounds(ac, propertyMap);//HM, JGraph3.4.1
1300: // taking upper-left corner, this will be reference for moving activitys
1301: Point acUpperLeft = acRect.getBounds().getLocation();//HM, JGraph3.4.1
1302: Point newAcUpperLeft = new Point(acUpperLeft);
1303:
1304: newPar = findParentActivityParticipantForLocation(
1305: newAcUpperLeft, propertyMap, parentMap);
1306:
1307: // System.out.println("Old par for activity "+ac+" is "+oldPar+", and new par is "+newPar);
1308: // if previous method changed location of upper-left point,
1309: // move activity to new location
1310: if (!newAcUpperLeft.equals(acUpperLeft)) {
1311: Rectangle r = new Rectangle(acRect.getBounds());//HM, JGraph3.4.1
1312: r.setLocation(newAcUpperLeft);
1313: changeBounds(ac, propertyMap, r);
1314: }
1315:
1316: if (newPar != null) {
1317: // adds newPar to the set to be returned
1318: oldAndNewPar.add(newPar);
1319:
1320: // VERY IMPORTANT IS TO CHANGE THE PARENT
1321: // changing the parent participant of Activity cell if it has changed
1322: // position
1323: if (!newPar.equals(oldPar)) {
1324: parentMap.addEntry(ac, newPar);
1325: }
1326: }
1327:
1328: return oldAndNewPar;
1329:
1330: }
1331:
1332: public GraphParticipantInterface findParentForLocation(Point loc) {
1333: GraphParticipantInterface newPar = null;
1334: // if user put activity cell somewhere outside visible area, move it back
1335: if (loc.y <= 0) {
1336: loc.y = 1;
1337: }
1338: if (loc.x <= 0) {
1339: loc.x = 1;
1340: }
1341:
1342: // determining the container for new position
1343: if (isGraphRotated()) {
1344: newPar = getLeafParticipantForXPos(loc.x, null, null);
1345: } else {
1346: newPar = getLeafParticipantForYPos(loc.y, null, null);
1347: }
1348:
1349: return newPar;
1350: }
1351:
1352: /**
1353: * Finds new participant for activity after it's position changes. WARNING:
1354: * this method changes it's argument loc if not appropriate.
1355: */
1356: public GraphParticipantInterface findParentActivityParticipantForLocation(
1357: Point loc, Map propertyMap, ParentMap parentMap) {
1358: GraphParticipantInterface newPar = null;
1359: // if user put activity cell somewhere outside visible area, move it back
1360: if (loc.y <= 0) {
1361: loc.y = 1;
1362: }
1363: if (loc.x <= 0) {
1364: loc.x = 1;
1365: }
1366:
1367: // determining the container for new position
1368: if (isGraphRotated()) {
1369: newPar = getLeafParticipantForXPos(loc.x, propertyMap,
1370: parentMap);
1371:
1372: // if new container isn't found -> activity is placed under all
1373: // participants
1374: // so it's new participant will be the leaf participant with the
1375: // highest y-coord
1376: if (newPar == null) {
1377: newPar = getLeafParticipantForXPos(getNewRootParXPos(
1378: propertyMap, null) - 10, propertyMap, parentMap);
1379: }
1380:
1381: if (newPar != null) {
1382: // Adjust activities x-pos if needed
1383: Rectangle2D newParRect = getBounds(newPar, propertyMap);//HM,
1384: // JGraph3.4.1
1385: // if x-position is not OK, set appropriate position
1386: if (newParRect.getY() + defParNameWidth >= loc.y) {
1387: loc.y = (int) (newParRect.getY() + defParNameWidth + 1);
1388: }
1389: }
1390: // it is activity that belongs to an block activity
1391: else {
1392: // if x-position is not OK, set appropriate position
1393: if (verticalOffset >= loc.y) {
1394: loc.y = horizontalOffset;
1395: }
1396: }
1397: } else {
1398: newPar = getLeafParticipantForYPos(loc.y, propertyMap,
1399: parentMap);
1400:
1401: // if new container isn't found -> activity is placed under all
1402: // participants
1403: // so it's new participant will be the leaf participant with the
1404: // highest y-coord
1405: if (newPar == null) {
1406: newPar = getLeafParticipantForYPos(getNewRootParYPos(
1407: propertyMap, null) - 10, propertyMap, parentMap);
1408: }
1409:
1410: if (newPar != null) {
1411: // Adjust activities x-pos if needed
1412: Rectangle2D newParRect = getBounds(newPar, propertyMap);//HM,
1413: // JGraph3.4.1
1414: // if x-position is not OK, set appropriate position
1415: if (newParRect.getX() + defParNameWidth >= loc.x) {
1416: loc.x = (int) newParRect.getX() + defParNameWidth
1417: + 1;
1418: }
1419: }
1420: // it is activity that belongs to an block activity
1421: else {
1422: // if x-position is not OK, set appropriate position
1423: if (horizontalOffset >= loc.x) {
1424: loc.x = horizontalOffset;
1425: }
1426: }
1427: }
1428:
1429: return newPar;
1430: }
1431:
1432: protected void arrangeParticipantsHorizontally(Object[] pars,
1433: Map propertyMap, ParentMap parentMap) {
1434: if ((pars == null) || (pars.length == 0))
1435: return;
1436:
1437: for (int i = 0; i < pars.length; i++) {
1438: arrangeParticipantHorizontally(pars[i], propertyMap,
1439: parentMap);
1440: }
1441: }
1442:
1443: /**
1444: * Arranging heights and positions of given participants and positions of
1445: * participants that must be translated due to a change of given
1446: * participants.
1447: */
1448: protected void arrangeParticipantsVertically(Object[] pars,
1449: Map propertyMap, ParentMap parentMap) {
1450: if ((pars == null) || (pars.length == 0))
1451: return;
1452:
1453: for (int i = 0; i < pars.length; i++) {
1454: // arrange participants vertically
1455: arrangeParticipantVertically(pars[i], propertyMap,
1456: parentMap);
1457: }
1458: }
1459:
1460: protected void arrangeParticipantHorizontally(Object par,
1461: Map propertyMap, ParentMap parentMap) {
1462: // can't be null, must be instance of Participant,
1463: // and can't have other participants
1464: // also it can't be removed
1465: if (par == null)
1466: return;
1467: if (!(par instanceof GraphParticipantInterface))
1468: return;
1469: GraphParticipantInterface p = (GraphParticipantInterface) par;
1470: if (hasAnyParticipant(p, parentMap))
1471: return;
1472: ArrayList removedPars = ((JaWEParentMap) parentMap)
1473: .getRemovedNodes();
1474: if (removedPars.contains(p))
1475: return;
1476: // getting optimal and current height for participant
1477: int optWidth = optimalParticipantWidth(p, propertyMap,
1478: parentMap);
1479: int curWidth = getParticipantWidth(p, propertyMap);
1480: // calculating value for vertical resizing of new participant
1481: int dwidth = optWidth - curWidth;
1482:
1483: if (dwidth != 0) {
1484: // translating horizontally participants under right edge
1485: // of participant for value of dwidth
1486: translateHorizontally(propertyMap, parentMap, getBounds(p,
1487: propertyMap).getBounds().x
1488: + curWidth - 1, dwidth);//HM,
1489: // JGraph3.4.1
1490:
1491: // gets all parents participant (and given participant) into array
1492: // and resizes them for value of dheight
1493: Object[] allParentsAndPar = p.getPath();
1494: resize(allParentsAndPar, propertyMap, dwidth, 0);
1495: }
1496: }
1497:
1498: /**
1499: * Resizing participant par and it's parents to appropriate height, and
1500: * translating other participants accordingly to changes of participant par.
1501: * The size's and positions are calculated considering propertyMap and
1502: * parentMap - which means for future children state, and for bounds that are
1503: * constantly changed during other calculations. If propertyMap and parentMap
1504: * are null, size's and positions are calculated for current state. Also, if
1505: * par that is to be arranged has entry in parentMap as removed participant,
1506: * it will not be arranged.
1507: */
1508: protected void arrangeParticipantVertically(Object par,
1509: Map propertyMap, ParentMap parentMap) {
1510: // can't be null, must be instance of Participant,
1511: // and can't have other participants
1512: // also it can't be removed
1513: if (par == null)
1514: return;
1515: if (!(par instanceof GraphParticipantInterface))
1516: return;
1517: GraphParticipantInterface p = (GraphParticipantInterface) par;
1518: if (hasAnyParticipant(p, parentMap))
1519: return;
1520: ArrayList removedPars = ((JaWEParentMap) parentMap)
1521: .getRemovedNodes();
1522: if (removedPars.contains(p))
1523: return;
1524: // getting optimal and current height for participant
1525: int optHeight = optimalParticipantHeight(p, propertyMap,
1526: parentMap);
1527: int curHeight = getParticipantHeight(p, propertyMap);
1528: // calculating value for vertical resizing of new participant
1529: int dheight = optHeight - curHeight;
1530:
1531: if (dheight != 0) {
1532: // translating verticaly participants under bottom edge
1533: // of participant for value of dheight
1534: translateVertically(propertyMap, parentMap, getBounds(p,
1535: propertyMap).getBounds().y
1536: + curHeight - 1, dheight);//HM,
1537: // JGraph3.4.1
1538:
1539: // gets all parents participant (and given participant) into array
1540: // and resizes them for value of dheight
1541: Object[] allParentsAndPar = p.getPath();
1542: resize(allParentsAndPar, propertyMap, 0, dheight);
1543: }
1544:
1545: }
1546:
1547: /**
1548: * Method that resizes all participants horizontally to get there minimal
1549: * needed sizes. The size is calculated considering propertyMap and parentMap -
1550: * which means for future children state, and for bounds that are constantly
1551: * changed during other calculations. If propertyMap and parentMap are null,
1552: * size is calculated for current state.
1553: */
1554: protected void resizeAllParticipantsHorizontally(Map propertyMap,
1555: ParentMap parentMap) {
1556: List participants = JaWEGraphModel
1557: .getAllParticipantsInModel(graphModel());
1558: // removing ones which parent in a parentMap is null
1559: if (parentMap != null && participants != null) {
1560: participants.removeAll(((JaWEParentMap) parentMap)
1561: .getRemovedNodes());
1562: }
1563: // if there is a need for resizing
1564: int optimalRDW = optimalRootParticipantWidth(participants,
1565: propertyMap, parentMap);
1566: int rootParWidth = getRootParticipantWidth(propertyMap,
1567: parentMap);
1568: if (optimalRDW != rootParWidth) {
1569: // resize all participants for needed increment
1570: int dw = optimalRDW - rootParWidth;
1571: if (participants != null) {
1572: resize(participants.toArray(), propertyMap, dw, 0);
1573: }
1574: }
1575: }
1576:
1577: protected void resizeAllParticipantsVertically(Map propertyMap,
1578: ParentMap parentMap) {
1579: List participants = JaWEGraphModel
1580: .getAllParticipantsInModel(graphModel());
1581: // removing ones which parent in a parentMap is null
1582: if (parentMap != null && participants != null) {
1583: participants.removeAll(((JaWEParentMap) parentMap)
1584: .getRemovedNodes());
1585: }
1586: // if there is a need for resizing
1587: int optimalBDW = optimalRootParticipantHeight(participants,
1588: propertyMap, parentMap);
1589: int rootParHeight = getRootParticipantHeight(propertyMap,
1590: parentMap);
1591: if (optimalBDW != rootParHeight) {
1592: // resize all participants for needed increment
1593: int dw = optimalBDW - rootParHeight;
1594: if (participants != null) {
1595: resize(participants.toArray(), propertyMap, 0, dw);
1596: }
1597: }
1598: }
1599:
1600: protected int optimalRootParticipantHeight(List participants,
1601: Map propertyMap, ParentMap parentMap) {
1602: // initial value for width stays the same
1603: int minHeight;
1604: if (isGraphRotated())
1605: minHeight = minParWidth;
1606: else
1607: minHeight = minParHeight;
1608:
1609: // exits if there are no participants created
1610: if (participants == null)
1611: return minHeight;
1612:
1613: // finds the leaf participants
1614: Set leafParticipants = new HashSet();
1615:
1616: Iterator it = participants.iterator();
1617: while (it.hasNext()) {
1618: GraphParticipantInterface par = (GraphParticipantInterface) it
1619: .next();
1620: // if participant doesn't have any other participants,
1621: // it is a leaf participant and should be added to collection
1622: if (!hasAnyParticipant(par, parentMap)) {
1623: leafParticipants.add(par);
1624: }
1625: }
1626:
1627: // max. right edge position minus horizontalOffset (of all leafs) becomes
1628: // minWidth
1629: it = leafParticipants.iterator();
1630: int maxBottomEdgePosition = 0;
1631:
1632: while (it.hasNext()) {
1633: GraphParticipantInterface lpar = (GraphParticipantInterface) it
1634: .next();
1635: int minBEdge;
1636: int minParBEdge;
1637: int minChildrenBEdge = 0;
1638: // getting future participant bounds
1639: if (isGraphRotated())
1640: minParBEdge = (int) getBounds(lpar, propertyMap).getY()
1641: + minParWidth;//HM,
1642: else
1643: minParBEdge = (int) getBounds(lpar, propertyMap).getY()
1644: + minParHeight;//HM,
1645: // JGraph3.4.1
1646: // getting the future child views bounding rectangle -> its right
1647: // edge plus some extra space is min. right edge for that participant
1648: Rectangle r = getBoundsOfParticipantFutureActivities(lpar,
1649: propertyMap, parentMap);
1650: if (r != null) {
1651: minChildrenBEdge = r.y + r.height + defParNameWidth;
1652: }
1653:
1654: minBEdge = java.lang.Math
1655: .max(minParBEdge, minChildrenBEdge);
1656: // if entering first time, set the starting max.
1657: if (maxBottomEdgePosition == 0) {
1658: maxBottomEdgePosition = minBEdge;
1659: } else if (minBEdge > maxBottomEdgePosition) {
1660: maxBottomEdgePosition = minBEdge;
1661: }
1662: }
1663:
1664: int minH = maxBottomEdgePosition - verticalOffset;
1665:
1666: // can't allow that the minWidth<minParWidth
1667: if (minH > minParWidth) {
1668: minHeight = minH;
1669: }
1670:
1671: return minHeight;
1672:
1673: }
1674:
1675: /**
1676: * Calculates the minimal width of root participants. It depends of minimal
1677: * allowed width of leaf participants, which depends on the position of
1678: * Activity cells in them. The width is calculated considering propertyMap
1679: * and parentMap - which means for future children state, and for bounds that
1680: * are constantly changed during other calculations. If propertyMap and
1681: * parentMap are null, size is calculated for current state.
1682: */
1683: protected int optimalRootParticipantWidth(List participants,
1684: Map propertyMap, ParentMap parentMap) {
1685: // initial value for width stays the same
1686: int minWidth;
1687: if (isGraphRotated())
1688: minWidth = minParHeight;
1689: else
1690: minWidth = minParWidth;
1691:
1692: // exits if there are no participants created
1693: if (participants == null)
1694: return minWidth;
1695:
1696: // finds the leaf participants
1697: Set leafParticipants = new HashSet();
1698:
1699: Iterator it = participants.iterator();
1700: while (it.hasNext()) {
1701: GraphParticipantInterface par = (GraphParticipantInterface) it
1702: .next();
1703: // if participant doesn't have any other participants,
1704: // it is a leaf participant and should be added to collection
1705: if (!hasAnyParticipant(par, parentMap)) {
1706: leafParticipants.add(par);
1707: }
1708: }
1709:
1710: // max. right edge position minus horizontalOffset (of all leafs) becomes
1711: // minWidth
1712: it = leafParticipants.iterator();
1713: int maxRightEdgePosition = 0;
1714:
1715: while (it.hasNext()) {
1716: GraphParticipantInterface lpar = (GraphParticipantInterface) it
1717: .next();
1718: int minREdge;
1719: int minParREdge;
1720: int minChildrenREdge = 0;
1721: // getting future participant bounds
1722: if (isGraphRotated())
1723: minParREdge = (int) getBounds(lpar, propertyMap).getX()
1724: + minParHeight;//HM,
1725: // JGraph3.4.1
1726: else
1727: minParREdge = (int) getBounds(lpar, propertyMap).getX()
1728: + minParWidth;//HM,
1729: // JGraph3.4.1
1730: // getting the future child views bounding rectangle -> its right
1731: // edge plus some extra space is min. right edge for that participant
1732: Rectangle r = getBoundsOfParticipantFutureActivities(lpar,
1733: propertyMap, parentMap);
1734: if (r != null) {
1735: minChildrenREdge = r.x + r.width + defParNameWidth;
1736: }
1737:
1738: minREdge = java.lang.Math
1739: .max(minParREdge, minChildrenREdge);
1740: // if entering first time, set the starting max.
1741: if (maxRightEdgePosition == 0) {
1742: maxRightEdgePosition = minREdge;
1743: } else if (minREdge > maxRightEdgePosition) {
1744: maxRightEdgePosition = minREdge;
1745: }
1746: }
1747:
1748: int minW = maxRightEdgePosition - horizontalOffset;
1749:
1750: // can't allow that the minWidth<minParWidth
1751: if (minW > minParWidth) {
1752: minWidth = minW;
1753: }
1754:
1755: return minWidth;
1756:
1757: }
1758:
1759: protected int optimalParticipantWidth(
1760: GraphParticipantInterface par, Map propertyMap,
1761: ParentMap parentMap) {
1762: // initial value for width
1763: int optWidth;
1764: if (isGraphRotated())
1765: optWidth = minParHeight;
1766: else
1767: optWidth = minParWidth;
1768:
1769: // exits returning minParHeight if there are no activity cells within
1770: // participant
1771: if (!hasAnyActivity(par, parentMap))
1772: return optWidth;
1773:
1774: // get bounds of par (either current or future)
1775: Rectangle2D rCurrent = getBounds(par, propertyMap);//HM,
1776: // JGraph3.4.1
1777: // get preffered bounding rectangle of participant (according to it's
1778: // children)
1779: Rectangle rPreferred = getBoundsOfParticipantFutureActivities(
1780: par, propertyMap, parentMap);
1781:
1782: // difference of these rectangle's bottom positions plus current par
1783: // height
1784: // plus some extra space is min. height for given participant
1785:
1786: // calculate difference in bottom edges of these rectangles, and optimal
1787: // height
1788: if (rPreferred != null) {
1789: int dRight = (rPreferred.x + rPreferred.width)
1790: - (int) (rCurrent.getX() + rCurrent.getWidth());
1791: int optW = (int) rCurrent.getWidth() + dRight + 10;
1792:
1793: // optimal height can't be less then minHeight
1794: if (optW > optWidth) {
1795: optWidth = optW;
1796: }
1797: } else {
1798: }
1799:
1800: return optWidth;
1801: }
1802:
1803: /**
1804: * Calculates minimal participant height, which depends of position of all of
1805: * its Activity cells. The height is calculated considering propertyMap and
1806: * parentMap - which means for future children state, and for bounds that are
1807: * constantly changed during other calculations. If propertyMap and parentMap
1808: * are null, size is calculated for current state.
1809: */
1810: protected int optimalParticipantHeight(
1811: GraphParticipantInterface par, Map propertyMap,
1812: ParentMap parentMap) {
1813: // initial value for height
1814: int optHeight;
1815: if (isGraphRotated())
1816: optHeight = minParWidth;
1817: else
1818: optHeight = minParHeight;
1819:
1820: // exits returning minParHeight if there are no activity cells within
1821: // participant
1822: if (!hasAnyActivity(par, parentMap))
1823: return optHeight;
1824:
1825: // get bounds of par (either current or future)
1826: Rectangle2D rCurrent = getBounds(par, propertyMap);//HM, JGraph3.4.1
1827: // get preffered bounding rectangle of participant (according to it's
1828: // children)
1829: Rectangle rPreferred = getBoundsOfParticipantFutureActivities(
1830: par, propertyMap, parentMap);
1831:
1832: // difference of these rectangle's bottom positions plus current par
1833: // height
1834: // plus some extra space is min. height for given participant
1835:
1836: // calculate difference in bottom edges of these rectangles, and optimal
1837: // height
1838: if (rPreferred != null) {
1839: int dBottom = (rPreferred.y + rPreferred.height)
1840: - (int) (rCurrent.getY() + rCurrent.getHeight());
1841: int optH = (int) rCurrent.getHeight() + dBottom + 10;
1842:
1843: // optimal height can't be less then minHeight
1844: if (optH > optHeight) {
1845: optHeight = optH;
1846: }
1847: } else {
1848: //System.err.println("OHINNNNNNNNNNNNNNNNNNNUUUUUUUUUUUUULLLLLLLLLL");
1849: }
1850:
1851: return optHeight;
1852:
1853: }
1854:
1855: /**
1856: * Resizes given participants. The resizing is done to propertyMap which will
1857: * later (after all needed operation) be applied.
1858: */
1859: protected void resize(Object[] cells, Map propertyMap, int dw,
1860: int dh) {
1861: if (cells != null && cells.length > 0) {
1862: Rectangle r;
1863: for (int i = 0; i < cells.length; i++) {
1864: r = new Rectangle(getBounds(cells[i], propertyMap)
1865: .getBounds());//HM,
1866: // JGraph3.4.1
1867:
1868: int newWidth = r.width + dw;
1869: int newHeight = r.height + dh;
1870:
1871: if (isGraphRotated()) {
1872: if (newWidth < minParHeight
1873: || newHeight < minParWidth) {
1874: System.err
1875: .println("There was an error in calculating size of participant "
1876: + cells[i] + "!!!");
1877: System.err.println("New width=" + newWidth
1878: + ", new height=" + newHeight);
1879: }
1880: } else {
1881: if (newWidth < minParWidth
1882: || newHeight < minParHeight) {
1883: System.err
1884: .println("There was an error in calculating size of participant "
1885: + cells[i] + "!!!");
1886: System.err.println("New width=" + newWidth
1887: + ", new height=" + newHeight);
1888: }
1889: }
1890:
1891: r.setSize(newWidth, newHeight);
1892: changeBounds(cells[i], propertyMap, r);
1893: }
1894: }
1895: }
1896:
1897: protected void translateHorizontally(Map propertyMap,
1898: ParentMap parentMap, int xPos, int dv) {
1899: GraphParticipantInterface[] pars = getParticipantsForXPos(xPos,
1900: 0, propertyMap, parentMap);
1901: translateParticipants(pars, propertyMap, parentMap, dv, 0);
1902: }
1903:
1904: /**
1905: * Translates participants under given position yPos vertically for a value
1906: * of dv. The translating is done to propertyMap which will later (after all
1907: * needed operation) be applied.
1908: *
1909: * @see #translateParticipants
1910: */
1911: protected void translateVertically(Map propertyMap,
1912: ParentMap parentMap, int yPos, int dv) {
1913: GraphParticipantInterface[] pars = getParticipantsForYPos(yPos,
1914: 0, propertyMap, parentMap);
1915: translateParticipants(pars, propertyMap, parentMap, 0, dv);
1916: }
1917:
1918: /**
1919: * Translates given participants using propertyMap for bounds checking and
1920: * parentMap for future children checking. The translating is done to
1921: * propertyMap which will later (after all needed operation) be applied.
1922: *
1923: * @see #translateParticipant
1924: */
1925: protected void translateParticipants(
1926: GraphParticipantInterface[] cells, Map propertyMap,
1927: ParentMap parentMap, int dx, int dy) {
1928: if (cells != null && cells.length > 0) {
1929: for (int i = 0; i < cells.length; i++) {
1930: translateParticipant(cells[i], propertyMap, parentMap,
1931: dx, dy);
1932: }
1933: }
1934: }
1935:
1936: /**
1937: * Translates single participant and its children.The method checks for
1938: * bounds of cells within propertyMap and uses parentMap to translate right
1939: * children (the children that will be it's after applying parentMap). The
1940: * translating is done to propertyMap which will later (after all needed
1941: * operation) be applied.
1942: */
1943: protected void translateParticipant(GraphParticipantInterface par,
1944: Map propertyMap, ParentMap parentMap, int dx, int dy) {
1945: Set participantAndItsFutureActivities = new HashSet();
1946: participantAndItsFutureActivities.add(par);
1947:
1948: // Get future activities of participant
1949: Set futureActivities = getParticipantFutureActivities(par,
1950: parentMap);
1951:
1952: participantAndItsFutureActivities.addAll(futureActivities);
1953:
1954: // applying translations to the determined cells
1955: Rectangle r;
1956: Iterator it = participantAndItsFutureActivities.iterator();
1957: while (it.hasNext()) {
1958: Object cell = it.next();
1959: r = new Rectangle(getBounds(cell, propertyMap).getBounds());//HM,
1960: // JGraph3.4.1
1961: r.translate(dx, dy);
1962: changeBounds(cell, propertyMap, r);
1963: }
1964: }
1965:
1966: /**
1967: * Gets the bounding rectangle of future children activities of given
1968: * Participant par (that will be participants activities after parent map is
1969: * applied). Bounding rectangle is union of previous mentioned activities.
1970: */
1971: protected Rectangle getBoundsOfParticipantFutureActivities(
1972: GraphParticipantInterface par, Map propertyMap,
1973: ParentMap parentMap) {
1974: // simulate future state of children and get it's bounds
1975: Set futureActivities = getParticipantFutureActivities(par,
1976: parentMap);
1977: Set futureActivityBounds = new HashSet();
1978:
1979: Iterator it = futureActivities.iterator();
1980: while (it.hasNext()) {
1981: Rectangle actBnd = getBounds(it.next(), propertyMap)
1982: .getBounds();//HM,
1983: // JGraph3.4.1
1984: futureActivityBounds.add(actBnd);
1985: }
1986:
1987: Rectangle[] fab = new Rectangle[futureActivityBounds.size()];
1988: futureActivityBounds.toArray(fab);
1989: Rectangle unionBounds = getUnionBounds(fab);
1990:
1991: return unionBounds;
1992: }
1993:
1994: /**
1995: * Gets future children activities of given participant par (that will be
1996: * par's activities after parent map is applied).
1997: */
1998: protected Set getParticipantFutureActivities(
1999: GraphParticipantInterface par, ParentMap parentMap) {
2000: // if there is no parent map, or there is no entry for participant
2001: // in it, return current participants activities
2002: if (parentMap == null) {// || !parentMap.getChangedNodes().contains(par))
2003: // {
2004: return par.getChildActivities();
2005: }
2006: Set futureActivities = new HashSet();
2007: // getting participants which will be empty after applying parentMap
2008: ArrayList emptyPars = ((JaWEParentMap) parentMap)
2009: .emptyParentList();
2010: // returns empty set if there will be no activity cells within participant
2011: if (emptyPars.contains(par))
2012: return futureActivities;
2013: // get changed nodes from parent map (nodes which parent changed and
2014: // nodes which children changed)
2015: Set changedNodes = parentMap.getChangedNodes();
2016: // get all (previous) participants activities and make the future look
2017: // of participant activities
2018: futureActivities = new HashSet(par.getChildActivities());
2019: Object[] previousActivities = futureActivities.toArray();
2020: // iterate through child activities and remove ones which are
2021: // contained in changed nodes of parent map - they will no longer
2022: // be the children of current participant
2023: for (int i = 0; i < previousActivities.length; i++) {
2024: if (changedNodes.contains(previousActivities[i])) {
2025: futureActivities.remove(previousActivities[i]);
2026: }
2027: }
2028: // get new children of current participant from parent map
2029: // and add it to futureActivities set
2030: ArrayList nc = ((JaWEParentMap) parentMap).getNewChildren(par);
2031: futureActivities.addAll(nc);
2032:
2033: return futureActivities;
2034: }
2035:
2036: protected GraphParticipantInterface getLeafParticipantForXPos(
2037: int xPos, Map propertyMap, ParentMap parentMap) {
2038: // getting all participants that contains yPos
2039: GraphParticipantInterface[] pars = getParticipantsForXPos(xPos,
2040: 2, propertyMap, parentMap);
2041:
2042: // if there is no participants at this location, return null
2043: if (pars == null)
2044: return null;
2045:
2046: // getting leaf participant(s)
2047: Set leafPars = new HashSet();
2048: for (int i = 0; i < pars.length; i++) {
2049: if (!hasAnyParticipant(pars[i], parentMap)) {
2050: leafPars.add(pars[i]);
2051: }
2052: }
2053:
2054: // if there is no leaf participant at this location (THIS SHOULD
2055: // NEVER HAPPEND, BUT ...) return null
2056: if (leafPars.size() == 0)
2057: return null;
2058:
2059: // taking first and making it the right one
2060: Iterator it = leafPars.iterator();
2061: Object rightPar = it.next();
2062:
2063: if (leafPars.size() > 1) {
2064: int upperLeftX;
2065: int minUpperLeftX;
2066: Rectangle parRect;
2067:
2068: // taking bounding rectangle of first par
2069: parRect = getBounds(rightPar, propertyMap).getBounds();//HM,
2070: // JGraph3.4.1
2071: // taking upper-left corner y-coord
2072: upperLeftX = parRect.getLocation().x;
2073: minUpperLeftX = upperLeftX;
2074:
2075: // finding the participant with min. y-coord
2076: while (it.hasNext()) {
2077: Object curPar = it.next();
2078: parRect = getBounds(curPar, propertyMap).getBounds();//HM,
2079: // JGraph3.4.1
2080: upperLeftX = parRect.getLocation().x;
2081: if (upperLeftX < minUpperLeftX) {
2082: minUpperLeftX = upperLeftX;
2083: rightPar = curPar;
2084: }
2085: }
2086: }
2087:
2088: // return found participant
2089: return (GraphParticipantInterface) rightPar;
2090: }
2091:
2092: /**
2093: * Returns leaf participant that bounds given y-coordinate. If y-coordinate
2094: * is at boundary of two participants, method returns one that is above. The
2095: * method checks for bounds of cells within propertyMap.
2096: */
2097: protected GraphParticipantInterface getLeafParticipantForYPos(
2098: int yPos, Map propertyMap, ParentMap parentMap) {
2099: // getting all participants that contains yPos
2100: GraphParticipantInterface[] pars = getParticipantsForYPos(yPos,
2101: 2, propertyMap, parentMap);
2102:
2103: // if there is no participants at this location, return null
2104: if (pars == null)
2105: return null;
2106:
2107: // getting leaf participant(s)
2108: Set leafPars = new HashSet();
2109: for (int i = 0; i < pars.length; i++) {
2110: if (!hasAnyParticipant(pars[i], parentMap)) {
2111: leafPars.add(pars[i]);
2112: }
2113: }
2114:
2115: // if there is no leaf participant at this location (THIS SHOULD
2116: // NEVER HAPPEND, BUT ...) return null
2117: if (leafPars.size() == 0)
2118: return null;
2119:
2120: // taking first and making it the right one
2121: Iterator it = leafPars.iterator();
2122: Object rightPar = it.next();
2123:
2124: // if there is more than one leaf participant, take the one that
2125: // has minimal y-coord of upper left corner
2126: if (leafPars.size() > 1) {
2127: int upperLeftY;
2128: int minUpperLeftY;
2129: Rectangle parRect;
2130:
2131: // taking bounding rectangle of first par
2132: parRect = getBounds(rightPar, propertyMap).getBounds();//HM,
2133: // JGraph3.4.1
2134: // taking upper-left corner y-coord
2135: upperLeftY = parRect.getLocation().y;
2136: minUpperLeftY = upperLeftY;
2137:
2138: // finding the participant with min. y-coord
2139: while (it.hasNext()) {
2140: Object curPar = it.next();
2141: parRect = getBounds(curPar, propertyMap).getBounds();//HM,
2142: // JGraph3.4.1
2143: upperLeftY = parRect.getLocation().y;
2144: if (upperLeftY < minUpperLeftY) {
2145: minUpperLeftY = upperLeftY;
2146: rightPar = curPar;
2147: }
2148: }
2149: }
2150:
2151: // return found participant
2152: return (GraphParticipantInterface) rightPar;
2153:
2154: }
2155:
2156: protected GraphParticipantInterface[] getParticipantsForXPos(
2157: int xPos, int direction, Map propertyMap,
2158: ParentMap parentMap) {
2159: // getting all participants that are in collection
2160: List participants = JaWEGraphModel
2161: .getAllParticipantsInModel(graphModel());
2162:
2163: // if there are no participants, return null
2164: if (participants == null)
2165: return null;
2166:
2167: // removing ones which parent in a parentMap is null
2168: if (parentMap != null) {
2169: participants.removeAll(((JaWEParentMap) parentMap)
2170: .getRemovedNodes());
2171: }
2172:
2173: // making an array of participants
2174: GraphParticipantInterface[] pars = new GraphParticipantInterface[participants
2175: .size()];
2176: participants.toArray(pars);
2177:
2178: // Set of participants that will satisfy needs
2179: Set xPosPars = new HashSet();
2180:
2181: for (int i = 0; i < pars.length; i++) {
2182: Rectangle2D r = getBounds(pars[i], propertyMap);//HM,
2183: // JGraph3.4.1
2184: switch (direction) {
2185: case 0:
2186: if (r.getX() >= xPos) {
2187: xPosPars.add(pars[i]);
2188: }
2189: break;
2190: case 1:
2191: if (r.getX() < xPos) {
2192: xPosPars.add(pars[i]);
2193: }
2194: break;
2195: case 2:
2196: if ((r.getX() <= xPos)
2197: && (r.getX() + r.getWidth() >= xPos)) {
2198: xPosPars.add(pars[i]);
2199: }
2200: break;
2201: }
2202: }
2203:
2204: if (xPosPars.size() > 0) {
2205: pars = new GraphParticipantInterface[xPosPars.size()];
2206: xPosPars.toArray(pars);
2207: return pars;
2208: }
2209: return null;
2210: }
2211:
2212: /**
2213: * Returns participants that are under or above given yPos, or contains that
2214: * y-position: <BR>
2215: * direction=0 -> under, <BR>
2216: * direction=1 -> above, <BR>
2217: * direction=2 -> contains. The method checks for bounds of cells within
2218: * propertyMap. If some of model's participants is entered in parentMap as
2219: * removed participant, this method doesn't consider that participant.
2220: */
2221: protected GraphParticipantInterface[] getParticipantsForYPos(
2222: int yPos, int direction, Map propertyMap,
2223: ParentMap parentMap) {
2224: // getting all participants that are in collection
2225: List participants = JaWEGraphModel
2226: .getAllParticipantsInModel(graphModel());
2227:
2228: // if there are no participants, return null
2229: if (participants == null)
2230: return null;
2231:
2232: // removing ones which parent in a parentMap is null
2233: if (parentMap != null) {
2234: participants.removeAll(((JaWEParentMap) parentMap)
2235: .getRemovedNodes());
2236: }
2237:
2238: // making an array of participants
2239: GraphParticipantInterface[] pars = new GraphParticipantInterface[participants
2240: .size()];
2241: participants.toArray(pars);
2242:
2243: // Set of participants that will satisfy needs
2244: Set yPosPars = new HashSet();
2245:
2246: for (int i = 0; i < pars.length; i++) {
2247: Rectangle2D r = getBounds(pars[i], propertyMap);//HM, JGraph3.4.1
2248: switch (direction) {
2249: case 0:
2250: if (r.getY() >= yPos) {
2251: yPosPars.add(pars[i]);
2252: }
2253: break;
2254: case 1:
2255: if (r.getY() < yPos) {
2256: yPosPars.add(pars[i]);
2257: }
2258: break;
2259: case 2:
2260: if ((r.getY() <= yPos)
2261: && (r.getY() + r.getHeight() >= yPos)) {
2262: yPosPars.add(pars[i]);
2263: }
2264: break;
2265: }
2266: }
2267:
2268: if (yPosPars.size() > 0) {
2269: pars = new GraphParticipantInterface[yPosPars.size()];
2270: yPosPars.toArray(pars);
2271: return pars;
2272: }
2273: return null;
2274: }
2275:
2276: protected int getNewRootParXPos(Map propertyMap, ParentMap parentMap) {
2277: int newRootParXPos = 0;
2278:
2279: Set rootPars = JaWEGraphModel.getRootParticipants(graphModel());
2280:
2281: if (propertyMap != null) {
2282: Iterator it = propertyMap.keySet().iterator();
2283: while (it.hasNext()) {
2284: Object rootPar = it.next();
2285: if ((rootPar instanceof GraphParticipantInterface)
2286: && (((DefaultGraphCell) rootPar).getParent() == null)) {
2287: rootPars.add(rootPar);
2288: }
2289: }
2290: }
2291:
2292: if (parentMap != null) {
2293: rootPars.removeAll(((JaWEParentMap) parentMap)
2294: .getRemovedNodes());
2295: }
2296:
2297: // if there is no root participants, new Y-position is 0
2298: if (rootPars == null || rootPars.size() == 0)
2299: return newRootParXPos;
2300:
2301: newRootParXPos = minParHeight;
2302: // find the bottom of bottom most root participant
2303: Iterator it = rootPars.iterator();
2304: while (it.hasNext()) {
2305: Rectangle2D bounds = getBounds(it.next(), propertyMap);//HM,
2306: // JGraph3.4.1
2307: if (bounds.getX() + bounds.getWidth() > newRootParXPos) {
2308: newRootParXPos = (int) (bounds.getX() + bounds
2309: .getWidth());
2310: }
2311: }
2312:
2313: return newRootParXPos;
2314: }
2315:
2316: /**
2317: * Gets the insertation point (y-coordinate) of new root participant.
2318: */
2319: protected int getNewRootParYPos(Map propertyMap, ParentMap parentMap) {
2320: int newRootParYPos = 0;
2321:
2322: Set rootPars = JaWEGraphModel.getRootParticipants(graphModel());
2323:
2324: // adding to rootPars set a root participants from propertyMap -> that is
2325: // done because of proper calculation of y-position of in/out ports when
2326: // new root participant is added to graph
2327:
2328: if (propertyMap != null) {
2329: Iterator it = propertyMap.keySet().iterator();
2330: while (it.hasNext()) {
2331: Object rootPar = it.next();
2332: if ((rootPar instanceof GraphParticipantInterface)
2333: && (((DefaultGraphCell) rootPar).getParent() == null)) {
2334: rootPars.add(rootPar);
2335: }
2336: }
2337: }
2338:
2339: // removing from rootPars set a root participants from parentMap -> that
2340: // is
2341: // done because of proper calculation of y-position of in/out ports when
2342: // root participant is removed from graph
2343:
2344: if (parentMap != null) {
2345: rootPars.removeAll(((JaWEParentMap) parentMap)
2346: .getRemovedNodes());
2347: }
2348:
2349: // if there is no root participants, new Y-position is 0
2350: if (rootPars == null || rootPars.size() == 0)
2351: return newRootParYPos;
2352:
2353: newRootParYPos = minParHeight;
2354: // find the bottom of bottom most root participant
2355: Iterator it = rootPars.iterator();
2356: while (it.hasNext()) {
2357: Rectangle bounds = getBounds(it.next(), propertyMap)
2358: .getBounds();// HM,
2359: // JGraph3.4.1
2360: if (bounds.getY() + bounds.getHeight() > newRootParYPos) {
2361: newRootParYPos = (int) (bounds.getY() + bounds
2362: .getHeight());
2363: }
2364: }
2365:
2366: return newRootParYPos;
2367: }
2368:
2369: protected int getRootParticipantHeight(Map propertyMap,
2370: ParentMap parentMap) {
2371: int rootParHeight;
2372: if (isGraphRotated())
2373: rootParHeight = minParWidth;
2374: else
2375: rootParHeight = minParHeight;
2376:
2377: Set rootPars = JaWEGraphModel.getRootParticipants(graphModel());
2378:
2379: // if there is no root participants, width is equal to minParWidth
2380: if (rootPars == null)
2381: return rootParHeight;
2382:
2383: // removing ones which parent in a parentMap is null (this means they
2384: // will be removed from a graph)
2385: if (parentMap != null) {
2386: rootPars.removeAll(((JaWEParentMap) parentMap)
2387: .getRemovedNodes());
2388: }
2389:
2390: // if there is no root participants, width is equal to minParWidth
2391: if (rootPars.size() == 0)
2392: return rootParHeight;
2393:
2394: // all root participants has same width, so take the first
2395: Iterator it = rootPars.iterator();
2396: Object firstPar = it.next();
2397: rootParHeight = getParticipantHeight(firstPar, propertyMap);
2398:
2399: return rootParHeight;
2400: }
2401:
2402: /**
2403: * Gets the width of root participants. The method checks for bounds of cells
2404: * within propertyMap. If some of model's participants has entry within
2405: * propertyMap as removed, this participant doesn't count.
2406: */
2407: protected int getRootParticipantWidth(Map propertyMap,
2408: ParentMap parentMap) {
2409: int rootParWidth;
2410: if (isGraphRotated())
2411: rootParWidth = minParHeight;
2412: else
2413: rootParWidth = minParWidth;
2414: Set rootPars = JaWEGraphModel.getRootParticipants(graphModel());
2415:
2416: // if there is no root participants, width is equal to minParWidth
2417: if (rootPars == null)
2418: return rootParWidth;
2419:
2420: // removing ones which parent in a parentMap is null (this means they
2421: // will be removed from a graph)
2422: if (parentMap != null) {
2423: rootPars.removeAll(((JaWEParentMap) parentMap)
2424: .getRemovedNodes());
2425: }
2426:
2427: // if there is no root participants, width is equal to minParWidth
2428: if (rootPars.size() == 0)
2429: return rootParWidth;
2430:
2431: // all root participants has same width, so take the first
2432: Iterator it = rootPars.iterator();
2433: Object firstPar = it.next();
2434: rootParWidth = getParticipantWidth(firstPar, propertyMap);
2435:
2436: return rootParWidth;
2437: }
2438:
2439: /**
2440: * Checks if given participant par has other participants. If parentMap is
2441: * null, or there is no entry for this this participant within a parentMap,
2442: * the current state is checked, elsewhere parentMap is checked-in other
2443: * words future state of participant participants (state after aplying
2444: * parentMap) is returned.
2445: * <p>
2446: * This method has meaning in previous versions of JaWE, now it always
2447: * returns <tt>false</tt>.
2448: */
2449: protected boolean hasAnyParticipant(GraphParticipantInterface par,
2450: ParentMap parentMap) {
2451: // if there is no parent map, or there is no entry for participant
2452: // in it, return original participant state
2453: if (parentMap == null
2454: || !parentMap.getChangedNodes().contains(par)) {
2455: return par.hasAnyParticipant();
2456: }
2457: // else, check if participant will be empty after applying parent map
2458: return ((JaWEParentMap) parentMap).hasAnyParticipant(par);
2459: }
2460:
2461: /**
2462: * Checks if given participant par has activities. If parentMap is null, or
2463: * there is no entry for this this participant within a parentMap, the
2464: * current state is checked, elsewhere parentMap is checked-in other words
2465: * future state of participant activities (state after aplying parentMap) is
2466: * returned.
2467: */
2468: protected boolean hasAnyActivity(GraphParticipantInterface par,
2469: ParentMap parentMap) {
2470: // if there is no parent map, or there is no entry for participant
2471: // in it, return original participant state
2472: if (parentMap == null
2473: || !parentMap.getChangedNodes().contains(par)) {
2474: return par.hasAnyActivity();
2475: }
2476:
2477: // else, check if participant will be empty after applying parent map
2478:
2479: // getting participants which will be empty after applying parentMap
2480: ArrayList emptyPars = ((JaWEParentMap) parentMap)
2481: .emptyParentList();
2482: // returns empty set if there will be no activity cells within
2483: // participant
2484: if (emptyPars.contains(par)) {
2485: return false;
2486: }
2487: return true;
2488: }
2489:
2490: // Useful only if JaWE is set to work with start/end bubbles
2491: public static boolean hasConnectedStartBubble(
2492: GraphActivityInterface act) {
2493: Set acts = act.getReferencingActivities();
2494: Iterator it = acts.iterator();
2495: while (it.hasNext()) {
2496: Object o = it.next();
2497: if (o instanceof GraphBubbleActivityInterface) {
2498: if (((GraphBubbleActivityInterface) o).isStart()) {
2499: return true;
2500: }
2501: }
2502: }
2503: return false;
2504: }
2505:
2506: // Useful only if JaWE is set to work with start/end bubbles
2507: public static boolean hasConnectedEndBubble(
2508: GraphActivityInterface act) {
2509: Set acts = act.getReferencedActivities();
2510: Iterator it = acts.iterator();
2511: while (it.hasNext()) {
2512: Object o = it.next();
2513: if (o instanceof GraphBubbleActivityInterface) {
2514: if (!((GraphBubbleActivityInterface) o).isStart()) {
2515: return true;
2516: }
2517: }
2518: }
2519: return false;
2520: }
2521:
2522: /**
2523: * Returns start bubbles.
2524: */
2525: protected Set getStarts() {
2526: Set starts = new HashSet();
2527: List allActivities = JaWEGraphModel
2528: .getAllBubblesInModel(graphModel());
2529:
2530: if (allActivities != null) {
2531: Iterator it = allActivities.iterator();
2532: while (it.hasNext()) {
2533: Object act = it.next();
2534: if (((GraphBubbleActivityInterface) act).isStart()) {
2535: starts.add(act);
2536: }
2537: }
2538: }
2539: return starts;
2540: }
2541:
2542: /**
2543: * Returns end bubbles.
2544: */
2545: protected Set getEnds() {
2546: Set ends = new HashSet();
2547: List allActivities = JaWEGraphModel
2548: .getAllActivitiesInModel(graphModel());
2549:
2550: if (allActivities != null) {
2551: Iterator it = allActivities.iterator();
2552: while (it.hasNext()) {
2553: Object act = it.next();
2554: if (!((GraphBubbleActivityInterface) act).isStart()) {
2555: ends.add(act);
2556: }
2557: }
2558: }
2559: return ends;
2560: }
2561:
2562: /**
2563: * Gets view of given object.
2564: */
2565: public CellView getView(Object cell) {
2566: //return graph.getView().getMapping(cell,false);
2567: return graph.getGraphLayoutCache().getMapping(cell, false);
2568: }
2569:
2570: /**
2571: * Gets width of given participant (from it's current view or from
2572: * propertyMap).
2573: */
2574: protected int getParticipantWidth(Object par, Map propertyMap) {
2575: return getBounds(par, propertyMap).getBounds().width;//HM, JGraph3.4.1
2576: }
2577:
2578: /**
2579: * Gets height of given participant (from it's current view or from
2580: * propertyMap).
2581: */
2582: protected int getParticipantHeight(Object par, Map propertyMap) {
2583: return getBounds(par, propertyMap).getBounds().height;//HM, JGraph3.4.1
2584: }
2585:
2586: /**
2587: * Replaces bounding rectangle of given cell in propertyMap object with
2588: * rectangle r if cell is contained within the propertyMap object, otherwise
2589: * adds new entry to the propertyMap that consists of given cell and a map
2590: * containing given rectangle r.
2591: */
2592: protected void changeBounds(Object cell, Map propertyMap,
2593: Rectangle r) {
2594: AttributeMap map;
2595: if (propertyMap == null || !propertyMap.containsKey(cell)) {
2596: map = new AttributeMap();
2597: GraphConstants.setBounds(map, r);
2598: propertyMap.put(cell, map);
2599: } else {
2600: map = (AttributeMap) propertyMap.get(cell);
2601: GraphConstants.setBounds(map, r);
2602: }
2603: }
2604:
2605: /**
2606: * Gets bounding rectangle of given cell. The rectangle is either current
2607: * rectangle of cellView either from propertyMap where are held bounding
2608: * rectangles of various cells during multiple resizing and/or translating of
2609: * cells.
2610: */
2611: public Rectangle getBounds(Object cell, Map propertyMap) {//HM,
2612: // JGraph3.4.1
2613: Rectangle2D bounds = null;
2614: if (propertyMap != null && propertyMap.containsKey(cell)) {
2615: Map map = (Map) propertyMap.get(cell);
2616: bounds = GraphConstants.getBounds(map);
2617: } else {
2618: CellView view = getView(cell);
2619: bounds = view.getBounds();
2620: }
2621: if (bounds != null) {
2622: return bounds.getBounds();
2623: }
2624: return null;
2625: }
2626:
2627: /**
2628: * Gets union of given rectangles.
2629: */
2630: public Rectangle getUnionBounds(Rectangle[] rects) {
2631: if (rects != null && rects.length > 0) {
2632: Rectangle unionRect = null;
2633: for (int i = 0; i < rects.length; i++) {
2634: if (unionRect == null) {
2635: unionRect = new Rectangle(rects[i]);
2636: } else {
2637: SwingUtilities.computeUnion(rects[i].x, rects[i].y,
2638: rects[i].width, rects[i].height, unionRect);
2639: }
2640: }
2641: return unionRect;
2642: }
2643: return null;
2644: }
2645:
2646: /**
2647: * Returns the central point of given graph object.
2648: */
2649: public Point getCenter(Object go) {
2650: if (go == null)
2651: return null;
2652: Rectangle2D r = getBounds(go, null);//HM, JGraph3.4.1
2653: if (!(go instanceof GraphParticipantInterface)) {
2654: return new Point(
2655: (int) (r.getX() + (int) (r.getWidth() / 2)),
2656: (int) (r.getY() + (int) (r.getHeight() / 2)));
2657: }
2658: return new Point((int) (r.getX() + defParNameWidth / 2),
2659: (int) (r.getY() + (int) (r.getHeight() / 2)));
2660: }
2661:
2662: ///////////////////////////// retreival of graph object for corresponding
2663: // XPDL object
2664: /**
2665: * Returns graph Activity object which represents XPDL activity with given Id
2666: * attribute.
2667: */
2668: public GraphActivityInterface getGraphActivity(String id) {
2669: List allActs = JaWEGraphModel
2670: .getAllActivitiesInModel(graphModel());
2671: if (allActs != null) {
2672: Iterator it = allActs.iterator();
2673: GraphActivityInterface gact;
2674: while (it.hasNext()) {
2675: gact = (GraphActivityInterface) it.next();
2676: if (!(gact instanceof GraphBubbleActivityInterface)) {
2677: if (gact.getPropertyObject().get("Id").toValue()
2678: .equals(id)) {
2679: return gact;
2680: }
2681: }
2682: }
2683: }
2684: return null;
2685: }
2686:
2687: public GraphActivityInterface getGraphActivity(Activity act) {
2688: List allActs = JaWEGraphModel
2689: .getAllActivitiesInModel(graphModel());
2690: if (allActs != null) {
2691: Iterator it = allActs.iterator();
2692: GraphActivityInterface gact;
2693: while (it.hasNext()) {
2694: gact = (GraphActivityInterface) it.next();
2695: if (gact.getUserObject() == act) {
2696: return gact;
2697: }
2698: }
2699: }
2700: return null;
2701: }
2702:
2703: /**
2704: * Returns start/end graph bubble object which represents start/end ext.
2705: * attrib.
2706: */
2707: public GraphBubbleActivityInterface getBubble(ExtendedAttribute ea) {
2708: List allActs = JaWEGraphModel
2709: .getAllBubblesInModel(graphModel());
2710: if (allActs != null) {
2711: Iterator it = allActs.iterator();
2712: GraphActivityInterface se;
2713: while (it.hasNext()) {
2714: se = (GraphBubbleActivityInterface) it.next();
2715: if (se.getUserObject() == ea) {
2716: return (GraphBubbleActivityInterface) se;
2717: }
2718: }
2719: }
2720: return null;
2721: }
2722:
2723: /**
2724: * Returns graph Transition object which represents XPDL transition with
2725: * given Id attribute.
2726: */
2727: public GraphTransitionInterface getGraphTransition(String id) {
2728: List allTrans = JaWEGraphModel
2729: .getAllTransitionsInModel(graphModel());
2730: if (allTrans != null) {
2731: Iterator it = allTrans.iterator();
2732: GraphTransitionInterface gtra;
2733: while (it.hasNext()) {
2734: gtra = (GraphTransitionInterface) it.next();
2735: Transition tra = (Transition) gtra.getUserObject();
2736: if (tra != null && tra.getId().equals(id)) {
2737: return gtra;
2738: }
2739: }
2740: }
2741: return null;
2742: }
2743:
2744: public GraphTransitionInterface getGraphTransition(Transition tra) {
2745: List allTrans = JaWEGraphModel
2746: .getAllTransitionsInModel(graphModel());
2747: if (allTrans != null) {
2748: Iterator it = allTrans.iterator();
2749: GraphTransitionInterface gtra;
2750: while (it.hasNext()) {
2751: gtra = (GraphTransitionInterface) it.next();
2752: if (gtra.getUserObject() == tra) {
2753: return gtra;
2754: }
2755: }
2756: }
2757: return null;
2758: }
2759:
2760: /**
2761: * Returns graph Participant object which represents XPDL participant with
2762: * given Id attribute.
2763: */
2764: public GraphParticipantInterface getGraphParticipant(String id) {
2765: List allPartic = JaWEGraphModel
2766: .getAllParticipantsInModel(graphModel());
2767: if (allPartic != null) {
2768: Iterator it = allPartic.iterator();
2769: GraphParticipantInterface gpar;
2770: while (it.hasNext()) {
2771: gpar = (GraphParticipantInterface) it.next();
2772: if (gpar.getPropertyObject().get("Id").toValue()
2773: .equals(id)) {
2774: return gpar;
2775: }
2776: }
2777: }
2778: return null;
2779: }
2780:
2781: public GraphParticipantInterface getGraphParticipant(Participant par) {
2782: List allPartic = JaWEGraphModel
2783: .getAllParticipantsInModel(graphModel());
2784: if (allPartic != null) {
2785: Iterator it = allPartic.iterator();
2786: GraphParticipantInterface gpar;
2787: while (it.hasNext()) {
2788: gpar = (GraphParticipantInterface) it.next();
2789: if (gpar.getUserObject() == par) {
2790: return gpar;
2791: }
2792: }
2793: }
2794: return null;
2795: }
2796:
2797: public boolean isFreeTextExpressionParticipantShown() {
2798: List allPartic = JaWEGraphModel
2799: .getAllParticipantsInModel(graphModel());
2800: if (allPartic != null) {
2801: Iterator it = allPartic.iterator();
2802: GraphParticipantInterface gpar;
2803: while (it.hasNext()) {
2804: gpar = (GraphParticipantInterface) it.next();
2805: if (gpar.getUserObject() == FreeTextExpressionParticipant
2806: .getInstance()) {
2807: return true;
2808: }
2809: }
2810: }
2811: return false;
2812: }
2813:
2814: ///////////////////// Position handling
2815: // //////////////////////////////////////
2816:
2817: /**
2818: * Finds the nearest cell to the given cell in given direction.
2819: *
2820: * @param selectedCell
2821: * first currently selected cell
2822: * @param direction
2823: * 0-Up, 1-Down, 2-Left, 3-Right (if given some other no, the Up is
2824: * assumed)
2825: * @return The nearest cell to the given one in given direction, or null if
2826: * no such cell.
2827: */
2828: public Object findNearestCell(Object selectedCell, int direction) {
2829: // retrieve all cells from model
2830: List cellSet = JaWEGraphModel.getAllCellsInModel(graphModel());
2831: //Set cellSet=PEGraphModel.getAllActivitiesInModel(graphModel());
2832: // if there is no any return null
2833: if (cellSet == null || cellSet.size() == 0)
2834: return null;
2835:
2836: Object[] cells = cellSet.toArray();
2837: // if current cell is null (nothing is selected), return
2838: // the first cell from array
2839: if (selectedCell == null)
2840: return cells[0];
2841:
2842: // get the center point of currently selected cell
2843: Point centerOfSelectedCell = getCenter(selectedCell);
2844: // if something went wrong, return the first cell from array
2845: if (centerOfSelectedCell == null)
2846: return cells[0];
2847:
2848: // initialy set the nearest cell to null, and min distance
2849: // to max. double value
2850: Object nearestCell = null;
2851: double minDistance = Double.MAX_VALUE;
2852:
2853: // search for the nearest cell considering the wanted direction
2854: for (int i = 0; i < cells.length; i++) {
2855: // skip the cell that we check for the nearest cell
2856: // and skip port cells
2857: if (cells[i] == selectedCell || cells[i] instanceof Port)
2858: continue;
2859:
2860: // the center of the next cell
2861: Point centerOfCell = getCenter(cells[i]);
2862: Point ref = new Point(centerOfCell.x,
2863: centerOfSelectedCell.y);
2864: double dist = centerOfSelectedCell.distance(centerOfCell);
2865: double absOfTan = centerOfCell.distance(ref)
2866: / ref.distance(centerOfSelectedCell);
2867:
2868: switch (direction) {
2869: case 1: //DOWN
2870: if (centerOfCell.y >= centerOfSelectedCell.y) {
2871: if (dist < minDistance && absOfTan >= 1) {
2872: minDistance = dist;
2873: nearestCell = cells[i];
2874: }
2875: }
2876: break;
2877: case 2: //LEFT
2878: if (centerOfCell.x <= centerOfSelectedCell.x) {
2879: if (dist < minDistance && absOfTan <= 1) {
2880: minDistance = dist;
2881: nearestCell = cells[i];
2882: }
2883: }
2884: break;
2885: case 3: //RIGHT
2886: if (centerOfCell.x >= centerOfSelectedCell.x) {
2887: if (dist < minDistance && absOfTan <= 1) {
2888: minDistance = dist;
2889: nearestCell = cells[i];
2890: }
2891: }
2892: break;
2893: default: //UP
2894: if (centerOfCell.y <= centerOfSelectedCell.y) {
2895: if (dist < minDistance && absOfTan >= 1) {
2896: minDistance = dist;
2897: nearestCell = cells[i];
2898: }
2899: }
2900: break;
2901: }
2902: }
2903: return nearestCell;
2904: }
2905:
2906: public boolean moveParticipants(List partsToMove,
2907: boolean direction, Map propertyMap, ParentMap parentMap) {
2908: boolean updated = false;
2909: for (int i = 0; i < partsToMove.size(); i++) {
2910: GraphParticipantInterface parSource = (GraphParticipantInterface) partsToMove
2911: .get(i);
2912: Rectangle rSource = getBounds(parSource, propertyMap)
2913: .getBounds();// getting
2914: // bounds
2915: // of
2916: // rectangle//HM,
2917: // JGraph3.4.1
2918:
2919: Rectangle matching = new Rectangle(rSource); // added by SB
2920:
2921: int yPos;
2922: int xPos;
2923: GraphParticipantInterface[] parts;
2924: if (direction) {//move up
2925: yPos = rSource.y - 1;
2926: xPos = rSource.x - 1;
2927: if (!isGraphRotated()) {
2928: parts = getParticipantsForYPos(yPos, 2,
2929: propertyMap, parentMap);
2930: if (parts != null && parts.length > 0) {
2931: GraphParticipantInterface parTarget = parts[0];
2932: Rectangle rTarget = getBounds(parTarget,
2933: propertyMap);//HM,
2934: // JGraph3.4.1
2935:
2936: translateParticipant(parSource, propertyMap,
2937: parentMap, 0, -rTarget.height);//source
2938: // part
2939: // up
2940:
2941: translateParticipant(parTarget, propertyMap,
2942: parentMap, 0, rSource.height);//target
2943: // part
2944: // down
2945: }
2946: } else {
2947: parts = getParticipantsForXPos(xPos, 2,
2948: propertyMap, parentMap);
2949: if (parts != null && parts.length > 0) {
2950: GraphParticipantInterface parTarget = parts[0];
2951: Rectangle rTarget = getBounds(parTarget,
2952: propertyMap);//HM,
2953: // JGraph3.4.1
2954:
2955: translateParticipant(parSource, propertyMap,
2956: parentMap, -rTarget.width, 0);//source
2957: // part
2958: // up
2959:
2960: translateParticipant(parTarget, propertyMap,
2961: parentMap, rSource.width, 0);//target
2962: // part
2963: // down
2964: }
2965: }
2966: } else {//move down
2967: yPos = rSource.y + rSource.height + 1;
2968: xPos = rSource.x + rSource.width + 1;
2969: if (!isGraphRotated()) {
2970: parts = getParticipantsForYPos(yPos, 2,
2971: propertyMap, parentMap);
2972: if (parts != null && parts.length > 0) {
2973: GraphParticipantInterface parTarget = parts[0];
2974: Rectangle rTarget = getBounds(parTarget,
2975: propertyMap);//HM,
2976: // JGraph3.4.1
2977:
2978: translateParticipant(parSource, propertyMap,
2979: parentMap, 0, rTarget.height);//source
2980: // part
2981: // down
2982:
2983: translateParticipant(parTarget, propertyMap,
2984: parentMap, 0, -rSource.height);//target
2985: // part
2986: // up
2987: }
2988: } else {
2989: parts = getParticipantsForXPos(xPos, 2,
2990: propertyMap, parentMap);
2991: if (parts != null && parts.length > 0) {
2992: GraphParticipantInterface parTarget = parts[0];
2993: Rectangle rTarget = getBounds(parTarget,
2994: propertyMap);//HM,
2995: // JGraph3.4.1
2996:
2997: translateParticipant(parSource, propertyMap,
2998: parentMap, rTarget.width, 0);//source
2999: // part
3000: // down
3001:
3002: translateParticipant(parTarget, propertyMap,
3003: parentMap, -rSource.width, 0);//target
3004: // part
3005: // up
3006: }
3007: }
3008: }
3009:
3010: Rectangle toMatch = getBounds(parSource, propertyMap); // added
3011: // by
3012: // SB//HM,
3013: // JGraph3.4.1
3014: arrangeParticipants(propertyMap, parentMap);
3015:
3016: if (!toMatch.equals(matching)) {
3017: updated = true;
3018: }
3019: }
3020: return updated;
3021: }
3022:
3023: // Harald Meister
3024:
3025: public Dimension getGraphsPreferredSize() {
3026: if (!isGraphRotated()) {
3027: return new Dimension(
3028: getRootParticipantWidth(null, null) + 50,
3029: getNewRootParYPos(null, null) + 50);
3030: }
3031: return new Dimension(getNewRootParXPos(null, null) + 50,
3032: getRootParticipantHeight(null, null) + 50);
3033: }
3034:
3035: protected List getPoints(GraphTransitionInterface cell,
3036: Map propertyMap) {//HM,
3037: // JGraph3.4.1
3038: if (propertyMap != null && propertyMap.containsKey(cell)) {
3039: Map map = (Map) propertyMap.get(cell);
3040: List points = GraphConstants.getPoints(map);
3041: List toRet = new ArrayList();
3042: for (int i = 1; i < points.size() - 1; i++) {
3043: Point2D p2d = (Point2D) points.get(i);
3044: Point p = new Point();
3045: p.setLocation(p2d);
3046: toRet.add(p);
3047: }
3048: return toRet;
3049: }
3050: return new ArrayList();
3051: }
3052:
3053: protected boolean isGraphRotated() {
3054: return GraphUtilities
3055: .getGraphParticipantOrientation(getWorkflowProcess(),
3056: getXPDLOwner())
3057: .equals(
3058: GraphEAConstants.EA_JAWE_GRAPH_PARTICIPANT_ORIENTATION_VALUE_VERTICAL);
3059: }
3060:
3061: //// THE FOLLOWING METHODS ARE MODIFYING XPDL MODEL !!!
3062: public void moveCellsAndArrangeParticipants(Map propertyMap) {
3063: if (getGraphController().isUpdateInProgress() == true)
3064: Thread.dumpStack();
3065: JaWEManager.getInstance().getJaWEController()
3066: .startUndouableChange();
3067: getGraphController().setUpdateInProgress(true);
3068: updateModelAndArrangeParticipants(null, propertyMap, null,
3069: null, getGraphController().getSettings()
3070: .getLanguageDependentString(
3071: "MessageMovingObjects"), null, true);
3072: JaWEManager.getInstance().getJaWEController()
3073: .endUndouableChange(
3074: updateXPDLActivitiesPosition(propertyMap));
3075: getGraphController().setUpdateInProgress(false);
3076: }
3077:
3078: protected List updateXPDLActivitiesPosition(Map propertyMap) {
3079: List updatedPositions = new ArrayList();
3080: if (propertyMap == null) {
3081: return updatedPositions;
3082: }
3083: Object[] cellsToManage = propertyMap.keySet().toArray();
3084: for (int i = 0; i < cellsToManage.length; i++) {
3085: Object cell = cellsToManage[i];
3086: if (cell instanceof GraphActivityInterface) {
3087: GraphActivityInterface gact = (GraphActivityInterface) cell;
3088: GraphParticipantInterface gpar = (GraphParticipantInterface) gact
3089: .getParent();
3090: Point offset = getOffset(gact, propertyMap);
3091: XMLElement el = gact.getPropertyObject();
3092: if (gact instanceof GraphBubbleActivityInterface) {
3093: ExtendedAttribute ea = (ExtendedAttribute) el;
3094: StartEndDescription sed = new StartEndDescription(
3095: ea);
3096: if (!sed.getOffset().equals(offset)) {
3097: sed.setOffset(offset);
3098: ea.setVValue(sed.toString());
3099: updatedPositions.add(el);
3100: }
3101: } else {
3102: Activity a = (Activity) el;
3103: if (!GraphUtilities.getOffsetPoint(a)
3104: .equals(offset)) {
3105: GraphUtilities.setOffsetPoint((Activity) el,
3106: offset);
3107: updatedPositions.add(el);
3108: }
3109: }
3110: Participant defaultP = FreeTextExpressionParticipant
3111: .getInstance();
3112: Participant newPar = (Participant) gpar
3113: .getPropertyObject();
3114: if (el instanceof Activity) {
3115: Activity act = (Activity) el;
3116: String parIdOld = GraphUtilities
3117: .getParticipantId(act);
3118: // Setting the new performer for activity
3119: int actType = act.getActivityType();
3120: if ((actType == XPDLConstants.ACTIVITY_TYPE_NO || actType == XPDLConstants.ACTIVITY_TYPE_TOOL)) {
3121: if (!newPar.getId().equals(parIdOld)) {
3122: if (newPar != defaultP) {
3123: act.setPerformer(newPar.getId());
3124: } else {
3125: act.setPerformer("");
3126: }
3127: }
3128: }
3129:
3130: GraphUtilities
3131: .setParticipantId(act, newPar.getId());
3132: } else {
3133: ExtendedAttribute ea = (ExtendedAttribute) el;
3134: StartEndDescription sed = new StartEndDescription(
3135: ea);
3136: sed.setParticipantId(newPar.getId());
3137: ea.setVValue(sed.toString());
3138: // System.err.println("Setting pid for ea "+el);
3139: }
3140:
3141: } else if (cell instanceof GraphTransitionInterface) {
3142: GraphTransitionInterface gtra = (GraphTransitionInterface) cell;
3143: Transition tra = (Transition) gtra.getPropertyObject();
3144: if (tra == null) {
3145: continue;
3146: }
3147: List points = getPoints(gtra, propertyMap);
3148: List bps = GraphUtilities.getBreakpoints(tra);
3149: if (!points.equals(bps)) {
3150: GraphUtilities.setBreakpoints(tra, points);
3151: updatedPositions.add(tra);
3152: }
3153: }
3154: }
3155: return updatedPositions;
3156: }
3157:
3158: public void removeCells(Object[] cellsToDelete) {
3159: boolean updated = false;
3160: Set bubblesToDelete = new HashSet();
3161: Set bubblesToDisconnect = new HashSet();
3162: Set transitionsToDelete = new HashSet();
3163: Set activitiesToDelete = new HashSet();
3164: Set participantsToDelete = new HashSet();
3165:
3166: // begining arrangement of parent of cells that will be deleted
3167: if (cellsToDelete != null && cellsToDelete.length > 0) {
3168:
3169: // All cells in model to be deleted
3170: Set allCellsToDelete = new HashSet(JaWEGraphModel
3171: .getDescendantList(graphModel(), cellsToDelete));
3172:
3173: // getting transitions(edges) which are connected to the cellsForDel ->
3174: // also has to be deleted
3175: Set edges = new HashSet(JaWEGraphModel.getEdges(
3176: graphModel(), allCellsToDelete.toArray()));
3177:
3178: // putting all items for deletion (edges and cells) together - thats
3179: // ALL FOR DELETION
3180: allCellsToDelete.addAll(edges);
3181:
3182: int i = 0;
3183: // Separate cells and edges
3184: Iterator it = allCellsToDelete.iterator();
3185: while (it.hasNext()) {
3186: i++;
3187: Object cell = it.next();
3188: // System.out.println("Cell "+i+"="+cell+",
3189: // cn="+cell.getClass().getName()+", hc="+cell.hashCode());
3190: if (cell instanceof GraphTransitionInterface) {
3191: if (((GraphTransitionInterface) cell)
3192: .getPropertyObject() != null) {
3193: transitionsToDelete.add(cell);
3194: } else {
3195: GraphTransitionInterface gtra = (GraphTransitionInterface) cell;
3196: GraphBubbleActivityInterface sOrE = null;
3197: if (gtra.getSourceActivity() instanceof GraphBubbleActivityInterface) {
3198: sOrE = (GraphBubbleActivityInterface) gtra
3199: .getSourceActivity();
3200: } else {
3201: sOrE = (GraphBubbleActivityInterface) gtra
3202: .getTargetActivity();
3203: }
3204: bubblesToDisconnect.add(sOrE);
3205: }
3206: } else if (cell instanceof GraphBubbleActivityInterface) {
3207: bubblesToDelete.add(cell);
3208: } else if (cell instanceof GraphActivityInterface) {
3209: activitiesToDelete.add(cell);
3210: } else if (cell instanceof GraphParticipantInterface) {
3211: participantsToDelete.add(cell);
3212: }
3213: }
3214: }
3215:
3216: updated = updated || bubblesToDisconnect.size() > 0
3217: || bubblesToDelete.size() > 0
3218: || transitionsToDelete.size() > 0
3219: || activitiesToDelete.size() > 0
3220: || participantsToDelete.size() > 0;
3221:
3222: if (updated) {
3223: GraphController gcon = getGraph().getGraphController();
3224: JaWEController jc = JaWEManager.getInstance()
3225: .getJaWEController();
3226: gcon.setUpdateInProgress(true);
3227: jc.startUndouableChange();
3228: removeCellsAndArrangeParticipants(cellsToDelete);
3229:
3230: // JaWEManager.getInstance().getLoggingManager().debug(
3231: // "BTD=" + bubblesToDisconnect.size() + ",BTD=" + bubblesToDelete.size() + ", TRTD=" + transitionsToDelete.size() + ", ATD="
3232: // + activitiesToDelete.size());
3233: Iterator it = bubblesToDisconnect.iterator();
3234: List toDel = new ArrayList();
3235: while (it.hasNext()) {
3236: GraphBubbleActivityInterface b = (GraphBubbleActivityInterface) it
3237: .next();
3238: ExtendedAttribute ea = (ExtendedAttribute) b
3239: .getPropertyObject();
3240: StartEndDescription sed = new StartEndDescription(ea);
3241: sed.setActId(null);
3242: ea.setVValue(sed.toString());
3243: }
3244: it = bubblesToDelete.iterator();
3245: toDel = new ArrayList();
3246: while (it.hasNext()) {
3247: GraphBubbleActivityInterface b = (GraphBubbleActivityInterface) it
3248: .next();
3249: ExtendedAttribute ea = (ExtendedAttribute) b
3250: .getPropertyObject();
3251: toDel.add(ea);
3252: }
3253: getWorkflowProcess().getExtendedAttributes().removeAll(
3254: toDel);
3255: toDel.clear();
3256:
3257: it = transitionsToDelete.iterator();
3258: while (it.hasNext()) {
3259: GraphTransitionInterface gt = (GraphTransitionInterface) it
3260: .next();
3261: Transition t = (Transition) gt.getPropertyObject();
3262: toDel.add(t);
3263: }
3264: ((Transitions) getXPDLOwner().get("Transitions"))
3265: .removeAll(toDel);
3266: toDel.clear();
3267:
3268: it = activitiesToDelete.iterator();
3269: while (it.hasNext()) {
3270: GraphActivityInterface ga = (GraphActivityInterface) it
3271: .next();
3272: Activity a = (Activity) ga.getPropertyObject();
3273: toDel.add(a);
3274: }
3275: ((Activities) getXPDLOwner().get("Activities"))
3276: .removeAll(toDel);
3277: toDel.clear();
3278:
3279: List porder = GraphUtilities
3280: .getParticipantVisualOrder(getXPDLOwner());
3281:
3282: it = participantsToDelete.iterator();
3283: while (it.hasNext()) {
3284: GraphParticipantInterface gp = (GraphParticipantInterface) it
3285: .next();
3286: Participant p = (Participant) gp.getPropertyObject();
3287: String toRem = p.getId();
3288: if (p instanceof CommonExpressionParticipant) {
3289: toRem = CommonExpressionParticipants.getInstance()
3290: .getIdForVisualOrderEA(toRem);
3291: CommonExpressionParticipants.getInstance()
3292: .remove(p);
3293: }
3294: porder.remove(toRem);
3295: }
3296: GraphUtilities.setParticipantVisualOrder(getXPDLOwner(),
3297: porder);
3298: List toSelect = new ArrayList();
3299: toSelect.add(getXPDLOwner());
3300: jc.endUndouableChange(toSelect);
3301: gcon.setUpdateInProgress(false);
3302: }
3303: }
3304:
3305: //Harald Meister: method for moving participants in graph
3306: // direction=true for up, false for down
3307: //Note: the participants have to be correctly sorted so that moving of
3308: // multiple part's works
3309: public void moveParticipants(Object[] cellsToMove, boolean direction) {
3310: GraphParticipantComparator pc = new GraphParticipantComparator(
3311: this );
3312: List partsToMove = new ArrayList();
3313: List toSelect = new ArrayList();
3314:
3315: if (cellsToMove != null) {
3316: for (int i = 0; i < cellsToMove.length; i++) {
3317: if (cellsToMove[i] instanceof GraphParticipantInterface) {
3318: GraphParticipantInterface gpar = (GraphParticipantInterface) cellsToMove[i];
3319: partsToMove.add(gpar);
3320: toSelect.add(gpar.getPropertyObject());
3321: }
3322: }
3323: } else {
3324: return;
3325: }
3326: Collections.sort(partsToMove, pc);//sort so that the move works correctly with mutliple selected participants
3327: Map propertyMap = new HashMap();
3328: ParentMap parentMap = new JaWEParentMap();
3329: boolean updated = moveParticipants(partsToMove, direction,
3330: propertyMap, parentMap);
3331: // changed by Sasa Bojanic - so that undo/redo actions are compound
3332: // and that there is no action if position doesn't change
3333: if (updated) {
3334: getGraphController().setUpdateInProgress(true);
3335: graphModel().insertAndEdit(null, propertyMap, null,
3336: parentMap, null, "");
3337: // make new visual order list
3338: List allGraphParticipants = JaWEGraphModel
3339: .getAllParticipantsInModel(graph.getModel());
3340: if (allGraphParticipants != null) {
3341: GraphParticipantComparator gpc = new GraphParticipantComparator(
3342: this );
3343: Collections.sort(allGraphParticipants, gpc);
3344: }
3345: List vo = new ArrayList();
3346: for (int i = 0; i < allGraphParticipants.size(); i++) {
3347: GraphParticipantInterface gp = (GraphParticipantInterface) allGraphParticipants
3348: .get(i);
3349: Participant par = (Participant) gp.getPropertyObject();
3350: if (!(par instanceof CommonExpressionParticipant)) {
3351: vo.add(par.getId());
3352: } else {
3353: vo.add(CommonExpressionParticipants.getInstance()
3354: .getIdForVisualOrderEA(par.getId()));
3355: }
3356: }
3357: JaWEManager.getInstance().getJaWEController()
3358: .startUndouableChange();
3359:
3360: GraphUtilities
3361: .setParticipantVisualOrder(getXPDLOwner(), vo);
3362: JaWEManager.getInstance().getJaWEController()
3363: .endUndouableChange(toSelect);
3364: getGraphController().setUpdateInProgress(false);
3365: }
3366: }
3367:
3368: public void removeStartEndBubbles() {
3369: XMLCollectionElement wpOrAs = getXPDLOwner();
3370: List eas = GraphUtilities.getStartOrEndExtendedAttributes(
3371: wpOrAs, true);
3372: eas.addAll(GraphUtilities.getStartOrEndExtendedAttributes(
3373: wpOrAs, false));
3374: if (eas.size() > 0) {
3375: getGraphController().setUpdateInProgress(true);
3376: for (int i = 0; i < eas.size(); i++) {
3377: removeBubble((ExtendedAttribute) eas.get(i));
3378: }
3379: JaWEManager.getInstance().getJaWEController()
3380: .startUndouableChange();
3381: XMLUtil.getWorkflowProcess(wpOrAs).getExtendedAttributes()
3382: .removeAll(eas);
3383: List toSelect = new ArrayList();
3384: toSelect.add(wpOrAs);
3385: JaWEManager.getInstance().getJaWEController()
3386: .endUndouableChange(toSelect);
3387: getGraphController().setUpdateInProgress(false);
3388: }
3389: }
3390:
3391: public List insertMissingStartEndBubbles() {
3392: XMLCollectionElement wpOrAs = getXPDLOwner();
3393: WorkflowProcess wp = getWorkflowProcess();
3394: String asId = null;
3395: if (wpOrAs instanceof ActivitySet) {
3396: asId = wpOrAs.getId();
3397: }
3398: GraphController gc = getGraphController();
3399: Dimension defActDim = new Dimension(gc.getGraphSettings()
3400: .getActivityWidth(), gc.getGraphSettings()
3401: .getActivityHeight());
3402: Set sas = XMLUtil.getStartingActivities(wpOrAs);
3403: Set eas = XMLUtil.getEndingActivities(wpOrAs);
3404:
3405: List easToAdd = new ArrayList();
3406: Iterator it = sas.iterator();
3407: String eaname = null;
3408: if (wpOrAs instanceof WorkflowProcess) {
3409: eaname = GraphEAConstants.EA_JAWE_GRAPH_START_OF_WORKFLOW;
3410: } else {
3411: eaname = GraphEAConstants.EA_JAWE_GRAPH_START_OF_BLOCK;
3412: }
3413: int ah = gc.getGraphSettings().getActivityHeight();
3414: int aw = gc.getGraphSettings().getActivityWidth();
3415: while (it.hasNext()) {
3416: Activity act = (Activity) it.next();
3417: GraphActivityInterface gact = getGraphActivity(act);
3418: Set racts = gact.getReferencingActivities();
3419: if (!GraphManager.containsBubble(racts, true)) {
3420: StartEndDescription sed = new StartEndDescription();
3421: sed.setEAName(eaname);
3422: sed.setActSetId(asId);
3423: sed.setActId(act.getId());
3424: sed.setParticipantId(GraphUtilities
3425: .getParticipantId(act));
3426: Point op = GraphManager.getBubbleOffsetPoint(
3427: GraphUtilities.getOffsetPoint(act), true,
3428: defActDim, isGraphRotated());
3429: // if (!isGraphRotated()) {
3430: op.x += (aw - 0.6 * ah) / 2;
3431: op.y += ah / 5;
3432: // } else {
3433: // op.x+=(aw-0.6*ah)/2;
3434: // op.y+=ah/5;
3435: // }
3436: sed.setOffset(op);
3437: sed.setType(GraphEAConstants.START_TYPE_DEFAULT);
3438: ExtendedAttribute ea = (ExtendedAttribute) wp
3439: .getExtendedAttributes().generateNewElement();
3440: ea.setName(sed.getEAName());
3441: ea.setVValue(sed.toString());
3442: easToAdd.add(ea);
3443: insertStart(ea);
3444: }
3445: }
3446:
3447: if (wpOrAs instanceof WorkflowProcess) {
3448: eaname = GraphEAConstants.EA_JAWE_GRAPH_END_OF_WORKFLOW;
3449: } else {
3450: eaname = GraphEAConstants.EA_JAWE_GRAPH_END_OF_BLOCK;
3451: }
3452: it = eas.iterator();
3453: while (it.hasNext()) {
3454: Activity act = (Activity) it.next();
3455: GraphActivityInterface gact = getGraphActivity(act);
3456: Set racts = gact.getReferencedActivities();
3457: if (!GraphManager.containsBubble(racts, false)) {
3458: StartEndDescription sed = new StartEndDescription();
3459: sed.setEAName(eaname);
3460: sed.setActSetId(asId);
3461: sed.setActId(act.getId());
3462: sed.setParticipantId(GraphUtilities
3463: .getParticipantId(act));
3464: Point op = GraphManager.getBubbleOffsetPoint(
3465: GraphUtilities.getOffsetPoint(act), false,
3466: defActDim, isGraphRotated());
3467: // if (!isGraphRotated()) {
3468: op.x += (aw - 0.6 * ah) / 2;
3469: op.y += ah / 5;
3470: // } else {
3471: // op.x+=(aw-0.6*ah)/2;
3472: // op.y+=ah/5;
3473: // }
3474: sed.setOffset(op);
3475: sed.setType(GraphEAConstants.END_TYPE_DEFAULT);
3476: ExtendedAttribute ea = (ExtendedAttribute) wp
3477: .getExtendedAttributes().generateNewElement();
3478: ea.setName(sed.getEAName());
3479: ea.setVValue(sed.toString());
3480: easToAdd.add(ea);
3481: insertEnd(ea);
3482: }
3483: }
3484:
3485: return easToAdd;
3486: }
3487:
3488: protected static boolean containsBubble(Set gacts, boolean start) {
3489: boolean ret = false;
3490:
3491: Iterator it = gacts.iterator();
3492: while (it.hasNext()) {
3493: GraphActivityInterface gact = (GraphActivityInterface) it
3494: .next();
3495: if (gact instanceof GraphBubbleActivityInterface) {
3496: if (((GraphBubbleActivityInterface) gact).isStart() == start) {
3497: return true;
3498: }
3499: }
3500: }
3501:
3502: return ret;
3503: }
3504:
3505: protected static Point getBubbleOffsetPoint(Point actOffs,
3506: boolean start, Dimension defActDim, boolean isGraphRotated) {
3507: Point p = new Point(actOffs);
3508:
3509: if (start) {
3510: if (!isGraphRotated) {
3511: p.x -= defActDim.width * 1.5;
3512: } else {
3513: p.y -= defActDim.height * 1.5;
3514: }
3515: } else {
3516: if (!isGraphRotated) {
3517: p.x += defActDim.width * 1.5;
3518: } else {
3519: p.y += defActDim.height * 1.5;
3520: }
3521: }
3522: if (!isGraphRotated) {
3523: if (p.x < 0) {
3524: p.x = 0;
3525: }
3526: } else {
3527: if (p.y < 0) {
3528: p.y = 0;
3529: }
3530: }
3531: return p;
3532: }
3533: }
|