https://bugs.eclipse.org/bugs/show_bug.cgi?id=488889
MultInstanceLoopCharacteristics input and output data objects are not
handled properly for Tasks
diff --git a/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java b/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java
index 83de9e4..2e87372 100644
--- a/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java
+++ b/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java
@@ -12,6 +12,7 @@
import org.eclipse.bpmn2.DataInput;
import org.eclipse.bpmn2.DataObject;
+import org.eclipse.bpmn2.DataOutput;
import org.eclipse.bpmn2.Error;
import org.eclipse.bpmn2.Escalation;
import org.eclipse.bpmn2.Message;
@@ -68,12 +69,12 @@
object instanceof Error ||
object instanceof Escalation ||
object instanceof GlobalType ||
- (
- // DataInput objects are a special case: Only keep the name and
- // ID in sync if the DataInput is being used as the instance
- // parameter for MultiInstanceLoopCharacteristics (or if the
- // DataInput hasn't been added to a container yet).
- object instanceof DataInput && (
+ (
+ // DataInput and DataOutput objects are a special case: Only
+ // keep the name and ID in sync if the DataInput is being used
+ // as the instance parameter for MultiInstanceLoopCharacteristics
+ // (or if the object hasn't been added to a container yet).
+ (object instanceof DataInput || object instanceof DataOutput) && (
object.eContainer() instanceof MultiInstanceLoopCharacteristics ||
object.eContainer()==null)
)
diff --git a/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/adapters/JbpmMultiInstanceLoopCharacteristicsPropertiesAdapter.java b/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/adapters/JbpmMultiInstanceLoopCharacteristicsPropertiesAdapter.java
index 16f722d..03eeded 100644
--- a/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/adapters/JbpmMultiInstanceLoopCharacteristicsPropertiesAdapter.java
+++ b/plugins/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/adapters/JbpmMultiInstanceLoopCharacteristicsPropertiesAdapter.java
@@ -10,266 +10,69 @@
******************************************************************************/
package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.property.adapters;
+import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.List;
-import org.eclipse.bpmn2.Bpmn2Package;
-import org.eclipse.bpmn2.DataInput;
-import org.eclipse.bpmn2.DataInputAssociation;
-import org.eclipse.bpmn2.DataOutput;
-import org.eclipse.bpmn2.DataOutputAssociation;
-import org.eclipse.bpmn2.InputOutputSpecification;
-import org.eclipse.bpmn2.InputSet;
-import org.eclipse.bpmn2.ItemAwareElement;
import org.eclipse.bpmn2.MultiInstanceLoopCharacteristics;
-import org.eclipse.bpmn2.OutputSet;
import org.eclipse.bpmn2.Process;
-import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.JavaVariableNameObjectEditor;
-import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory;
-import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.core.model.ModelDecorator;
+import org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.model.drools.GlobalType;
import org.eclipse.bpmn2.modeler.ui.adapters.properties.MultiInstanceLoopCharacteristicsPropertiesAdapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.resource.Resource;
public class JbpmMultiInstanceLoopCharacteristicsPropertiesAdapter extends MultiInstanceLoopCharacteristicsPropertiesAdapter {
public JbpmMultiInstanceLoopCharacteristicsPropertiesAdapter(AdapterFactory adapterFactory, MultiInstanceLoopCharacteristics object) {
super(adapterFactory, object);
- EStructuralFeature feature = Bpmn2Package.eINSTANCE.getMultiInstanceLoopCharacteristics_InputDataItem();
- setProperty(feature, UI_OBJECT_EDITOR_CLASS, JavaVariableNameObjectEditor.class);
-
- feature = Bpmn2Package.eINSTANCE.getMultiInstanceLoopCharacteristics_OutputDataItem();
- setProperty(feature, UI_OBJECT_EDITOR_CLASS, JavaVariableNameObjectEditor.class);
+ setProperty(INPUT_DATA_ITEM, UI_OBJECT_EDITOR_CLASS, JavaVariableNameObjectEditor.class);
+ setProperty(OUTPUT_DATA_ITEM, UI_OBJECT_EDITOR_CLASS, JavaVariableNameObjectEditor.class);
- setFeatureDescriptor(LOOP_DATA_INPUT_REF, new LoopCharacteristicsDataIoFeatureDescriptor(this, object, LOOP_DATA_INPUT_REF) {
+ setFeatureDescriptor(LOOP_DATA_INPUT_REF, new LoopDataInputCollectionFeatureDescriptor(this, object) {
@Override
public Hashtable<String, Object> getChoiceOfValues() {
- Hashtable<String, Object> choices = new Hashtable<String, Object>();
- EObject container = ModelUtil.getContainer(object);
- if (container instanceof SubProcess) {
- // get the Property instances (a.k.a. "local variables") of the containing Process or SubProcess
- for (EObject p : ModelUtil.collectAncestorObjects(object, "properties", new Class[] {Process.class, SubProcess.class})) {
- choices.put( getChoiceString(p), p);
- }
+ Hashtable<String, Object> choices = super.getChoiceOfValues();
+ for (GlobalType g : getAllGlobals(object)) {
+ ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(g);
+ choices.put(adapter.getObjectDescriptor().getTextValue(), g);
}
return choices;
}
-
- @Override
- protected void internalSet(MultiInstanceLoopCharacteristics object, EStructuralFeature feature, Object value, int index) {
- if (object.eContainer() instanceof SubProcess) {
- SubProcess subprocess = (SubProcess) object.eContainer();
- InputOutputSpecification ioSpec = subprocess.getIoSpecification();
- Resource resource = getResource();
- if (value instanceof ItemAwareElement) {
- ItemAwareElement element = (ItemAwareElement) value;
- DataInput input = null;
- InputSet inputSet = null;
- DataInputAssociation inputAssociation = null;
- if (ioSpec==null) {
- ioSpec = Bpmn2ModelerFactory.create(resource, InputOutputSpecification.class);
- subprocess.setIoSpecification(ioSpec);
- }
- else {
- for (DataInput din : ioSpec.getDataInputs()) {
- if (din == object.getLoopDataInputRef()) {
- input = din;
- break;
- }
- }
- }
- if (input == null)
- input = Bpmn2ModelerFactory.create(resource, DataInput.class);
- input.setName(element.getId());
- input.setItemSubjectRef(element.getItemSubjectRef());
- input.setIsCollection(true);
- if (!ioSpec.getDataInputs().contains(input))
- ioSpec.getDataInputs().add(input);
-
- for (InputSet is : ioSpec.getInputSets()) {
- if (is.getDataInputRefs().contains(input)) {
- inputSet = is;
- break;
- }
- }
- if (inputSet == null) {
- if (ioSpec.getInputSets().size()==0) {
- inputSet = Bpmn2ModelerFactory.create(resource, InputSet.class);
- ioSpec.getInputSets().add(inputSet);
- }
- else
- inputSet = ioSpec.getInputSets().get(0);
- }
- if (!inputSet.getDataInputRefs().contains(input))
- inputSet.getDataInputRefs().add(input);
-
- for (DataInputAssociation dia : subprocess.getDataInputAssociations()) {
- if (dia.getTargetRef()==input) {
- inputAssociation = dia;
- break;
- }
- }
- if (inputAssociation == null) {
- inputAssociation = Bpmn2ModelerFactory.create(resource, DataInputAssociation.class);
- subprocess.getDataInputAssociations().add(inputAssociation);
- }
-
- inputAssociation.setTargetRef(input);
- inputAssociation.getSourceRef().clear();
- inputAssociation.getSourceRef().add(element);
-
- value = input;
- }
- else if (value==null) {
- ItemAwareElement input = object.getLoopDataInputRef();
- if (ioSpec!=null) {
- if (input!=null) {
- for (DataInput din : ioSpec.getDataInputs()) {
- if (din == input) {
- ioSpec.getDataInputs().remove(din);
- if (ioSpec.getInputSets().size()>0) {
- ioSpec.getInputSets().get(0).getDataInputRefs().remove(din);
- if (ioSpec.getInputSets().get(0).getDataInputRefs().size()==0)
- ioSpec.getInputSets().remove(0);
- }
- break;
- }
- }
- int i = 0;
- for (DataInputAssociation dia : subprocess.getDataInputAssociations()) {
- if (dia.getTargetRef() == input) {
- subprocess.getDataInputAssociations().remove(i);
- break;
- }
- ++i;
- }
- }
- if (ioSpec.getDataInputs().size()==0 && ioSpec.getDataOutputs().size()==0) {
- subprocess.setIoSpecification(null);
- }
- }
- }
- }
- super.internalSet(object, feature, value, index);
- }
});
- setFeatureDescriptor(LOOP_DATA_OUTPUT_REF, new LoopCharacteristicsDataIoFeatureDescriptor(this, object, LOOP_DATA_OUTPUT_REF) {
+ setFeatureDescriptor(LOOP_DATA_OUTPUT_REF, new LoopDataOutputCollectionFeatureDescriptor(this, object) {
@Override
public Hashtable<String, Object> getChoiceOfValues() {
- Hashtable<String, Object> choices = new Hashtable<String, Object>();
- EObject container = ModelUtil.getContainer(object);
- if (container instanceof SubProcess) {
- // get the Property instances (a.k.a. "local variables") of the containing Process or SubProcess
- for (EObject p : ModelUtil.collectAncestorObjects(object, "properties", new Class[] {Process.class, SubProcess.class})) {
- choices.put( getChoiceString(p), p);
- }
+ Hashtable<String, Object> choices = super.getChoiceOfValues();
+ for (GlobalType g : getAllGlobals(object)) {
+ ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(g);
+ choices.put(adapter.getObjectDescriptor().getTextValue(), g);
}
return choices;
}
-
- @Override
- protected void internalSet(MultiInstanceLoopCharacteristics object, EStructuralFeature feature, Object value, int index) {
- if (object.eContainer() instanceof SubProcess) {
- SubProcess subprocess = (SubProcess) object.eContainer();
- InputOutputSpecification ioSpec = subprocess.getIoSpecification();
- Resource resource = getResource();
- if (value instanceof ItemAwareElement) {
- ItemAwareElement element = (ItemAwareElement) value;
- DataOutput output = null;
- OutputSet outputSet = null;
- DataOutputAssociation outputAssociation = null;
- if (ioSpec==null) {
- ioSpec = Bpmn2ModelerFactory.create(resource, InputOutputSpecification.class);
- subprocess.setIoSpecification(ioSpec);
- }
- else {
- for (DataOutput dout : ioSpec.getDataOutputs()) {
- if (dout == object.getLoopDataOutputRef()) {
- output = dout;
- break;
- }
- }
- }
- if (output == null)
- output = Bpmn2ModelerFactory.create(resource, DataOutput.class);
- output.setName(element.getId());
- output.setItemSubjectRef(element.getItemSubjectRef());
- output.setIsCollection(true);
- if (!ioSpec.getDataOutputs().contains(output))
- ioSpec.getDataOutputs().add(output);
-
- for (OutputSet os : ioSpec.getOutputSets()) {
- if (os.getDataOutputRefs().contains(output)) {
- outputSet = os;
- break;
- }
- }
- if (outputSet == null) {
- if (ioSpec.getOutputSets().size()==0) {
- outputSet = Bpmn2ModelerFactory.create(resource, OutputSet.class);
- ioSpec.getOutputSets().add(outputSet);
- }
- else
- outputSet = ioSpec.getOutputSets().get(0);
- }
- if (!outputSet.getDataOutputRefs().contains(output))
- outputSet.getDataOutputRefs().add(output);
-
- for (DataOutputAssociation doa : subprocess.getDataOutputAssociations()) {
- if (doa.getSourceRef().size()==1 && doa.getSourceRef().get(0)==output) {
- outputAssociation = doa;
- break;
- }
- }
- if (outputAssociation == null) {
- outputAssociation = Bpmn2ModelerFactory.create(resource, DataOutputAssociation.class);
- subprocess.getDataOutputAssociations().add(outputAssociation);
- }
-
- outputAssociation.getSourceRef().clear();
- outputAssociation.getSourceRef().add(output);
- outputAssociation.setTargetRef(element);
-
- value = output;
- }
- else if (value==null) {
- ItemAwareElement output = object.getLoopDataOutputRef();
- if (ioSpec!=null) {
- if (output!=null) {
- for (DataOutput dout : ioSpec.getDataOutputs()) {
- if (dout == output) {
- ioSpec.getDataOutputs().remove(dout);
- if (ioSpec.getOutputSets().size()>0) {
- ioSpec.getOutputSets().get(0).getDataOutputRefs().remove(dout);
- if (ioSpec.getOutputSets().get(0).getDataOutputRefs().size()==0)
- ioSpec.getOutputSets().remove(0);
- }
- break;
- }
- }
- int i = 0;
- for (DataOutputAssociation doa : subprocess.getDataOutputAssociations()) {
- if (doa.getSourceRef().size()>0 && doa.getSourceRef().get(0) == output) {
- subprocess.getDataOutputAssociations().remove(i);
- break;
- }
- ++i;
- }
- }
- if (ioSpec.getDataInputs().size()==0 && ioSpec.getDataOutputs().size()==0) {
- subprocess.setIoSpecification(null);
- }
- }
-
- }
- }
- super.internalSet(object, feature, value, index);
- }
});
}
-
+
+ private List<GlobalType> getAllGlobals(EObject object) {
+ List<GlobalType> results = new ArrayList<GlobalType>();
+ // navigate up to the Process from the given EObject
+ Process process = null;
+ while (object!=null) {
+ if (object instanceof Process) {
+ process = (Process) object;
+ break;
+ }
+ object = object.eContainer();
+ }
+ if (process!=null) {
+ for (Object g : ModelDecorator.getAllExtensionAttributeValues(process, GlobalType.class)) {
+ results.add((GlobalType)g);
+ }
+ }
+ return results;
+ }
}
diff --git a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataInputPropertiesAdapter.java b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataInputPropertiesAdapter.java
index 4b4aad2..c676712 100644
--- a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataInputPropertiesAdapter.java
+++ b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataInputPropertiesAdapter.java
@@ -58,11 +58,12 @@
text = dataInput.getId();
if (text!=null) {
- if (dataInput.isIsCollection())
- text += "[]"; //$NON-NLS-1$
- String type = ExtendedPropertiesProvider.getTextValue(dataInput.getItemSubjectRef());
- if (type!=null)
- text += " (" + type + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ // TODO: add CONTEXT_TEXT to Data Association inputs and outputs
+// if (dataInput.isIsCollection())
+// text += "[]"; //$NON-NLS-1$
+// String type = ExtendedPropertiesProvider.getTextValue(dataInput.getItemSubjectRef());
+// if (type!=null && !type.isEmpty())
+// text += " (" + type + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
return text;
}
diff --git a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataOutputPropertiesAdapter.java b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataOutputPropertiesAdapter.java
index 0a2eef3..a998c8f 100644
--- a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataOutputPropertiesAdapter.java
+++ b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/DataOutputPropertiesAdapter.java
@@ -58,11 +58,12 @@
text = dataOutput.getId();
if (text!=null) {
- if (dataOutput.isIsCollection())
- text += "[]"; //$NON-NLS-1$
- String type = ExtendedPropertiesProvider.getTextValue(dataOutput.getItemSubjectRef());
- if (type!=null)
- text += " (" + type + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ // TODO: add CONTEXT_TEXT to Data Association inputs and outputs
+// if (dataOutput.isIsCollection())
+// text += "[]"; //$NON-NLS-1$
+// String type = ExtendedPropertiesProvider.getTextValue(dataOutput.getItemSubjectRef());
+// if (type!=null && !type.isEmpty())
+// text += " (" + type + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
return text;
}
diff --git a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/ItemDefinitionPropertiesAdapter.java b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/ItemDefinitionPropertiesAdapter.java
index befdc17..29c24c1 100644
--- a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/ItemDefinitionPropertiesAdapter.java
+++ b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/ItemDefinitionPropertiesAdapter.java
@@ -185,8 +185,9 @@
String name = ""; //$NON-NLS-1$
if (itemDefinition!=null) {
name = getStructureName(itemDefinition);
- if (itemDefinition.isIsCollection())
- name += "[]"; //$NON-NLS-1$
+ // TODO: add CONTEXT_TEXT to Data Association inputs and outputs
+// if (itemDefinition.isIsCollection())
+// name += "[]"; //$NON-NLS-1$
}
return name;
}
diff --git a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/MultiInstanceLoopCharacteristicsPropertiesAdapter.java b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/MultiInstanceLoopCharacteristicsPropertiesAdapter.java
index 7167888..6e702a4 100644
--- a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/MultiInstanceLoopCharacteristicsPropertiesAdapter.java
+++ b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/adapters/properties/MultiInstanceLoopCharacteristicsPropertiesAdapter.java
@@ -20,17 +20,25 @@
import org.eclipse.bpmn2.Activity;
import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.DataInput;
+import org.eclipse.bpmn2.DataInputAssociation;
import org.eclipse.bpmn2.DataObject;
import org.eclipse.bpmn2.DataObjectReference;
import org.eclipse.bpmn2.DataOutput;
+import org.eclipse.bpmn2.DataOutputAssociation;
import org.eclipse.bpmn2.InputOutputSpecification;
+import org.eclipse.bpmn2.InputSet;
+import org.eclipse.bpmn2.ItemAwareElement;
import org.eclipse.bpmn2.MultiInstanceLoopCharacteristics;
+import org.eclipse.bpmn2.OutputSet;
import org.eclipse.bpmn2.Process;
import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.Task;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter;
import org.eclipse.bpmn2.modeler.core.adapters.FeatureDescriptor;
import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.ui.adapters.properties.MultiInstanceLoopCharacteristicsPropertiesAdapter.LoopDataCollectionFeatureDescriptor;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
@@ -55,25 +63,24 @@
public MultiInstanceLoopCharacteristicsPropertiesAdapter(AdapterFactory adapterFactory, MultiInstanceLoopCharacteristics object) {
super(adapterFactory, object);
- setFeatureDescriptor(LOOP_DATA_INPUT_REF, new LoopCharacteristicsDataIoFeatureDescriptor(this, object, LOOP_DATA_INPUT_REF));
setProperty(LOOP_DATA_INPUT_REF, UI_IS_MULTI_CHOICE, Boolean.TRUE);
setProperty(LOOP_DATA_INPUT_REF, UI_CAN_EDIT, Boolean.TRUE);
setProperty(LOOP_DATA_INPUT_REF, UI_CAN_CREATE_NEW, Boolean.TRUE);
-
-// setFeatureDescriptor(INPUT_DATA_ITEM, new LoopCharacteristicsDataIoFeatureDescriptor(adapterFactory,object, INPUT_DATA_ITEM));
-// setProperty(INPUT_DATA_ITEM, UI_IS_MULTI_CHOICE, Boolean.TRUE);
- setFeatureDescriptor(LOOP_DATA_OUTPUT_REF, new LoopCharacteristicsDataIoFeatureDescriptor(this, object, LOOP_DATA_OUTPUT_REF));
setProperty(LOOP_DATA_OUTPUT_REF, UI_IS_MULTI_CHOICE, Boolean.TRUE);
setProperty(LOOP_DATA_OUTPUT_REF, UI_CAN_EDIT, Boolean.TRUE);
setProperty(LOOP_DATA_OUTPUT_REF, UI_CAN_CREATE_NEW, Boolean.TRUE);
-// setFeatureDescriptor(OUTPUT_DATA_ITEM, new LoopCharacteristicsDataIoFeatureDescriptor(adapterFactory,object, OUTPUT_DATA_ITEM));
-// setProperty(OUTPUT_DATA_ITEM, UI_IS_MULTI_CHOICE, Boolean.TRUE);
+ setFeatureDescriptor(LOOP_DATA_INPUT_REF, new LoopDataInputCollectionFeatureDescriptor(this, object));
+ setFeatureDescriptor(INPUT_DATA_ITEM, new LoopInputDataItemFeatureDescriptor(this, object));
+
+ setFeatureDescriptor(LOOP_DATA_OUTPUT_REF, new LoopDataOutputCollectionFeatureDescriptor(this, object));
+ setFeatureDescriptor(OUTPUT_DATA_ITEM, new LoopOutputDataItemFeatureDescriptor(this, object));
}
/**
- * This class calculates the Loop Input/Output collections and Input/Output parameters that are in scope for the
+ * This is a base class for LoopDataInputCollectionFeatureDescriptor and LoopDataOutputCollectionFeatureDescriptor.
+ * It calculates the Loop Input/Output collections and Input/Output parameters that are in scope for the
* Activity that owns this Multi-Instance Loop Characteristics object. From the BPMN2 spec:
*
* Loop Data Input/Output (the collection):
@@ -86,12 +93,13 @@
* Activitys InputOutputSpecification.
* The type of this Data Input/Output MUST be the scalar of the type defined for the loopDataInput/Output.
*/
- protected class LoopCharacteristicsDataIoFeatureDescriptor extends FeatureDescriptor<MultiInstanceLoopCharacteristics> {
+ protected class LoopDataCollectionFeatureDescriptor extends FeatureDescriptor<MultiInstanceLoopCharacteristics> {
- public LoopCharacteristicsDataIoFeatureDescriptor(
+ public LoopDataCollectionFeatureDescriptor(
ExtendedPropertiesAdapter<MultiInstanceLoopCharacteristics> owner,
MultiInstanceLoopCharacteristics object, EStructuralFeature feature) {
super(owner, object, feature);
+ Assert.isTrue(feature==LOOP_DATA_INPUT_REF || feature==LOOP_DATA_OUTPUT_REF);
}
@Override
@@ -99,19 +107,17 @@
EObject value = super.createFeature(resource, eclass);
// if the new object is the collection reference, we need to attach it to the
// activity's InputOutputSpecification.
- if (feature==LOOP_DATA_INPUT_REF || feature==LOOP_DATA_OUTPUT_REF) {
- Activity container = (Activity)ModelUtil.getContainer(object);
- EStructuralFeature f = container.eClass().getEStructuralFeature("ioSpecification"); //$NON-NLS-1$
- if (f!=null) {
- InputOutputSpecification ioSpecification = (InputOutputSpecification)container.eGet(f);
- if (ioSpecification==null) {
- ioSpecification = Bpmn2ModelerFactory.createFeature(object.eResource(), container, f, InputOutputSpecification.class);
- }
- if (value instanceof DataInput)
- ioSpecification.getDataInputs().add((DataInput)value);
- else
- ioSpecification.getDataOutputs().add((DataOutput)value);
+ Activity container = (Activity)ModelUtil.getContainer(object);
+ EStructuralFeature f = container.eClass().getEStructuralFeature("ioSpecification"); //$NON-NLS-1$
+ if (f!=null) {
+ InputOutputSpecification ioSpecification = (InputOutputSpecification)container.eGet(f);
+ if (ioSpecification==null) {
+ ioSpecification = Bpmn2ModelerFactory.createFeature(object.eResource(), container, f, InputOutputSpecification.class);
}
+ if (value instanceof DataInput)
+ ioSpecification.getDataInputs().add((DataInput)value);
+ else
+ ioSpecification.getDataOutputs().add((DataOutput)value);
}
return value;
}
@@ -122,57 +128,44 @@
Activity container = (Activity)ModelUtil.getContainer(object);
List values = new ArrayList<EObject>();
- if (feature == LOOP_DATA_INPUT_REF || feature == LOOP_DATA_OUTPUT_REF) {
-// if (container instanceof Task)
- {
- EStructuralFeature f = container.eClass().getEStructuralFeature("ioSpecification"); //$NON-NLS-1$
- if (f!=null) {
- InputOutputSpecification ioSpecification = (InputOutputSpecification)container.eGet(f);
- if (ioSpecification!=null) {
- if (feature == LOOP_DATA_INPUT_REF)
- values.addAll(ioSpecification.getDataInputs());
- else
- values.addAll(ioSpecification.getDataOutputs());
- }
- }
- }
-// else
- if (container instanceof SubProcess) {
- // Collect all DataObjects from Process and SubProcess ancestors
- // DataObjects are FlowElements, so we will have to weed those out from other FlowElements.
- List<EObject> flowElements = ModelUtil.collectAncestorObjects(object, "flowElements", new Class[] {Process.class, SubProcess.class}); //$NON-NLS-1$
- for (EObject fe : flowElements) {
- if (fe instanceof DataObjectReference) {
- fe = ((DataObjectReference)fe).getDataObjectRef();
- }
- if (!(fe instanceof DataObject)) {
- fe = null;
- }
- if (fe!=null && !values.contains(fe))
- values.add(fe);
- }
- // Collect all Properties from Process and SubProcess ancestors
- EObject parent = container.eContainer();
- while (parent!=null) {
- if (parent instanceof Process) {
- values.addAll(((Process)parent).getProperties());
- }
- if (parent instanceof SubProcess) {
- values.addAll(((SubProcess)parent).getProperties());
- }
- parent = parent.eContainer();
- }
+
+ EStructuralFeature f = container.eClass().getEStructuralFeature("ioSpecification"); //$NON-NLS-1$
+ if (f!=null) {
+ InputOutputSpecification ioSpecification = (InputOutputSpecification)container.eGet(f);
+ if (ioSpecification!=null) {
+ if (feature == LOOP_DATA_INPUT_REF)
+ values.addAll(ioSpecification.getDataInputs());
+ else
+ values.addAll(ioSpecification.getDataOutputs());
}
}
- else {
- // INPUT_DATA_ITEM or OUTPUT_DATA_ITEM feature
- // TODO: This part of the spec is unclear to me. It looks like the Data Input/Output Items need to
- // be contained in the MI Loop Characteristics. Something like this:
- //
- // <multiInstanceLoopCharacteristics id="MI_6">
- // <loopDataInputRef>DataObject_3</bpmn2:loopDataInputRef>
- // <inputDataItem xsi:type="bpmn2:tDataInput" id="DataInput_1" itemSubjectRef="ItemDefinition_1" name="input_param"/>
- // </multiInstanceLoopCharacteristics>
+
+// if (container instanceof SubProcess)
+ {
+ // Collect all DataObjects from Process and SubProcess ancestors
+ // DataObjects are FlowElements, so we will have to weed those out from other FlowElements.
+ List<EObject> flowElements = ModelUtil.collectAncestorObjects(object, "flowElements", new Class[] {Process.class, SubProcess.class}); //$NON-NLS-1$
+ for (EObject fe : flowElements) {
+ if (fe instanceof DataObjectReference) {
+ fe = ((DataObjectReference)fe).getDataObjectRef();
+ }
+ if (!(fe instanceof DataObject)) {
+ fe = null;
+ }
+ if (fe!=null && !values.contains(fe))
+ values.add(fe);
+ }
+ // Collect all Properties from Process and SubProcess ancestors
+ EObject parent = container.eContainer();
+ while (parent!=null) {
+ if (parent instanceof Process) {
+ values.addAll(((Process)parent).getProperties());
+ }
+ if (parent instanceof SubProcess) {
+ values.addAll(((SubProcess)parent).getProperties());
+ }
+ parent = parent.eContainer();
+ }
}
if (values!=null) {
@@ -183,5 +176,540 @@
super.setChoiceOfValues(choices);
return super.getChoiceOfValues();
}
+
+ @Override
+ public String getTextValue() {
+ Object value = getValue();
+ if (value!=null) {
+ return super.getChoiceString(value);
+ }
+ return "";
+ }
+ }
+
+ protected class LoopDataInputCollectionFeatureDescriptor extends LoopDataCollectionFeatureDescriptor {
+
+ public LoopDataInputCollectionFeatureDescriptor(
+ ExtendedPropertiesAdapter<MultiInstanceLoopCharacteristics> owner,
+ MultiInstanceLoopCharacteristics object) {
+ super(owner, object, LOOP_DATA_INPUT_REF);
+ }
+
+ @Override
+ protected void internalSet(MultiInstanceLoopCharacteristics object, EStructuralFeature feature, Object value, int index) {
+ ItemAwareElement element = null;
+ if (value instanceof ItemAwareElement)
+ element = (ItemAwareElement) value;
+
+ if (object.eContainer() instanceof Activity) {
+ value = setInputCollection(object, (Activity) object.eContainer(), element);
+ }
+ super.internalSet(object, feature, value, index);
+ }
+
+ @Override
+ public Object getValue() {
+ ItemAwareElement din = object.getLoopDataInputRef();
+ if (din==null)
+ return null;
+ // this is the LoopDataInputRef in the MI Loop Characteristics
+ if (object.eContainer() instanceof SubProcess) {
+ // get the name from the DataInput itself
+ return super.getValue();
+ }
+ else if (object.eContainer() instanceof Task) {
+ // get the name from the Task's mapped DataInput
+ Task task = (Task) object.eContainer();
+ for (DataInputAssociation dia : task.getDataInputAssociations()) {
+ if (din == dia.getTargetRef() && dia.getSourceRef().size()>0 && dia.getSourceRef().get(0) instanceof ItemAwareElement) {
+ return dia.getSourceRef().get(0);
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ protected class LoopDataOutputCollectionFeatureDescriptor extends LoopDataCollectionFeatureDescriptor {
+
+ public LoopDataOutputCollectionFeatureDescriptor(
+ ExtendedPropertiesAdapter<MultiInstanceLoopCharacteristics> owner,
+ MultiInstanceLoopCharacteristics object) {
+ super(owner, object, LOOP_DATA_OUTPUT_REF);
+ }
+
+ @Override
+ protected void internalSet(MultiInstanceLoopCharacteristics object, EStructuralFeature feature, Object value, int index) {
+ ItemAwareElement element = null;
+ if (value instanceof ItemAwareElement)
+ element = (ItemAwareElement) value;
+
+ if (object.eContainer() instanceof Activity) {
+ value = setOutputCollection(object, (Activity) object.eContainer(), element);
+ }
+ super.internalSet(object, feature, value, index);
+ }
+
+ @Override
+ public Object getValue() {
+ ItemAwareElement dout = object.getLoopDataOutputRef();
+ if (dout==null)
+ return null;
+ // this is the DataInput in the MI Loop Characteristics
+ if (object.eContainer() instanceof SubProcess) {
+ // get the name from the DataInput itself
+ return super.getValue();
+ }
+ else if (object.eContainer() instanceof Task) {
+ // get the name from the Task's mapped DataInput
+ Task task = (Task) object.eContainer();
+ for (DataOutputAssociation doa : task.getDataOutputAssociations()) {
+ if (doa.getSourceRef().contains(dout) && doa.getTargetRef() instanceof ItemAwareElement) {
+ return doa.getTargetRef();
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ protected class LoopDataItemFeatureDescriptor extends FeatureDescriptor<MultiInstanceLoopCharacteristics> {
+
+ public LoopDataItemFeatureDescriptor(ExtendedPropertiesAdapter<MultiInstanceLoopCharacteristics> owner,
+ MultiInstanceLoopCharacteristics object, EStructuralFeature feature) {
+ super(owner, object, feature);
+ Assert.isTrue(feature==INPUT_DATA_ITEM || feature==OUTPUT_DATA_ITEM);
+ }
+
+ @Override
+ public Hashtable<String, Object> getChoiceOfValues() {
+ Hashtable<String, Object> choices = new Hashtable<String, Object>();
+ EObject container = ModelUtil.getContainer(object);
+ // get the Property instances (a.k.a. "local variables") of the containing Process or SubProcess
+ if (container instanceof Activity) {
+ Activity activity = (Activity) container;
+ InputOutputSpecification iospec = activity.getIoSpecification();
+ if (iospec!=null) {
+ if (feature==INPUT_DATA_ITEM) {
+ for (ItemAwareElement e : iospec.getDataInputs()) {
+ if (object.getLoopDataInputRef()!=e)
+ choices.put(getChoiceString(e), e);
+ }
+ }
+ else {
+ for (ItemAwareElement e : iospec.getDataOutputs()) {
+ if (object.getLoopDataOutputRef()!=e)
+ choices.put(getChoiceString(e), e);
+ }
+ }
+ }
+ }
+ return choices;
+ }
+
+ @Override
+ public String getTextValue() {
+ Object value = getValue();
+ if (value!=null) {
+ return super.getChoiceString(value);
+ }
+ return "";
+ }
+ }
+
+ protected class LoopInputDataItemFeatureDescriptor extends LoopDataItemFeatureDescriptor {
+
+ public LoopInputDataItemFeatureDescriptor(ExtendedPropertiesAdapter<MultiInstanceLoopCharacteristics> owner,
+ MultiInstanceLoopCharacteristics object) {
+ super(owner, object, INPUT_DATA_ITEM);
+ }
+
+ @Override
+ protected void internalSet(MultiInstanceLoopCharacteristics object, EStructuralFeature feature, Object value, int index) {
+ ItemAwareElement element = null;
+ if (value instanceof ItemAwareElement)
+ element = (ItemAwareElement) value;
+
+ if (object.eContainer() instanceof SubProcess) {
+ value = setSubProcessInputItem(object, (SubProcess) object.eContainer(), element);
+ }
+ else if (object.eContainer() instanceof Task) {
+ value = setTaskInputItem(object, (Task) object.eContainer(), element);
+ }
+ super.internalSet(object, feature, value, index);
+ }
+
+ @Override
+ public Object getValue() {
+ DataInput din = object.getInputDataItem();
+ if (din==null)
+ return null;
+ // this is the DataInput in the MI Loop Characteristics
+ if (object.eContainer() instanceof SubProcess) {
+ // get the name from the DataInput itself
+ return din;
+ }
+ else if (object.eContainer() instanceof Task) {
+ // get the name from the Task's mapped DataInput
+ Task task = (Task) object.eContainer();
+ for (DataInputAssociation dia : task.getDataInputAssociations()) {
+ if (dia.getSourceRef().contains(din) && dia.getTargetRef() instanceof DataInput) {
+ return dia.getTargetRef();
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ protected class LoopOutputDataItemFeatureDescriptor extends LoopDataItemFeatureDescriptor {
+
+ public LoopOutputDataItemFeatureDescriptor(ExtendedPropertiesAdapter<MultiInstanceLoopCharacteristics> owner,
+ MultiInstanceLoopCharacteristics object) {
+ super(owner, object, OUTPUT_DATA_ITEM);
+ }
+
+ @Override
+ protected void internalSet(MultiInstanceLoopCharacteristics object, EStructuralFeature feature, Object value, int index) {
+ ItemAwareElement element = null;
+ if (value instanceof ItemAwareElement)
+ element = (ItemAwareElement) value;
+
+ if (object.eContainer() instanceof SubProcess) {
+ value = setSubProcessOutputItem(object, (SubProcess) object.eContainer(), element);
+ }
+ else if (object.eContainer() instanceof Task) {
+ value = setTaskOutputItem(object, (Task) object.eContainer(), element);
+ }
+ super.internalSet(object, feature, value, index);
+ }
+
+ @Override
+ public Object getValue() {
+ DataOutput dout = object.getOutputDataItem();
+ if (dout==null)
+ return null;
+ // this is the DataOutput in the MI Loop Characteristics
+ if (object.eContainer() instanceof SubProcess) {
+ // get the name from the DataOutput itself
+ return dout;
+ }
+ else if (object.eContainer() instanceof Task) {
+ // get the name from the Task's mapped DataOutput
+ Task task = (Task) object.eContainer();
+ for (DataOutputAssociation dia : task.getDataOutputAssociations()) {
+ if (dia.getTargetRef()==dout && dia.getSourceRef().size()>0 && dia.getSourceRef().get(0) instanceof DataOutput) {
+ return dia.getSourceRef().get(0);
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Set or clear the Loop Data Input Reference feature of the given
+ * MultiInstancLoopCharacteristics object.
+ *
+ * This also manages the Activity's Data Inputs and Input Sets in the
+ * IOSpecificaiont as well as the Activity's DataInputAssociations.
+ *
+ * @param milc
+ * the MultiInstancLoopCharacteristics object
+ * @param subprocess
+ * the affected Activity
+ * @param element
+ * the new value for the Loop Data Input
+ * @see MultiInstanceLoopCharacteristics#setLoopDataOutputRef(ItemAwareElement)
+ */
+ private ItemAwareElement setInputCollection(MultiInstanceLoopCharacteristics milc, Activity subprocess, ItemAwareElement element) {
+ InputOutputSpecification ioSpec = subprocess.getIoSpecification();
+ Resource resource = getResource();
+ if (element!=null) {
+ DataInput input = null;
+ InputSet inputSet = null;
+ DataInputAssociation inputAssociation = null;
+ if (ioSpec==null) {
+ ioSpec = Bpmn2ModelerFactory.create(resource, InputOutputSpecification.class);
+ subprocess.setIoSpecification(ioSpec);
+ }
+ else {
+ for (DataInput din : ioSpec.getDataInputs()) {
+ if (din == milc.getLoopDataInputRef()) {
+ input = din;
+ break;
+ }
+ }
+ }
+ if (input == null)
+ input = Bpmn2ModelerFactory.create(resource, DataInput.class);
+ input.setName(element.getId());
+ input.setItemSubjectRef(element.getItemSubjectRef());
+ input.setIsCollection(true);
+ if (!ioSpec.getDataInputs().contains(input))
+ ioSpec.getDataInputs().add(input);
+
+ for (InputSet is : ioSpec.getInputSets()) {
+ if (is.getDataInputRefs().contains(input)) {
+ inputSet = is;
+ break;
+ }
+ }
+ if (inputSet == null) {
+ if (ioSpec.getInputSets().size()==0) {
+ inputSet = Bpmn2ModelerFactory.create(resource, InputSet.class);
+ ioSpec.getInputSets().add(inputSet);
+ }
+ else
+ inputSet = ioSpec.getInputSets().get(0);
+ }
+ if (!inputSet.getDataInputRefs().contains(input))
+ inputSet.getDataInputRefs().add(input);
+
+ for (DataInputAssociation dia : subprocess.getDataInputAssociations()) {
+ if (dia.getTargetRef()==input) {
+ inputAssociation = dia;
+ break;
+ }
+ }
+ if (inputAssociation == null) {
+ inputAssociation = Bpmn2ModelerFactory.create(resource, DataInputAssociation.class);
+ subprocess.getDataInputAssociations().add(inputAssociation);
+ }
+
+ inputAssociation.setTargetRef(input);
+ inputAssociation.getSourceRef().clear();
+ inputAssociation.getSourceRef().add(element);
+
+ element = input;
+ }
+ else {
+ ItemAwareElement input = milc.getLoopDataInputRef();
+ if (ioSpec!=null) {
+ if (input!=null) {
+ for (DataInput din : ioSpec.getDataInputs()) {
+ if (din == input) {
+ ioSpec.getDataInputs().remove(din);
+ if (ioSpec.getInputSets().size()>0) {
+ ioSpec.getInputSets().get(0).getDataInputRefs().remove(din);
+ if (ioSpec.getInputSets().get(0).getDataInputRefs().size()==0)
+ ioSpec.getInputSets().remove(0);
+ }
+ break;
+ }
+ }
+ int i = 0;
+ for (DataInputAssociation dia : subprocess.getDataInputAssociations()) {
+ if (dia.getTargetRef() == input) {
+ subprocess.getDataInputAssociations().remove(i);
+ break;
+ }
+ ++i;
+ }
+ }
+ if (ioSpec.getDataInputs().size()==0 && ioSpec.getDataOutputs().size()==0) {
+ subprocess.setIoSpecification(null);
+ }
+ }
+ }
+
+ return element;
+ }
+
+ /**
+ * Set or clear the Loop Data Output Reference feature of the given
+ * MultiInstancLoopCharacteristics object.
+ *
+ * This also manages the Activity's Data Outputs and Output Sets in the
+ * IOSpecificaiont as well as the Activity's DataOutputAssociations.
+ *
+ * @param milc
+ * the MultiInstancLoopCharacteristics object
+ * @param activity
+ * the affected Activity
+ * @param element
+ * the new value for the Loop Data Output
+ * @see MultiInstanceLoopCharacteristics#setLoopDataOutputRef(ItemAwareElement)
+ */
+ private ItemAwareElement setOutputCollection(MultiInstanceLoopCharacteristics milc, Activity activity, ItemAwareElement element) {
+ InputOutputSpecification ioSpec = activity.getIoSpecification();
+ Resource resource = getResource();
+ if (element!=null) {
+ DataOutput output = null;
+ OutputSet outputSet = null;
+ DataOutputAssociation outputAssociation = null;
+ if (ioSpec==null) {
+ ioSpec = Bpmn2ModelerFactory.create(resource, InputOutputSpecification.class);
+ activity.setIoSpecification(ioSpec);
+ }
+ else {
+ for (DataOutput dout : ioSpec.getDataOutputs()) {
+ if (dout == milc.getLoopDataOutputRef()) {
+ output = dout;
+ break;
+ }
+ }
+ }
+ if (output == null)
+ output = Bpmn2ModelerFactory.create(resource, DataOutput.class);
+ output.setName(element.getId());
+ output.setItemSubjectRef(element.getItemSubjectRef());
+ output.setIsCollection(true);
+ if (!ioSpec.getDataOutputs().contains(output))
+ ioSpec.getDataOutputs().add(output);
+
+ for (OutputSet os : ioSpec.getOutputSets()) {
+ if (os.getDataOutputRefs().contains(output)) {
+ outputSet = os;
+ break;
+ }
+ }
+ if (outputSet == null) {
+ if (ioSpec.getOutputSets().size()==0) {
+ outputSet = Bpmn2ModelerFactory.create(resource, OutputSet.class);
+ ioSpec.getOutputSets().add(outputSet);
+ }
+ else
+ outputSet = ioSpec.getOutputSets().get(0);
+ }
+ if (!outputSet.getDataOutputRefs().contains(output))
+ outputSet.getDataOutputRefs().add(output);
+
+ for (DataOutputAssociation doa : activity.getDataOutputAssociations()) {
+ if (doa.getSourceRef().size()==1 && doa.getSourceRef().get(0)==output) {
+ outputAssociation = doa;
+ break;
+ }
+ }
+ if (outputAssociation == null) {
+ outputAssociation = Bpmn2ModelerFactory.create(resource, DataOutputAssociation.class);
+ activity.getDataOutputAssociations().add(outputAssociation);
+ }
+
+ outputAssociation.getSourceRef().clear();
+ outputAssociation.getSourceRef().add(output);
+ outputAssociation.setTargetRef(element);
+
+ element = output;
+ }
+ else {
+ ItemAwareElement output = milc.getLoopDataOutputRef();
+ if (ioSpec!=null) {
+ if (output!=null) {
+ for (DataOutput dout : ioSpec.getDataOutputs()) {
+ if (dout == output) {
+ ioSpec.getDataOutputs().remove(dout);
+ if (ioSpec.getOutputSets().size()>0) {
+ ioSpec.getOutputSets().get(0).getDataOutputRefs().remove(dout);
+ if (ioSpec.getOutputSets().get(0).getDataOutputRefs().size()==0)
+ ioSpec.getOutputSets().remove(0);
+ }
+ break;
+ }
+ }
+ int i = 0;
+ for (DataOutputAssociation doa : activity.getDataOutputAssociations()) {
+ if (doa.getSourceRef().size()>0 && doa.getSourceRef().get(0) == output) {
+ activity.getDataOutputAssociations().remove(i);
+ break;
+ }
+ ++i;
+ }
+ }
+ if (ioSpec.getDataInputs().size()==0 && ioSpec.getDataOutputs().size()==0) {
+ activity.setIoSpecification(null);
+ }
+ }
+
+ }
+ return element;
+ }
+
+ private ItemAwareElement setSubProcessInputItem(MultiInstanceLoopCharacteristics milc, SubProcess subprocess, ItemAwareElement element) {
+ return element;
+ }
+
+ private ItemAwareElement setSubProcessOutputItem(MultiInstanceLoopCharacteristics milc, SubProcess subprocess, ItemAwareElement element) {
+ return element;
+ }
+
+ private ItemAwareElement setTaskInputItem(MultiInstanceLoopCharacteristics milc, Task task, ItemAwareElement element) {
+ Resource resource = task.eResource();
+ // find the old DataInputAssociation for the current MI Input Data Item
+ // and delete it because it will be replaced by a new one.
+ DataInput oldDin = milc.getInputDataItem();
+ if (oldDin!=null) {
+ for (DataInputAssociation dia : task.getDataInputAssociations()) {
+ if (dia.getSourceRef().contains(oldDin)) {
+ task.getDataInputAssociations().remove(dia);
+ break;
+ }
+ }
+ }
+
+ // find the DataInputAssociation for this DataInput, if it exists
+ DataInputAssociation dataInputAssociation = null;
+ for (DataInputAssociation dia : task.getDataInputAssociations()) {
+ if (dia.getTargetRef() == element) {
+ dataInputAssociation = dia;
+ break;
+ }
+ }
+ if (dataInputAssociation==null) {
+ // not found? create one!
+ dataInputAssociation = Bpmn2ModelerFactory.create(resource, DataInputAssociation.class);
+ task.getDataInputAssociations().add(dataInputAssociation);
+ dataInputAssociation.setTargetRef(element);
+ }
+ // create a new DataInput for the MI loop input item
+ // and map it to the given element
+ DataInput din = Bpmn2ModelerFactory.create(resource, DataInput.class);
+ din.setName(((DataInput)element).getName());
+ din.setItemSubjectRef(element.getItemSubjectRef());
+ dataInputAssociation.getSourceRef().clear();
+ dataInputAssociation.getSourceRef().add(din);
+ return din;
+ }
+
+ private ItemAwareElement setTaskOutputItem(MultiInstanceLoopCharacteristics milc, Task task, ItemAwareElement element) {
+ Resource resource = task.eResource();
+ // find the old DataOutputAssociation for the current MI Output Data Item
+ // and delete it because it will be replaced by a new one.
+ DataOutput oldDout = milc.getOutputDataItem();
+ if (oldDout!=null) {
+ for (DataOutputAssociation doa : task.getDataOutputAssociations()) {
+ if (doa.getTargetRef() == oldDout) {
+ task.getDataOutputAssociations().remove(doa);
+ break;
+ }
+ }
+ }
+
+ // find the DataOutputAssociation for this DataOutput, if it exists
+ DataOutputAssociation dataOutputAssociation = null;
+ for (DataOutputAssociation doa : task.getDataOutputAssociations()) {
+ if (doa.getSourceRef().contains(element)) {
+ dataOutputAssociation = doa;
+ break;
+ }
+ }
+ if (dataOutputAssociation==null) {
+ // not found? create one!
+ dataOutputAssociation = Bpmn2ModelerFactory.create(resource, DataOutputAssociation.class);
+ task.getDataOutputAssociations().add(dataOutputAssociation);
+ dataOutputAssociation.getSourceRef().clear();
+ dataOutputAssociation.getSourceRef().add(element);
+ }
+ // create a new DataOutput for the MI loop input item
+ // and map it to the given element
+ DataOutput dout = Bpmn2ModelerFactory.create(resource, DataOutput.class);
+ dout.setName(((DataOutput)element).getName());
+ dout.setItemSubjectRef(element.getItemSubjectRef());
+ dataOutputAssociation.setTargetRef(dout);
+ return dout;
}
}
diff --git a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/tasks/MultiInstanceLoopCharacteristicsDetailComposite.java b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/tasks/MultiInstanceLoopCharacteristicsDetailComposite.java
index 891d724..f62c7fc 100644
--- a/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/tasks/MultiInstanceLoopCharacteristicsDetailComposite.java
+++ b/plugins/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/tasks/MultiInstanceLoopCharacteristicsDetailComposite.java
@@ -16,8 +16,12 @@
import org.eclipse.bpmn2.DataOutput;
import org.eclipse.bpmn2.Expression;
import org.eclipse.bpmn2.FormalExpression;
+import org.eclipse.bpmn2.InputOutputSpecification;
+import org.eclipse.bpmn2.ItemAwareElement;
import org.eclipse.bpmn2.MultiInstanceBehavior;
import org.eclipse.bpmn2.MultiInstanceLoopCharacteristics;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.Task;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesProvider;
import org.eclipse.bpmn2.modeler.core.adapters.InsertionAdapter;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractBpmn2PropertySection;
@@ -31,7 +35,9 @@
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.FeatureEditingDialog;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.TextAndButtonObjectEditor;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory;
import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
@@ -652,14 +658,13 @@
};
editor.createControl(getAttributesParent(), Messages.MultiInstanceLoopCharacteristicsDetailComposite_Input_Data_Label);
-
- DataInput input = lc.getInputDataItem();
- if (input==null) {
- input = createModelObject(DataInput.class);
- input.setName("");
- InsertionAdapter.add(lc, PACKAGE.getMultiInstanceLoopCharacteristics_InputDataItem(), input);
+ if (be.eContainer() instanceof SubProcess) {
+ editor = new LoopDataItemObjectEditor(this, lc, PACKAGE.getMultiInstanceLoopCharacteristics_InputDataItem());
}
- editor = new DataInputOutputObjectEditor(this, input, PACKAGE.getDataInput_Name());
+ else {
+ // must be a Task
+ editor = new LoopDataItemSelectionEditor(this, lc, PACKAGE.getMultiInstanceLoopCharacteristics_InputDataItem());
+ }
editor.createControl(getAttributesParent(), Messages.MultiInstanceLoopCharacteristicsDetailComposite_Input_Parameter_Label);
}
};
@@ -684,13 +689,13 @@
editor.createControl(getAttributesParent(), Messages.MultiInstanceLoopCharacteristicsDetailComposite_Output_Data_Label);
- DataOutput output = lc.getOutputDataItem();
- if (output==null) {
- output = createModelObject(DataOutput.class);
- output.setName("");
- InsertionAdapter.add(lc, PACKAGE.getMultiInstanceLoopCharacteristics_OutputDataItem(), output);
+ if (be.eContainer() instanceof SubProcess) {
+ editor = new LoopDataItemObjectEditor(this, lc, PACKAGE.getMultiInstanceLoopCharacteristics_OutputDataItem());
}
- editor = new DataInputOutputObjectEditor(this, output, PACKAGE.getDataOutput_Name());
+ else {
+ // must be a Task
+ editor = new LoopDataItemSelectionEditor(this, lc, PACKAGE.getMultiInstanceLoopCharacteristics_OutputDataItem());
+ }
editor.createControl(getAttributesParent(), Messages.MultiInstanceLoopCharacteristicsDetailComposite_Output_Parameter_Label);
}
};
@@ -791,14 +796,50 @@
}
- public class DataInputOutputObjectEditor extends TextAndButtonObjectEditor {
- public DataInputOutputObjectEditor(AbstractDetailComposite parent, EObject object, EStructuralFeature feature) {
+ private class LoopDataItemObjectEditor extends TextAndButtonObjectEditor {
+
+ /**
+ * The DataInput or DataOutput element of the MI InputDataItem or OutputDataItem
+ */
+ ItemAwareElement element;
+ /**
+ * The "name" feature of the above element
+ */
+ EStructuralFeature elementFeature;
+ boolean isInput = false;
+
+ public LoopDataItemObjectEditor(AbstractDetailComposite parent, MultiInstanceLoopCharacteristics object, EStructuralFeature feature) {
super(parent, object, feature);
+ if (feature==PACKAGE.getMultiInstanceLoopCharacteristics_InputDataItem()) {
+ isInput = true;
+ element = object.getInputDataItem();
+ elementFeature = PACKAGE.getDataInput_Name();
+ }
+ else if (feature==PACKAGE.getMultiInstanceLoopCharacteristics_OutputDataItem()) {
+ isInput = false;
+ element = object.getOutputDataItem();
+ elementFeature = PACKAGE.getDataOutput_Name();
+ }
+ else
+ Assert.isTrue(false);
+
+ if (element==null) {
+ if (isInput) {
+ element = createModelObject(DataInput.class);
+ element.eSet(elementFeature, "");
+ InsertionAdapter.add(object, PACKAGE.getMultiInstanceLoopCharacteristics_InputDataItem(), element);
+ }
+ else {
+ element = createModelObject(DataOutput.class);
+ element.eSet(elementFeature, "");
+ InsertionAdapter.add(object, PACKAGE.getMultiInstanceLoopCharacteristics_OutputDataItem(), element);
+ }
+ }
}
@Override
protected void buttonClicked(int buttonId) {
- FeatureEditingDialog dialog = new FeatureEditingDialog(getDiagramEditor(), object, Bpmn2Package.eINSTANCE.getItemAwareElement_ItemSubjectRef(), object);
+ FeatureEditingDialog dialog = new FeatureEditingDialog(getDiagramEditor(), element, Bpmn2Package.eINSTANCE.getItemAwareElement_ItemSubjectRef(), element);
if ( dialog.open() == Window.OK) {
this.updateText();
}
@@ -806,15 +847,47 @@
@Override
protected String getText() {
- String text = null;
- EStructuralFeature f = object.eClass().getEStructuralFeature("name"); //$NON-NLS-1$
- if (f!=null) {
- text = (String)object.eGet(f);
- }
+ String text = (String)element.eGet(elementFeature);
if (text==null)
return ""; //$NON-NLS-1$
return text;
}
};
+ private class LoopDataItemSelectionEditor extends ComboObjectEditor {
+
+ InputOutputSpecification ioSpec;
+ EStructuralFeature ioSpecFeature;
+ boolean isInput = false;
+
+ public LoopDataItemSelectionEditor(AbstractDetailComposite parent, MultiInstanceLoopCharacteristics object, EStructuralFeature feature) {
+ super(parent, object, feature);
+ if (feature==PACKAGE.getMultiInstanceLoopCharacteristics_InputDataItem()) {
+ isInput = true;
+ ioSpecFeature = PACKAGE.getInputOutputSpecification_DataInputs();
+ }
+ else if (feature==PACKAGE.getMultiInstanceLoopCharacteristics_OutputDataItem()) {
+ isInput = false;
+ ioSpecFeature = PACKAGE.getInputOutputSpecification_DataOutputs();
+ }
+ else
+ Assert.isTrue(false);
+ }
+
+ @Override
+ protected FeatureEditingDialog createFeatureEditingDialog(EObject value) {
+ // In this case the container is the I/O Specification of
+ // the Task that owns the "object" which is a instance of
+ // a MultiInstanceLoopCharacteristics
+ Task task = (Task) object.eContainer();
+ ioSpec = task.getIoSpecification();
+ if (ioSpec==null) {
+ ioSpec = Bpmn2ModelerFactory.create(
+ task.eResource(), InputOutputSpecification.class);
+ InsertionAdapter.add(task, PACKAGE.getActivity_IoSpecification(), ioSpec);
+ }
+ return new FeatureEditingDialog(getDiagramEditor(), ioSpec, ioSpecFeature, value);
+ }
+
+ }
}