001: package com.opensymphony.workflow.designer;
002:
003: import java.util.List;
004:
005: import javax.swing.JOptionPane;
006:
007: import com.opensymphony.workflow.loader.AbstractDescriptor;
008: import com.opensymphony.workflow.loader.ActionDescriptor;
009: import com.opensymphony.workflow.loader.DescriptorBuilder;
010: import com.opensymphony.workflow.loader.JoinDescriptor;
011: import com.opensymphony.workflow.loader.ResultDescriptor;
012: import com.opensymphony.workflow.loader.SplitDescriptor;
013: import com.opensymphony.workflow.loader.StepDescriptor;
014: import com.opensymphony.workflow.loader.WorkflowDescriptor;
015: import com.opensymphony.workflow.designer.dialogs.ActionTypeDialog;
016:
017: /**
018: * @author baab
019: */
020: public class ConnectHelper {
021:
022: public static final int CONDITIONAL = 0;
023: public static final int UNCONDITIONAL = 1;
024: private static final int UNKNOWN = -1;
025:
026: private static boolean isConnectable(WorkflowCell source,
027: WorkflowCell target) {
028:
029: if (source == null || target == null) {
030: return false;
031: }
032:
033: if (source instanceof InitialActionCell
034: && target instanceof StepCell) {
035: return true;
036: } else if (source instanceof StepCell
037: && !(target instanceof InitialActionCell)) {
038: return true;
039: } else if (source instanceof JoinCell
040: && target instanceof StepCell) {
041: return true;
042: } else if (source instanceof SplitCell
043: && target instanceof StepCell) {
044: return true;
045: }
046:
047: return false;
048: }
049:
050: public static boolean connect(WorkflowCell source,
051: WorkflowCell target, WorkflowGraphModel model) {
052:
053: if (!isConnectable(source, target)) {
054: return false;
055: }
056:
057: if (source instanceof SplitCell && target instanceof StepCell) {
058: return connectSplitToStep((SplitCell) source,
059: (StepCell) target, model);
060: } else if (source instanceof InitialActionCell
061: && target instanceof StepCell) {
062: return connectStartToStep((InitialActionCell) source,
063: (StepCell) target, model);
064: } else if (source instanceof JoinCell
065: && target instanceof StepCell) {
066: return connectJoinToStep((JoinCell) source,
067: (StepCell) target, model);
068: } else if (source instanceof StepCell
069: && !(target instanceof InitialActionCell)) {
070: return connectStepTo((StepCell) source, target, model);
071: }
072: return true;
073: }
074:
075: private static boolean isConnected(List results,
076: AbstractDescriptor desc) {
077: if (results == null || results.size() == 0) {
078: return false;
079: }
080:
081: if (desc instanceof StepDescriptor) {
082: return _isConnected(results, (StepDescriptor) desc);
083: } else if (desc instanceof SplitDescriptor) {
084: return _isConnected(results, (SplitDescriptor) desc);
085: } else if (desc instanceof JoinDescriptor) {
086: return _isConnected(results, (JoinDescriptor) desc);
087: }
088: return false;
089: }
090:
091: private static boolean _isConnected(List results,
092: StepDescriptor step) {
093: if (results == null) {
094: return false;
095: }
096: for (int i = 0; i < results.size(); i++) {
097: ResultDescriptor result = (ResultDescriptor) results.get(i);
098: if (result.getStep() == step.getId()) {
099: // already connected
100: return true;
101: }
102: }
103: return false;
104: }
105:
106: private static boolean _isConnected(List results,
107: JoinDescriptor join) {
108: if (results == null) {
109: return false;
110: }
111: for (int i = 0; i < results.size(); i++) {
112: ResultDescriptor result = (ResultDescriptor) results.get(i);
113: if (result.getJoin() == join.getId()) {
114: // already connected
115: return true;
116: }
117: }
118: return false;
119: }
120:
121: private static boolean _isConnected(List results,
122: SplitDescriptor split) {
123: if (results == null) {
124: return false;
125: }
126: for (int i = 0; i < results.size(); i++) {
127: ResultDescriptor result = (ResultDescriptor) results.get(i);
128: if (result.getSplit() == split.getId()) {
129: // already connected
130: return true;
131: }
132: }
133: return false;
134: }
135:
136: public static boolean isConnected(ResultDescriptor result,
137: AbstractDescriptor desc) {
138: if (result == null) {
139: return false;
140: }
141: if (desc instanceof StepDescriptor) {
142: return _isConnected(result, (StepDescriptor) desc);
143: } else if (desc instanceof JoinDescriptor) {
144: return _isConnected(result, (JoinDescriptor) desc);
145: } else if (desc instanceof SplitDescriptor) {
146: return _isConnected(result, (SplitDescriptor) desc);
147: }
148:
149: return false;
150: }
151:
152: private static boolean _isConnected(ResultDescriptor result,
153: StepDescriptor step) {
154: return result.getStep() == step.getId();
155: }
156:
157: private static boolean _isConnected(ResultDescriptor result,
158: JoinDescriptor join) {
159: return result.getJoin() == join.getId();
160: }
161:
162: private static boolean _isConnected(ResultDescriptor result,
163: SplitDescriptor split) {
164: return result.getSplit() == split.getId();
165: }
166:
167: private static int getConnectType(ActionDescriptor from,
168: AbstractDescriptor to) {
169: List results = from.getConditionalResults();
170: if (isConnected(results, to)) {
171: return UNKNOWN;
172: }
173:
174: ResultDescriptor result = from.getUnconditionalResult();
175: if (isConnected(result, to)) {
176: return UNKNOWN;
177: }
178:
179: int type;
180: if (result != null) {
181: type = CONDITIONAL;
182: } else {
183: // choose unconditional or conditional
184: String conditional = ResourceManager
185: .getString("result.conditional");
186: String unconditional = ResourceManager
187: .getString("result.unconditional");
188: String cancel = ResourceManager.getString("cancel");
189: type = JOptionPane.showOptionDialog(null, ResourceManager
190: .getString("result.select.long"), ResourceManager
191: .getString("result.select"),
192: JOptionPane.DEFAULT_OPTION,
193: JOptionPane.PLAIN_MESSAGE, null, new Object[] {
194: conditional, unconditional, cancel },
195: conditional);
196: if (type != 0 && type != 1) {
197: // cancel
198: return UNKNOWN;
199: }
200: }
201: return type;
202: }
203:
204: private static boolean connectStepTo(StepCell source,
205: WorkflowCell target, WorkflowGraphModel model) {
206: AbstractDescriptor to;
207: if (target instanceof StepCell) {
208: to = ((StepCell) target).getDescriptor();
209: } else if (target instanceof SplitCell) {
210: to = ((SplitCell) target).getSplitDescriptor();
211: } else if (target instanceof JoinCell) {
212: to = ((JoinCell) target).getJoinDescriptor();
213: } else {
214: return false;
215: }
216:
217: ResultDescriptor result;
218:
219: ActionTypeDialog selectType = new ActionTypeDialog(
220: WorkflowDesigner.INSTANCE, source.getDescriptor());
221: selectType.setModel(model);
222: if (!selectType.ask(WorkflowDesigner.INSTANCE))
223: return false;
224:
225: ActionDescriptor sourceAction = selectType.getRelatedAction();
226:
227: int type = selectType.getType();
228:
229: if (type == CONDITIONAL) {
230: result = DescriptorBuilder.createConditionalResult(model,
231: to);
232: } else if (type == UNCONDITIONAL) {
233: result = DescriptorBuilder.createResult(model, to);
234: } else {
235: return false;
236: }
237:
238: result.setParent(sourceAction);
239: if (type == CONDITIONAL) {
240: sourceAction.getConditionalResults().add(result);
241: } else {
242: sourceAction.setUnconditionalResult(result);
243: }
244:
245: model.recordResult(source, result, sourceAction);
246: model.connectCells(source, sourceAction, target, result);
247:
248: // update the workspace navigator
249: WorkflowDescriptor workflow = WorkflowDesigner.INSTANCE
250: .getCurrentGraph().getDescriptor();
251: WorkflowDesigner.INSTANCE.navigator().reloadStep(workflow,
252: source.getDescriptor());
253: WorkflowDesigner.INSTANCE.navigator().selectTreeNode(workflow,
254: result);
255:
256: return true;
257: }
258:
259: private static boolean connectStartToStep(InitialActionCell source,
260: StepCell target, WorkflowGraphModel model) {
261: ActionDescriptor start = source.getActionDescriptor();
262: StepDescriptor step = target.getDescriptor();
263: ResultDescriptor result;
264:
265: int type = getConnectType(start, step);
266:
267: if (type == CONDITIONAL) {
268: result = DescriptorBuilder.createConditionalResult(model,
269: step);
270: } else if (type == UNCONDITIONAL) {
271: result = DescriptorBuilder.createResult(model, step);
272: } else {
273: return false;
274: }
275:
276: result.setParent(start);
277: if (type == CONDITIONAL) {
278: start.getConditionalResults().add(result);
279: } else {
280: start.setUnconditionalResult(result);
281: }
282:
283: // create new resultCell
284: model.recordResult(source, result, start);
285: model.connectCells(source, start, target, result);
286:
287: // update the workspace navigator
288: WorkflowDescriptor workflow = WorkflowDesigner.INSTANCE
289: .getCurrentGraph().getDescriptor();
290: WorkflowDesigner.INSTANCE.navigator().reloadInitialAction(
291: workflow);
292: WorkflowDesigner.INSTANCE.navigator().selectTreeNode(workflow,
293: result);
294:
295: return true;
296: }
297:
298: private static boolean connectSplitToStep(SplitCell source,
299: StepCell target, WorkflowGraphModel model) {
300: SplitDescriptor split = source.getSplitDescriptor();
301: StepDescriptor step = target.getDescriptor();
302:
303: List results = split.getResults();
304:
305: if (isConnected(results, step)) {
306: return false;
307: }
308:
309: // create new unconditional result
310: ResultDescriptor result = DescriptorBuilder.createResult(model,
311: step);
312: result.setParent(split);
313:
314: // add to split's result list
315: results.add(result);
316:
317: model.recordResult(source, result, null);
318:
319: // update the graph
320: model.connectCells(source, null, target, result);
321:
322: // update the workspace navigator
323: WorkflowDescriptor workflow = WorkflowDesigner.INSTANCE
324: .getCurrentGraph().getDescriptor();
325: WorkflowDesigner.INSTANCE.navigator().reloadSplit(workflow,
326: source.getSplitDescriptor());
327: WorkflowDesigner.INSTANCE.navigator().selectTreeNode(workflow,
328: result);
329:
330: return true;
331: }
332:
333: private static boolean connectJoinToStep(JoinCell source,
334: StepCell target, WorkflowGraphModel model) {
335: JoinDescriptor join = source.getJoinDescriptor();
336: StepDescriptor step = target.getDescriptor();
337:
338: ResultDescriptor result = join.getResult();
339: if (result != null) {
340: return false;
341: }
342:
343: // create new unconditional result
344: result = DescriptorBuilder.createResult(model, step);
345: result.setParent(join);
346: join.setResult(result);
347:
348: model.recordResult(source, result, null);
349:
350: // update the graph
351: model.connectCells(source, null, target, result);
352:
353: // update the workspace navigator
354: WorkflowDescriptor workflow = WorkflowDesigner.INSTANCE
355: .getCurrentGraph().getDescriptor();
356: WorkflowDesigner.INSTANCE.navigator().reloadJoin(workflow,
357: source.getJoinDescriptor());
358: WorkflowDesigner.INSTANCE.navigator().selectTreeNode(workflow,
359: result);
360:
361: return true;
362: }
363:
364: }
|