| /******************************************************************************* |
| * Copyright (c) 2011, 2012 Red Hat, Inc. |
| * All rights reserved. |
| * This program is made available under the terms of the |
| * Eclipse Public License v1.0 which accompanies this distribution, |
| * and is available at http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Red Hat, Inc. - initial API and implementation |
| * |
| * @author Bob Brodt |
| ******************************************************************************/ |
| package org.eclipse.bpmn2.modeler.core.runtime; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Comparator; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.bpmn2.Bpmn2Package; |
| import org.eclipse.bpmn2.modeler.core.IBpmn2RuntimeExtension; |
| import org.eclipse.bpmn2.modeler.core.LifecycleEvent; |
| import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter; |
| import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceImpl; |
| import org.eclipse.bpmn2.modeler.core.preferences.ShapeStyle; |
| import org.eclipse.bpmn2.modeler.core.runtime.ModelExtensionDescriptor.Property; |
| import org.eclipse.bpmn2.modeler.core.utils.ErrorDialog; |
| import org.eclipse.bpmn2.modeler.core.utils.ModelUtil; |
| import org.eclipse.bpmn2.modeler.core.utils.ModelUtil.Bpmn2DiagramType; |
| import org.eclipse.bpmn2.util.Bpmn2Resource; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IContributor; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.platform.IDiagramBehavior; |
| import org.eclipse.graphiti.platform.IDiagramContainer; |
| import org.eclipse.graphiti.services.Graphiti; |
| import org.eclipse.graphiti.ui.editor.DiagramEditor; |
| import org.eclipse.ui.IEditorInput; |
| |
| |
| /** |
| * Target Runtime Extension Descriptor class for Target Runtime definition. |
| * Instances of this class correspond to <runtime> extension elements in the extension's plugin.xml |
| * See the description of the "runtime" element in the org.eclipse.bpmn2.modeler.runtime extension point schema. |
| */ |
| public class TargetRuntime extends BaseRuntimeExtensionDescriptor implements IRuntimeExtensionDescriptor { |
| |
| public static final String EXTENSION_NAME = "runtime"; //$NON-NLS-1$ |
| |
| // extension point ID for Target Runtimes |
| public static final String RUNTIME_EXTENSION_ID = "org.eclipse.bpmn2.modeler.runtime"; //$NON-NLS-1$ |
| public static final String DEFAULT_RUNTIME_ID = "org.eclipse.bpmn2.modeler.runtime.none"; //$NON-NLS-1$ |
| // ID for BPMN2 specific problem markers |
| public static final String BPMN2_MARKER_ID = "org.eclipse.bpmn2.modeler.core.problemMarker"; //$NON-NLS-1$ |
| |
| // our cached registry of target runtimes contributed by other plugins |
| private static List<TargetRuntime> targetRuntimes; |
| |
| // the Target Runtime properties |
| private String name; |
| private String[] versions; |
| private String description; |
| private IBpmn2RuntimeExtension runtimeExtension; |
| private String problemMarkerId; |
| |
| // the lists of Extension Descriptors defined in the extension plugin's plugin.xml |
| protected List<ModelDescriptor> modelDescriptors; |
| protected List<PropertyTabDescriptor> propertyTabDescriptors; |
| protected List<CustomTaskDescriptor> customTaskDescriptors; |
| protected List<ModelExtensionDescriptor> modelExtensionDescriptors; |
| protected List<ModelEnablementDescriptor> modelEnablementDescriptors; |
| // protected ModelEnablementDescriptor defaultModelEnablementDescriptors; |
| protected List<PropertyExtensionDescriptor> propertyExtensionDescriptors; |
| protected List<FeatureContainerDescriptor> featureContainerDescriptors; |
| protected List<ToolPaletteDescriptor> toolPaletteDescriptors; |
| protected List<ShapeStyle> shapeStyles; |
| protected List<DataTypeDescriptor> dataTypeDescriptors; |
| protected List<TypeLanguageDescriptor> typeLanguageDescriptors; |
| protected List<ExpressionLanguageDescriptor> expressionLanguageDescriptors; |
| protected List<ServiceImplementationDescriptor> serviceImplementationDescriptors; |
| |
| // all of the extension descriptor classes in the order in which they need to be processed |
| static Class extensionDescriptorClasses[] = { |
| TargetRuntime.class, |
| ModelDescriptor.class, |
| DataTypeDescriptor.class, |
| PropertyTabDescriptor.class, |
| ModelExtensionDescriptor.class, |
| CustomTaskDescriptor.class, |
| ModelEnablementDescriptor.class, |
| ToolPaletteDescriptor.class, |
| PropertyExtensionDescriptor.class, |
| FeatureContainerDescriptor.class, |
| TypeLanguageDescriptor.class, |
| ExpressionLanguageDescriptor.class, |
| ServiceImplementationDescriptor.class, |
| ShapeStyle.class, |
| }; |
| |
| /** |
| * Target Runtime Construction with a ConfigurationElement. |
| * This initializes all of our Target Runtime properties (name, ID, implementation class, etc.) |
| * |
| * @param e - an IConfigurationElement defined in a plugin.xml |
| */ |
| public TargetRuntime(IConfigurationElement e) { |
| super(e); |
| name = e.getAttribute("name"); //$NON-NLS-1$ |
| String s = e.getAttribute("versions"); //$NON-NLS-1$ |
| if (s!=null) { |
| versions = s.split("[, ]"); //$NON-NLS-1$ |
| } |
| description = e.getAttribute("description"); //$NON-NLS-1$ |
| try { |
| setRuntimeExtension((IBpmn2RuntimeExtension) e.createExecutableExtension("class")); //$NON-NLS-1$ |
| } catch (CoreException e1) { |
| e1.printStackTrace(); |
| } //$NON-NLS-1$ |
| |
| // add validation problem marker IDs |
| IContributor contributor = e.getDeclaringExtension().getContributor(); |
| IConfigurationElement[] markers = Platform.getExtensionRegistry().getConfigurationElementsFor( |
| "org.eclipse.core.resources.markers"); //$NON-NLS-1$ |
| for (IConfigurationElement m : markers) { |
| if (m.getDeclaringExtension().getContributor() == contributor) { |
| problemMarkerId = m.getDeclaringExtension().getUniqueIdentifier(); |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.runtime.IRuntimeExtensionDescriptor#getExtensionName() |
| */ |
| @Override |
| public String getExtensionName() { |
| return EXTENSION_NAME; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.runtime.IRuntimeExtensionDescriptor#setRuntime(org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime) |
| */ |
| @Override |
| public void setRuntime(TargetRuntime targetRuntime) { |
| targetRuntimes.add(this); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.runtime.IRuntimeExtensionDescriptor#getRuntime() |
| */ |
| @Override |
| public TargetRuntime getRuntime() { |
| return this; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.runtime.IRuntimeExtensionDescriptor#getConfigFile() |
| */ |
| @Override |
| public IFile getConfigFile() { |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.runtime.IRuntimeExtensionDescriptor#setConfigFile(org.eclipse.core.resources.IFile) |
| */ |
| @Override |
| public void setConfigFile(IFile configFile) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.runtime.IRuntimeExtensionDescriptor#dispose() |
| */ |
| @Override |
| public void dispose() { |
| } |
| |
| /** |
| * Notify the TargetRuntime of a LifeCycle event. |
| * |
| * @param event |
| */ |
| public void notify(LifecycleEvent event) { |
| TargetRuntime.getDefaultRuntime().getRuntimeExtension().notify(event); |
| if (this!=TargetRuntime.getDefaultRuntime()) { |
| getRuntimeExtension().notify(event); |
| } |
| } |
| |
| /* |
| * Target Runtime property accessors |
| */ |
| |
| /** |
| * Returns the Target Runtime's unique ID string. |
| * |
| * @return |
| */ |
| public String getId() { |
| return id; |
| } |
| |
| /** |
| * Returns the Target Runtime's name for use in UI components |
| * |
| * @return |
| */ |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * Returns the Target Runtime's version number strings for use in UI components |
| * |
| * @return |
| */ |
| public String[] getVersions() { |
| return versions; |
| } |
| |
| /** |
| * Returns the Target Runtime's descriptive text for use in UI components |
| * |
| * @return |
| */ |
| public String getDescription() { |
| return description; |
| } |
| |
| /** |
| * Returns the extension plugin class that implements the Target Runtime behavior |
| * defined by the IBpmn2RuntimeExtension interface. |
| * |
| * @return |
| */ |
| public IBpmn2RuntimeExtension getRuntimeExtension() { |
| return runtimeExtension; |
| } |
| |
| /** |
| * Sets the extension plugin's IBpmn2RuntimeExtension implementation class. |
| * |
| * @param runtimeExtension |
| */ |
| public void setRuntimeExtension(IBpmn2RuntimeExtension runtimeExtension) { |
| this.runtimeExtension = runtimeExtension; |
| } |
| |
| /** |
| * Returns the Target Runtime's Model Descriptor which defines the EMF extension model. |
| * |
| * @return |
| */ |
| public ModelDescriptor getModelDescriptor() { |
| if (getModelDescriptors().size()==0) |
| return null; |
| return getModelDescriptors().get(0); |
| } |
| |
| public void setModelDescriptor(ModelDescriptor md) { |
| getModelDescriptors().clear(); |
| getModelDescriptors().add(md); |
| } |
| |
| public String getProblemMarkerId() { |
| if (problemMarkerId==null) |
| return BPMN2_MARKER_ID; |
| return problemMarkerId; |
| } |
| |
| /* |
| * Helper methods for access to global Target Runtime data |
| */ |
| |
| /** |
| * Fetch the TargetRuntime for the given ID string |
| * |
| * @param id |
| * @return |
| */ |
| public static TargetRuntime getRuntime(String id) { |
| if (targetRuntimes == null) { |
| return null; |
| } |
| |
| for (TargetRuntime rt : targetRuntimes) { |
| if (rt.id.equals(id)) |
| return rt; |
| } |
| return null; |
| } |
| |
| public static TargetRuntime getRuntime(IEditorInput input) { |
| TargetRuntime runtime = null; |
| if (input!=null) { |
| // If the project has not been configured for a specific runtime through the "BPMN2" |
| // project properties page (i.e. the target is "None") then allow the runtime extension |
| // plug-ins an opportunity to identify the given process file contents as their own. |
| // If none of the plug-ins respond with "yes, this file is targeted for my runtime", |
| // then use the "None" as the extension. This will configure the BPMN2 Modeler with |
| // generic property sheets and other default behavior. |
| for (TargetRuntime rt : TargetRuntime.createTargetRuntimes()) { |
| if (rt.getRuntimeExtension().isContentForRuntime(input)) { |
| runtime = rt; |
| break; |
| } |
| } |
| } |
| if (runtime==null) |
| runtime = getDefaultRuntime(); |
| return runtime; |
| } |
| |
| /** |
| * return the target runtime according to the namespace and diagram type |
| * |
| * @param targetNamespace |
| * @param type may be null |
| * @return |
| */ |
| public static TargetRuntime getRuntime(String targetNamespace, Bpmn2DiagramType type) { |
| if (targetNamespace!=null) { |
| for (TargetRuntime rt : TargetRuntime.createTargetRuntimes()) { |
| String tns = rt.getRuntimeExtension().getTargetNamespace(type); |
| if (targetNamespace.equals(tns)) { |
| return rt; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * return the target runtime according to a business model or diagram model object |
| * |
| * @param object business model or diagram model object |
| * @return |
| */ |
| public static TargetRuntime getRuntime(EObject object) { |
| if (object instanceof EClass) { |
| throw new IllegalArgumentException("can not retrieve target runtime from EClass"); //$NON-NLS-1$ |
| } |
| Resource resource = ExtendedPropertiesAdapter.getResource(object); |
| return resource != null ? getRuntime(resource) : getDefaultRuntime(); |
| } |
| |
| /** |
| * return the target runtime according to a model resource |
| * |
| * @param resource |
| * @return |
| */ |
| public static TargetRuntime getRuntime(Resource resource) { |
| if (resource instanceof Bpmn2Resource) { |
| TargetRuntime runtime = TargetRuntimeAdapter.getTargetRuntime(resource); |
| if (runtime == null) { |
| throw new IllegalStateException("missing target runtime on resource"); //$NON-NLS-1$ |
| } |
| return runtime; |
| } |
| return null; |
| } |
| |
| /** |
| * return the target runtime according to a diagram behavior |
| * |
| * @param diagramBehavior |
| * @return |
| */ |
| public static TargetRuntime getRuntime(IDiagramBehavior diagramBehavior) { |
| return getRuntime(diagramBehavior.getDiagramContainer()); |
| } |
| |
| /** |
| * return the target runtime according to a diagram container |
| * |
| * @param container |
| * @return |
| */ |
| public static TargetRuntime getRuntime(IDiagramContainer container) { |
| if (container instanceof IAdaptable) { |
| TargetRuntime runtime = (TargetRuntime) ((IAdaptable) container).getAdapter(TargetRuntime.class); |
| if (runtime != null) { |
| return runtime; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * find the target runtime according to complete target namespace |
| * |
| * @param targetNamespace namespace which may contain a {@link Bpmn2DiagramType} |
| * @return |
| */ |
| public static TargetRuntime getRuntimeByNamespace(String targetNamespace) { |
| // figure out diagram type |
| int separator = targetNamespace.lastIndexOf("/"); //$NON-NLS-1$ |
| Bpmn2DiagramType type = separator != -1 ? Bpmn2DiagramType.fromString(targetNamespace.substring(separator+1)) : null; |
| return TargetRuntime.getRuntime(targetNamespace, type); |
| } |
| |
| /** |
| * Returns the "None" TargetRuntime definition. |
| * |
| * @return |
| */ |
| public static TargetRuntime getDefaultRuntime() { |
| return getRuntime(DEFAULT_RUNTIME_ID); |
| } |
| |
| /** |
| * Returns the first TargetRuntime which is not the "None", or "default" runtime. |
| * If there are no other TargetRuntime extension plugins loaded, this returns the default runtime. |
| * |
| * @return |
| */ |
| public static String getFirstNonDefaultId(){ |
| String runtimeId = null; |
| int nonDefaultRuntimeCount = 0; |
| |
| if (TargetRuntime.createTargetRuntimes() == null) { |
| return TargetRuntime.DEFAULT_RUNTIME_ID; |
| } |
| |
| for (TargetRuntime rt :TargetRuntime.createTargetRuntimes()) { |
| if (!rt.getId().equals(TargetRuntime.DEFAULT_RUNTIME_ID)){ |
| nonDefaultRuntimeCount++; |
| runtimeId = rt.getId(); |
| } |
| } |
| |
| if (nonDefaultRuntimeCount == 1 && runtimeId != null){ |
| return runtimeId; |
| }else{ |
| return TargetRuntime.DEFAULT_RUNTIME_ID; |
| } |
| } |
| |
| public void registerExtensionResourceFactory(ResourceSet resourceSet) { |
| resourceSet.getResourceFactoryRegistry().getContentTypeToFactoryMap().put( |
| Bpmn2ModelerResourceImpl.BPMN2_CONTENT_TYPE_ID, getModelDescriptor().getResourceFactory()); |
| } |
| |
| public static List<TargetRuntime> createTargetRuntimes() { |
| if (targetRuntimes==null) { |
| // load runtimes contributions from other plugins |
| targetRuntimes = new ArrayList<TargetRuntime>(); |
| |
| IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(RUNTIME_EXTENSION_ID); |
| for (IConfigurationElement e : elements) { |
| if (EXTENSION_NAME.equals(e.getName())) { |
| String id = e.getAttribute("id"); //$NON-NLS-1$ |
| if (getRuntime(id)==null) { |
| TargetRuntime rt = new TargetRuntime(e); |
| targetRuntimes.add(rt); |
| } |
| } |
| } |
| |
| try { |
| loadExtensions(null, elements, null); |
| } |
| catch (Exception e) { |
| ErrorDialog dlg = new ErrorDialog(org.eclipse.bpmn2.modeler.core.runtime.Messages.TargetRuntime_Config_Error, e); |
| dlg.show(); |
| } |
| |
| // All done parsing configuration elements |
| // now go back and fix up some things... |
| for (TargetRuntime rt : targetRuntimes) { |
| |
| if (rt.getModelDescriptor()==null) { |
| rt.setModelDescriptor( getDefaultRuntime().getModelDescriptor() ); |
| } |
| for (ToolPaletteDescriptor tp : rt.getToolPaletteDescriptors()) { |
| tp.sortCategories(); |
| } |
| } |
| |
| CustomTaskImageProvider.registerAvailableImages(); |
| } |
| return targetRuntimes; |
| } |
| |
| static TargetRuntime getRuntime(IConfigurationElement e, TargetRuntime currentRuntime) { |
| TargetRuntime rt = getRuntime( getRuntimeId(e) ); |
| if (rt==null) { |
| if (currentRuntime!=null) |
| rt = currentRuntime; |
| else |
| rt = getDefaultRuntime(); |
| } |
| return rt; |
| } |
| |
| static String getRuntimeId(IConfigurationElement e) { |
| String id = null; |
| if (EXTENSION_NAME.equals(e.getName())) |
| id = e.getAttribute("id"); //$NON-NLS-1$ |
| else { |
| id = e.getAttribute("runtimeId"); //$NON-NLS-1$ |
| // this extension does not define a runtimeId, so get it from the containing |
| // plugin.xml's <runtime> definition |
| if (id==null) { |
| for (IConfigurationElement ep : e.getDeclaringExtension().getConfigurationElements()) { |
| if (EXTENSION_NAME.equals(ep.getName())) { |
| id = ep.getAttribute("id"); //$NON-NLS-1$ |
| break; |
| } |
| } |
| } |
| } |
| return id; |
| } |
| |
| public List<TargetRuntime> getTargetRuntimes() { |
| return createTargetRuntimes(); |
| } |
| |
| /* |
| * Custom Task convenience methods |
| */ |
| public CustomTaskDescriptor getCustomTask( String id ) { |
| Iterator<CustomTaskDescriptor> ctIter = customTaskDescriptors.iterator(); |
| while (ctIter.hasNext()) { |
| CustomTaskDescriptor ctd = ctIter.next(); |
| if (ctd.getId().equalsIgnoreCase(id)) |
| return ctd; |
| } |
| return null; |
| } |
| |
| public boolean customTaskExists ( String id ) { |
| Iterator<CustomTaskDescriptor> ctIter = customTaskDescriptors.iterator(); |
| while (ctIter.hasNext()) { |
| CustomTaskDescriptor ctd = ctIter.next(); |
| if (ctd.getId().equalsIgnoreCase(id)) |
| return true; |
| } |
| return false; |
| } |
| |
| public void addCustomTask(CustomTaskDescriptor ct) { |
| getCustomTaskDescriptors().add(ct); |
| ct.targetRuntime = this; |
| } |
| |
| // FIXME: {@see ICustomElementFeatureContainer#getId(EObject)} |
| public String getCustomTaskId(EObject object) { |
| for (CustomTaskDescriptor ctd : getCustomTaskDescriptors()) { |
| String id = ctd.getFeatureContainer().getId(object); |
| if (ctd.getId().equals(id)) |
| return id; |
| } |
| return null; |
| } |
| |
| /* |
| * Model Extension convenience methods |
| */ |
| public void addModelExtension(ModelExtensionDescriptor me) { |
| getModelExtensionDescriptors().add(me); |
| } |
| |
| /* |
| * Property Extension convenience methods |
| */ |
| public void addPropertyExtension(PropertyExtensionDescriptor me) { |
| getPropertyExtensionDescriptors().add(me); |
| } |
| |
| public PropertyExtensionDescriptor getPropertyExtension(Class clazz) { |
| for (PropertyExtensionDescriptor ped : getPropertyExtensionDescriptors()) { |
| String className = clazz.getName(); |
| if (className.equals(ped.type)) |
| return ped; |
| // well, that didn't work... |
| // The "type" name should be the BPMN2 element's interface definition; |
| // if it's an implementation class name, try to convert it to its |
| // interface name. |
| className = className.replaceFirst("\\.impl\\.", "."); //$NON-NLS-1$ //$NON-NLS-2$ |
| className = className.replaceFirst("Impl$", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (className.equals(ped.type)) |
| return ped; |
| } |
| return null; |
| } |
| |
| /* |
| * Feature Container Extension convenience methods |
| */ |
| public void addFeatureContainer(FeatureContainerDescriptor me) { |
| getFeatureContainerDescriptors().add(me); |
| } |
| |
| public FeatureContainerDescriptor getFeatureContainer(EClass clazz) { |
| for (FeatureContainerDescriptor fcd : getFeatureContainerDescriptors()) { |
| String className = clazz.getInstanceClassName(); |
| if (className.equals(fcd.type)) |
| return fcd; |
| // well, that didn't work... |
| // The "type" name should be the BPMN2 element's interface definition; |
| // if it's an implementation class name, try to convert it to its |
| // interface name. |
| className = className.replaceFirst("\\.impl\\.", "."); //$NON-NLS-1$ //$NON-NLS-2$ |
| className = className.replaceFirst("Impl$", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (className.equals(fcd.type)) |
| return fcd; |
| } |
| return null; |
| } |
| |
| /* |
| * Model Enablement Extension convenience methods |
| */ |
| public ModelEnablementDescriptor getModelEnablements(EObject object) |
| { |
| // TODO: At some point the separation of "Core" and "UI" plugins is going to become |
| // an unmanageable problem: I am having to resort to using DiagramEditor.getAdapter() |
| // more and more just to get things done. |
| // Think about either reorganizing these two plugins, or simply combining them... |
| TargetRuntime rt = this; |
| DiagramEditor diagramEditor = ModelUtil.getEditor(object); |
| if (diagramEditor!=null) { |
| rt = (TargetRuntime) diagramEditor.getAdapter(TargetRuntime.class); |
| } |
| List<ModelEnablementDescriptor> meds = rt.getModelEnablementDescriptors(); |
| if (meds.size()>0) |
| return meds.get(0); |
| return null; |
| } |
| |
| public List<ModelEnablementDescriptor> getModelEnablements() |
| { |
| List<ModelEnablementDescriptor> list = new ArrayList<ModelEnablementDescriptor>(); |
| for (ModelEnablementDescriptor me : getModelEnablementDescriptors()) { |
| list.add(me); |
| } |
| return list; |
| } |
| |
| public ModelEnablementDescriptor getModelEnablements(String profileName) |
| { |
| if (profileName!=null && profileName.isEmpty()) |
| profileName = null; |
| |
| for (ModelEnablementDescriptor me : getModelEnablementDescriptors()) { |
| if (profileName==null || profileName.equalsIgnoreCase(me.getProfileName())) |
| return me; |
| } |
| if (this != getDefaultRuntime()) { |
| // fall back to enablements from Default Runtime |
| return getDefaultRuntime().getModelEnablements(profileName); |
| } |
| return null; |
| } |
| |
| public void addModelEnablements(ModelEnablementDescriptor me) { |
| getModelEnablementDescriptors().add(me); |
| } |
| |
| /* |
| * Tool Palette Extension convenience methods |
| */ |
| public ToolPaletteDescriptor getToolPalette(EObject object) |
| { |
| DiagramEditor diagramEditor = ModelUtil.getEditor(object); |
| return (ToolPaletteDescriptor) diagramEditor.getAdapter(ToolPaletteDescriptor.class); |
| } |
| |
| public ToolPaletteDescriptor getToolPalette(String profileName) { |
| ToolPaletteDescriptor defaultToolPalette = null; |
| // search from the end of the ToolPaletteDescriptors list so that |
| // we'll find the most recently defined ToolPalette, which may be |
| // in a .bpmn2config file |
| List<ToolPaletteDescriptor> allToolPalettes = getToolPaletteDescriptors(); |
| for (int i = allToolPalettes.size() - 1; i >= 0; --i) { |
| ToolPaletteDescriptor tp = allToolPalettes.get(i); |
| if (profileName == null) |
| return tp; |
| for (String p : tp.getProfileIds()) { |
| if (profileName.equalsIgnoreCase(p)) |
| return tp; |
| } |
| if (defaultToolPalette==null) |
| defaultToolPalette = tp; |
| } |
| |
| if (defaultToolPalette != null) |
| return defaultToolPalette; |
| |
| if (this != getDefaultRuntime()) { |
| // fall back to toolPalettes from Default Runtime |
| return getDefaultRuntime().getToolPalette(profileName); |
| } |
| return null; |
| } |
| |
| public void addToolPalette(ToolPaletteDescriptor tp) { |
| getToolPaletteDescriptors().add(tp); |
| } |
| |
| /* |
| * Property Tab Extension convenience methods |
| */ |
| private void addAfterTab(ArrayList<PropertyTabDescriptor> list, PropertyTabDescriptor tab) { |
| |
| createTargetRuntimes(); |
| String afterTab = tab.getAfterTab(); |
| if (afterTab!=null && !afterTab.isEmpty() && !afterTab.equals("top")) { //$NON-NLS-1$ |
| String id = tab.getId(); |
| for (TargetRuntime rt : targetRuntimes) { |
| for (PropertyTabDescriptor td : rt.getPropertyTabDescriptors()) { |
| if (tab!=td) { |
| if (td.getId().equals(afterTab) || td.isReplacementForTab(afterTab)) { |
| addAfterTab(list,td); |
| if (rt==this || rt==TargetRuntime.getDefaultRuntime()) { |
| if (!list.contains(td)) |
| list.add(td); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| public void addPropertyTabDescriptor(PropertyTabDescriptor td) { |
| getPropertyTabDescriptors().add(td); |
| } |
| |
| public static PropertyTabDescriptor findPropertyTabDescriptor(String id) { |
| for (TargetRuntime rt : TargetRuntime.createTargetRuntimes()) { |
| PropertyTabDescriptor tab = rt.getPropertyTabDescriptor(id); |
| if (tab!=null) |
| return tab; |
| } |
| return null; |
| } |
| |
| public PropertyTabDescriptor getPropertyTabDescriptor(String id) { |
| for (PropertyTabDescriptor tab : getPropertyTabDescriptors()) { |
| if (tab.getId().equals(id)) |
| return tab; |
| } |
| return null; |
| } |
| |
| public List<PropertyTabDescriptor> buildPropertyTabDescriptors() { |
| ArrayList<PropertyTabDescriptor> list = new ArrayList<PropertyTabDescriptor>(); |
| for (PropertyTabDescriptor tab : getPropertyTabDescriptors()) { |
| addAfterTab(list, tab); |
| if (!list.contains(tab)) |
| list.add(tab); |
| } |
| |
| return list; |
| } |
| |
| /** |
| * Gets the default Type Language for this Target Runtime. If the Target Runtime does |
| * not define its own Type Languages, use the Default Target Runtime. |
| * |
| * @return the Type Language URI |
| */ |
| public String getTypeLanguage() { |
| if (getTypeLanguageDescriptors().size()>0) { |
| return getTypeLanguageDescriptors().get(0).getUri(); |
| } |
| // extension plugin does not specify a type language, so use default |
| return TargetRuntime.getDefaultRuntime().getTypeLanguage(); |
| } |
| |
| public TypeLanguageDescriptor getTypeLanguageDescriptor(String uri) { |
| if (uri!=null) { |
| for (TypeLanguageDescriptor tld : getTypeLanguageDescriptors()) { |
| if (uri.equals(tld.getUri())) |
| return tld; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Gets the default Expression Language for this Target Runtime. If the Target Runtime does |
| * not define its own Expression Languages, use the Default Target Runtime. |
| * |
| * @return the Expression Language URI |
| */ |
| public String getExpressionLanguage() { |
| if (getExpressionLanguageDescriptors().size()>0) { |
| return getExpressionLanguageDescriptors().get(0).getUri(); |
| } |
| // extension plugin does not specify an expression language, so use default |
| return TargetRuntime.getDefaultRuntime().getExpressionLanguage(); |
| } |
| |
| public ExpressionLanguageDescriptor getExpressionLanguageDescriptor(String uri) { |
| if (uri!=null) { |
| for (ExpressionLanguageDescriptor tld : getExpressionLanguageDescriptors()) { |
| if (uri.equals(tld.getUri())) |
| return tld; |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean equals(Object arg0) { |
| if (arg0 instanceof TargetRuntime) { |
| if (id!=null && id.equals(((TargetRuntime)arg0).getId())) |
| return true; |
| } |
| else if (arg0 instanceof String) { |
| return ((String)arg0).equals(id); |
| } |
| return super.equals(arg0); |
| } |
| |
| /* |
| * Runtime Extension Descriptor handling |
| */ |
| public static void loadExtensions(TargetRuntime targetRuntime, IConfigurationElement[] elements, IFile file) throws TargetRuntimeConfigurationException { |
| ConfigurationElementSorter.sort(elements); |
| |
| unloadExtensions(file); |
| |
| for (IConfigurationElement e : elements) { |
| if (!EXTENSION_NAME.equals(e.getName())) { |
| TargetRuntime currentRuntime = getRuntime(e, targetRuntime); |
| createRuntimeExtensionDescriptor(currentRuntime, e, file); |
| } |
| } |
| } |
| |
| public static void unloadExtensions(IFile file) { |
| if (file != null) { |
| List<IRuntimeExtensionDescriptor> disposed = new ArrayList<IRuntimeExtensionDescriptor>(); |
| |
| for (TargetRuntime rt : targetRuntimes) { |
| for (Class c : extensionDescriptorClasses) { |
| String name = getExtensionNameForClass(c); |
| for (IRuntimeExtensionDescriptor d : rt.getRuntimeExtensionDescriptors(name)) { |
| if (file.equals(d.getConfigFile())) { |
| disposed.add(d); |
| } |
| } |
| } |
| } |
| for (IRuntimeExtensionDescriptor d : disposed) { |
| d.dispose(); |
| } |
| } |
| |
| } |
| |
| public static IRuntimeExtensionDescriptor createRuntimeExtensionDescriptor(TargetRuntime rt, IConfigurationElement e, IFile file) throws TargetRuntimeConfigurationException { |
| IRuntimeExtensionDescriptor d = null; |
| try { |
| Class c = getClassForExtensionName(e.getName()); |
| Constructor ctor = c.getConstructor(IConfigurationElement.class); |
| d = (IRuntimeExtensionDescriptor)ctor.newInstance(e); |
| d.setRuntime(rt); |
| d.setConfigFile(file); |
| } |
| catch (Exception ex) { |
| throw new TargetRuntimeConfigurationException(rt, ex); |
| } |
| return d; |
| } |
| |
| public List<IRuntimeExtensionDescriptor> getRuntimeExtensionDescriptors(String name) { |
| List<IRuntimeExtensionDescriptor> result = new ArrayList<IRuntimeExtensionDescriptor>(); |
| try { |
| Class c = getClassForExtensionName(name); |
| Method m = TargetRuntime.class.getMethod("get"+c.getSimpleName()+"s"); //$NON-NLS-1$ //$NON-NLS-2$ |
| result = (List<IRuntimeExtensionDescriptor>) m.invoke(this); |
| } |
| catch (Exception ex) { |
| throw new TargetRuntimeConfigurationException(this, ex); |
| } |
| return result; |
| } |
| |
| public static Class getClassForExtensionName(String name) { |
| try { |
| Class clazz = null; |
| for (int i=0; i<extensionDescriptorClasses.length; ++i) { |
| Class c = extensionDescriptorClasses[i]; |
| Field field = c.getField("EXTENSION_NAME"); //$NON-NLS-1$ |
| String n = (String) field.get(null); |
| if (name.equals(n)) { |
| return c; |
| } |
| } |
| } |
| catch (Exception ex) { |
| throw new TargetRuntimeConfigurationException(null, ex); |
| } |
| return null; |
| } |
| |
| public static String getExtensionNameForClass(Class clazz) { |
| try { |
| Field field = clazz.getField("EXTENSION_NAME"); //$NON-NLS-1$ |
| return (String) field.get(null); |
| } |
| catch (Exception ex) { |
| throw new TargetRuntimeConfigurationException(null, ex); |
| } |
| } |
| |
| /* |
| * List Accessors for all Runtime Extension Descriptors |
| */ |
| public List<CustomTaskDescriptor> getCustomTaskDescriptors() |
| { |
| if (customTaskDescriptors==null) { |
| customTaskDescriptors = new ArrayList<CustomTaskDescriptor>(); |
| } |
| return customTaskDescriptors; |
| } |
| |
| public List<ModelExtensionDescriptor> getModelExtensionDescriptors() |
| { |
| if (modelExtensionDescriptors==null) { |
| modelExtensionDescriptors = new ArrayList<ModelExtensionDescriptor>(); |
| } |
| return modelExtensionDescriptors; |
| } |
| |
| public List<ModelExtensionDescriptor> getAllModelExtensionDescriptors() |
| { |
| List<ModelExtensionDescriptor> list = new ArrayList<ModelExtensionDescriptor>(); |
| list.addAll(getCustomTaskDescriptors()); |
| list.addAll(getModelExtensionDescriptors()); |
| return list; |
| } |
| |
| public ModelExtensionDescriptor getModelExtensionDescriptor(EObject object) { |
| EClass eClass = (EClass) ((object instanceof EClass) ? object : object.eClass()); |
| |
| for (ModelExtensionDescriptor md : getModelExtensionDescriptors()) { |
| String type = eClass.getName(); |
| if (md.getType().equals(type)) |
| return md; |
| for (EClass ec : eClass.getESuperTypes()) { |
| type = ec.getName(); |
| if (md.getType().equals(type)) |
| return md; |
| ModelExtensionDescriptor md2 = getModelExtensionDescriptor(ec); |
| if (md2!=null) |
| return md2; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns a list of model extension types and their features. A filter can |
| * be used to select only BPMN2 model elements, plugin model elements or |
| * both. |
| * |
| * @param filter selects which elements to return: 0 = all, 1 = BPMN2 model |
| * extensions only, 2 = plugin model extension elements only |
| * @return a list of EClass objects, and their lists of EStructuralFeatures. |
| */ |
| public Hashtable<EClass, List<EStructuralFeature>> getModelExtensions(int filter) { |
| Hashtable<EClass, List<EStructuralFeature>> list = new Hashtable<EClass, List<EStructuralFeature>>(); |
| for (CustomTaskDescriptor ctd : getCustomTaskDescriptors()) { |
| getModelExtensions(filter, ctd, list); |
| } |
| for (ModelExtensionDescriptor med : getModelExtensionDescriptors()) { |
| getModelExtensions(filter, med, list); |
| } |
| if (filter==2) { // plugin extension elements only |
| ModelDescriptor md = getModelDescriptor(); |
| if (md.getEPackage() != Bpmn2Package.eINSTANCE) { |
| for (EClassifier ec : md.getEPackage().getEClassifiers()) { |
| if (ec.getName().equals("DocumentRoot")) //$NON-NLS-1$ |
| continue; |
| if (ec instanceof EClass) { |
| EClass eClass = (EClass)ec; |
| List<EStructuralFeature> features = list.get(eClass); |
| if (features==null) { |
| features = new ArrayList<EStructuralFeature>(); |
| list.put(eClass,features); |
| } |
| for (EStructuralFeature f : eClass.getEStructuralFeatures()) { |
| features.add(f); |
| } |
| } |
| } |
| } |
| } |
| return list; |
| } |
| |
| private void getModelExtensions(int filter, ModelExtensionDescriptor med, Hashtable<EClass, List<EStructuralFeature>> list) { |
| String type = med.getType(); |
| EClassifier bpmn2type = Bpmn2Package.eINSTANCE.getEClassifier(type); |
| if (filter==1) { // BPMN2 elements only |
| if (bpmn2type==null) |
| return; |
| } |
| if (filter==2) { // plugin extension elements only |
| if (bpmn2type!=null) |
| return; |
| } |
| EClass eClass = med.createEClass(type); |
| List<EStructuralFeature> features = list.get(eClass); |
| if (features==null) { |
| features = new ArrayList<EStructuralFeature>(); |
| list.put(eClass,features); |
| } |
| for (Property p : med.getProperties()) { |
| if (bpmn2type instanceof EClass) { |
| // ignore structural features that are already defined in |
| // the BPMN2 package. These <property> elements are used |
| // only for initialization of these features and should not |
| // be considered as model extensions. |
| if (((EClass) bpmn2type).getEStructuralFeature(p.name)!=null) |
| continue; |
| } |
| EStructuralFeature feature = med.createEFeature(eClass, p); |
| if (feature!=null && !features.contains(feature)) |
| features.add(feature); |
| for (Object v : p.getValues()) { |
| if (v instanceof Property) { |
| getModelExtensions(med, (Property)v, list); |
| } |
| } |
| } |
| if (features.isEmpty()) |
| list.remove(eClass); |
| } |
| |
| private void getModelExtensions(ModelExtensionDescriptor med, Property p, Hashtable<EClass, List<EStructuralFeature>> list) { |
| if (p.parent!=null) { |
| EClass eClass = med.getModelDecorator().getEClass(p.parent.type); |
| if (eClass!=null) { |
| List<EStructuralFeature> features = list.get(eClass); |
| if (features==null) { |
| features = new ArrayList<EStructuralFeature>(); |
| list.put(eClass,features); |
| } |
| EStructuralFeature feature = med.createEFeature(eClass, p); |
| if (feature!=null && !features.contains(feature)) |
| features.add(feature); |
| for (Object v : p.getValues()) { |
| if (v instanceof Property) { |
| getModelExtensions(med, (Property)v, list); |
| } |
| } |
| } |
| } |
| } |
| |
| public List<PropertyExtensionDescriptor> getPropertyExtensionDescriptors() |
| { |
| if (propertyExtensionDescriptors==null) { |
| propertyExtensionDescriptors = new ArrayList<PropertyExtensionDescriptor>(); |
| } |
| return propertyExtensionDescriptors; |
| } |
| |
| public List<FeatureContainerDescriptor> getFeatureContainerDescriptors() |
| { |
| if (featureContainerDescriptors==null) { |
| featureContainerDescriptors = new ArrayList<FeatureContainerDescriptor>(); |
| } |
| return featureContainerDescriptors; |
| } |
| |
| public List<ModelEnablementDescriptor> getModelEnablementDescriptors() |
| { |
| if (modelEnablementDescriptors==null) { |
| modelEnablementDescriptors = new ArrayList<ModelEnablementDescriptor>(); |
| } |
| return modelEnablementDescriptors; |
| } |
| |
| public List<ToolPaletteDescriptor> getToolPaletteDescriptors() |
| { |
| if (toolPaletteDescriptors==null) { |
| toolPaletteDescriptors = new ArrayList<ToolPaletteDescriptor>(); |
| } |
| return toolPaletteDescriptors; |
| } |
| |
| public List<ShapeStyle> getShapeStyles() { |
| if (shapeStyles==null) { |
| shapeStyles = new ArrayList<ShapeStyle>(); |
| } |
| return shapeStyles; |
| } |
| |
| public List<PropertyTabDescriptor> getPropertyTabDescriptors() { |
| if (propertyTabDescriptors==null) |
| propertyTabDescriptors = new ArrayList<PropertyTabDescriptor>(); |
| return propertyTabDescriptors; |
| } |
| |
| public List<ModelDescriptor> getModelDescriptors() { |
| if (modelDescriptors==null) |
| modelDescriptors = new ArrayList<ModelDescriptor>(); |
| return modelDescriptors; |
| } |
| |
| public List<DataTypeDescriptor> getDataTypeDescriptors() { |
| if (dataTypeDescriptors==null) |
| dataTypeDescriptors = new ArrayList<DataTypeDescriptor>(); |
| return dataTypeDescriptors; |
| } |
| |
| public List<TypeLanguageDescriptor> getTypeLanguageDescriptors() { |
| if (typeLanguageDescriptors==null) |
| typeLanguageDescriptors = new ArrayList<TypeLanguageDescriptor>(); |
| return typeLanguageDescriptors; |
| } |
| |
| public List<ExpressionLanguageDescriptor> getExpressionLanguageDescriptors() { |
| if (expressionLanguageDescriptors==null) |
| expressionLanguageDescriptors = new ArrayList<ExpressionLanguageDescriptor>(); |
| return expressionLanguageDescriptors; |
| } |
| |
| public List<ServiceImplementationDescriptor> getServiceImplementationDescriptors() { |
| if (serviceImplementationDescriptors==null) |
| serviceImplementationDescriptors = new ArrayList<ServiceImplementationDescriptor>(); |
| return serviceImplementationDescriptors; |
| } |
| |
| public static class ConfigurationElementSorter { |
| public static void sort(IConfigurationElement[] elements) { |
| Arrays.sort(elements, new Comparator<IConfigurationElement>() { |
| @Override |
| public int compare(IConfigurationElement e0, IConfigurationElement e1) { |
| return rank(e1) - rank(e0); |
| } |
| |
| int rank(IConfigurationElement e) { |
| int rank = 0; |
| try { |
| String name = e.getName(); |
| Class clazz = null; |
| for (int i=0; i<extensionDescriptorClasses.length; ++i) { |
| Class c = extensionDescriptorClasses[i]; |
| Field field = c.getField("EXTENSION_NAME"); //$NON-NLS-1$ |
| String n = (String) field.get(null); |
| if (name.equals(n)) { |
| rank = extensionDescriptorClasses.length - i; |
| clazz = c; |
| break; |
| } |
| } |
| rank *= 2; |
| String id = getRuntimeId(e); |
| if (DEFAULT_RUNTIME_ID.equals(id)) |
| rank += 1; |
| } |
| catch (Exception ex) { |
| throw new TargetRuntimeConfigurationException(null, ex); |
| } |
| return rank; |
| } |
| }); |
| } |
| } |
| } |