blob: a6c93739d125da6e34e216bc0a2c5b52d2f6e85d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Red Hat, Inc.
* All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*
* @author Bob Brodt
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.features;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.Collaboration;
import org.eclipse.bpmn2.Participant;
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.model.Bpmn2ModelerFactory;
import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory.KeyValue;
import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences;
import org.eclipse.bpmn2.modeler.core.preferences.ModelEnablements;
import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
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,"",""); //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
public String getCreateName() {
return ModelUtil.getTypeLabel(getFeatureClass());
}
/* (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, getCreateName());
}
@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;
}
}
}
// attempting to create an object in a Participant that has been pushed down
// or a Participant that is just a reference to an actual Participant is not allowed.
// {@see CreateParticipantReferenceFeature}
if (FeatureSupport.isTargetParticipant(context)) {
Participant participant = FeatureSupport.getTargetParticipant(context);
if (FeatureSupport.isParticipantReference(getDiagram(), participant)) {
return false;
}
if (FeatureSupport.hasBpmnDiagram(participant)) {
return false;
}
}
// otherwise, we can create the object
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) {
Object bo = context.getProperty(GraphitiConstants.BUSINESS_OBJECT);
if (bo!=null)
return (T) bo;
Resource resource = getResource(context);
EClass eclass = getBusinessObjectClass();
String id = (String)context.getProperty(GraphitiConstants.CUSTOM_ELEMENT_ID);
T businessObject = (T) Bpmn2ModelerFactory.createObject(resource,eclass,
new KeyValue(GraphitiConstants.CUSTOM_ELEMENT_ID, id));
putBusinessObject(context, businessObject);
changesDone = true;
return businessObject;
}
protected Resource getResource(ICreateContext context) {
PictogramElement pe = context.getTargetContainer();
if (pe==null)
pe = context.getTargetConnection();
return ExtendedPropertiesAdapter.getResource(pe);
}
/* (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);
// ModelExtensionDescriptor#populateObject() is already called in Bpmn2ModelerFactory
// See https://issues.jboss.org/browse/SWITCHYARD-2484
// 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 rt = TargetRuntime.getRuntime(getDiagramEditor());
LifecycleEvent.notify(new LifecycleEvent(EventType.BUSINESSOBJECT_INITIALIZED,
getFeatureProvider(), context, businessObject, rt));
}
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;
}
protected DiagramEditor getDiagramEditor() {
return (DiagramEditor)getFeatureProvider().getDiagramTypeProvider().getDiagramBehavior().getDiagramContainer();
}
}