001: /**
002: * Miroslav Popov, Sep 14, 2005 miroslav.popov@gmail.com
003: */package org.enhydra.jawe.base.controller;
004:
005: import java.util.ArrayList;
006: import java.util.HashSet;
007: import java.util.Iterator;
008: import java.util.List;
009: import java.util.Set;
010:
011: import org.enhydra.jawe.XPDLElementChangeInfo;
012: import org.enhydra.shark.xpdl.XMLAttribute;
013: import org.enhydra.shark.xpdl.XMLCollection;
014: import org.enhydra.shark.xpdl.XMLComplexChoice;
015: import org.enhydra.shark.xpdl.XMLComplexElement;
016: import org.enhydra.shark.xpdl.XMLElement;
017: import org.enhydra.shark.xpdl.XMLSimpleElement;
018: import org.enhydra.shark.xpdl.XMLUtil;
019: import org.enhydra.shark.xpdl.elements.Activities;
020: import org.enhydra.shark.xpdl.elements.Activity;
021: import org.enhydra.shark.xpdl.elements.ActivitySet;
022: import org.enhydra.shark.xpdl.elements.Application;
023: import org.enhydra.shark.xpdl.elements.DataField;
024: import org.enhydra.shark.xpdl.elements.FormalParameter;
025: import org.enhydra.shark.xpdl.elements.Package;
026: import org.enhydra.shark.xpdl.elements.Participant;
027: import org.enhydra.shark.xpdl.elements.Transition;
028: import org.enhydra.shark.xpdl.elements.TypeDeclaration;
029: import org.enhydra.shark.xpdl.elements.WorkflowProcess;
030: import org.enhydra.shark.xpdl.elements.WorkflowProcesses;
031:
032: /**
033: * @author Miroslav Popov
034: * @author Sasa Bojanic
035: */
036: public class JaWESelectionManager {
037:
038: protected JaWEController jc;
039:
040: protected List selectedElements = new ArrayList();
041:
042: protected Package workingPKG;
043:
044: protected WorkflowProcess workingWP;
045:
046: protected ActivitySet workingAS;
047:
048: public JaWESelectionManager(JaWEController controller) {
049: jc = controller;
050: }
051:
052: public void clear() {
053: selectedElements = new ArrayList();
054: workingPKG = null;
055: workingWP = null;
056: workingAS = null;
057: }
058:
059: public List getSelectedElements() {
060: return new ArrayList(selectedElements);
061: }
062:
063: public XMLElement getSelectedElement() {
064: if (selectedElements.size() > 0) {
065: return (XMLElement) selectedElements.get(0);
066: }
067: return null;
068: }
069:
070: public void setSelection(XMLElement el, boolean setPkgAndWpAndas) {
071: selectedElements = new ArrayList();
072: if (el != null)
073: selectedElements.add(el);
074:
075: if (setPkgAndWpAndas)
076: setPkgWpAndAs();
077:
078: XPDLElementChangeInfo info = jc.createInfo(el,
079: XPDLElementChangeInfo.SELECTED);
080: jc.sendEvent(info);
081: }
082:
083: public void setSelection(List selection, boolean setPkgAndWpAndas) {
084: if (checkSelection(selection)) {
085: if (selection == null) {
086: selectedElements = new ArrayList();
087: } else {
088: selectedElements = selection;
089: }
090: } else {
091: selectedElements = new ArrayList();
092: selectedElements.add(selection.get(selection.size() - 1));
093: }
094:
095: if (setPkgAndWpAndas)
096: setPkgWpAndAs();
097:
098: if (selectedElements.size() == 0)
099: return;
100:
101: List temp = new ArrayList(selectedElements);
102: XMLElement firstEl = (XMLElement) temp.get(0);
103: XMLElement selOwner = firstEl;
104: if (temp.size() > 1) {
105: selOwner = firstEl.getParent();
106: if (selOwner == null) {
107: selOwner = firstEl;
108: }
109: } else {
110: temp.clear();
111: }
112: XPDLElementChangeInfo info = jc.createInfo(selOwner, temp,
113: XPDLElementChangeInfo.SELECTED);
114: jc.sendEvent(info);
115: }
116:
117: public void addToSelection(XMLElement el) {
118: List temp = new ArrayList();
119: temp.add(el);
120: addToSelection(temp);
121: }
122:
123: public void addToSelection(List elements) {
124: if (canBeAddedToSelection(elements)) {
125: selectedElements.addAll(elements);
126: } else {
127: selectedElements = new ArrayList();
128: selectedElements.add(elements.get(elements.size() - 1));
129: }
130:
131: setPkgWpAndAs();
132:
133: if (selectedElements.size() == 0)
134: return;
135:
136: List temp = new ArrayList(selectedElements);
137: XMLElement firstEl = (XMLElement) temp.get(0);
138: XMLElement selOwner = firstEl;
139: if (temp.size() > 1) {
140: selOwner = firstEl.getParent();
141: if (selOwner == null) {
142: selOwner = firstEl;
143: }
144: } else {
145: temp.clear();
146: }
147: XPDLElementChangeInfo info = jc.createInfo(selOwner, temp,
148: XPDLElementChangeInfo.SELECTED);
149: jc.sendEvent(info);
150: }
151:
152: public void removeFromSelection(XMLElement el) {
153: List temp = new ArrayList();
154: temp.add(el);
155: removeFromSelection(temp);
156: }
157:
158: public void removeFromSelection(List elements) {
159: Set elementsToRemove = new HashSet();
160:
161: for (int i = 0; i < elements.size(); i++) {
162: XMLElement el = (XMLElement) elements.get(i);
163:
164: // for (int j = 0; j < selectedElements.size(); j++) {
165: // XMLElement element = (XMLElement)selectedElements.get(j);
166: //
167: // XMLElement parent = element.getParent();
168: // while (parent != null && parent != el) {
169: // parent = parent.getParent();
170: // }
171: //
172: // if (parent != null)
173: // elementsToRemove.add(element);
174: // }
175:
176: elementsToRemove.add(el);
177: }
178:
179: for (Iterator it = elementsToRemove.iterator(); it.hasNext();) {
180: selectedElements.remove(it.next());
181: }
182:
183: setPkgWpAndAs();
184: jc.adjustActions();
185: }
186:
187: protected void setPkgWpAndAs() {
188: if (selectedElements.size() != 0) {
189: XMLElement el = (XMLElement) selectedElements.get(0);
190: workingPKG = XMLUtil.getPackage(el);
191: if (workingPKG != null) {
192: WorkflowProcess oldWp = workingWP;
193: if (oldWp != null) {
194: WorkflowProcesses wprs = (WorkflowProcesses) oldWp
195: .getParent();
196: if (!wprs.contains(oldWp)) {
197: oldWp = null;
198: }
199: }
200: workingWP = XMLUtil.getWorkflowProcess(el);
201: if (workingWP == null) {
202: if (oldWp != null
203: && XMLUtil.getPackage(oldWp) == workingPKG) {
204: workingWP = oldWp;
205: } else {
206: List wps = workingPKG.getWorkflowProcesses()
207: .toElements();
208: if (wps.size() != 0) {
209: workingWP = (WorkflowProcess) wps.get(0);
210: }
211: }
212: }
213: workingAS = XMLUtil.getActivitySet(el);
214: } else {
215: workingWP = null;
216: workingAS = null;
217: }
218: } else {
219: workingPKG = null;
220: workingWP = null;
221: workingAS = null;
222: }
223: }
224:
225: public Package getWorkingPKG() {
226: return workingPKG;
227: }
228:
229: public String getWorkingPackageId() {
230: if (workingPKG != null) {
231: return workingPKG.getId();
232: }
233: return null;
234: }
235:
236: public WorkflowProcess getWorkingProcess() {
237: return workingWP;
238: }
239:
240: public String getWorkingWorkflowProcessId() {
241: if (workingWP != null) {
242: return workingWP.getId();
243: }
244: return null;
245: }
246:
247: public ActivitySet getWorkingActivitySet() {
248: return workingAS;
249: }
250:
251: public String getWorkingActivitySetId() {
252: if (workingAS != null) {
253: return workingAS.getId();
254: }
255: return null;
256: }
257:
258: public boolean canBeAddedToSelection(List selection) {
259: List temp = new ArrayList(selectedElements);
260: temp.addAll(selection);
261:
262: return checkSelection(temp);
263: }
264:
265: public boolean checkSelection(List selection) {
266: if (selection == null) {
267: return true;
268: }
269:
270: if (selection.size() <= 1) {
271: return true;
272: }
273:
274: boolean hasActivity = false;
275: boolean hasTransition = false;
276: boolean hasSingleSelectionElement = false;
277: boolean hasOther = false;
278:
279: Set parents = new HashSet();
280: Set classes = new HashSet();
281:
282: for (int i = 0; i < selection.size(); i++) {
283: XMLElement el = (XMLElement) selection.get(i);
284: XMLElement parent = el.getParent();
285: Class cls = el.getClass();
286: if (el instanceof Activity) {
287: hasActivity = true;
288: } else if (el instanceof Transition) {
289: hasTransition = true;
290: } else if (!(parent instanceof XMLCollection)) {
291: hasSingleSelectionElement = true;
292: } else {
293: hasOther = true;
294: }
295: if (parent != null) {
296: parents.add(parent);
297: }
298: classes.add(cls);
299: }
300:
301: // only one other component is allowed
302: if (hasSingleSelectionElement) {
303: return false;
304: }
305:
306: // if only activities and transitions are selected, check if they
307: // are contained in the same WorkflowProcess/ActivitySet
308: if (hasActivity && hasTransition && !hasOther) {
309: Set parentsParents = new HashSet();
310: for (int i = 0; i < selection.size(); i++) {
311: XMLElement elParentParent = ((XMLElement) selection
312: .get(i)).getParent().getParent();
313: parentsParents.add(elParentParent);
314: }
315: if (parentsParents.size() != 1) {
316: return false;
317: }
318:
319: return true;
320: }
321:
322: // if there are more than one parent, or more than one type of object class, return
323: // false
324: return !(parents.size() > 1 || classes.size() > 1);
325: }
326:
327: public boolean canEditProperties() {
328: if (getSelectedElements().size() == 1) {
329: XMLElement firstSelected = (XMLElement) selectedElements
330: .get(0);
331: if (XMLUtil.getPackage(firstSelected) != null) {
332: return true;
333: }
334: }
335: return false;
336: }
337:
338: public boolean canCut() {
339: return checkCutOrCopySelection(true);
340: }
341:
342: public boolean canCopy() {
343: return checkCutOrCopySelection(false);
344: }
345:
346: public boolean canDuplicate() {
347: if (selectedElements.size() != 1) {
348: return false;
349: }
350:
351: XMLElement firstSelected = (XMLElement) selectedElements.get(0);
352: XMLElement parent = firstSelected.getParent();
353: if (!(parent instanceof XMLCollection)) {
354: return false;
355: }
356:
357: return jc.canDuplicateElement((XMLCollection) parent,
358: firstSelected);
359: }
360:
361: public boolean canInsertNew() {
362: if (selectedElements.size() == 0) {
363: return false;
364: }
365:
366: XMLElement firstSelected = (XMLElement) selectedElements.get(0);
367: XMLElement parent = firstSelected.getParent();
368: if (!(firstSelected instanceof XMLCollection
369: || parent instanceof XMLCollection || firstSelected instanceof Package)) {
370: return false;
371: }
372:
373: if (firstSelected instanceof XMLCollection) {
374: return jc.canCreateElement((XMLCollection) firstSelected);
375: } else if (parent instanceof XMLCollection) {
376: return jc.canCreateElement((XMLCollection) parent);
377: } else if (firstSelected instanceof Package
378: && !((Package) firstSelected).isReadOnly()) {
379: return true;
380: }
381: return false;
382: }
383:
384: public boolean canPaste() {
385: if (jc.getEdit().getClipboard().size() == 0) {
386: return false;
387: }
388:
389: if (selectedElements.size() == 0) {
390: return false;
391: }
392:
393: Class clipboardParentsClass1 = null;
394: Class clipboardParentsClass2 = null;
395: Class clipboardElementsClass1 = null;
396: Class clipboardElementsClass2 = null;
397: for (int i = 0; i < jc.getEdit().getClipboard().size(); i++) {
398: XMLElement el = (XMLElement) jc.getEdit().getClipboard()
399: .get(i);
400: XMLElement parent = el.getParent();
401:
402: if (el instanceof Transition) {
403: clipboardParentsClass2 = parent.getClass();
404: clipboardElementsClass2 = el.getClass();
405: } else {
406: clipboardParentsClass1 = parent.getClass();
407: clipboardElementsClass1 = el.getClass();
408: }
409: }
410:
411: Class selectionElementsClass1 = null;
412: Class selectionElementsClass2 = null;
413: for (int i = 0; i < selectedElements.size(); i++) {
414: XMLElement el = (XMLElement) selectedElements.get(i);
415: if (el.isReadOnly()) {
416: return false;
417: }
418:
419: if (el instanceof Transition) {
420: selectionElementsClass2 = el.getClass();
421: } else {
422: selectionElementsClass1 = el.getClass();
423: }
424:
425: }
426: // System.err.println("CEC1="+clipboardElementsClass1+",
427: // CEC2="+clipboardElementsClass2);
428: // System.err.println("SEC1="+selectionElementsClass1+",
429: // SEC2="+selectionElementsClass2);
430: boolean allowPaste1 = clipboardElementsClass1 == null ? false
431: : (selectionElementsClass1 == null ? false
432: : clipboardElementsClass1 == selectionElementsClass1);
433: // System.err.println("AP1="+allowPaste1);
434: boolean allowPaste2 = clipboardElementsClass2 == null ? false
435: : (selectionElementsClass2 == null ? false
436: : clipboardElementsClass2 == selectionElementsClass2);
437: // System.err.println("AP2="+allowPaste2);
438: boolean allowPaste = (allowPaste1 || allowPaste2);
439:
440: if (allowPaste)
441: return true;
442: if (selectedElements.size() > 1)
443: return false;
444:
445: XMLElement firstSelected = (XMLElement) selectedElements.get(0);
446: if (firstSelected instanceof XMLAttribute
447: || firstSelected instanceof XMLSimpleElement
448: || firstSelected instanceof XMLComplexChoice) {
449: return false;
450: }
451: if (firstSelected instanceof XMLCollection) {
452: Class selectionElementClass = selectionElementsClass1;
453: if (selectionElementClass == null) {
454: selectionElementClass = selectionElementsClass2;
455: }
456: if (selectionElementClass == clipboardParentsClass1
457: || selectionElementClass == clipboardParentsClass2)
458: return true;
459:
460: return false;
461: }
462:
463: if (firstSelected instanceof XMLComplexElement) {
464: Class clipboardParentsClass = clipboardParentsClass1;
465: if (clipboardParentsClass == null) {
466: clipboardParentsClass = clipboardParentsClass2;
467: }
468: List subEls = ((XMLComplexElement) firstSelected)
469: .toElements();
470: for (int i = 0; i < subEls.size(); i++) {
471: if (subEls.get(i).getClass() == clipboardParentsClass) {
472: return true;
473: }
474: }
475: return false;
476: }
477:
478: return false;
479: }
480:
481: public boolean canDelete() {
482: if (selectedElements.size() == 0) {
483: return false;
484: }
485:
486: for (int i = 0; i < selectedElements.size(); i++) {
487: XMLElement selected = (XMLElement) selectedElements.get(i);
488: XMLElement parent = selected.getParent();
489: if (!(parent instanceof XMLCollection)) {
490: return false;
491: }
492: if (!jc.canRemoveElement((XMLCollection) parent, selected)) {
493: return false;
494: }
495: }
496: return true;
497: }
498:
499: public boolean canGetReferences() {
500: if (selectedElements.size() != 1) {
501: return false;
502: }
503: XMLElement selected = (XMLElement) selectedElements.get(0);
504:
505: if (selected instanceof TypeDeclaration
506: || selected instanceof Participant
507: || selected instanceof Application
508: || selected instanceof WorkflowProcess
509: || selected instanceof ActivitySet
510: || selected instanceof DataField
511: || (selected instanceof FormalParameter && selected
512: .getParent().getParent() instanceof WorkflowProcess)
513: || selected instanceof Activity
514: || selected instanceof Transition
515: || selected instanceof Package) {
516: return true;
517: }
518: return false;
519: }
520:
521: protected boolean checkCutOrCopySelection(boolean isCut) {
522: if (selectedElements.size() == 0) {
523: return false;
524: }
525:
526: for (int i = 0; i < selectedElements.size(); i++) {
527: XMLElement el = (XMLElement) selectedElements.get(i);
528: XMLElement parent = el.getParent();
529: if (el instanceof Transition) {
530: Activities acts = (Activities) ((XMLComplexElement) el
531: .getParent().getParent()).get("Activities");
532:
533: Activity from = acts.getActivity(((Transition) el)
534: .getFrom());
535: Activity to = acts.getActivity(((Transition) el)
536: .getTo());
537:
538: if (!(selectedElements.contains(from) && selectedElements
539: .contains(to))) {
540: return false;
541: }
542: } else if (!(parent instanceof XMLCollection)) {
543: return false;
544: }
545: XMLCollection col = (XMLCollection) parent;
546: if ((!(el instanceof Transition) && !jc
547: .canDuplicateElement(col, el, false))
548: || !jc.canInsertElement(col, el, false)
549: || !jc.canCreateElement(col, false)) {
550: return false;
551: }
552:
553: if (isCut && !jc.canRemoveElement(col, el)) {
554: return false;
555: }
556: }
557:
558: return true;
559: }
560:
561: protected void removeNonExistingElementsFromSelection(
562: List selection, List removedElements) {
563: Set removeFromSelection = new HashSet();
564: for (int i = 0; i < removedElements.size(); i++) {
565: XMLElement removedEl = (XMLElement) removedElements.get(i);
566: for (int j = 0; j < selection.size(); j++) {
567: XMLElement selEl = (XMLElement) selection.get(j);
568: if (XMLUtil.isParentsChild(removedEl, selEl)) {
569: removeFromSelection.add(selEl);
570: }
571: }
572: }
573: selection.removeAll(removeFromSelection);
574: }
575: }
|