blob: 649123e17986dde65f1eaf9bfcca3f7b3c732521 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Red Hat, Inc.
* All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*
* @author Bob Brodt
******************************************************************************/
package org.eclipse.bpmn2.modeler.ui.adapters.properties;
import java.util.Hashtable;
import java.util.Stack;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.DataAssociation;
import org.eclipse.bpmn2.DataInputAssociation;
import org.eclipse.bpmn2.DataOutputAssociation;
import org.eclipse.bpmn2.Definitions;
import org.eclipse.bpmn2.Event;
import org.eclipse.bpmn2.EventDefinition;
import org.eclipse.bpmn2.ItemAwareElement;
import org.eclipse.bpmn2.ItemDefinition;
import org.eclipse.bpmn2.ItemKind;
import org.eclipse.bpmn2.RootElement;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter;
import org.eclipse.bpmn2.modeler.core.adapters.FeatureDescriptor;
import org.eclipse.bpmn2.modeler.core.utils.EventDefinitionsUtil;
import org.eclipse.bpmn2.modeler.core.utils.ImportUtil;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
import org.eclipse.bpmn2.modeler.core.utils.Tuple;
import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
/**
* @author Bob Brodt
*
*/
public class ItemDefinitionRefFeatureDescriptor<T extends BaseElement> extends FeatureDescriptor<T> {
protected ImportUtil importer = new ImportUtil();
/**
* @param adapterFactory
* @param object
* @param feature
*/
public ItemDefinitionRefFeatureDescriptor(ExtendedPropertiesAdapter<T> owner, T object, EStructuralFeature feature) {
super(owner, object, feature);
// I found a couple of instances where this class was used for references that were NOT
// RootElements - just check to make sure here...
Assert.isTrue( RootElement.class.isAssignableFrom(feature.getEType().getInstanceClass()) );
}
@Override
public String getLabel() {
return ItemDefinitionPropertiesAdapter.getLabel();
}
@Override
public String getTextValue() {
ItemDefinition itemDefinition = (ItemDefinition) object.eGet(feature);
return ItemDefinitionPropertiesAdapter.getDisplayName(itemDefinition);
}
@Override
public EObject createFeature(Resource resource, EClass eClass) {
ItemDefinition itemDefinition = ItemDefinitionPropertiesAdapter.createItemDefinition(object.eResource());
return itemDefinition;
}
@Override
public Object getValue() {
ItemDefinition itemDefinition = (ItemDefinition) object.eGet(feature);
return ItemDefinitionPropertiesAdapter.getStructureRef(itemDefinition);
}
@Override
protected void internalSet(T object, EStructuralFeature feature, Object value, int index) {
Definitions definitions = ModelUtil.getDefinitions(object);
if (value instanceof String) {
value = importer.createItemDefinition(definitions, null, (String)value, ItemKind.INFORMATION);
}
if (value==null || value instanceof ItemDefinition) {
ItemDefinition itemDefinition = (ItemDefinition) value;
super.internalSet(object, feature, itemDefinition, index);
// if there are any DataInputAssociations or DataOutputAssociations that map to this object
// then change their ItemDefinitions to match.
if (definitions!=null) {
// We use a stack to track the ItemAwareElements that were changed as
// a result of this object's change.
if (object instanceof ItemAwareElement) {
changeReferences((ItemAwareElement)object, itemDefinition);
}
else if (object instanceof RootElement) {
// find all references to this root element:
// for event definitions, correlate the input/output association with the event definition
// that references this object, and change the ItemDefinition of that data input/output.
changeReferences((RootElement)object, itemDefinition);
}
}
}
}
private void changeReferences(RootElement object, ItemDefinition itemDefinition) {
for (EObject ed : ModelUtil.getAllReachableObjects(object, Bpmn2Package.eINSTANCE.getEventDefinition())) {
if (EventDefinitionsUtil.getEventDefinitionTarget((EventDefinition)ed) == object) {
Tuple<ItemAwareElement, DataAssociation> param =
EventDefinitionsUtil.getIOParameter((Event)ed.eContainer(), (EventDefinition)ed);
changeReferences(param.getFirst(), itemDefinition);
}
}
}
private void changeReferences(ItemAwareElement object, ItemDefinition itemDefinition) {
Definitions definitions = ModelUtil.getDefinitions(object);
Stack<ItemAwareElement> changedObjects = new Stack<ItemAwareElement>();
changedObjects.push((ItemAwareElement)object);
while (!changedObjects.isEmpty()) {
ItemAwareElement element = changedObjects.pop();
if (element.eContainer() instanceof Event) {
EventDefinition ed = EventDefinitionsUtil.getEventDefinition(element);
if (ed!=null) {
ItemDefinition id = EventDefinitionsUtil.getItemDefinition(ed);
if (id!=itemDefinition) {
EventDefinitionsUtil.setItemDefinition(ed,itemDefinition);
RootElement re = EventDefinitionsUtil.getEventDefinitionTarget(ed);
changeReferences(re,itemDefinition);
}
}
}
if (element.getItemSubjectRef()!=itemDefinition) {
element.setItemSubjectRef(itemDefinition);
}
TreeIterator<EObject> iter = definitions.eAllContents();
while (iter.hasNext()) {
EObject o = iter.next();
if (o instanceof DataInputAssociation) {
DataInputAssociation da = (DataInputAssociation) o;
if (da.getSourceRef().contains(element)) {
if (da.getTargetRef()!=null) {
if (da.getTargetRef().getItemSubjectRef()!=itemDefinition) {
da.getTargetRef().setItemSubjectRef(itemDefinition);
changedObjects.push(da.getTargetRef());
}
}
}
else if (da.getTargetRef()==element) {
for (ItemAwareElement e : da.getSourceRef()) {
if (e.getItemSubjectRef()!=itemDefinition) {
e.setItemSubjectRef(itemDefinition);
changedObjects.push(e);
}
}
}
}
else if (o instanceof DataOutputAssociation) {
DataOutputAssociation da = (DataOutputAssociation) o;
if (da.getSourceRef().contains(element)) {
if (da.getTargetRef()!=null) {
if (da.getTargetRef().getItemSubjectRef()!=itemDefinition) {
da.getTargetRef().setItemSubjectRef(itemDefinition);
changedObjects.push(da.getTargetRef());
}
}
}
else if (da.getTargetRef()==element) {
for (ItemAwareElement e : da.getSourceRef()) {
if (e.getItemSubjectRef()!=itemDefinition) {
e.setItemSubjectRef(itemDefinition);
changedObjects.push(e);
}
}
}
}
}
}
}
@Override
public Hashtable<String, Object> getChoiceOfValues() {
return ItemDefinitionPropertiesAdapter.getChoiceOfValues(object);
}
}