blob: 9632b3f8ceb2beb39e7a38768abdabc7be243a77 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.bpel.ui.util;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.eclipse.bpel.common.extension.model.ExtensionMap;
import org.eclipse.bpel.common.ui.ImageUtils;
import org.eclipse.bpel.common.ui.details.viewers.ComboViewer;
import org.eclipse.bpel.common.ui.details.widgets.DecoratedLabel;
import org.eclipse.bpel.common.ui.markers.ModelMarkerUtil;
import org.eclipse.bpel.model.BPELFactory;
import org.eclipse.bpel.model.BPELPackage;
import org.eclipse.bpel.model.Catch;
import org.eclipse.bpel.model.CompensateScope;
import org.eclipse.bpel.model.CorrelationSet;
import org.eclipse.bpel.model.CorrelationSets;
import org.eclipse.bpel.model.Flow;
import org.eclipse.bpel.model.ForEach;
import org.eclipse.bpel.model.Invoke;
import org.eclipse.bpel.model.OnEvent;
import org.eclipse.bpel.model.PartnerLink;
import org.eclipse.bpel.model.PartnerLinks;
import org.eclipse.bpel.model.Process;
import org.eclipse.bpel.model.Scope;
import org.eclipse.bpel.model.Sequence;
import org.eclipse.bpel.model.Variable;
import org.eclipse.bpel.model.Variables;
import org.eclipse.bpel.model.adapters.AdapterRegistry;
import org.eclipse.bpel.model.messageproperties.MessagepropertiesPackage;
import org.eclipse.bpel.model.messageproperties.PropertyAlias;
import org.eclipse.bpel.model.partnerlinktype.PartnerlinktypePackage;
import org.eclipse.bpel.model.util.BPELUtils;
import org.eclipse.bpel.names.NCNameWordDetector;
import org.eclipse.bpel.runtimes.IBPELModuleFacetConstants;
import org.eclipse.bpel.ui.BPELEditor;
import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.IBPELUIConstants;
import org.eclipse.bpel.ui.Messages;
import org.eclipse.bpel.ui.Policy;
import org.eclipse.bpel.ui.adapters.BPELUIAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIExtensionAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIMessagePropertiesAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIPartnerLinkTypeAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIWSDLAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIWSILAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIXSDAdapterFactory;
import org.eclipse.bpel.ui.adapters.IContainer;
import org.eclipse.bpel.ui.adapters.ILabeledElement;
import org.eclipse.bpel.ui.adapters.INamedElement;
import org.eclipse.bpel.ui.bpelactions.AbstractBPELAction;
import org.eclipse.bpel.ui.dialogs.NamespaceMappingDialog;
import org.eclipse.bpel.ui.editparts.BPELEditPart;
import org.eclipse.bpel.ui.editparts.FlowEditPart;
import org.eclipse.bpel.ui.editparts.InvokeEditPart;
import org.eclipse.bpel.ui.editparts.LinkEditPart;
import org.eclipse.bpel.ui.editparts.ScopeEditPart;
import org.eclipse.bpel.ui.editparts.StartNodeEditPart;
import org.eclipse.bpel.ui.editparts.borders.GradientBorder;
import org.eclipse.bpel.ui.editparts.util.OverlayCompositeImageDescriptor;
import org.eclipse.bpel.ui.extensions.ActionDescriptor;
import org.eclipse.bpel.ui.extensions.BPELUIRegistry;
import org.eclipse.bpel.ui.uiextensionmodel.ActivityExtension;
import org.eclipse.bpel.ui.uiextensionmodel.UiextensionmodelPackage;
import org.eclipse.bpel.validator.EmfModelQuery;
import org.eclipse.bpel.wsil.model.inspection.InspectionPackage;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicEList;
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.EClass;
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.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.gef.AccessibleEditPart;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.Tool;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.WSDLPackage;
import org.eclipse.wst.wsdl.util.WSDLResourceImpl;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDPackage;
/**
* BPELUtil is a place to put *static* helper methods for the BPEL editor.
*
* Note that helpers which have specifically to do with accessing model objects are
* usually found in the ModelHelper class.
*/
public class BPELUtil {
private static final Variable[] EMPTY_VARIABLE_ARRAY = new Variable[0];
private static final PartnerLink[] EMPTY_PARTNERLINK_ARRAY = new PartnerLink[0];
private static final CorrelationSet[] EMPTY_CORRELATIONSET_ARRAY = new CorrelationSet[0];
/**
* This global variable stores the path of the last WSDL file selected with
* a WorkbenchFileSelectionDialog.
*/
public static IPath lastWSDLFilePath = null;
/**
* Global variable storing the path of the last BPEL file selected
*/
public static IPath lastBPELFilePath = null;
/**
* Global variable storing the path of the last XSD file selected
*/
public static IPath lastXSDFilePath;
static {
AdapterRegistry.INSTANCE.registerAdapterFactory(
BPELPackage.eINSTANCE, BPELUIAdapterFactory.getInstance());
AdapterRegistry.INSTANCE.registerAdapterFactory(
WSDLPackage.eINSTANCE, BPELUIWSDLAdapterFactory.getInstance());
AdapterRegistry.INSTANCE.registerAdapterFactory(
PartnerlinktypePackage.eINSTANCE, BPELUIPartnerLinkTypeAdapterFactory.getInstance());
AdapterRegistry.INSTANCE.registerAdapterFactory(
XSDPackage.eINSTANCE, BPELUIXSDAdapterFactory.getInstance());
AdapterRegistry.INSTANCE.registerAdapterFactory(
MessagepropertiesPackage.eINSTANCE, BPELUIMessagePropertiesAdapterFactory.getInstance());
AdapterRegistry.INSTANCE.registerAdapterFactory(
UiextensionmodelPackage.eINSTANCE, BPELUIExtensionAdapterFactory.getInstance());
AdapterRegistry.INSTANCE.registerAdapterFactory(
InspectionPackage.eINSTANCE, BPELUIWSILAdapterFactory.getInstance() );
}
/**
* Register adapter factory for the given EClass.
*
* @param key
* @param factory
*/
public static void registerAdapterFactory(EClass key, AdapterFactory factory) {
AdapterRegistry.INSTANCE.registerAdapterFactory(key,factory);
}
public static void registerAdapterFactory(EPackage key, AdapterFactory factory) {
AdapterRegistry.INSTANCE.registerAdapterFactory(key, factory);
}
static Class<?> adapterInterface ( Object type ) {
if (type instanceof Class) {
return (Class) type;
}
if (type instanceof String) {
try {
return Class.forName((String)type);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
throw new RuntimeException("Adapter type " + type + " is not understood."); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* @param <T>
* @param target
* @param clazz
* @return the adapted interface or object
*/
public static <T extends Object> T adapt ( Object target, Class<T> clazz) {
return AdapterRegistry.INSTANCE.adapt(target, clazz);
}
/**
* This method tries the registered adapter factories one by one, returning
* the first non-null result it gets. If none of the factories can adapt
* the result, it returns null.
* @param target target object
* @param type type of the adapter to find
* @return the adapter for the target.
*/
public static Object adapt (Object target, Object type) {
return AdapterRegistry.INSTANCE.adapt(target, type);
}
/**
* Create an adapter for the given target of the given type.
* In addition, pass a context object to the adapter(s) of the target.
*
* The idea is that some adapters can be stateful and depend not only
* on the objects that they wrap, but also on some other context that is needed
* to completely and correctly implement the interface for which the adaptor is
* needed.
*
* Adapters that are stateless, should ignore any notifications sent to them.
*
* @param target the target object
* @param type the type it wants to adapt to
* @param context the context object
*
* @return the adapter
*/
public static Object adapt (Object target, Object type, Object context) {
return AdapterRegistry.INSTANCE.adapt(target, type,context);
}
/**
* Returns the effective EClass for a custom activity (action).
*/
public static EClass getEClassFor(Object target) {
if (target instanceof Invoke) {
ActionDescriptor[] descriptors = BPELUIRegistry.getInstance().getActionDescriptors();
for( ActionDescriptor descriptor : descriptors ) {
AbstractBPELAction action = descriptor.getAction();
if (action.isInstanceOf(target)) {
return action.getModelType();
}
}
}
if (!(target instanceof EObject)) {
return null;
}
return ((EObject)target).eClass();
}
public static boolean isCustomActivity(Object target) {
if (target instanceof Invoke) {
ActionDescriptor[] descriptors = BPELUIRegistry.getInstance().getActionDescriptors();
for( ActionDescriptor descriptor : descriptors ) {
AbstractBPELAction action = descriptor.getAction();
if (action.getModelType() == BPELPackage.eINSTANCE.getInvoke()) continue;
if (action.isInstanceOf(target)) {
return true;
}
}
}
return false;
}
public static boolean isBPELAction(EClass target) {
ActionDescriptor[] descriptors = BPELUIRegistry.getInstance().getActionDescriptors();
for( ActionDescriptor descriptor : descriptors ) {
AbstractBPELAction action = descriptor.getAction();
if (action.getModelType() == target) {
return true;
}
}
return false;
}
/**
* Creates a new instance of clazz using the EFactory of the EPackage clazz belongs to.
*/
public static EObject createEObject(EClass clazz) {
return clazz.getEPackage().getEFactoryInstance().create(clazz);
}
// This is a hack to bundle the result of a cloneSubtree with enough state to undo/redo
// the extension map changes it caused.
public static class CloneResult {
/** The result of the clone */
public EObject targetRoot;
Map<EObject,EObject> targetMap;
Map<EObject,EObject> targetMapAdditions = new HashMap<EObject,EObject>();
/**
* Undo ... ?
*/
public void undo() {
for (EObject next : this.targetMapAdditions.keySet()) {
this.targetMap.remove(next);
}
}
/**
* Redo ... ?
*/
public void redo() {
for (EObject key : this.targetMapAdditions.keySet()) {
this.targetMap.put(key, this.targetMapAdditions.get(key));
}
}
}
// This helper is used by the cloneSubtree() method.
protected static void cloneSubtreeHelper (EObject source, Map<EObject,EObject> sourceMap, Map<EObject,EObject> targetMap,
Map<EObject,EObject> copyMap, CloneResult result)
{
EObject targetObject = createEObject(source.eClass());
copyMap.put(source, targetObject);
if (sourceMap != null && sourceMap.containsKey(source)) {
EObject sourceExtension = sourceMap.get(source);
EObject targetExtension = createEObject(sourceExtension.eClass());
copyMap.put(sourceExtension, targetExtension);
for (TreeIterator<?> it2 = sourceExtension.eAllContents(); it2.hasNext(); ) {
EObject source2 = (EObject)it2.next();
EObject target2 = createEObject(source2.eClass());
copyMap.put(source2, target2);
}
targetMap.put(targetObject, targetExtension);
result.targetMapAdditions.put(targetObject, targetExtension);
}
}
/**
* Clones an EObject and all EObjects contained directly or indirectly within it. All
* cloned objects possessing an extension in the sourceMap will also have their extensions
* cloned into the targetMap. Containment references and other references to any of the
* cloned object(s) will be fixed up to point into the target objects. Any references to
* non-cloned objects will be copied as-is in the cloned objects.
*
* NOTE: This method relies on BPELUtil.createEObject() knowing how to create new instances
* of the EClasses of all copied objects (i.e. objectFactories must contain the necessary
* EFactory instances for everything copied by this method).
*
* @param source The root of the source subtree to clone.
* @param sourceMap The extension map containing source extensions of cloned objects.
* @param targetMap The extension map in which cloned extensions should be recorded.
* @return a CloneResult containing the root of the target subtree, which can be used
* for undo/redo.
*/
@SuppressWarnings("nls")
public static CloneResult cloneSubtree (EObject source, Map<EObject,EObject> sourceMap, Map<EObject,EObject> targetMap) {
HashMap<EObject,EObject> copyMap = new HashMap<EObject,EObject>();
CloneResult result = new CloneResult();
result.targetMap = targetMap;
// (1) Create target objects for each EObject in the containment subtree of source.
// If the source object has an extension in sourceMap, create copies of the extension
// and its containment tree as well.
// NOTE: we can NOT just recursively call cloneSubtree for the extension, it wouldn't
// work with fixing up references. We have to iterate its eAllContents also here.
cloneSubtreeHelper(source, sourceMap, targetMap, copyMap, result);
for (TreeIterator<?> it = source.eAllContents(); it.hasNext(); ) {
EObject sourceObject = (EObject)it.next();
cloneSubtreeHelper(sourceObject, sourceMap, targetMap, copyMap, result);
}
// (2) Copy the features from each cloned source object to the corresponding target
// object. As we copy, we replace any references to cloned source objects with
// references to the corresponding target objects--but references to non-cloned
// objects are copied as-is.
for (Map.Entry<EObject,EObject> entry : copyMap.entrySet() ) {
EObject sourceObject = entry.getKey();
EObject targetObject = entry.getValue();
if (sourceObject.eClass() != targetObject.eClass()) {
throw new IllegalStateException("Source and target objects are not of the same class after cloning.");
}
if (Policy.DEBUG) {
System.out.println("copying a "+sourceObject.eClass().getName()); //$NON-NLS-1$
}
for ( EStructuralFeature feature : sourceObject.eClass().getEAllStructuralFeatures()) {
// special cases first.
if (!feature.isChangeable()) {
if (Policy.DEBUG) System.out.println(" *** skipping unchangeable feature "+feature); //$NON-NLS-1$
continue;
}
if (feature.isUnsettable() && !targetObject.eIsSet(feature)) {
if (Policy.DEBUG) System.out.println(" unsetting feature "+feature.getName()); //$NON-NLS-1$
targetObject.eUnset(feature);
continue;
}
Object value = sourceObject.eGet(feature);
boolean treatAsReference = (feature instanceof EReference);
if (treatAsReference) {
if (feature.isMany()) {
// list of references.
EList<Object> newValues = new BasicEList<Object>();
if (Policy.DEBUG) System.out.println(" copying multi-reference feature "+feature.getName()+":"); //$NON-NLS-1$ //$NON-NLS-2$
for (Iterator<?> it3 = ((Collection)value).iterator(); it3.hasNext(); ) {
Object oldValue = it3.next();
Object newValue = (oldValue==null ? null : copyMap.get(oldValue));
if (newValue == null) {
newValue = oldValue;
}
if (Policy.DEBUG) System.out.println("+ (oldValue="+oldValue+" newValue="+newValue+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
newValues.add(newValue);
}
targetObject.eSet(feature, newValues);
} else {
// single reference.
Object newValue = (value==null? null : copyMap.get(value));
if (newValue == null) {
newValue = value;
}
if (Policy.DEBUG) System.out.println(" copying reference feature "+feature.getName() //$NON-NLS-1$
+" (value="+value+" newValue="+newValue+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
targetObject.eSet(feature, newValue);
}
} else {
/** In case of a DOM Node and the "element" feature, we simply clone the result */
if (value instanceof org.w3c.dom.Node && "element".equals(feature.getName())) {
org.w3c.dom.Node e = (org.w3c.dom.Node)value;
value = e.cloneNode(true);
}
// non-reference attribute. just copy the value
if (Policy.DEBUG) System.out.println(" copying attr feature "+feature.getName()+" (value="+value+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
targetObject.eSet(feature, value);
}
}
}
result.targetRoot = copyMap.get(source);
return result;
}
/**
* Convenience formatting methods.
*/
public static String formatString(String format, String arg1) {
return MessageFormat.format(format, new Object[] { arg1 });
}
public static String formatString(String format, String arg1, String arg2) {
return MessageFormat.format(format, new Object[] { arg1, arg2 });
}
/**
* strips out invalid characters to conform to QName specs.
* If the resulting name is null, returns "bpel" as a valid QName
* to guarantee that something valid is returned.
*
* TODO: This has to be a valid NCName ...
*
* @param str
*
* @return
*/
public static String generateValidName(String str) {
StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
if (str != null) {
for(char ch : str.trim().toCharArray()) {
int destLength = result.length();
if (((destLength == 0) && (Character.isLetter(ch) || ch == '_'))
|| ((destLength > 0) && Character.isJavaIdentifierPart(ch))) {
result.append(ch);
}
}
}
if (result.length() == 0)
result.append(IBPELUIConstants.EXTENSION_BPEL);
return result.toString();
}
/**
* Helper that traverses the IContainer hierarchy of the given modelObject in depth
* first fashion and applies the given visitor to each node.
*
* DO NOT USE THIS for anything that must see "all" model objects (including implicit
* sequences, for example). Use TreeIterator modelObject.eAllContents() for that.
*/
public static void visitModelDepthFirst(Object modelObject, IModelVisitor visitor) {
if (visitor.visit(modelObject)) {
IContainer container = BPELUtil.adapt(modelObject, IContainer.class);
if (container != null) {
for (Iterator it = container.getChildren(modelObject).iterator(); it.hasNext(); ) {
visitModelDepthFirst(it.next(), visitor);
}
}
// TODO: Make this go away
if (modelObject instanceof Flow) {
// Hack: also visit the links of a flow!
Flow flow = (Flow)modelObject;
for (Iterator it = FlowLinkUtil.getFlowLinks(flow).iterator(); it.hasNext(); ) {
visitModelDepthFirst(it.next(), visitor);
}
}
}
}
private static class NameUnusedVisitor implements IModelVisitor {
private boolean unused = true;
private final String candidateName;
private final Collection<EObject> ignoreObjects;
NameUnusedVisitor(String candidateName, Collection<EObject> ignoreObjects) {
this.candidateName = candidateName;
if (ignoreObjects == null) ignoreObjects = Collections.emptySet();
this.ignoreObjects = ignoreObjects;
}
@Override
public boolean visit(Object child) {
if (!this.ignoreObjects.contains(child)) {
INamedElement namedElement = BPELUtil.adapt(child, INamedElement.class);
if (namedElement != null) {
String name = namedElement.getName(child);
if ((name != null) && (name.compareToIgnoreCase(this.candidateName) == 0))
this.unused = false;
}
}
return true;//unused;
}
public boolean isUnused() {
return this.unused;
}
}
/**
* checks if a name is available for use within the given process (i.e. if this name
* were added within the modelRoot, would it be unique).
*/
public static boolean isNameUnused(EObject modelRoot, String candidateName, Collection ignoreObjects) {
NameUnusedVisitor visitor = new NameUnusedVisitor(candidateName, ignoreObjects);
for (TreeIterator<EObject> it = modelRoot.eAllContents(); it.hasNext(); ) {
visitor.visit(it.next());
if (visitor.isUnused() == false) return false;
}
return true;
}
/**
* return a mangled name (based on the given hint) which is unique in the given process.
*/
public static String getUniqueModelName(EObject context, String hint, Collection ignoreObjects) {
return getUniqueModelName2(context, hint, ignoreObjects);
}
/**
* return a mangled name (based on the given hint) which is unique in the given WSDL definition.
*/
public static String getUniqueModelName (Definition definition, String hint, Collection ignoreObjects) {
return getUniqueModelName2(definition, hint, ignoreObjects);
}
protected static String getUniqueModelName2 (EObject modelRoot, String hint, Collection ignoreObjects) {
// first try it exactly as hinted.
String result = BPELUtil.generateValidName((hint==null)?"":hint.trim()); //$NON-NLS-1$
if (isNameUnused(modelRoot, result, ignoreObjects)) return result;
// go back to the first non-digit
int digitPos = result.length()-1;
while (digitPos >= 0 && Character.isDigit(result.charAt(digitPos))) digitPos--;
digitPos++; // move back to the digit
String nameWithoutNum = result.substring(0, digitPos);
// try increasing numbers until one is accepted.
for (int num = 1; ; num++) {
result = nameWithoutNum+String.valueOf(num);
if (isNameUnused(modelRoot, result, ignoreObjects)) return result;
}
}
public static String generateUniqueModelName (EObject context, String hint, EObject model) {
if (hint == null || "".equals(hint)) { //$NON-NLS-1$
ILabeledElement element = BPELUtil.adapt(model, ILabeledElement.class);
hint = (element != null) ? element.getTypeLabel(model) : ""; //$NON-NLS-1$
}
return BPELUtil.getUniqueModelName(context, hint, Collections.singletonList(model));
}
public static String getFilenameFromUri(String uri) {
if (uri == null) return Messages.BPELUtil__unknown_URI__54;
// Hack. Why aren't we just using URI objects?
int idx = Math.max(uri.lastIndexOf("/"), uri.lastIndexOf("\\")); //$NON-NLS-1$ //$NON-NLS-2$
return (idx >= 0)? uri.substring(idx+1) : uri;
}
/**
* Converts the first letter of the target String to upper case.
* @param target
* @return the name with the first letter uppercased.
*/
public static String upperCaseFirstLetter (String target) {
if (target.length() < 1) {
return target;
}
StringBuilder buf = new StringBuilder (target.length());
buf.append(target.substring(0, 1).toUpperCase());
buf.append(target.substring(1, target.length()));
return buf.toString();
}
/**
* Converts the first letter of the target String to lower case.
*/
public static String lowerCaseFirstLetter(String target) {
if (target.length() < 1) {
return target;
}
StringBuffer buf = new StringBuffer(target.length());
buf.append(target.substring(0, 1).toLowerCase());
buf.append(target.substring(1, target.length()));
return buf.toString();
}
/**
* Returns all of the PropertyAlias objects from WSDL files in the same ResourceSet as
* the resource containing messageType, which are aliases for messageType.
*/
public static List<PropertyAlias> getPropertyAliasesForMessageType(Message messageType) {
List<PropertyAlias> aliases = new ArrayList<PropertyAlias>();
Resource resource = messageType.eResource();
if (resource == null) {
return aliases;
}
ResourceSet resourceSet = resource.getResourceSet();
for (Iterator<Resource> it = resourceSet.getResources().iterator(); it.hasNext(); ) {
resource = it.next();
// TODO: this is a hack. Why is there no WSDLResource interface??
if (resource instanceof WSDLResourceImpl) {
for (TreeIterator<EObject> treeIt = resource.getAllContents(); treeIt.hasNext(); ) {
EObject object = treeIt.next();
if (object instanceof PropertyAlias) {
PropertyAlias alias = (PropertyAlias)object;
if (messageType.equals(alias.getMessageType()))
aliases.add(alias);
}
}
}
}
return aliases;
}
// Creates an implicit sequence with a name that is unique in the editor's process.
// Note that an ActivityExtension is created and inserted in the extension map,
// but the implicit sequence itself should be inserted in the model by the caller.
public static Sequence createImplicitSequence (Process process, ExtensionMap extensionMap) {
Sequence impSeq = BPELFactory.eINSTANCE.createSequence();
ModelHelper.createExtensionIfNecessary(extensionMap, impSeq);
Collection ignoreObjects = Collections.singletonList(impSeq);
if (ModelHelper.isSpecCompliant(process)) {
impSeq.setName(getUniqueModelName(process, Messages.BPELUtil_Sequence_1, ignoreObjects));
} else {
impSeq.setName(getUniqueModelName(process, Messages.BPELUtil_HiddenSequence_2, ignoreObjects));
((ActivityExtension)ModelHelper.getExtension(impSeq)).setImplicit(true);
}
// TODO: also give sequence a unique ID marked as implicit!
return impSeq;
}
public static TreeIterator nodeAndAllContents(final EObject node) {
final TreeIterator<EObject> allContents = node.eAllContents();
return new TreeIterator() {
boolean didNode = false;
@Override
public void prune() {
// TODO: This won't work when calling on the first item.
if (!this.didNode) throw new IllegalStateException();
allContents.prune();
}
@Override
public boolean hasNext() {
if (this.didNode) return allContents.hasNext();
return node != null;
}
@Override
public Object next() {
if (this.didNode) return allContents.next();
this.didNode = true; return node;
}
@Override
public void remove() {
// This won't work when calling on the first item.
if (!this.didNode) throw new IllegalStateException();
allContents.remove();
}
};
}
private static class RefreshActionVisitor implements IModelVisitor {
private final GraphicalViewer viewer;
public RefreshActionVisitor(GraphicalViewer viewer) {
this.viewer = viewer;
}
@Override
public boolean visit(Object child) {
EditPart ep = (EditPart) this.viewer.getEditPartRegistry().get(child);
if (ep != null && ep instanceof BPELEditPart) {
IFigure fig = ((BPELEditPart)ep).getContentPane();
if (fig != null) {
((BPELEditPart)ep).regenerateVisuals();
ep.refresh();
}
}
if(ep instanceof LinkEditPart){
ep.refresh();
}
return true;//unused;
}
}
/**
* refreshes all the editparts of the process. Useful for changing layouts etc
*/
public static void regenerateVisuals(Process process, GraphicalViewer viewer) {
RefreshActionVisitor visitor = new RefreshActionVisitor(viewer);
visitModelDepthFirst(process, visitor);
return;
}
/**
* The policy for whether a BPELEditPart's edges should be hilighted or not. This one defers
* to the active tool if it is an IHilightControllingTool and says no otherwise.
*/
public static boolean shouldHilightEdges(EditDomain domain, EObject modelObject) {
Tool tool = domain.getActiveTool();
if (tool instanceof IHilightControllingTool) {
return ((IHilightControllingTool)tool).hilightModelTarget(modelObject);
}
return false;
}
/**
* Used to determine the type of pattern to paint a container in the Process.
* Because the nesting of containers is confusing, we want to draw nice gradients
* to help the user.
* 1 and 3 return values mean solid fill.
* 0 and 2 mean gradient fills.
*/
public static int getRepaintFillType(IFigure fig) {
int depth = 0;
IFigure parent = fig.getParent();
while (parent != null) {
if (parent != null && parent.getBorder() != null && parent.getBorder() instanceof GradientBorder) {
depth++;
}
parent = parent.getParent();
}
return depth % 4;
}
public static void sortFlowList(List<FlowEditPart> listOfFlowEditParts) {
List<FlowEditPart> result = listOfFlowEditParts;
int resultSize = result.size();
for (int i = 0; i<resultSize; i++) {
for (int j = i+1; j<resultSize; j++) {
Flow flow1 = (Flow)(result.get(i)).getModel();
Flow flow2 = (Flow)(result.get(j)).getModel();
Flow[] parents = FlowLinkUtil.getParentFlows(flow2);
for( Flow parent : parents ) {
if (parent == flow1) {
// flow2 must be layed out before flow1 so its size will be known!
FlowEditPart temp = result.get(i);
result.set(i, result.get(j));
result.set(j, temp);
}
}
}
}
}
/**
* Refresh the given ComboViewer, and also make sure selectedObject is selected in it.
*/
public static void refreshCombo(ComboViewer viewer, Object selectedObject) {
viewer.refresh();
String s = ((ILabelProvider)viewer.getLabelProvider()).getText(selectedObject);
viewer.getCombo().setText(s);
}
/**
* Helper method to calculate the width of a button.
* This is necessary for internationalization and accessibility.
* Returned value is the calculated width or defaultSize, whichever
* is larger.
*/
public static int calculateButtonWidth(Widget widget, int defaultSize){
GC gc;
int width = 0;
if (widget instanceof Button) {
Button w = (Button)widget;
gc = new GC(w);
gc.setFont(w.getFont());
width = gc.textExtent(w.getText()).x + 17;
gc.dispose();
return Math.max(width, defaultSize);
}
return defaultSize;
}
public static String getMaxLengthString(String strings[]) {
int max = -1;
int index = -1;
for (int i = 0; i < strings.length; i++) {
if (strings[i].length() > max) {
max = strings[i].length();
index = i;
}
}
if (index >= 0) return strings[index];
return ""; //$NON-NLS-1$
}
/**
* Helper method to calculate the width of a CLabel.
* This is necessary for internationalization and accessibility.
*
* Returned value is the calculated width or defaultSize, whichever
* is larger.
*/
public static int calculateLabelWidth(Widget widget, int defaultSize){
GC gc;
int width = 0;
if (widget instanceof CLabel) {
CLabel w = (CLabel)widget;
gc = new GC(w);
gc.setFont(w.getFont());
width = gc.textExtent(w.getText()).x + 17;
gc.dispose();
return Math.max(width, defaultSize);
}
if (widget instanceof DecoratedLabel) {
DecoratedLabel w = (DecoratedLabel)widget;
gc = new GC(w);
gc.setFont(w.getFont());
width = gc.textExtent(w.getText()).x + 17;
gc.dispose();
return Math.max(width, defaultSize);
}
if (widget instanceof Label) {
Label w = (Label)widget;
gc = new GC(w);
gc.setFont(w.getFont());
width = gc.textExtent(w.getText()).x + 5;
gc.dispose();
return Math.max(width, defaultSize);
}
return defaultSize;
}
public static IFile getFileFromURI(URI uri) {
if (uri.isFile()) {
return getFileFromDeviceURI(uri);
}
return getFileFromPlatformURI(uri);
}
public static IFile getFileFromDeviceURI(URI uri) {
String device = uri.device();
Iterator pathIt = uri.segmentsList().iterator();
StringBuffer path = new StringBuffer();
while (pathIt.hasNext()) {
path.append("/" + pathIt.next()); //$NON-NLS-1$
}
return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(device, path.toString()));
}
public static IFile getFileFromPlatformURI(URI uri) {
String [] segs = uri.segments();
IPath path = null;
// start at 1 to skip resource
for (int i = 1; i< segs.length; i++) {
if (path == null) {
path = new Path(segs[i]);
} else {
path = path.append(segs[i]);
}
}
return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
}
/**
* Function to return a platform URI from a standard hierarchital URI.
* Normally we can use URI.createPlatformURI, but that function always assumes
* that it is non-platform
*/
public static URI getPlatformURI(URI uri) {
String str = uri.toString();
if (str.startsWith("platform:")) return uri; //$NON-NLS-1$
return URI.createPlatformResourceURI(uri.toString());
}
/* external fault handler helpers */
public static boolean getShowFaultHandler(EditPart part) {
if (part instanceof ScopeEditPart)
return ((ScopeEditPart)part).getShowFaultHandler();
else if (part instanceof InvokeEditPart)
return ((InvokeEditPart)part).getShowFaultHandler();
else if (part instanceof StartNodeEditPart)
return ((StartNodeEditPart)part).getShowFaultHandler();
return false;
}
public static void setShowFaultHandler(EditPart part, boolean show) {
if (part instanceof ScopeEditPart)
((ScopeEditPart)part).setShowFaultHandler(show);
else if (part instanceof InvokeEditPart)
((InvokeEditPart)part).setShowFaultHandler(show);
else if (part instanceof StartNodeEditPart)
((StartNodeEditPart)part).setShowFaultHandler(show);
}
/* external compensation handler helpers */
public static boolean getShowCompensationHandler(EditPart part) {
if (part instanceof ScopeEditPart)
return ((ScopeEditPart)part).getShowCompensationHandler();
else if (part instanceof InvokeEditPart)
return ((InvokeEditPart)part).getShowCompensationHandler();
return false;
}
public static boolean getShowTerminationHandler(EditPart part) {
if (part instanceof ScopeEditPart)
return ((ScopeEditPart)part).getShowTerminationHandler();
return false;
}
public static void setShowCompensationHandler(EditPart part, boolean show) {
if (part instanceof ScopeEditPart)
((ScopeEditPart)part).setShowCompensationHandler(show);
else if (part instanceof InvokeEditPart)
((InvokeEditPart)part).setShowCompensationHandler(show);
}
public static void setShowTerminationHandler(EditPart part, boolean show) {
if (part instanceof ScopeEditPart)
((ScopeEditPart)part).setShowTerminationHandler(show);
}
/* external event handler helpers */
public static boolean getShowEventHandler(EditPart part) {
if (part instanceof ScopeEditPart)
return ((ScopeEditPart)part).getShowEventHandler();
else if (part instanceof StartNodeEditPart)
return ((StartNodeEditPart)part).getShowEventHandler();
return false;
}
public static void setShowEventHandler(EditPart part, boolean show) {
if (part instanceof ScopeEditPart)
((ScopeEditPart)part).setShowEventHandler(show);
else if (part instanceof StartNodeEditPart)
((StartNodeEditPart)part).setShowEventHandler(show);
}
/**
* Returns the extension file of the given BPEL file.
*/
public static IFile getBPELEXFile(IFile bpelFile) {
IPath path = bpelFile.getFullPath().removeFileExtension().addFileExtension(IBPELUIConstants.EXTENSION_MODEL_EXTENSIONS);
return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
}
/**
* Returns the artifacts WSDL of the given BPEL file.
*/
public static IFile getArtifactsWSDLFile(IFile bpelFile) {
IPath wsdlPath = bpelFile.getFullPath().removeFileExtension();
String fileName = wsdlPath.lastSegment() + "Artifacts"; //$NON-NLS-1$
wsdlPath = wsdlPath.removeLastSegments(1).append(fileName);
wsdlPath = wsdlPath.addFileExtension(IBPELUIConstants.EXTENSION_WSDL);
return ResourcesPlugin.getWorkspace().getRoot().getFile(wsdlPath);
}
public static Image getImage(IMarker marker) {
Image img = ModelMarkerUtil.getImage(marker);
ImageData background = null;
if (img != null) {
background = img.getImageData();
}
if (background == null) {
// Don't give up yet. If this is also a problem marker, we can find an image to
// display...
try {
if (marker.isSubtypeOf(IMarker.PROBLEM)) {
background = ImageUtils.getImage(marker).getImageData();
}
} catch (CoreException e) {
BPELUIPlugin.log(e);
return null;
}
}
if (background == null) return null;
String uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGETOPLEFT, ""); //$NON-NLS-1$
ImageData topLeft = getImageData(uri);
uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGETOPRIGHT, ""); //$NON-NLS-1$
ImageData topRight = getImageData(uri);
uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGEBOTTOMLEFT, ""); //$NON-NLS-1$
ImageData bottomLeft = getImageData(uri);
uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGEBOTTOMRIGHT, ""); //$NON-NLS-1$
ImageData bottomRight = getImageData(uri);
OverlayCompositeImageDescriptor descriptor = new OverlayCompositeImageDescriptor(background, topLeft, topRight, bottomLeft, bottomRight);
return descriptor.createImage();
}
private static ImageData getImageData(String uri) {
if (uri.length() == 0) return null;
URL url = null;
try {
url = new URL(uri);
} catch (MalformedURLException e) {
return null;
}
ImageDescriptor desc = ImageDescriptor.createFromURL(url);
return desc.getImageData();
}
/**
* Returns the EditPart which is responsible for the given IFigure.
*/
public static EditPart mapFigure2EditPart(EditPartViewer viewer, IFigure figure) {
Map visualPartMap = viewer.getVisualPartMap();
EditPart part = null;
while (part == null && figure != null) {
part = (EditPart)visualPartMap.get(figure);
figure = figure.getParent();
}
return part;
}
/**
* Reads the process from disk.
*/
public static Process getProcess(IResource bpelFile, ResourceSet resourceSet) throws IOException {
URI uri = URI.createPlatformResourceURI(bpelFile.getFullPath().toString());
Resource processResource = resourceSet.getResource(uri, true);
EList<EObject> contents = processResource.getContents();
if (!contents.isEmpty()) {
return (Process) contents.get(0);
}
return null;
}
public static AccessibleEditPart getAccessibleEditPart(GraphicalEditPart part) {
final GraphicalEditPart thisPart = part;
return new AccessibleEditPart() {
@Override
public void getName(AccessibleEvent e) {
String childType = null;
String displayName = null;
ILabeledElement labeledElement = BPELUtil.adapt(thisPart.getModel(), ILabeledElement.class);
if (labeledElement != null) {
childType = labeledElement.getTypeLabel(thisPart.getModel());
displayName = labeledElement.getLabel(thisPart.getModel());
if (childType != null && displayName.equals(childType)) {
childType = null;
}
} else {
e.result = null;
return;
}
// return something reasonable (type followed by name if any)
// or nothing at all
StringBuffer concat = new StringBuffer();
if (childType != null && childType.length() > 0)
concat.append(childType);
if (concat.length() > 0)
concat.append(" "); //$NON-NLS-1$
if (displayName != null && displayName.length() > 0)
concat.append(displayName);
if (concat.length() > 0)
e.result = concat.toString();
else
e.result = null;
return;
}
@Override
public void getChildCount(AccessibleControlEvent e) {
List<EditPart> list = thisPart.getChildren();
int count = 0;
for (EditPart part : list) {
AccessibleEditPart access = (AccessibleEditPart)part.getAdapter(AccessibleEditPart.class);
if (access == null)
continue;
count++;
}
e.detail = count;
}
@Override
public void getChildren(AccessibleControlEvent e) {
List<EditPart> list = thisPart.getChildren();
Vector<Integer> childList = new Vector<Integer>();
for (EditPart part : list) {
AccessibleEditPart access = (AccessibleEditPart)part.getAdapter(AccessibleEditPart.class);
if (access == null)
continue;
childList.add( Integer.valueOf( access.getAccessibleID()));
}
e.children = childList.toArray();
}
@Override
public void getLocation(AccessibleControlEvent e) {
Rectangle bounds = thisPart.getFigure().getBounds().getCopy();
thisPart.getFigure().translateToAbsolute(bounds);
org.eclipse.swt.graphics.Point p = new org.eclipse.swt.graphics.Point(0, 0);
p = thisPart.getViewer().getControl().toDisplay(p);
e.x = bounds.x + p.x;
e.y = bounds.y + p.y;
e.width = bounds.width;
e.height = bounds.height;
}
/**
* @see AccessibleEditPart#getState(AccessibleControlEvent)
*/
@Override
public void getState(AccessibleControlEvent e) {
e.detail = ACC.STATE_SELECTABLE | ACC.STATE_FOCUSABLE;
if (thisPart.getSelected() != EditPart.SELECTED_NONE)
e.detail |= ACC.STATE_SELECTED;
if (thisPart.getViewer().getFocusEditPart() == thisPart)
e.detail = ACC.STATE_FOCUSED;
}
};
}
/** creates a table cursor that can be used to navigate tables for keyboard accessibility **/
public static TableCursor createTableCursor(final Table table, final TableViewer tableViewer) {
// create a TableCursor to navigate around the table
final TableCursor cursor = new TableCursor(table, SWT.NONE);
cursor.addSelectionListener(new SelectionAdapter() {
// when the TableEditor is over a cell, select the corresponding row in the table
@Override
public void widgetSelected(SelectionEvent e) {
if (cursor.getRow() != null)
table.setSelection(new TableItem[] {cursor.getRow()});
}
// when the user hits "ENTER" in the TableCursor, pop up an editor
@Override
public void widgetDefaultSelected(SelectionEvent e) {
TableItem row = cursor.getRow();
if (row != null) {
int nRow = table.indexOf(row);
int column = cursor.getColumn();
Object obj = tableViewer.getElementAt(nRow);
tableViewer.editElement(obj, column);
}
}
});
// Hide the TableCursor when the user hits the "CTRL" or "SHIFT" key.
// This alows the user to select multiple items in the table.
cursor.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if ((e.keyCode == SWT.CTRL) || (e.keyCode == SWT.SHIFT) ||
(e.stateMask & SWT.CONTROL) != 0 || (e.stateMask & SWT.SHIFT) != 0) {
cursor.setVisible(false);
}
}
});
cursor.addMouseListener(new MouseListener() {
@Override
public void mouseDoubleClick(MouseEvent e) { }
@Override
public void mouseDown(MouseEvent e) {
TableItem row = cursor.getRow();
if (row != null) {
int nRow = table.indexOf(row);
int column = cursor.getColumn();
Object obj = tableViewer.getElementAt(nRow);
tableViewer.editElement(obj, column);
}
}
@Override
public void mouseUp(MouseEvent e) {
}
});
// Show the TableCursor when the user releases the "SHIFT" or "CTRL" key.
// This signals the end of the multiple selection task.
table.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.keyCode == SWT.CONTROL && (e.stateMask & SWT.SHIFT) != 0)
return;
if (e.keyCode == SWT.SHIFT && (e.stateMask & SWT.CONTROL) != 0)
return;
if (e.keyCode != SWT.CONTROL && (e.stateMask & SWT.CONTROL) != 0)
return;
if (e.keyCode != SWT.SHIFT && (e.stateMask & SWT.SHIFT) != 0)
return;
if (table.getItemCount() == 0)
return;
TableItem[] selection = table.getSelection();
TableItem row = (selection.length == 0) ? table.getItem(table.getTopIndex()) : selection[0];
table.showItem(row);
cursor.setSelection(row, 0);
cursor.setVisible(true);
cursor.setFocus();
}
});
return cursor;
}
public static ResourceSet createResourceSetImpl() {
// TODO: Extensibility
return new ResourceSetImpl();
}
static final NCNameWordDetector NCNAME_DETECTOR = new NCNameWordDetector ();
/**
* Returns a validator that checks that the new value is a valid NCName.
*/
public static IInputValidator getNCNameValidator() {
return new IInputValidator() {
@Override
public String isValid (String newText) {
if ( NCNAME_DETECTOR.isValid( newText ) == false ) {
return Messages.BPELUtil_NCName;
}
// TODO ! temporary hack
return null;
}
};
}
public static void deleteNonContainmentRefs(EObject modelObject, Collection referents) {
if (modelObject == null) return;
for (EReference feature : modelObject.eClass().getEAllReferences()) {
if (feature.isMany()) {
EList<Object> list = (EList<Object>)modelObject.eGet(feature, true);
for (Object referent : referents) {
if (list.contains(referent)) list.remove(referent);
// TODO: support non-changeable features! print a warning.
}
} else {
Object oldValue = modelObject.eGet(feature, true);
for (Object referent : referents) {
if (oldValue == referent) {
if (feature.isUnsettable()) {
// this is okay, default is always null for EReferences.
modelObject.eUnset(feature);
} else {
modelObject.eSet(feature, null);
}
break;
}
// TODO: support non-changeable features! print a warning.
}
}
}
}
//@return: returns arraylist with all activities the compensate
// can validly point to
public static ArrayList getCompensableActivities(Object context){
final ArrayList returnObjects = new ArrayList();
if (context instanceof CompensateScope) {
CompensateScope compensateScope = (CompensateScope) context;
EObject enclosingContainer = compensateScope;
if (compensateScope.eContainer() != null) {
enclosingContainer = enclosingContainer.eContainer();
// Go to parent scope where compensate is contained
while (!(enclosingContainer instanceof Scope)
&& (enclosingContainer.eContainer() != null)) {
enclosingContainer = enclosingContainer.eContainer();
}
}
// Put all scopes and invokes within parent scope in arraylist
visitModelDepthFirst(enclosingContainer,
new IModelVisitor() {
@Override
public boolean visit(Object modelObject) {
if (modelObject instanceof Scope) {
returnObjects.add(modelObject);
} else if (modelObject instanceof Invoke) {
returnObjects.add(modelObject);
}
return true;
}
});
// https://issues.jboss.org/browse/JBIDE-8044
if (!returnObjects.isEmpty())
returnObjects.remove(0); //remove the scope containing the compensate
return returnObjects;
}
throw new IllegalArgumentException();
}
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;
}
public static String debugObject(Object object) {
if (object == null) return "null"; //$NON-NLS-1$
if (object instanceof String) { return "\""+(String)object+"\""; } //$NON-NLS-1$ //$NON-NLS-2$
if (object.getClass().getName().startsWith("java.lang")) { //$NON-NLS-1$
return object.toString();
}
if (object instanceof List) {
StringBuffer b = new StringBuffer("("); //$NON-NLS-1$
for (Iterator it = ((List)object).iterator(); it.hasNext(); ) {
b.append(debugObject(it.next()));
if (it.hasNext()) b.append(", "); //$NON-NLS-1$
}
b.append(")"); //$NON-NLS-1$
return b.toString();
}
if (object instanceof QName) {
QName qname = (QName)object;
return "QName(\""+qname.getNamespaceURI()+"\", \""+qname.getLocalPart()+"\")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
StringBuffer b = new StringBuffer(shortClassName(object.getClass()));
boolean proxy = (object instanceof EObject) && ((EObject)object).eIsProxy();
if (proxy) b.append("-proxy"); //$NON-NLS-1$
boolean isEObject = (object instanceof EObject);
INamedElement namedElement = null;
if (isEObject) {
namedElement = BPELUtil.adapt(object, INamedElement.class);
if (namedElement != null) {
try {
String s = namedElement.getName(object);
b.append((s==null)? "<null>" : "<\""+s+"\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} catch (Exception e) {
b.append("<???>"); //$NON-NLS-1$
}
}
}
if (namedElement==null) {
b.append("{"); b.append(String.valueOf(object.hashCode())); b.append("}"); //$NON-NLS-1$ //$NON-NLS-2$
}
return b.toString();
}
public static String debug(Notification n) {
StringBuffer b = new StringBuffer(shortClassName(n.getClass()));
b.append("("); //$NON-NLS-1$
b.append(debugObject(n.getNotifier()));
b.append(", "); //$NON-NLS-1$
switch (n.getEventType()) {
case Notification.SET-1: b.append("CREATE"); break; //$NON-NLS-1$
case Notification.SET: b.append("SET"); break; //$NON-NLS-1$
case Notification.UNSET: b.append("UNSET"); break; //$NON-NLS-1$
case Notification.ADD: b.append("ADD"); break; //$NON-NLS-1$
case Notification.REMOVE: b.append("REMOVE"); break; //$NON-NLS-1$
case Notification.ADD_MANY: b.append("ADD_MANY"); break; //$NON-NLS-1$
case Notification.MOVE: b.append("MOVE"); break; //$NON-NLS-1$
case Notification.REMOVING_ADAPTER: b.append("REMOVING_ADAPTER"); break; //$NON-NLS-1$
case Notification.RESOLVE: b.append("RESOLVE"); break; //$NON-NLS-1$
default: b.append("??? ("+String.valueOf(n.getEventType())+")"); //$NON-NLS-1$ //$NON-NLS-2$
}
b.append(" "); //$NON-NLS-1$
EStructuralFeature feature = (EStructuralFeature)n.getFeature();
if (feature == null) b.append("???"); else b.append(feature.getName()); //$NON-NLS-1$
if (n.getPosition() >= 0) {
b.append("["); //$NON-NLS-1$
b.append(String.valueOf(n.getPosition()));
b.append("]"); //$NON-NLS-1$
} else {
if (feature != null && feature.isMany()) b.append("{***}"); //$NON-NLS-1$
}
b.append(": "); //$NON-NLS-1$
b.append(debugObject(n.getOldValue()));
b.append(" --> "); //$NON-NLS-1$
b.append(debugObject(n.getNewValue()));
b.append(")"); //$NON-NLS-1$
return b.toString();
}
protected static String shortClassName(Class clazz) {
StringBuffer b = new StringBuffer(clazz.getName());
for (int i = b.indexOf("."); i >= 0; i = b.indexOf(".")) b.delete(0,i+1); //$NON-NLS-1$ //$NON-NLS-2$
//if (b.indexOf("Impl") == b.length()-4) b.delete(b.length()-4, b.length()));
return b.toString();
}
/**
* Creates a composite with a flat border around it.
*/
public static Composite createBorderComposite(Composite parent, TabbedPropertySheetWidgetFactory wf) {
final Composite result = wf.createComposite(parent);
FillLayout layout = new FillLayout();
final int margin = 1;
layout.marginHeight = margin;
layout.marginWidth = margin;
result.setLayout(layout);
result.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
org.eclipse.swt.graphics.Rectangle bounds = result.getBounds();
bounds.x = margin-1;
bounds.y = margin-1;
bounds.width = bounds.width - (margin*2) + 1;
bounds.height = bounds.height - (margin*2) + 1;
e.gc.drawRectangle(bounds);
}
});
return result;
}
static void addVariablesToMap(Map<String, Variable> targetMap, Variables vars, Variable refVar ) {
if (vars == null) {
return;
}
for(Variable v : vars.getChildren()) {
// scoping for initialization (only visible from).
if (v == refVar) {
break;
}
if (v.getName() != null) {
targetMap.put(v.getName(),v);
}
}
}
static void addVisibleVariables (Map<String,Variable> targetMap, EObject target, Variable refVariable ) {
if (target == null) {
return;
}
if (target instanceof Resource) {
return;
}
if (target instanceof Process) {
addVariablesToMap(targetMap, ((Process)target).getVariables(), refVariable );
return ;
}
// recursively add less local variables first
addVisibleVariables(targetMap, target.eContainer(), refVariable );
if (target instanceof Scope) {
addVariablesToMap(targetMap, ((Scope)target).getVariables(), refVariable );
}
if (target instanceof Catch) {
Variable v = ((Catch)target).getFaultVariable();
if (v != null && v.getName() != null) {
targetMap.put(v.getName(), v);
}
}
if (target instanceof OnEvent) {
Variable v = ((OnEvent)target).getVariable();
if (v != null && v.getName() != null) {
targetMap.put(v.getName(), v);
}
}
if (target instanceof ForEach) {
Variable v = ((ForEach)target).getCounterName();
if (v != null && v.getName() != null) {
targetMap.put(v.getName(), v);
}
}
}
private static void addPartnerLinksToMap(Map<String, PartnerLink> targetMap, PartnerLinks plinks) {
if (plinks == null) return;
for (PartnerLink p : plinks.getChildren()) {
if (p.getName() != null) targetMap.put(p.getName(), p);
}
}
private static void addVisiblePartnerLinks(Map<String, PartnerLink> targetMap, EObject target) {
if (target == null) return;
if (target instanceof Resource) return;
if (target instanceof Process) {
addPartnerLinksToMap(targetMap, ((Process)target).getPartnerLinks());
} else {
// recursively add less local partnerlinks first
addVisiblePartnerLinks(targetMap, target.eContainer());
if (target instanceof Scope) {
addPartnerLinksToMap(targetMap, ((Scope)target).getPartnerLinks());
}
}
}
private static void addCorrelationSetsToMap(Map<String, CorrelationSet> targetMap, CorrelationSets csets) {
if (csets == null) return;
for( CorrelationSet c : csets.getChildren() ) {
if (c.getName() != null) targetMap.put(c.getName(), c);
}
}
private static void addVisibleCorrelationSets(Map<String, CorrelationSet> targetMap, EObject target) {
if (target == null) return;
if (target instanceof Resource) return;
if (target instanceof Process) {
addCorrelationSetsToMap(targetMap, ((Process)target).getCorrelationSets());
} else {
// recursively add less local correlationsets first
addVisibleCorrelationSets(targetMap, target.eContainer());
if (target instanceof Scope) {
addCorrelationSetsToMap(targetMap, ((Scope)target).getCorrelationSets());
}
}
}
/**
* Look up the variables visible to a certain context activity (or the whole process).
* Variables in BPEL follow lexical scoping rules (resolved OASIS issue 101).
*
* The returned variables are in no particular order.
*/
public static Variable[] getVisibleVariables (EObject target) {
Map<String,Variable> name2Variable = new HashMap<String,Variable>();
addVisibleVariables(name2Variable, target, target instanceof Variable ? (Variable) target: null );
if (name2Variable.isEmpty()) {
return EMPTY_VARIABLE_ARRAY;
}
Collection<Variable> variables = name2Variable.values();
if (variables.size() == 1) {
return variables.toArray(EMPTY_VARIABLE_ARRAY);
}
ArrayList<Variable> list = new ArrayList<Variable>( variables );
Collections.sort(list, new Comparator<Variable>() {
@Override
public int compare(Variable o1, Variable o2) {
return o1.getName().compareTo(o2.getName());
}
});
return list.toArray(EMPTY_VARIABLE_ARRAY);
}
/**
* Look up the PartnerLinks visible to a certain context activity (or the whole process).
* When local PartnerLinks are added to the spec, they will follow lexical scoping rules
* just like variables.
*
* The returned PartnerLinks are in no particular order.
*/
public static PartnerLink[] getVisiblePartnerLinks(EObject target) {
Map<String, PartnerLink> name2PartnerLink = new HashMap<String, PartnerLink>();
addVisiblePartnerLinks(name2PartnerLink, target);
if (name2PartnerLink.isEmpty()) return EMPTY_PARTNERLINK_ARRAY;
PartnerLink[] result = new PartnerLink[name2PartnerLink.size()];
name2PartnerLink.values().toArray(result);
return result;
}
/**
* Look up the PartnerLinks visible to a certain context activity (or the whole process).
* When local PartnerLinks are added to the spec, they will follow lexical scoping rules
* just like variables.
*
* The returned PartnerLinks are in no particular order.
*/
public static CorrelationSet[] getVisibleCorrelationSets(EObject target) {
Map<String, CorrelationSet> name2CorrelationSet = new HashMap<String, CorrelationSet>();
addVisibleCorrelationSets(name2CorrelationSet, target);
if (name2CorrelationSet.isEmpty()) return EMPTY_CORRELATIONSET_ARRAY;
CorrelationSet[] result = new CorrelationSet[name2CorrelationSet.size()];
name2CorrelationSet.values().toArray(result);
return result;
}
/**
* If the given message is used by an operation in the same definition,
* returns the Operation that uses the given message.
* Otherwise, returns null.
*/
public static Operation getOperationFromMessage(Message message) {
if (message == null) return null;
Definition def = message.getEnclosingDefinition();
if (def == null) return null;
Iterator<PortType> ptIt = def.getEPortTypes().iterator();
while (ptIt.hasNext()) {
PortType pt = ptIt.next();
Iterator<Operation> it = pt.getOperations().iterator();
while (it.hasNext()) {
Operation op = it.next();
Input input = op.getEInput();
if (input != null) {
if (input.getMessage().getQName().equals(message.getQName())) {
return op;
}
}
Output output = op.getEOutput();
if (output != null) {
if (output.getMessage().getQName().equals(message.getQName())) {
return op;
}
}
Iterator<Fault> faultIterator = op.getEFaults().iterator();
while (faultIterator.hasNext()) {
Fault fault = faultIterator.next();
Message faultMessage = fault.getEMessage();
if (faultMessage != null) {
if (faultMessage.getQName() != null) {
if (faultMessage.getQName().equals(message.getQName())) {
return op;
}
}
}
}
}
}
return null;
}
public static void openEditor(EObject modelObject, BPELEditor editor) {
try {
// https://issues.jboss.org/browse/JBIDE-8044
if (modelObject==null) {
// https://issues.jboss.org/browse/JBIDE-8601
MessageDialog.openError(editor.getEditorSite().getShell(),
Messages.BPELUtil__Error,
Messages.BPELUtil_NoEditorForNullObject);
return;
}
EObject resolvedObject = null;
if (modelObject.eResource()==null) {
// https://jira.jboss.org/browse/JBIDE-7351
// try to resolve proxies here, otherwise we don't know editor input
if (modelObject.eIsProxy()) {
resolvedObject = EmfModelQuery.resolveProxy(editor.getProcess(), modelObject);
}
}
else
resolvedObject = modelObject;
if (resolvedObject==null) {
// https://issues.jboss.org/browse/JBIDE-8601
MessageDialog.openError(editor.getEditorSite().getShell(),
Messages.BPELUtil__Error, NLS.bind(
Messages.BPELUtil_NoEditorForObject,
(new Object[] { modelObject.getClass().getSimpleName() })));
return;
}
IFile file = BPELUtil.getFileFromURI(resolvedObject.eResource().getURI());
IDE.openEditor(editor.getSite().getWorkbenchWindow().getActivePage(), file);
} catch (PartInitException ex) {
BPELUIPlugin.log(ex, IStatus.WARNING);
}
}
/**
* Returns the BPEL file associated with the given process.
*/
public static IFile getBPELFile(Process process) {
return getFileFromURI(process.eResource().getURI());
}
public static String lookupOrCreateNamespacePrefix ( EObject context, String namespace, String prefix, Shell shell ) {
String nsPrefix = BPELUtils.getNamespacePrefix(context, namespace);
if (nsPrefix != null && nsPrefix.length() > 0) {
return nsPrefix;
}
NamespaceMappingDialog dialog = new NamespaceMappingDialog (shell, context);
dialog.setNamespace(namespace);
if (prefix != null) {
dialog.setPrefix(prefix);
}
if (dialog.open() == Window.CANCEL) {
return nsPrefix;
}
nsPrefix = dialog.getPrefix();
BPELUtils.setNamespacePrefix(context, namespace, nsPrefix);
return nsPrefix;
}
/**
* Traverses the root object and returns all objects under it that are of the same
* class or subclasses of "target".
*/
public static List<EObject> getAllEObjectsOfType(EObject root, EClass eClass) {
List<EObject> allElems = new ArrayList<EObject>();
for (TreeIterator<EObject> iter = root.eAllContents(); iter.hasNext();) {
EObject element = iter.next();
if (eClass.isSuperTypeOf(element.eClass()) ||
element.eClass() == eClass) {
allElems.add(element);
}
}
return allElems;
}
public static boolean isBPELProject(IProject project){
if (project == null) {
return false;
}
if (ModuleCoreNature.isFlexibleProject(project)) {
IFacetedProject fproj = null;
try {
fproj = ProjectFacetsManager.create(project);
} catch (CoreException e) {
return false;
}
if (fproj.hasProjectFacet(getBPELFacetVersion())) {
return true;
}
}
return false;
}
public static IProjectFacetVersion getBPELFacetVersion() {
IProjectFacet bpelFacet = ProjectFacetsManager.getProjectFacet(IBPELModuleFacetConstants.BPEL20_PROJECT_FACET);
IProjectFacetVersion bpelFacetVersion = bpelFacet.getVersion(IBPELModuleFacetConstants.BPEL20_MODULE_VERSION);
return bpelFacetVersion;
}
public static org.eclipse.core.resources.IContainer getBPELContentFolder(IProject project) {
org.eclipse.core.resources.IContainer bpelContent = null;
if (BPELUtil.isBPELProject(project)) {
IPath rootPath = getWebContentRootPath(project);
if (rootPath != null && !rootPath.isEmpty()) {
bpelContent = project.getFolder(rootPath);
}
}
return bpelContent;
}
public static IPath getWebContentRootPath(IProject project) {
IPath path = null;
IVirtualComponent component = ComponentCore.createComponent(project);
if (component != null && component.exists()) {
path = component.getRootFolder().getProjectRelativePath();
}
return path;
}
}