Index: src/org/jbpm/gd/jpdl/xml/ForkDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/ForkDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/ForkDomAdapter.java (working copy) @@ -10,6 +10,7 @@ import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; import org.jbpm.gd.jpdl.model.Fork; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.Script; import org.jbpm.gd.jpdl.model.Timer; import org.jbpm.gd.jpdl.model.Transition; @@ -121,6 +122,7 @@ fork.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { fork.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("description".equals(getNodeType(type))) { fork.setDescription((Description)jpdlElement); } Index: src/org/jbpm/gd/jpdl/xml/TransitionDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/TransitionDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/TransitionDomAdapter.java (working copy) @@ -13,6 +13,7 @@ import org.jbpm.gd.jpdl.model.Description; import org.jbpm.gd.jpdl.model.ExceptionHandler; import org.jbpm.gd.jpdl.model.MailAction; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.Script; import org.jbpm.gd.jpdl.model.Transition; @@ -86,6 +87,8 @@ transition.setTo(newValue); } else if ("name".equals(name)) { transition.setName(newValue); + } else if ("condition".equals(name)) { + transition.setName(newValue); } } Index: src/org/jbpm/gd/jpdl/xml/NodeDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/NodeDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/NodeDomAdapter.java (working copy) @@ -14,6 +14,7 @@ import org.jbpm.gd.jpdl.model.ExceptionHandler; import org.jbpm.gd.jpdl.model.MailAction; import org.jbpm.gd.jpdl.model.Node; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.Script; import org.jbpm.gd.jpdl.model.Timer; import org.jbpm.gd.jpdl.model.Transition; @@ -149,6 +150,7 @@ node.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { node.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } } Index: src/org/jbpm/gd/jpdl/xml/SubProcessDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/SubProcessDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/SubProcessDomAdapter.java (working copy) @@ -4,7 +4,10 @@ import org.jbpm.gd.common.model.SemanticElement; import org.jbpm.gd.common.xml.XmlAdapter; +import org.jbpm.gd.jpdl.model.Fork; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.SubProcess; +import org.jbpm.gd.jpdl.model.Transition; public class SubProcessDomAdapter extends XmlAdapter { Index: src/org/jbpm/gd/jpdl/xml/ProcessStateDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/ProcessStateDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/ProcessStateDomAdapter.java (working copy) @@ -9,6 +9,7 @@ import org.jbpm.gd.jpdl.model.Description; import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.ProcessState; import org.jbpm.gd.jpdl.model.SubProcess; import org.jbpm.gd.jpdl.model.Timer; @@ -124,6 +125,7 @@ processState.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { processState.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("variable".equals(type)) { processState.addVariable((Variable)jpdlElement); } else if ("sub-process".equals(type)) { Index: src/org/jbpm/gd/jpdl/xml/TaskNodeDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/TaskNodeDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/TaskNodeDomAdapter.java (working copy) @@ -9,6 +9,7 @@ import org.jbpm.gd.jpdl.model.Description; import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.Task; import org.jbpm.gd.jpdl.model.TaskNode; import org.jbpm.gd.jpdl.model.Timer; @@ -137,6 +138,7 @@ taskNode.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { taskNode.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("task".equals(type)) { taskNode.addTask((Task)jpdlElement); } else if ("description".equals(getNodeType(type))) { Index: src/org/jbpm/gd/jpdl/xml/StateDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/StateDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/StateDomAdapter.java (working copy) @@ -9,6 +9,7 @@ import org.jbpm.gd.jpdl.model.Description; import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.State; import org.jbpm.gd.jpdl.model.Timer; import org.jbpm.gd.jpdl.model.Transition; @@ -112,6 +113,7 @@ state.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { state.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("description".equals(getNodeType(type))) { state.setDescription((Description)jpdlElement); } Index: src/org/jbpm/gd/jpdl/xml/SuperStateDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/SuperStateDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/SuperStateDomAdapter.java (working copy) @@ -15,6 +15,7 @@ import org.jbpm.gd.jpdl.model.Join; import org.jbpm.gd.jpdl.model.MailNode; import org.jbpm.gd.jpdl.model.Node; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.ProcessState; import org.jbpm.gd.jpdl.model.State; import org.jbpm.gd.jpdl.model.SuperState; @@ -136,6 +137,7 @@ superState.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { superState.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("node".equals(type)) { superState.addNodeElement((Node)jpdlElement); } else if ("state".equals(type)) { Index: src/org/jbpm/gd/jpdl/xml/JoinDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/JoinDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/JoinDomAdapter.java (working copy) @@ -10,6 +10,7 @@ import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; import org.jbpm.gd.jpdl.model.Join; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.Timer; import org.jbpm.gd.jpdl.model.Transition; @@ -111,6 +112,7 @@ join.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { join.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("description".equals(getNodeType(type))) { join.setDescription((Description)jpdlElement); } Index: src/org/jbpm/gd/jpdl/xml/MailNodeDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/MailNodeDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/MailNodeDomAdapter.java (working copy) @@ -10,6 +10,7 @@ import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; import org.jbpm.gd.jpdl.model.MailNode; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.Subject; import org.jbpm.gd.jpdl.model.Text; import org.jbpm.gd.jpdl.model.Timer; @@ -148,6 +149,7 @@ mailNode.addTimer((Timer)jpdlElement); } else if ("transition".equals(type)) { mailNode.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("description".equals(getNodeType(type))) { mailNode.setDescription((Description)jpdlElement); } Index: src/org/jbpm/gd/jpdl/xml/StartStateDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/StartStateDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/StartStateDomAdapter.java (working copy) @@ -9,6 +9,7 @@ import org.jbpm.gd.jpdl.model.Description; import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.StartState; import org.jbpm.gd.jpdl.model.Task; import org.jbpm.gd.jpdl.model.Transition; @@ -96,6 +97,7 @@ startState.setDescription((Description)jpdlElement); } else if ("transition".equals(type)) { startState.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } else if ("event".equals(type)) { startState.addEvent((Event)jpdlElement); } else if ("exception-handler".equals(type)) { Index: src/org/jbpm/gd/jpdl/xml/DecisionDomAdapter.java =================================================================== --- src/org/jbpm/gd/jpdl/xml/DecisionDomAdapter.java (revision 31246) +++ src/org/jbpm/gd/jpdl/xml/DecisionDomAdapter.java (working copy) @@ -11,6 +11,7 @@ import org.jbpm.gd.jpdl.model.Event; import org.jbpm.gd.jpdl.model.ExceptionHandler; import org.jbpm.gd.jpdl.model.Handler; +import org.jbpm.gd.jpdl.model.NodeElement; import org.jbpm.gd.jpdl.model.Transition; public class DecisionDomAdapter extends XmlAdapter { @@ -120,6 +121,7 @@ decision.addExceptionHandler((ExceptionHandler)jpdlElement); } else if ("transition".equals(type)) { decision.addTransition((Transition)jpdlElement); + ((Transition)jpdlElement).setSource((NodeElement)getSemanticElement()); } } Index: src/org/jbpm/gd/jpdl/model/AbstractNode.java =================================================================== --- src/org/jbpm/gd/jpdl/model/AbstractNode.java (revision 31246) +++ src/org/jbpm/gd/jpdl/model/AbstractNode.java (working copy) @@ -59,6 +59,7 @@ public void removeTransition(Transition transition) { if (!(transitions.contains(transition))) return; transitions.remove(transition); + transition.setSource(null); firePropertyChange("transitionRemove", transition, null); } Index: src/org/jbpm/gd/jpdl/properties/ConditionSection.java =================================================================== --- src/org/jbpm/gd/jpdl/properties/ConditionSection.java (revision 31246) +++ src/org/jbpm/gd/jpdl/properties/ConditionSection.java (working copy) @@ -1,5 +1,6 @@ package org.jbpm.gd.jpdl.properties; +import org.eclipse.draw2d.ColorConstants; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; @@ -20,6 +21,7 @@ import org.jbpm.gd.common.part.OutlineEditPart; import org.jbpm.gd.common.properties.AbstractPropertySection; import org.jbpm.gd.jpdl.model.Condition; +import org.jbpm.gd.jpdl.model.Decision; import org.jbpm.gd.jpdl.model.Transition; @@ -30,27 +32,60 @@ private Label label; private Text expressionText; private Text scriptText; + private Label warningLabel; private Transition transition; + + private static final String CONDITION_ON_TRANSITION_WARNING = "Invalid condition: transitions with conditions only valid if the source node is a Decision!"; public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) { super.createControls(parent, aTabbedPropertySheetPage); Composite clientArea = getWidgetFactory().createFlatFormComposite(parent); + + warningLabel = getWidgetFactory().createLabel(clientArea, ""); + warningLabel.setForeground(ColorConstants.red); conditionLabel = getWidgetFactory().createLabel(clientArea, "Condition Type"); conditionCombo = getWidgetFactory().createCCombo(clientArea); - conditionCombo.setItems(new String[] {"Unconditional", "Expression", "Script" }); + // updateConditionCombo(); -- refresh is always called, and the ConditionCombo is set there. + conditionCombo.setEditable(false); label = getWidgetFactory().createLabel(clientArea, ""); expressionText = getWidgetFactory().createText(clientArea, ""); scriptText = getWidgetFactory().createText(clientArea, "", SWT.H_SCROLL | SWT.V_SCROLL); + + warningLabel.setLayoutData(createWarningLabelLayoutData()); conditionLabel.setLayoutData(createConditionLabelLayoutData()); conditionCombo.setLayoutData(createConditionComboLayoutData()); label.setLayoutData(createLabelLayoutData()); expressionText.setLayoutData(createExpressionTextLayoutData()); scriptText.setLayoutData(createScriptTextLayoutData()); + hookListeners(); refresh(); } + + private void updateConditionCombo() { + // SOA-2010: transitions with conditions may only be used on Decisions + if( transition == null ) { + conditionCombo.setItems(new String[] {"Unconditional" }); + } + else if( transition.getSource() instanceof Decision ) { + conditionCombo.setItems(new String[] {"Unconditional", "Expression", "Script" }); + } + else if( transition.getCondition() != null ) { + // backwards compatibility, warning will be shown + if(transition.getCondition().getExpression() != null) { + conditionCombo.setItems(new String[] {"Unconditional", "Expression" }); + } + else if( transition.getCondition().getScript() != null) { + conditionCombo.setItems(new String[] {"Unconditional", "Script" }); + } + } + else { + // if (transition.getCondition() == null && ! (transition.getSource() instanceof Decision)) + conditionCombo.setItems(new String[] {"Unconditional"}); + } + } private void hookListeners() { conditionCombo.addSelectionListener(this); @@ -60,6 +95,14 @@ scriptText.addFocusListener(this); } + private FormData createWarningLabelLayoutData() { + FormData result = new FormData(); + result.left = new FormAttachment(0, 5); + result.right = new FormAttachment(100, -5); + result.top = new FormAttachment(conditionCombo, 10); + return result; + } + private FormData createConditionLabelLayoutData() { FormData result = new FormData(); result.left = new FormAttachment(0, 5); @@ -78,7 +121,7 @@ FormData result = new FormData(); result.left = new FormAttachment(0, 5); result.right = new FormAttachment(100, -5); - result.top = new FormAttachment(conditionCombo, 10); + result.top = new FormAttachment(warningLabel, 10); return result; } @@ -116,6 +159,8 @@ } public void refresh() { + updateConditionCombo(); + updateWarningLabel(); if (transition == null || transition.getCondition() == null){ conditionCombo.setText("Unconditional"); label.setText(""); @@ -180,6 +225,7 @@ private void handleConditionComboSelected() { if ("Expression".equals(conditionCombo.getText())) { + updateWarningLabel(); label.setText("Expression"); scriptText.setVisible(false); expressionText.setVisible(true); @@ -187,6 +233,7 @@ updateCondition(); } } else if ("Script".equals(conditionCombo.getText())) { + updateWarningLabel(); label.setText("Script"); expressionText.setVisible(false); scriptText.setVisible(true); @@ -194,6 +241,7 @@ updateCondition(); } } else { + warningLabel.setText(""); label.setText(""); expressionText.setVisible(false); scriptText.setVisible(false); @@ -228,5 +276,18 @@ handleScriptTextChanged(); } } + + private void updateWarningLabel() { + // SOA-2010 + if( transition == null || transition.getCondition() == null || transition.getSource() == null || transition.getSource() instanceof Decision ) { + warningLabel.setText(""); + } + else if( transition.getCondition() != null && ! (transition.getSource() instanceof Decision) ) { + warningLabel.setText( CONDITION_ON_TRANSITION_WARNING ); + } + else { + warningLabel.setText(""); + } + } } \ No newline at end of file