| /******************************************************************************* |
| * 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.features; |
| |
| import org.eclipse.bpmn2.BaseElement; |
| import org.eclipse.bpmn2.Collaboration; |
| import org.eclipse.bpmn2.di.BPMNDiagram; |
| import org.eclipse.bpmn2.modeler.core.LifecycleEvent; |
| import org.eclipse.bpmn2.modeler.core.LifecycleEvent.EventType; |
| import org.eclipse.bpmn2.modeler.core.ToolTipProvider; |
| import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter; |
| import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ObjectEditingDialog; |
| import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences; |
| import org.eclipse.bpmn2.modeler.core.preferences.ModelEnablements; |
| import org.eclipse.bpmn2.modeler.core.runtime.CustomTaskDescriptor; |
| import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime; |
| import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil; |
| import org.eclipse.bpmn2.modeler.core.utils.ModelUtil; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.graphiti.IExecutionInfo; |
| import org.eclipse.graphiti.features.IFeatureAndContext; |
| import org.eclipse.graphiti.features.IFeatureProvider; |
| import org.eclipse.graphiti.features.context.IContext; |
| import org.eclipse.graphiti.features.context.ICreateContext; |
| import org.eclipse.graphiti.features.context.impl.AddContext; |
| import org.eclipse.graphiti.features.impl.AbstractCreateFeature; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.ui.editor.DiagramEditor; |
| import org.eclipse.osgi.util.NLS; |
| |
| /** |
| * This is the Graphiti CreateFeature base class for all BPMN2 model elements which are considered "shapes" |
| * e.g. {@link org.eclipse.bpmn2.Activity}, {@link org.eclipse.bpmn2.DataObject}, {@link org.eclipse.bpmn2.Gateway}, |
| * {@link org.eclipse.bpmn2.Event}, etc. |
| * |
| * The Type Parameter "T" is the BPMN2 element class. |
| * |
| * @param <T> the generic type of the BPMN2 element |
| */ |
| public abstract class AbstractBpmn2CreateFeature<T extends BaseElement> |
| extends AbstractCreateFeature |
| implements IBpmn2CreateFeature<T, ICreateContext> { |
| |
| /** The changes done. */ |
| protected boolean changesDone = true; |
| |
| /** |
| * Default constructor for this Create Feature. The name and description are |
| * generated by looking up the business object class name in the Messages |
| * class. |
| * |
| * @param fp the BPMN2 Modeler Feature Provider |
| * {@link org.eclipse.bpmn2.modeler.ui.diagram.BPMN2FeatureProvider} |
| */ |
| public AbstractBpmn2CreateFeature(IFeatureProvider fp) { |
| super(fp,"",""); |
| } |
| |
| @Override |
| public String getCreateName() { |
| // TODO: get name from Messages by generating a field name using the business object class |
| return ModelUtil.toCanonicalString(getFeatureClass().getName()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.graphiti.features.impl.AbstractCreateFeature#getCreateDescription() |
| * This is displayed in the Edit -> Undo/Redo menu |
| */ |
| @Override |
| public String getCreateDescription() { |
| // TODO: get description from Messages by generating a field name using the business object class |
| // {@see ExtendedPropertiesAdapter#getDescription()} |
| String description = ToolTipProvider.INSTANCE.getToolTip(this, getFeatureClass()); |
| if (!description.isEmpty()) |
| return description; |
| return NLS.bind(Messages.AbstractBpmn2CreateFeature_Create, ModelUtil.toCanonicalString(getFeatureClass().getName())); |
| } |
| |
| @Override |
| public String getName() { |
| return getCreateName(); |
| } |
| |
| @Override |
| public String getDescription() { |
| return getCreateDescription(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.graphiti.features.impl.AbstractFeature#isAvailable(org.eclipse.graphiti.features.context.IContext) |
| * Returns true if this type of shape is available in the tool palette and context menus. |
| */ |
| @Override |
| public boolean isAvailable(IContext context) { |
| return isModelObjectEnabled(); |
| } |
| |
| @Override |
| public boolean canCreate(ICreateContext context) { |
| if (context.getTargetContainer().equals(getDiagram())) { |
| // Only Participants are allowed in a Conversation |
| BPMNDiagram bpmnDiagram = BusinessObjectUtil.getFirstElementOfType(getDiagram(), BPMNDiagram.class); |
| BaseElement bpmnElement = bpmnDiagram.getPlane().getBpmnElement(); |
| if (bpmnElement instanceof Collaboration) { |
| // If this is a Collaboration and it already contains ConversationNodes |
| // then this is a Conversation Diagram - it can't contain any FlowNodes, |
| // Data items, or Lanes. |
| Collaboration collaboration = (Collaboration) bpmnElement; |
| if (!collaboration.getConversations().isEmpty()) { |
| return false; |
| } |
| } |
| } |
| // otherwise, we can create a Default Process |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.features.IBpmn2CreateFeature#createBusinessObject(org.eclipse.graphiti.features.context.IContext) |
| * Creates the business object, i.e. the BPMN2 element |
| */ |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| public T createBusinessObject(ICreateContext context) { |
| Resource resource = getResource(context); |
| EClass eclass = getBusinessObjectClass(); |
| ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(eclass); |
| String id = (String)context.getProperty(GraphitiConstants.CUSTOM_ELEMENT_ID); |
| if (id!=null) { |
| adapter.setProperty(GraphitiConstants.CUSTOM_ELEMENT_ID, id); |
| } |
| T businessObject = (T)adapter.getObjectDescriptor().createObject(resource,eclass); |
| putBusinessObject(context, businessObject); |
| changesDone = true; |
| return businessObject; |
| } |
| |
| protected Resource getResource(ICreateContext context) { |
| PictogramElement pe = context.getTargetContainer(); |
| if (pe==null) |
| pe = context.getTargetConnection(); |
| EObject bo = BusinessObjectUtil.getBusinessObjectForPictogramElement(pe); |
| return bo.eResource(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.features.IBpmn2CreateFeature#getBusinessObject(org.eclipse.graphiti.features.context.IContext) |
| * Fetches the business object from the Create Context |
| */ |
| @SuppressWarnings("unchecked") |
| public T getBusinessObject(ICreateContext context) { |
| return (T) context.getProperty(GraphitiConstants.BUSINESS_OBJECT); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.features.IBpmn2CreateFeature#putBusinessObject(org.eclipse.graphiti.features.context.IContext, org.eclipse.emf.ecore.EObject) |
| * Saves the business object in the Create Context. |
| * If the object is a Custom Element, it is initialized as defined in the extension plugin's plugin.xml |
| */ |
| public void putBusinessObject(ICreateContext context, T businessObject) { |
| context.putProperty(GraphitiConstants.BUSINESS_OBJECT, businessObject); |
| String id = (String)context.getProperty(GraphitiConstants.CUSTOM_ELEMENT_ID); |
| if (id!=null) { |
| TargetRuntime rt = TargetRuntime.getCurrentRuntime(); |
| CustomTaskDescriptor ctd = rt.getCustomTask(id); |
| ctd.populateObject(businessObject, businessObject.eResource(), true); |
| } |
| |
| TargetRuntime.getCurrentRuntime().notify(new LifecycleEvent(EventType.BUSINESSOBJECT_INITIALIZED, |
| getFeatureProvider(), context, businessObject)); |
| } |
| |
| public EClass getFeatureClass() { |
| return getBusinessObjectClass(); |
| } |
| |
| @Override |
| protected Object getBusinessObjectForPictogramElement(PictogramElement pe) { |
| // the Graphiti {@link |
| // org.eclipse.graphiti.features.impl.AbstractFeature#getBusinessObjectForPictogramElement()} |
| // will return null if the pictogram element is not "active". In some |
| // cases we also want to check |
| // the business object if the PE has not yet been realized {@see |
| // org.eclipse.bpmn2.modeler.core.features.CompoundCreateFeaturePart#canCreate(IContext)} |
| Object bo = super.getBusinessObjectForPictogramElement(pe); |
| if (bo!=null) |
| return bo; |
| return BusinessObjectUtil.getFirstBaseElement(pe); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.bpmn2.modeler.core.features.IBpmn2CreateFeature#postExecute(org.eclipse.graphiti.IExecutionInfo) |
| * Invoked after the graphic has been created to display an optional configuration dialog. |
| * The configuration dialog popup is enabled/disabled in the user Preferences for BPMN2 Editor. |
| */ |
| public void postExecute(IExecutionInfo executionInfo) { |
| for (IFeatureAndContext fc : executionInfo.getExecutionList()) { |
| IContext context = fc.getContext(); |
| if (context instanceof ICreateContext) { |
| ICreateContext cc = (ICreateContext)context; |
| T businessObject = getBusinessObject(cc); |
| Bpmn2Preferences prefs = (Bpmn2Preferences) ((DiagramEditor) getDiagramEditor()).getAdapter(Bpmn2Preferences.class); |
| if (prefs!=null && prefs.getShowPopupConfigDialog(businessObject)) { |
| ObjectEditingDialog dialog = |
| new ObjectEditingDialog((DiagramEditor)getDiagramEditor(), businessObject); |
| dialog.open(); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Creates and prepares a new AddContext from a CreateContext. |
| * |
| * @param context the original CreateContext |
| * @param newObject the new object, a BPMN2 model object. |
| * @return the new AddContext |
| */ |
| protected AddContext createAddContext(ICreateContext context, Object newObject) { |
| AddContext newContext = new AddContext(context, newObject); |
| |
| // copy properties into the new context |
| Object value = context.getProperty(GraphitiConstants.CUSTOM_ELEMENT_ID); |
| newContext.putProperty(GraphitiConstants.CUSTOM_ELEMENT_ID, value); |
| value = context.getProperty(GraphitiConstants.IMPORT_PROPERTY); |
| newContext.putProperty(GraphitiConstants.IMPORT_PROPERTY, value); |
| value = context.getProperty(GraphitiConstants.BUSINESS_OBJECT); |
| newContext.putProperty(GraphitiConstants.BUSINESS_OBJECT, value); |
| return newContext; |
| } |
| |
| /** |
| * Convenience method to check if a model object was disabled in the extension plugin. |
| * |
| * @return true/false depending on if the model object is enabled or disabled. |
| * If disabled, the object will not be available and will not appear in the tool palette |
| * or context menus. |
| */ |
| protected boolean isModelObjectEnabled() { |
| ModelEnablements me = getModelEnablements(); |
| if (me!=null) |
| return me.isEnabled(getBusinessObjectClass()); |
| return false; |
| } |
| |
| /** |
| * Checks if model object is enabled. |
| * |
| * @param object the object |
| * @return true, if model object is enabled |
| */ |
| protected boolean isModelObjectEnabled(EObject object) { |
| ModelEnablements me = getModelEnablements(); |
| if (me!=null) |
| return me.isEnabled(object.eClass()); |
| return false; |
| } |
| |
| /** |
| * Gets the model enablements. |
| * |
| * @return the model enablements |
| */ |
| protected ModelEnablements getModelEnablements() { |
| DiagramEditor editor = (DiagramEditor) getDiagramEditor(); |
| return (ModelEnablements) editor.getAdapter(ModelEnablements.class); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.graphiti.features.impl.AbstractFeature#hasDoneChanges() |
| */ |
| @Override |
| public boolean hasDoneChanges() { |
| return changesDone; |
| } |
| } |