blob: f7aafea7c7c199894bbc64e35cb4b52b06618327 [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 Ivar Meikas
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.bpmn2.AdHocSubProcess;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.Bpmn2Factory;
import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.Choreography;
import org.eclipse.bpmn2.ChoreographyActivity;
import org.eclipse.bpmn2.Collaboration;
import org.eclipse.bpmn2.Definitions;
import org.eclipse.bpmn2.DocumentRoot;
import org.eclipse.bpmn2.Event;
import org.eclipse.bpmn2.EventDefinition;
import org.eclipse.bpmn2.ExtensionAttributeValue;
import org.eclipse.bpmn2.FormalExpression;
import org.eclipse.bpmn2.Participant;
import org.eclipse.bpmn2.Process;
import org.eclipse.bpmn2.RootElement;
import org.eclipse.bpmn2.SubChoreography;
import org.eclipse.bpmn2.SubProcess;
import org.eclipse.bpmn2.Transaction;
import org.eclipse.bpmn2.di.BPMNDiagram;
import org.eclipse.bpmn2.di.BPMNPlane;
import org.eclipse.bpmn2.di.BpmnDiPackage;
import org.eclipse.bpmn2.modeler.core.Activator;
import org.eclipse.bpmn2.modeler.core.adapters.AdapterRegistry;
import org.eclipse.bpmn2.modeler.core.adapters.AdapterUtil;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter;
import org.eclipse.bpmn2.modeler.core.adapters.INamespaceMap;
import org.eclipse.bpmn2.modeler.core.adapters.InsertionAdapter;
import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory;
import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceSetImpl;
import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
import org.eclipse.bpmn2.util.Bpmn2Resource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.dd.dc.DcPackage;
import org.eclipse.dd.di.DiPackage;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
import org.eclipse.emf.ecore.impl.EAttributeImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.BasicFeatureMap;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMap.Entry;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.platform.IDiagramContainer;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.ui.editor.DiagramEditor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDElementDeclaration;
public class ModelUtil {
// TODO: need to determine whether IDs need to be unique within a Resource or ResourceSet - see getKey()
// Map of EMF resource sets to ID mapping tables. The ID mapping tables map a BPMN2 element ID string to the EObject.
// The EObject is not used anywhere (yet!) just a placeholder to allow use of a HashMap for fast lookups of the ID string.
// The ID strings are composed from the BPMN2 element description name and a sequence number (starting at 1).
// When a new ID is requested, generateID() simply increments the sequence number until an ID is found that isn't
// already in the table.
public static HashMap<Object, Hashtable<String, EObject>> ids = new HashMap<Object, Hashtable<String, EObject>>();
// Map of ID strings and sequential counters for each BPMN2 element description.
public static HashMap<String, Integer> defaultIds = new HashMap<String, Integer>();
/**
* Clear the IDs hashmap for the given EMF Resource. This should be called
* when the editor is disposed to avoid unnecessary growth of the IDs table.
*
* @param res - the EMF Resource that was used to generate the ID strings.
*/
public static void clearIDs(Resource res, boolean all) {
ids.remove( getKey(res) );
if (all) {
defaultIds.clear();
}
}
/**
* Construct the first part of the ID string using the BPMN2 element description name.
* If the object is a DI element, concatenate the BPMN2 element description name.
*
* @param obj - the BPMN2 object
* @return name string
*/
private static String getObjectName(EObject obj) {
String name;
EStructuralFeature feature = ((EObject)obj).eClass().getEStructuralFeature("bpmnElement"); //$NON-NLS-1$
if (feature!=null && obj.eGet(feature)!=null) {
EObject bpmnElement = (EObject) obj.eGet(feature);
name = obj.eClass().getName() + "_" + bpmnElement.eClass().getName(); //$NON-NLS-1$
}
else {
name = obj.eClass().getName();
}
return name;
}
private static Object getKey(EObject obj) {
Resource resource = getResource(obj);
if (resource==null) {
// System.out.println("The object type "+obj.getClass().getName()+" is not contained in a Resource");
return null;
}
Assert.isTrue(obj!=null);
return getKey(resource);
}
private static Object getKey(Resource res) {
Assert.isTrue(res!=null);
return res.getResourceSet();
}
/**
* If an EObject has not yet been added to a Resource (e.g. during construction)
* generate an ID string using a different strategy (basically same ID prefixed with an underscore).
* The "defaultIds" table is used to track the next sequential ID value for a given element description.
*
* @param obj - the BPMN2 object
* @return the ID string
*/
private static String generateDefaultID(EObject obj, String name) {
if (name==null)
name = getObjectName(obj);
Integer value = defaultIds.get(name);
if (value==null)
value = Integer.valueOf(1);
value = Integer.valueOf( value.intValue() + 1 );
defaultIds.put(name, Integer.valueOf(value));
return "_" + name + "_" + value; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Generate an ID string for a given BPMN2 object that will (eventually!) be added to the given Resource.
*
* CAUTION: IDs for objects that have already been deleted WILL be reused.
*
* @param obj - the BPMN2 object
* @param res - the Resource to which the object will be added
* @return the ID string
*/
private static String generateID(EObject obj, Resource res) {
return generateID(obj, res, null);
}
public static String generateID(EObject obj, Resource res, String name) {
Object key = (res==null ? getKey(obj) : getKey(res));
if (key!=null) {
Hashtable<String, EObject> tab = ids.get(key);
if (tab==null) {
tab = new Hashtable<String, EObject>();
ids.put(key, tab);
}
String id = name;
if (name==null) {
name = getObjectName(obj);
id = name + "_" + 1; //$NON-NLS-1$
}
for (int i=1;; ++i) {
if (tab.get(id)==null) {
tab.put(id, obj);
return id;
}
id = name + "_" + i; //$NON-NLS-1$
}
}
return generateDefaultID(obj, name);
}
public static void unsetID(EObject obj, Resource resource) {
EStructuralFeature feature = ((EObject)obj).eClass().getEStructuralFeature("id"); //$NON-NLS-1$
if (feature!=null) {
Object value = obj.eGet(feature);
if (value instanceof String) {
String id = (String)value;
Object key = getKey(resource);
if (key!=null) {
Hashtable<String, EObject> tab = ids.get(key);
if (tab!=null) {
tab.remove(id);
}
}
}
}
}
/**
* Add an ID string to the ID mapping table(s). This must be used during model import
* to add existing BPMN2 element IDs to the table so we don't generate duplicates.
*
* @param obj - the BPMN2 object
*/
public static void addID(EObject obj) {
EStructuralFeature feature = ((EObject)obj).eClass().getEStructuralFeature("id"); //$NON-NLS-1$
if (feature!=null) {
Object value = obj.eGet(feature);
if (value!=null) {
addID(obj,(String)value);
}
else {
// TODO: what to do here if the BPMN2 element has an "id" attribute which is not set?
// should we generate one and set it?
// yup
setID(obj);
}
}
}
/**
* Add an ID string to the ID mapping table(s). This must be used during model import
* to add existing BPMN2 element IDs to the table so we don't generate duplicates.
*
* @param obj - the BPMN2 object
* @param id - the object's ID string
*/
public static void addID(EObject obj, String id) {
Object key = getKey(obj);
String name = getObjectName(obj);
if (key==null || id.startsWith("_" + name + "_")) { //$NON-NLS-1$ //$NON-NLS-2$
int newValue = 0;
try {
int i = id.lastIndexOf('_') + 1;
if (i<id.length())
newValue = Integer.parseInt(id.substring(i));
} catch (Exception e) {
}
Integer oldValue = defaultIds.get(name);
if (oldValue==null || newValue > oldValue.intValue())
defaultIds.put(name, Integer.valueOf(newValue));
}
else {
Hashtable<String, EObject> tab = ids.get(key);
if (tab==null) {
tab = new Hashtable<String, EObject>();
ids.put(key, tab);
}
tab.put(id, obj);
}
}
/**
* Generate a unique ID for the given BPMN2 element and set it.
* This should only be used during object construction AFTER an object has
* already been added to a Resource.
*
* @param obj - the BPMN2 object
*/
public static String setID(EObject obj) {
return setID(obj,getResource(obj));
}
/**
* Generate a unique ID for the given BPMN2 element and set it.
* This should be used during object construction if the object has NOT YET
* been added to a Resource.
*
* @param obj - the BPMN2 object
* @param res - the Resource to which the object will be added
*/
public static String setID(EObject obj, Resource res) {
String id = null;
EStructuralFeature feature = ((EObject)obj).eClass().getEStructuralFeature("id"); //$NON-NLS-1$
if (feature!=null) {
if (obj.eGet(feature)==null) {
id = generateID(obj,res);
obj.eSet(feature, id);
}
}
return id;
}
public static String getID(EObject obj) {
EStructuralFeature feature = ((EObject)obj).eClass().getEStructuralFeature("id"); //$NON-NLS-1$
if (feature!=null) {
return (String)obj.eGet(feature);
}
return null;
}
public static String generateUndefinedID(String base) {
String name = "undefined"; //$NON-NLS-1$
if (base.contains("_")) { //$NON-NLS-1$
return "<" + name + "_" + base.replaceFirst(".*_", "") + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
Integer value = defaultIds.get(name);
if (value==null)
value = Integer.valueOf(1);
value = Integer.valueOf( value.intValue() + 1 );
defaultIds.put(name, Integer.valueOf(value));
return "<" + name + "_" + value + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public static int getIDNumber(String id) {
try {
int i = id.lastIndexOf("_"); //$NON-NLS-1$
return Integer.parseInt(id.substring(i+1));
}
catch (Exception e) {
return -1;
}
}
public static String getName(BaseElement element) {
if (element != null) {
EStructuralFeature feature = element.eClass().getEStructuralFeature("name"); //$NON-NLS-1$
if (feature==null)
feature = getAnyAttribute(element,"name"); //$NON-NLS-1$
if (feature!=null && element.eGet(feature) instanceof String)
return (String) element.eGet(feature);
}
return null;
}
public static boolean hasName(BaseElement obj) {
EStructuralFeature feature = obj.eClass().getEStructuralFeature("name"); //$NON-NLS-1$
if (feature==null)
feature = getAnyAttribute(obj,"name"); //$NON-NLS-1$
return feature!=null;
}
/*
public static String getLabel(EObject object) {
if (object==null)
return "";
return toDisplayName(object.eClass().getName());
}
*/
public static String toDisplayName(String anyName) {
// get rid of the "Impl" java suffix
anyName = anyName.replaceAll("Impl$", ""); //$NON-NLS-1$ //$NON-NLS-2$
String displayName = ""; //$NON-NLS-1$
boolean first = true;
char[] chars = anyName.toCharArray();
for (int i=0; i<chars.length; ++i) {
char c = chars[i];
if (Character.isUpperCase(c)) {
if (displayName.length()>0 && i+1<chars.length && !Character.isUpperCase(chars[i+1]))
displayName += " "; //$NON-NLS-1$
}
if (first) {
c = Character.toUpperCase(c);
first = false;
}
if (c=='_')
c = ' ';
displayName += c;
}
return displayName.trim();
}
@SuppressWarnings("unchecked")
public static List<EventDefinition> getEventDefinitions(Event event) {
if (event!=null) {
EStructuralFeature feature = event.eClass().getEStructuralFeature("eventDefinitions"); //$NON-NLS-1$
if (feature!=null) {
return (List<EventDefinition>) event.eGet(feature);
}
}
return new ArrayList<EventDefinition>();
}
/**
* Checks if an event has a specific event definition type defined
*
* @param event the event to be checked
* @param clazz the class of the event definition to
* @return true if the event definition is defined for this event instance, false otherwise
*/
public static boolean hasEventDefinition (Event event, Class<?> clazz) {
for (EventDefinition def : getEventDefinitions(event)) {
if (clazz.isInstance(def)) {
return true;
}
}
return false;
}
/**
* Get the first event definition for an given event and given type
*
* @param event the event
* @param clazz the event definition class
* @return the first event definition definied for this event instance
*/
public static EventDefinition getEventDefinition (Event event, Class<?> clazz) {
for (EventDefinition def : getEventDefinitions(event)) {
if (clazz.isInstance(def)) {
return def;
}
}
return null;
}
/**
* This is a slightly hacked resource set that we will be using for to solve
* the problem of loading the right resources from URLs that betray no
* information on the type of the resource.
*
* @param resourceSet
*
* @return the BPMN2ResourceSetImpl that walks around the problem indicated.
*
*/
public static Bpmn2ModelerResourceSetImpl slightlyHackedResourceSet(
ResourceSet resourceSet) {
if (resourceSet instanceof Bpmn2ModelerResourceSetImpl) {
return (Bpmn2ModelerResourceSetImpl) resourceSet;
}
Map<Object, Object> map = resourceSet.getLoadOptions();
Bpmn2ModelerResourceSetImpl result = (Bpmn2ModelerResourceSetImpl) map
.get(Bpmn2ModelerResourceSetImpl.SLIGHTLY_HACKED_KEY);
if (result == null) {
result = new Bpmn2ModelerResourceSetImpl();
map.put(Bpmn2ModelerResourceSetImpl.SLIGHTLY_HACKED_KEY, result);
}
return result;
}
/**
* Return the resource set that we should be using to load "specific" type
* of resources. The "slightlyHacked" resource set is kept in the load
* options map.
*
* @param eObj
* @return the slightly hacked resource set.
*
*/
public static Bpmn2ModelerResourceSetImpl slightlyHackedResourceSet(EObject eObj) {
return slightlyHackedResourceSet(eObj.eResource().getResourceSet());
}
public static Object resolveXSDObject(Object xsdObject) {
if (xsdObject instanceof XSDElementDeclaration) {
XSDElementDeclaration resolvedElement = ((XSDElementDeclaration)xsdObject).getResolvedElementDeclaration();
if (resolvedElement != null) xsdObject = resolvedElement;
} else if (xsdObject instanceof XSDAttributeDeclaration) {
XSDAttributeDeclaration resolvedAttribute = ((XSDAttributeDeclaration)xsdObject).getResolvedAttributeDeclaration();
if (resolvedAttribute != null) xsdObject = resolvedAttribute;
}
return xsdObject;
}
/**
* @param eObject
* @return the namespace map for the given object.
*/
@SuppressWarnings("unchecked")
static public INamespaceMap<String, String> getNamespaceMap(EObject eObject) {
if (eObject == null) {
throw new NullPointerException(
"eObject cannot be null in getNamespaceMap()"); //$NON-NLS-1$
}
INamespaceMap<String, String> nsMap = null;
// Bug 120110 - this eObject may not have a namespace map, but its
// ancestors might, so keep searching until we find one or until
// we run out of ancestors.
while (nsMap==null && eObject!=null) {
nsMap = AdapterRegistry.INSTANCE.adapt(
eObject, INamespaceMap.class);
if (nsMap==null)
eObject = eObject.eContainer();
}
if (nsMap == null) {
throw new IllegalStateException(
"INamespaceMap cannot be attached to an eObject"); //$NON-NLS-1$
}
return nsMap;
}
public static String getNamespacePrefix(EObject eObject, String namespace) {
for (EObject context = eObject; context != null; context = context
.eContainer()) {
List<String> pfxList = getNamespaceMap(context).getReverse(
namespace);
if (pfxList.size() > 0) {
return pfxList.get(0);
}
}
return null;
}
public enum Bpmn2DiagramType {
NONE("None"), //$NON-NLS-1$
PROCESS("Process"), //$NON-NLS-1$
CHOREOGRAPHY("Choreography"), //$NON-NLS-1$
COLLABORATION("Collaboration"), //$NON-NLS-1$
CONVERSATION("Conversation"); //$NON-NLS-1$
String value;
Bpmn2DiagramType(String value) {
this.value = value;
}
public static Bpmn2DiagramType fromString(String value) {
if (value != null) {
for (Bpmn2DiagramType type : Bpmn2DiagramType.values()) {
if (value.equalsIgnoreCase(type.value)) {
return type;
}
}
}
return null;
}
@Override
public String toString() {
return value;
}
}
public static Bpmn2DiagramType getDiagramType(String name) {
for (Bpmn2DiagramType t : Bpmn2DiagramType.values()) {
if (t.toString().equalsIgnoreCase(name))
return t;
}
return Bpmn2DiagramType.NONE;
}
public static DiagramEditor getDiagramEditor(EObject object) {
return getDiagramEditor(getResource(object));
}
public static DiagramEditor getDiagramEditor(Resource res) {
if (res != null) {
for (Adapter a : res.getResourceSet().eAdapters()) {
if (a instanceof DiagramEditorAdapter) {
return ((DiagramEditorAdapter)a).getDiagramEditor();
}
}
}
return null;
}
public static Bpmn2DiagramType getDiagramType(EObject object) {
if (object instanceof Diagram) {
object = BusinessObjectUtil.getBusinessObjectForPictogramElement((Diagram)object);
}
if (object instanceof BPMNDiagram)
return getDiagramType((BPMNDiagram)object);
DiagramEditor editor = getDiagramEditor(object);
return getDiagramType(editor);
}
public static Bpmn2DiagramType getDiagramType(DiagramEditor editor) {
if (editor!=null) {
Diagram diagram = editor.getDiagramTypeProvider().getDiagram();
if (diagram!=null) {
EObject object = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(diagram);
if (object instanceof BPMNDiagram)
return getDiagramType((BPMNDiagram)object);
}
}
return Bpmn2DiagramType.NONE;
}
public static Bpmn2DiagramType getDiagramType(BPMNDiagram diagram) {
if (diagram!=null && getResource(diagram)!=null) {
BPMNPlane plane = diagram.getPlane();
if (plane!=null) {
BaseElement be = plane.getBpmnElement();
if (be==null)
be = getDefaultBPMNPlaneReference(diagram);
if (be instanceof Choreography)
return Bpmn2DiagramType.CHOREOGRAPHY;
else if (be instanceof Collaboration)
return Bpmn2DiagramType.COLLABORATION;
else
// everything else (like SubProcess, etc.) belongs to a Process diagram
return Bpmn2DiagramType.PROCESS;
}
}
return Bpmn2DiagramType.NONE;
}
/**
* Return the first Process, SubProcess, AdHocSubProcess, Transaction, Collaboration,
* Choreography or SubChoreography defined in this document.
*
* @param object
* @return
*/
public static BaseElement getDefaultBPMNPlaneReference(EObject object) {
Definitions definitions = getDefinitions(object);
if (definitions!=null) {
for (RootElement re : definitions.getRootElements()) {
if ( re instanceof Process ||
re instanceof SubProcess ||
re instanceof AdHocSubProcess ||
re instanceof Transaction ||
re instanceof Collaboration ||
re instanceof Choreography ||
re instanceof SubChoreography
) {
return re;
}
}
}
return null;
}
public static String getDiagramTypeName(BPMNDiagram object) {
Bpmn2DiagramType type = getDiagramType((BPMNDiagram)object);
if (type == Bpmn2DiagramType.CHOREOGRAPHY) {
return Messages.ModelUtil_Choreograpy_Diagram;
}
else if (type == Bpmn2DiagramType.COLLABORATION) {
return Messages.ModelUtil_Collaboration_Diagram;
}
else if (type == Bpmn2DiagramType.PROCESS) {
return Messages.ModelUtil_Process_Diagram;
}
return Messages.ModelUtil_Unknown_Diagram_Type;
}
public static List<EStructuralFeature> getAnyAttributes(EObject object) {
List<EStructuralFeature> list = new ArrayList<EStructuralFeature>();
EStructuralFeature anyAttribute = ((EObject)object).eClass().getEStructuralFeature("anyAttribute"); //$NON-NLS-1$
if (anyAttribute!=null && object.eGet(anyAttribute) instanceof BasicFeatureMap) {
BasicFeatureMap map = (BasicFeatureMap)object.eGet(anyAttribute);
for (Entry entry : map) {
EStructuralFeature feature = entry.getEStructuralFeature();
list.add(feature);
}
}
return list;
}
public static EStructuralFeature getAnyAttribute(EObject object, String name) {
EStructuralFeature anyAttribute = ((EObject)object).eClass().getEStructuralFeature("anyAttribute"); //$NON-NLS-1$
if (anyAttribute!=null && object.eGet(anyAttribute) instanceof BasicFeatureMap) {
BasicFeatureMap map = (BasicFeatureMap)object.eGet(anyAttribute);
for (Entry entry : map) {
EStructuralFeature feature = entry.getEStructuralFeature();
if (feature.getName().equals(name))
return feature;
}
}
return null;
}
/**
* Removed "deprecated" annotation: ModelExtensionDescriptor.populateObject() needs this
*/
public static EStructuralFeature addAnyAttribute(EObject childObject, String name, String type, Object value) {
EPackage pkg = childObject.eClass().getEPackage();
String nsURI = pkg.getNsURI();
return addAnyAttribute(childObject, nsURI, name, type, value);
}
/**
* Removed "deprecated" annotation: ModelExtensionDescriptor.populateObject() needs this
*/
@SuppressWarnings("unchecked")
public static EStructuralFeature addAnyAttribute(EObject childObject, String namespace, String name, String type, Object value) {
EStructuralFeature attr = null;
EClass eclass = null;
if (childObject instanceof EClass) {
eclass = (EClass)childObject;
childObject = ExtendedPropertiesAdapter.getDummyObject(eclass);
}
else
eclass = childObject.eClass();
EStructuralFeature anyAttribute = eclass.getEStructuralFeature(Bpmn2Package.BASE_ELEMENT__ANY_ATTRIBUTE);
List<BasicFeatureMap.Entry> anyMap = (List<BasicFeatureMap.Entry>)childObject.eGet(anyAttribute);
if (anyMap==null)
return null;
for (BasicFeatureMap.Entry fe : anyMap) {
if (fe.getEStructuralFeature() instanceof EAttributeImpl) {
EAttributeImpl a = (EAttributeImpl) fe.getEStructuralFeature();
if (namespace.equals(a.getExtendedMetaData().getNamespace()) && name.equals(a.getName())) {
attr = a;
break;
}
}
}
// this featuremap can only hold attributes, not elements
if (type==null)
type = "E" + value.getClass().getSimpleName(); //$NON-NLS-1$
EDataType eDataType = (EDataType)ModelUtil.getEClassifierFromString(null, type);//(EDataType)EcorePackage.eINSTANCE.getEClassifier(type);
if (eDataType!=null) {
if (attr==null) {
attr = ExtendedMetaData.INSTANCE.demandFeature(namespace, name, false);
attr.setEType(eDataType);
anyMap.add( FeatureMapUtil.createEntry(attr, value) );
}
else {
EClassifier dt = attr.getEType();
if (dt==null || !eDataType.getInstanceClass().isAssignableFrom(dt.getInstanceClass()))
throw new IllegalArgumentException(
NLS.bind(
Messages.ModelUtil_Illegal_Value,
new Object[] {
childObject.eClass().getName(),
attr.getName(),
attr.getEType().getName(),
value.toString()
}
)
);
anyMap.add( FeatureMapUtil.createEntry(attr, value) );
}
}
else if (attr==null) {
attr = ExtendedMetaData.INSTANCE.demandFeature(namespace, name, false);
anyMap.add( FeatureMapUtil.createEntry(attr, value) );
}
else {
anyMap.add( FeatureMapUtil.createEntry(attr, value) );
}
return attr;
}
public static boolean isBpmnPackage(EPackage pkg) {
return pkg == Bpmn2Package.eINSTANCE || pkg == BpmnDiPackage.eINSTANCE || pkg == DcPackage.eINSTANCE || pkg == DiPackage.eINSTANCE;
}
public static EAttribute createDynamicAttribute(EPackage pkg, EObject object, String name, String type) {
if (isBpmnPackage(pkg)) {
String namespace = TargetRuntime.getDefaultRuntime().getRuntimeExtension().getTargetNamespace(Bpmn2DiagramType.NONE);
EStructuralFeature feature = ModelUtil.addAnyAttribute(object, namespace, name, type, null);
if (feature instanceof EAttribute)
return (EAttribute) feature;
throw new IllegalArgumentException(NLS.bind(Messages.ModelUtil_Illegal_EPackage_For_Attribute, pkg.getName()));
}
EClass eClass = object instanceof EClass ? (EClass)object : object.eClass();
EAttribute attr = null;
EClass docRoot = (EClass)pkg.getEClassifier("DocumentRoot"); //$NON-NLS-1$
if (docRoot==null) {
ExtendedMetaData.INSTANCE.demandPackage(pkg.getNsURI());
docRoot = ExtendedMetaData.INSTANCE.getDocumentRoot(pkg);
}
if (docRoot!=null) {
for (EStructuralFeature f : docRoot.getEStructuralFeatures()) {
if (f.getName().equals(name)) {
if (f instanceof EAttribute) {
attr = (EAttribute)f;
break;
}
return null;
}
}
}
if (type==null)
type = "EString"; //$NON-NLS-1$
EClassifier eClassifier = null;
if (type!=null) {
eClassifier = getEClassifierFromString(pkg,type);
if (eClassifier==null || !(eClassifier instanceof EDataType)) {
String message =
NLS.bind(
Messages.ModelUtil_Unknown_Attribute_Data_Type,
new Object[] {
name,
eClass.getName(),
type
}
);
MessageDialog.openError(Display.getDefault().getActiveShell(),
Messages.ModelUtil_Internal_Error,
message);
throw new IllegalArgumentException(message);
}
}
if (attr==null) {
attr = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
attr.setName(name);
attr.setEType(eClassifier);
ExtendedMetaData.INSTANCE.setFeatureKind(attr,ExtendedMetaData.ATTRIBUTE_FEATURE);
docRoot.getEStructuralFeatures().add(attr);
ExtendedMetaData.INSTANCE.setNamespace(attr, pkg.getNsURI());
ExtendedMetaData.INSTANCE.setDocumentRoot(docRoot);
}
else if (eClassifier!=null)
attr.setEType(eClassifier);
// force this feature to be serialized regardless of whether its value is the default value
attr.setUnsettable(true);
return attr;
}
public static EReference createDynamicReference(EPackage pkg, EObject object, String name, String type) {
if (isBpmnPackage(pkg)) {
throw new IllegalArgumentException(NLS.bind(Messages.ModelUtil_Illegal_EPackage_For_Reference,pkg.getName()));
}
EClass eClass = object instanceof EClass ? (EClass)object : object.eClass();
EReference ref = null;
EClass docRoot = ExtendedMetaData.INSTANCE.getDocumentRoot(pkg);
if (docRoot==null) {
ExtendedMetaData.INSTANCE.demandPackage(pkg.getNsURI());
docRoot = ExtendedMetaData.INSTANCE.getDocumentRoot(pkg);
if (docRoot==null) {
EClassifier e = pkg.getEClassifier("DocumentRoot"); //$NON-NLS-1$
if (e instanceof EClass) {
docRoot = (EClass)e;
}
}
}
if (docRoot!=null) {
for (EStructuralFeature f : docRoot.getEStructuralFeatures()) {
if (f.getName().equals(name)) {
if (f instanceof EReference) {
ref = (EReference)f;
break;
}
return null;
}
}
}
EClassifier eClassifier = null;
if (type!=null) {
eClassifier = getEClassifierFromString(pkg,type);
if (eClassifier==null || !(eClassifier instanceof EClass)) {
String message =
NLS.bind(
Messages.ModelUtil_Unknown_Reference_Object_Type,
new Object[] {
name,
eClass.getName(),
type
}
);
MessageDialog.openError(Display.getDefault().getActiveShell(),
Messages.ModelUtil_Internal_Error,
message);
throw new IllegalArgumentException(message);
}
}
if (ref==null) {
ref = EcorePackage.eINSTANCE.getEcoreFactory().createEReference();
ref.setName(name);
ref.setEType(eClassifier);
ExtendedMetaData.INSTANCE.setFeatureKind(ref,ExtendedMetaData.ATTRIBUTE_FEATURE);
docRoot.getEStructuralFeatures().add(ref);
ExtendedMetaData.INSTANCE.setNamespace(ref, pkg.getNsURI());
ExtendedMetaData.INSTANCE.setDocumentRoot(docRoot);
}
else if (eClassifier!=null)
ref.setEType(eClassifier);
return ref;
}
public static boolean removeDynamicFeature(EPackage pkg, EObject object, String name) {
if (isBpmnPackage(pkg)) {
throw new IllegalArgumentException("Can not remove dynamic feature from "+pkg.getName()); //$NON-NLS-1$
}
EStructuralFeature anyAttribute = ((EObject)object).eClass().getEStructuralFeature("anyAttribute"); //$NON-NLS-1$
if (anyAttribute!=null && object.eGet(anyAttribute) instanceof BasicFeatureMap) {
BasicFeatureMap map = (BasicFeatureMap)object.eGet(anyAttribute);
for (Entry entry : map) {
EStructuralFeature feature = entry.getEStructuralFeature();
if (feature.getName().equals(name)) {
map.remove(entry);
return true;
}
}
}
return false;
}
public static EClassifier getEClassifierFromString(EPackage pkg, String type) {
EClassifier eClassifier = null;
if (type==null) {
return EcorePackage.eINSTANCE.getEObject();
}
if (pkg!=null) {
eClassifier = pkg.getEClassifier(type);
if (eClassifier!=null)
return eClassifier;
}
eClassifier = EcorePackage.eINSTANCE.getEClassifier(type);
if (eClassifier!=null)
return eClassifier;
eClassifier = Bpmn2Package.eINSTANCE.getEClassifier(type);
if (eClassifier!=null)
return eClassifier;
eClassifier = BpmnDiPackage.eINSTANCE.getEClassifier(type);
if (eClassifier!=null)
return eClassifier;
return null;
}
public static EObject createStringWrapper(String value) {
DynamicEObjectImpl de = new DynamicEObjectImpl() {
// prevent owners from trying to resolve this thing - it's just a string!
public boolean eIsProxy() {
return false;
}
@Override
public boolean equals(Object object) {
if (object instanceof DynamicEObjectImpl) {
DynamicEObjectImpl that = (DynamicEObjectImpl) object;
if (eProxyURI()==null) {
return that.eProxyURI()==null;
}
String thisString = eProxyURI().toString();
String thatString = that.eProxyURI() == null ? null : that.eProxyURI().toString();
return thisString.equals(thatString);
}
else if (object instanceof String) {
String thisString = eProxyURI().toString();
return thisString.equals(object);
}
return super.equals(object);
}
};
de.eSetClass(EcorePackage.eINSTANCE.getEObject());
de.eSetProxyURI(URI.createURI(value));
return de;
}
public static String getStringWrapperValue(Object wrapper) {
if (wrapper instanceof DynamicEObjectImpl) {
DynamicEObjectImpl de = (DynamicEObjectImpl)wrapper;
URI uri = de.eProxyURI();
return uri.toString();
}
else if (wrapper instanceof EObject) {
return EcoreUtil.getURI((EObject)wrapper).toString();
}
return null;
}
public static boolean setStringWrapperValue(Object wrapper, String value) {
if (isStringWrapper(wrapper)) {
DynamicEObjectImpl de = (DynamicEObjectImpl)wrapper;
de.eSetProxyURI(URI.createURI(value));
return true;
}
return false;
}
public static boolean isStringWrapper(Object wrapper) {
return wrapper instanceof DynamicEObjectImpl;
}
public static boolean isElementSelected(IDiagramContainer editor, PictogramElement element) {
for (PictogramElement search : editor.getSelectedPictogramElements()) {
if (search.equals(element)) {
return true;
}
}
return false;
}
/**
* Given an EObject always returns the BPMN2 Resource that is associated with that object.
* This may involve searching for all Resources in the ResourceSet that the EObject belongs to.
* This also searches for a Resource in the object's InsertionAdapter if the object is not yet
* contained in any Resource.
*
* @param object
* @return
*/
public static Resource getResource(EObject object) {
Resource resource = null;
if (object!=null) {
resource = object.eResource();
if (resource!=null) {
ResourceSet rs = resource.getResourceSet();
if (rs!=null) {
for (Resource r : rs.getResources()) {
if (r instanceof Bpmn2Resource) {
return r;
}
}
}
}
if (resource==null) {
InsertionAdapter insertionAdapter = AdapterUtil.adapt(object, InsertionAdapter.class);
if (insertionAdapter!=null)
resource = insertionAdapter.getResource();
// TODO: can we use any of the referenced objects to find a Resource?
}
}
return resource;
}
public static Resource getResource(DiagramEditor editor) {
if (editor!=null)
return getResource(editor.getDiagramTypeProvider().getDiagram());
return null;
}
public static EObject getContainer(EObject object) {
EObject container = null;
if (object!=null) {
container = object.eContainer();
if (container==null) {
InsertionAdapter insertionAdapter = AdapterUtil.adapt(object, InsertionAdapter.class);
if (insertionAdapter!=null)
container = insertionAdapter.getObject();
}
}
return container;
}
public static Definitions getDefinitions(EObject object) {
Resource resource = getResource(object);
return getDefinitions(resource);
}
public static Definitions getDefinitions(Resource resource) {
if (resource!=null && !resource.getContents().isEmpty() && !resource.getContents().get(0).eContents().isEmpty()) {
Object defs = resource.getContents().get(0).eContents().get(0);
if (defs instanceof Definitions)
return (Definitions)defs;
}
return null;
}
public static DocumentRoot getDocumentRoot(EObject object) {
Resource resource = getResource(object);
if (resource!=null) {
EList<EObject> contents = resource.getContents();
if (!contents.isEmpty() && contents.get(0) instanceof DocumentRoot)
return (DocumentRoot)contents.get(0);
}
return null;
}
public static List<EObject> getAllReachableObjects(EObject object, EStructuralFeature feature) {
ArrayList<EObject> list = null;
if (object!=null && feature.getEType() instanceof EClass) {
Resource resource = getResource(object);
if (resource!=null) {
EClass eClass = (EClass)feature.getEType();
if (eClass != EcorePackage.eINSTANCE.getEObject()) {
list = new ArrayList<EObject>();
TreeIterator<EObject> contents = resource.getAllContents();
while (contents.hasNext()) {
Object item = contents.next();
if (eClass.isInstance(item)) {
list.add((EObject)item);
}
}
}
}
}
return list;
}
public static List<EObject> getAllReachableObjects(EObject object, EClass eClass) {
ArrayList<EObject> list = null;
Resource resource = getResource(object);
if (resource!=null) {
list = new ArrayList<EObject>();
if (eClass != EcorePackage.eINSTANCE.getEObject()) {
TreeIterator<EObject> contents = resource.getAllContents();
while (contents.hasNext()) {
Object item = contents.next();
if (eClass.isInstance(item)) {
list.add((EObject)item);
}
}
}
}
return list;
}
@SuppressWarnings("unchecked")
public static <T> List<T> getAllRootElements(Definitions definitions, final Class<T> class1) {
ArrayList<T> list = new ArrayList<T>();
if (definitions!=null) {
for (RootElement re : definitions.getRootElements()) {
if (class1.isInstance(re)) {
list.add((T) re);
}
}
}
return list;
}
@SuppressWarnings("unchecked")
public static <T> List<T> getAllObjectsOfType(Resource resource, final Class<T> class1) {
ArrayList<T> l = new ArrayList<T>();
TreeIterator<EObject> iter = resource.getAllContents();
while (iter.hasNext()) {
Object t = iter.next();
if (class1.isInstance(t)) {
l.add((T) t);
}
}
return l;
}
public static boolean compare(Object v1, Object v2) {
if (v1==null) {
if (v2!=null)
return false;
}
else if (v2==null) {
if (v1!=null)
return false;
}
return v1.equals(v2);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static EObject findNearestAncestor(EObject object, Class[] types) {
EObject ancestor = null;
if (object!=null) {
ancestor = getContainer(object);
while (ancestor!=null) {
Class type = ancestor.getClass();
for (Class t : types) {
if (t.isAssignableFrom(type))
return ancestor;
}
ancestor = getContainer(ancestor);
}
}
return ancestor;
}
@SuppressWarnings("rawtypes")
public static List<EObject> collectAncestorObjects(EObject object, String featureName, Class[] ancestorTypes) {
return collectAncestorObjects(object, featureName, ancestorTypes, null);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static List<EObject> collectAncestorObjects(EObject object, String featureName, Class[] ancestorTypes, Class[] objectTypes) {
List<EObject> values = new ArrayList<EObject>();
EObject ancestor = ModelUtil.findNearestAncestor(object, ancestorTypes);
while (ancestor!=null) {
EStructuralFeature feature = ancestor.eClass().getEStructuralFeature(featureName);
if (feature!=null && ancestor.eGet(feature) instanceof List) {
List<EObject> objects = (List<EObject>) ancestor.eGet(feature);
if (objectTypes==null) {
values.addAll(objects);
}
else {
for (EObject item : objects) {
for (Class t : objectTypes) {
if (t.isAssignableFrom(item.getClass()))
values.add(item);
}
}
}
}
ancestor = ModelUtil.findNearestAncestor(ancestor, ancestorTypes);
}
return values;
}
@SuppressWarnings("unchecked")
public static <T> List<T> getAllExtensionAttributeValues(EObject object, Class<T> clazz) {
List<T> results = new ArrayList<T>();
if (object!=null) {
EStructuralFeature evf = object.eClass().getEStructuralFeature("extensionValues"); //$NON-NLS-1$
EList<ExtensionAttributeValue> list = (EList<ExtensionAttributeValue>)object.eGet(evf);
for (ExtensionAttributeValue eav : list) {
FeatureMap fm = eav.getValue();
for (Entry e : fm) {
if (clazz.isInstance(e.getValue())) {
results.add((T)e.getValue());
}
}
}
}
return results;
}
public static List<ExtensionAttributeValue> getExtensionAttributeValues(EObject be) {
if (be instanceof Participant) {
final Participant participant = (Participant) be;
if (participant.getProcessRef() == null) {
if (participant.eContainer() instanceof Collaboration) {
Collaboration collab = (Collaboration) participant.eContainer();
if (collab.eContainer() instanceof Definitions) {
final Definitions definitions = getDefinitions(collab);
TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(definitions.eResource());
domain.getCommandStack().execute(new RecordingCommand(domain) {
@Override
protected void doExecute() {
Process process = Bpmn2ModelerFactory.create(Process.class);
participant.setProcessRef(process);
definitions.getRootElements().add(process);
ModelUtil.setID(process);
}
});
}
}
}
return participant.getProcessRef().getExtensionValues();
}
if (be instanceof BPMNDiagram) {
BPMNDiagram diagram = (BPMNDiagram) be;
BaseElement bpmnElement = diagram.getPlane().getBpmnElement();
if (bpmnElement instanceof org.eclipse.bpmn2.Process) {
return bpmnElement.getExtensionValues();
}
}
if (be instanceof BaseElement) {
return ((BaseElement) be).getExtensionValues();
}
return new ArrayList<ExtensionAttributeValue>();
}
public static void addExtensionAttributeValue(EObject object, EStructuralFeature feature, Object value) {
addExtensionAttributeValue(object, feature, value, false);
}
@SuppressWarnings("unchecked")
public static void addExtensionAttributeValue(EObject object, EStructuralFeature feature, Object value, boolean delay) {
EStructuralFeature evf = object.eClass().getEStructuralFeature("extensionValues"); //$NON-NLS-1$
EList<EObject> list = (EList<EObject>)object.eGet(evf);
if (list.size()==0) {
ExtensionAttributeValue newItem = Bpmn2ModelerFactory.create(ExtensionAttributeValue.class);
ModelUtil.setID(newItem);
FeatureMap map = newItem.getValue();
map.add(feature, value);
if (delay) {
InsertionAdapter.add(object, evf, newItem, feature, value);
}
else {
list.add(newItem);
}
}
else {
ExtensionAttributeValue oldItem = (ExtensionAttributeValue) list.get(0);
if (delay) {
InsertionAdapter.add(object, evf, oldItem, feature, value);
}
else {
FeatureMap map = oldItem.getValue();
map.add(feature, value);
}
}
}
/*
* Various model object and feature UI property methods
*/
@SuppressWarnings("rawtypes")
public static String getLabel(Object object) {
String label = ""; //$NON-NLS-1$
if (object instanceof EObject) {
EObject eObject = (EObject)object;
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(eObject);
if (adapter!=null)
label = adapter.getObjectDescriptor().getLabel(eObject);
else
label = toDisplayName( eObject.eClass().getName() );
}
else
label = object.toString();
label = label.replaceAll(" Ref$", ""); //$NON-NLS-1$ //$NON-NLS-2$
return label;
}
@SuppressWarnings("rawtypes")
public static void setLabel(EObject object, EStructuralFeature feature, String label) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null)
adapter.getFeatureDescriptor(feature).setLabel(label);
}
@SuppressWarnings("rawtypes")
public static String getLabel(EObject object, EStructuralFeature feature) {
String label = ""; //$NON-NLS-1$
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null)
label = adapter.getFeatureDescriptor(feature).getLabel(object);
else
label = toDisplayName( feature.getName() );
label = label.replaceAll(" Ref$", ""); //$NON-NLS-1$ //$NON-NLS-2$
return label;
}
@SuppressWarnings("rawtypes")
public static String getDisplayName(Object object) {
if (object instanceof EObject) {
EObject eObject = (EObject)object;
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(eObject);
if (adapter!=null) {
String text = adapter.getObjectDescriptor().getDisplayName(eObject);
if (text!=null && !text.isEmpty()) {
return text;
}
}
return getLongDisplayName(eObject);
}
return object==null ? null : object.toString();
}
@SuppressWarnings("rawtypes")
public static String getDisplayName(EObject object, EStructuralFeature feature) {
if (feature==null)
return getDisplayName(object);
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null)
return adapter.getFeatureDescriptor(feature).getDisplayName(object);
return getLongDisplayName(object, feature);
}
@SuppressWarnings("rawtypes")
public static boolean setMultiLine(EObject object, EStructuralFeature feature, boolean multiLine) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null) {
adapter.getFeatureDescriptor(feature).setMultiLine(multiLine);
return true;
}
return false;
}
@SuppressWarnings("rawtypes")
public static boolean isMultiLine(EObject object, EStructuralFeature feature) {
if (feature==null)
return false;
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null)
return adapter.getFeatureDescriptor(feature).isMultiLine(object);
return false;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Hashtable<String, Object> getChoiceOfValues(EObject object, EStructuralFeature feature) {
if (feature==null)
return null;
if (feature.getEType() instanceof EEnum) {
EEnum en = (EEnum)feature.getEType();
Hashtable<String,Object> choices = new Hashtable<String,Object>();
for (EEnumLiteral el : en.getELiterals()) {
choices.put(el.getLiteral(), el.getInstance());
}
return choices;
}
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null)
return adapter.getFeatureDescriptor(feature).getChoiceOfValues(object);
return null;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static boolean setValue(TransactionalEditingDomain domain, final EObject object, final EStructuralFeature feature, Object value) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
try {
InsertionAdapter.executeIfNeeded(object);
if (value instanceof EObject) {
// make sure the new object is added to its control first
// so that it inherits the control's Resource and EditingDomain
// before we try to change its value.
InsertionAdapter.executeIfNeeded((EObject)value);
}
if (value instanceof String && ((String) value).isEmpty()) {
if (!(feature.getDefaultValue() instanceof String))
value = null;
}
if (adapter!=null) {
if (!adapter.getFeatureDescriptor(feature).equals(value)) {
adapter.getFeatureDescriptor(feature).setValue(value);
}
}
else if (domain!=null) {
final Object v = value;
domain.getCommandStack().execute(new RecordingCommand(domain) {
@Override
protected void doExecute() {
if (object.eGet(feature) instanceof List) {
((List)object.eGet(feature)).add(v);
}
else
object.eSet(feature, v);
}
});
}
else {
if (object.eGet(feature) instanceof List) {
((List)object.eGet(feature)).add(value);
}
else
object.eSet(feature, value);
}
} catch (Exception e) {
ErrorUtils.showErrorMessage(e.getMessage());
return false;
}
return true;
}
@SuppressWarnings("rawtypes")
public static Object getValue(final EObject object, final EStructuralFeature feature) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
Object value = adapter==null ? object.eGet(feature) : adapter.getFeatureDescriptor(feature).getValue();
return value;
}
public static boolean compare(EObject object1, EObject object2, boolean similar) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object1, null);
if (adapter!=null)
return adapter.getObjectDescriptor().compare(object1, object2, similar);
return object1.equals(object2);
}
@SuppressWarnings("rawtypes")
public static boolean canEdit(EObject object, EStructuralFeature feature) {
if (feature!=null && feature.getEType() instanceof EClass) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null) {
Object result = adapter.getProperty(feature, ExtendedPropertiesAdapter.UI_CAN_EDIT);
if (result instanceof Boolean)
return ((Boolean)result);
}
if (feature instanceof EReference) {
if (((EReference)feature).isContainment())
return true;
if (Bpmn2Package.eINSTANCE.getRootElement().isSuperTypeOf((EClass)feature.getEType()))
return true;
if (feature.isMany())
return true;
return false;
}
return true;
}
return false;
}
@SuppressWarnings("rawtypes")
public static boolean canCreateNew(EObject object, EStructuralFeature feature) {
if (feature!=null && feature.getEType() instanceof EClass) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null) {
Object result = adapter.getProperty(feature, ExtendedPropertiesAdapter.UI_CAN_CREATE_NEW);
if (result instanceof Boolean)
return ((Boolean)result);
}
if (feature instanceof EReference) {
if (((EReference)feature).isContainment())
return true;
if (Bpmn2Package.eINSTANCE.getRootElement().isSuperTypeOf((EClass)feature.getEType()))
return true;
return false;
}
return true;
}
return false;
}
@SuppressWarnings("rawtypes")
public static boolean canEditInline(EObject object, EStructuralFeature feature) {
if (feature!=null && feature.getEType() instanceof EClass) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null) {
Object result = adapter.getProperty(feature, ExtendedPropertiesAdapter.UI_CAN_EDIT_INLINE);
if (result instanceof Boolean)
return ((Boolean)result);
}
}
return false;
}
@SuppressWarnings("rawtypes")
public static boolean canSetNull(EObject object, EStructuralFeature feature) {
if (feature!=null && feature.getEType() instanceof EClass) {
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null) {
Object result = adapter.getProperty(feature, ExtendedPropertiesAdapter.UI_CAN_SET_NULL);
if (result instanceof Boolean)
return ((Boolean)result);
}
return true;
}
return false;
}
@SuppressWarnings("rawtypes")
public static boolean isMultiChoice(EObject object, EStructuralFeature feature) {
if (feature==null) {
return false;
}
if (feature.getEType() instanceof EEnum) {
return true;
}
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object, feature);
if (adapter!=null) {
Object result = adapter.getProperty(feature, ExtendedPropertiesAdapter.UI_IS_MULTI_CHOICE);
if (result instanceof Boolean)
return ((Boolean)result);
}
return getChoiceOfValues(object,feature) != null;
}
/*
* Fallbacks in case a property provider does not exist
*/
public static String getLongDisplayName(EObject object) {
String objName = null;
if (object instanceof BPMNDiagram) {
Bpmn2DiagramType type = getDiagramType((BPMNDiagram)object);
if (type == Bpmn2DiagramType.CHOREOGRAPHY) {
objName = Messages.ModelUtil_Choreography_Diagram;
}
else if (type == Bpmn2DiagramType.COLLABORATION) {
objName = Messages.ModelUtil_Collaboration_Diagram;
}
else if (type == Bpmn2DiagramType.PROCESS) {
objName = Messages.ModelUtil_Process_Diagram;
}
}
if (objName==null){
objName = toDisplayName( object.eClass().getName() );
}
EStructuralFeature feature = object.eClass().getEStructuralFeature("name"); //$NON-NLS-1$
if (feature!=null) {
String name = (String)object.eGet(feature);
if (name==null || name.isEmpty())
name = NLS.bind(Messages.ModelUtil_Unnamed_Object, objName);
else
name = objName + " \"" + name + "\""; //$NON-NLS-1$ //$NON-NLS-2$
return name;
}
feature = object.eClass().getEStructuralFeature("id"); //$NON-NLS-1$
if (feature!=null) {
String id = (String)object.eGet(feature);
if (id==null || id.isEmpty())
id = Messages.ModelUtil_Unknown_Object + objName;
else
id = objName + " \"" + id + "\""; //$NON-NLS-1$ //$NON-NLS-2$
return id;
}
feature = object.eClass().getEStructuralFeature("qName"); //$NON-NLS-1$
if (feature!=null) {
Object qName = object.eGet(feature);
if (qName!=null) {
return qName.toString();
}
}
return objName;
}
public static String getLongDisplayName(EObject object, EStructuralFeature feature) {
Object value = object.eGet(feature);
if (value==null)
return ""; //$NON-NLS-1$
return value.toString();
}
public static boolean isEmpty(Object result) {
if (result == null)
return true;
if (result instanceof String)
return ((String) result).isEmpty();
return false;
}
public static void disposeChildWidgets(Composite parent) {
int i = 0;
Control[] kids = parent.getChildren();
for (Control k : kids) {
if (k instanceof Composite) {
disposeChildWidgets((Composite)k);
}
k.dispose();
++i;
}
kids = parent.getChildren();
}
/**
* Ugly hack to force layout of the entire widget tree of the property sheet page.
* @param parent
*/
public static void recursivelayout(Composite parent) {
Control[] kids = parent.getChildren();
for (Control k : kids) {
if (k.isDisposed())
Activator.logError(new SWTException("Widget is disposed.")); //$NON-NLS-1$
if (k instanceof Composite) {
recursivelayout((Composite)k);
((Composite)k).layout(true);
}
}
parent.layout(true);
}
public static DiagramEditor getEditor(EObject object) {
Resource resource = InsertionAdapter.getResource(object);
if(resource!=null)
return getEditor(resource.getResourceSet());
return null;
}
public static DiagramEditor getEditor(Resource resource) {
if(resource!=null)
return getEditor(resource.getResourceSet());
return null;
}
public static DiagramEditor getEditor(ResourceSet resourceSet) {
Iterator<Adapter> it = resourceSet.eAdapters().iterator();
while (it.hasNext()) {
Object next = it.next();
if (next instanceof DiagramEditorAdapter) {
return ((DiagramEditorAdapter)next).getDiagramEditor();
}
}
return null;
}
public static EPackage getEPackage(EStructuralFeature feature) {
EObject o = feature;
while ( o.eContainer()!=null ) {
o = o.eContainer();
if (o instanceof EPackage) {
return (EPackage)o;
}
}
return null;
}
/**
* This is a workaround to deal with FormalExpressions: if the "body" of an expression
* is null, the default FormalExpression.getBody() method returns the string "null"
* which is not exactly what we want! We need to know if the body is actually null,
* or if it contains the string "null".
*
* @param expression
* @return
*/
public static String getExpressionBody(FormalExpression expression) {
String body = null;
if (expression.getMixed() != null && !expression.getMixed().isEmpty()) {
StringBuilder result = new StringBuilder();
boolean isNull = true;
for (FeatureMap.Entry cur : expression.getMixed()) {
switch (cur.getEStructuralFeature().getFeatureID()) {
case XMLTypePackage.XML_TYPE_DOCUMENT_ROOT__CDATA:
case XMLTypePackage.XML_TYPE_DOCUMENT_ROOT__TEXT:
if (cur.getValue()!=null) {
isNull = false;
result.append(cur.getValue());
}
break;
default:
break;
}
}
if (!isNull)
body = result.toString();
}
return body;
}
public static List<Tuple<EObject,EObject>> findDuplicateIds(Resource resource) {
List<Tuple<EObject,EObject>> list = new ArrayList<Tuple<EObject,EObject>>();
Definitions definitions = ModelUtil.getDefinitions(resource);
TreeIterator<EObject> iter1 = definitions.eAllContents();
HashSet<EObject> map = new HashSet<EObject>();
while (iter1.hasNext()) {
EObject o1 = iter1.next();
EStructuralFeature id1Feature = o1.eClass().getEIDAttribute();
if (id1Feature!=null && !map.contains(o1)) {
TreeIterator<EObject> iter2 = definitions.eAllContents();
map.add(o1);
String id1 = (String)o1.eGet(id1Feature);
while (iter2.hasNext()) {
EObject o2 = iter2.next();
EStructuralFeature id2Feature = o2.eClass().getEIDAttribute();
if (id2Feature!=null && o1!=o2 && !map.contains(o2)) {
String id2 = (String)o2.eGet(id2Feature);
if (id1!=null && !id1.isEmpty() && id2!=null && !id2.isEmpty()) {
if (id1.equals(id2)) {
list.add( new Tuple<EObject,EObject>(o1,o2) );
}
}
}
}
}
}
return list;
}
public static boolean isParticipantBand(Participant participant) {
Resource resource = ModelUtil.getResource(participant);
for (ChoreographyActivity ca : ModelUtil.getAllObjectsOfType(resource, ChoreographyActivity.class)) {
if (ca.getParticipantRefs().contains(participant)) {
return true;
}
}
return false;
}
}