blob: eb686c8a338fa11bf39c9c943f15d3e42f671dd0 [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
*******************************************************************************/
package org.eclipse.bpmn2.modeler.core.features;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.modeler.core.runtime.CustomTaskImageProvider.IconSize;
import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.IExecutionInfo;
import org.eclipse.graphiti.features.IAddFeature;
import org.eclipse.graphiti.features.ICreateConnectionFeature;
import org.eclipse.graphiti.features.IDeleteFeature;
import org.eclipse.graphiti.features.IDirectEditingFeature;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.ILayoutFeature;
import org.eclipse.graphiti.features.IMoveConnectionDecoratorFeature;
import org.eclipse.graphiti.features.IReconnectionFeature;
import org.eclipse.graphiti.features.IRemoveFeature;
import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.IAddContext;
import org.eclipse.graphiti.features.context.IAreaContext;
import org.eclipse.graphiti.features.context.IContext;
import org.eclipse.graphiti.features.context.ICreateConnectionContext;
import org.eclipse.graphiti.features.context.impl.AddContext;
import org.eclipse.graphiti.features.custom.ICustomFeature;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.osgi.util.NLS;
/**
* The Feature Container for Custom Connections.
* <p>
* This class must be extended by contributing plug-ins that want to extend any
* of the BPMN2 connection elements, e.g. {@link org.eclipse.bpmn2.SequenceFlow}, {@link org.eclipse.bpmn2.Association},
* {@link org.eclipse.bpmn2.MessageFlow} and
* {@link org.eclipse.bpmn2.ConversationLink}
* <p>
* See the {@code <customTask>} element of the
* {@code org.eclipse.bpmn2.modeler.runtime} extension point.
*/
public class CustomConnectionFeatureContainer extends CustomElementFeatureContainer implements
IConnectionFeatureContainer {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getDescription()
*/
public String getDescription() {
if (customTaskDescriptor != null)
return customTaskDescriptor.getDescription();
return Messages.CustomConnectionFeatureContainer_Description;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.IConnectionFeatureContainer#
* getCreateConnectionFeature
* (org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public ICreateConnectionFeature getCreateConnectionFeature(IFeatureProvider fp) {
return new CreateCustomConnectionFeature(fp);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getAddFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public IAddFeature getAddFeature(IFeatureProvider fp) {
return new AddCustomConnectionFeature(fp);
}
/**
* The {@code CreateFeature} base class for creating custom connections.
* <p>
* Custom Connections contributed to the editor <b>MUST</b> subclass this in
* their FeatureContainer implementation.
* <p>
* The creation process copies the modelObject ID string into the Graphiti
* Create Context during the construction phase, then migrates that ID into
* the created {@code PictogramElement}. This is necessary because the ID
* must be associated with the {@code PictogramElement} to allow our Feature
* Provider to correctly identify the Custom Task.
* <p>
* Custom Elements are not available to the Context Button Pad because the
* Graphiti {@code CreateConnectionCommand} constructs a single
* {@code ICreateConnectionContext}, and reuses it for all command/context
* pairs that are collected for display and user selection in a popup menu.
* See
* {@link org.eclipse.graphiti.ui.internal.command.CreateConnectionCommand#execute()}
* . Each command/context pair is first tested with
* {@link org.eclipse.graphiti.internal.command#canExecute()} which
* eventually calls our {@link CreateCustomConnectionFeature#canCreate()}
* where we insert the Custom Element ID into the context properties. Thus,
* all command/context pairs will contain this ID and will attempt to create
* a Custom Element when executed.
*/
public class CreateCustomConnectionFeature extends
AbstractBpmn2CreateConnectionFeature<BaseElement, EObject, EObject> {
/** The create feature delegate. */
protected AbstractBpmn2CreateConnectionFeature createFeatureDelegate;
/** Our own copies of create name and description because the ones in super are private **/
protected String name;
protected String description;
/**
* Instantiates a new {@code CreateFeature} for custom connections. If
* the name and/or description are null or empty strings then they are
* fetched from the Create Feature delegate when required.
*
* @param fp the Feature Provider
* @param name the name of the element being created
* @param description the description of the Create Feature
*/
public CreateCustomConnectionFeature(IFeatureProvider fp, String name, String description) {
super(fp);
IConnectionFeatureContainer fc = (IConnectionFeatureContainer) getFeatureContainer(fp);
createFeatureDelegate = (AbstractBpmn2CreateConnectionFeature) fc.getCreateConnectionFeature(fp);
Assert.isNotNull(createFeatureDelegate);
this.name = name;
this.description = description;
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2CreateConnectionFeature#getCreateName()
*/
@Override
public String getCreateName() {
if (name!=null && !name.isEmpty())
return name;
return createFeatureDelegate.getCreateName();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.
* AbstractBpmn2CreateConnectionFeature#getCreateDescription()
*/
@Override
public String getCreateDescription() {
if (description!=null && !description.isEmpty())
return description;
return createFeatureDelegate.getCreateDescription();
}
/**
* Alternate constructor.
*
* @param fp the Feature Provider
*/
public CreateCustomConnectionFeature(IFeatureProvider fp) {
this(fp, customTaskDescriptor.getName(), NLS.bind(Messages.CustomElementFeatureContainer_Create,
customTaskDescriptor.getName()));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.
* AbstractBpmn2CreateConnectionFeature
* #isAvailable(org.eclipse.graphiti.features.context.IContext)
*/
@Override
public boolean isAvailable(IContext context) {
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.graphiti.features.impl.AbstractFeature#
* addGraphicalRepresentation
* (org.eclipse.graphiti.features.context.IAreaContext,
* java.lang.Object)
*/
@Override
protected PictogramElement addGraphicalRepresentation(IAreaContext context, Object newObject) {
// create a new AddContext and copy our ID into it.
IAddContext addContext = new AddContext(context, newObject);
setId(addContext, getId());
// create the PE and copy our ID into its properties.
PictogramElement pe = getFeatureProvider().addIfPossible(addContext);
FeatureSupport.setPropertyValue(pe, GraphitiConstants.CUSTOM_ELEMENT_ID, id);
return pe;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.func.ICreateConnection#canCreate(org.eclipse
* .graphiti.features.context.ICreateConnectionContext)
*/
@Override
public boolean canCreate(ICreateConnectionContext context) {
// copy our ID into the CreateContext - this is where it all starts!
setId(context, id);
return createFeatureDelegate.canCreate(context);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.
* AbstractBpmn2CreateConnectionFeature
* #canStartConnection(org.eclipse.graphiti
* .features.context.ICreateConnectionContext)
*/
@Override
public boolean canStartConnection(ICreateConnectionContext context) {
setId(context, id);
return createFeatureDelegate.canStartConnection(context);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.
* AbstractBpmn2CreateConnectionFeature
* #createBusinessObject(org.eclipse.
* graphiti.features.context.ICreateConnectionContext)
*/
@Override
public BaseElement createBusinessObject(ICreateConnectionContext context) {
BaseElement businessObject = createFeatureDelegate.createBusinessObject(context);
return businessObject;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.AbstractCreateFlowElementFeature
* #getFlowElementClass()
*/
@Override
public EClass getBusinessObjectClass() {
return createFeatureDelegate.getBusinessObjectClass();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.func.ICreateConnection#create(org.eclipse.graphiti
* .features.context.ICreateConnectionContext)
*/
@Override
public Connection create(ICreateConnectionContext context) {
// Our Custom Task ID should have already been set in canCreate()
// if not, we have a problem; in other words, canCreate() MUST have
// been called by the framework before create()
Assert.isNotNull(getId(context));
return createFeatureDelegate.create(context);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.impl.AbstractCreateConnectionFeature
* #getCreateImageId()
*/
@Override
public String getCreateImageId() {
String icon = customTaskDescriptor.getIcon();
if (icon != null) {
String id = customTaskDescriptor.getImageId(icon, IconSize.SMALL);
if (id != null)
return id;
}
return createFeatureDelegate.getCreateImageId();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.impl.AbstractCreateConnectionFeature
* #getCreateLargeImageId()
*/
@Override
public String getCreateLargeImageId() {
String icon = customTaskDescriptor.getIcon();
if (icon != null) {
String id = customTaskDescriptor.getImageId(icon, IconSize.LARGE);
if (id != null)
return id;
}
return createFeatureDelegate.getCreateLargeImageId();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.
* AbstractBpmn2CreateConnectionFeature#getSourceClass()
*/
@Override
protected Class<EObject> getSourceClass() {
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.
* AbstractBpmn2CreateConnectionFeature#getTargetClass()
*/
@Override
protected Class<EObject> getTargetClass() {
// TODO Auto-generated method stub
return null;
}
}
/**
* The {@code AddFeature} base class for creating custom connections.
* <p>
* Custom Connections contributed to the editor <b>MUST</b> subclass this in
* their FeatureContainer implementation.
*/
public class AddCustomConnectionFeature extends AbstractBpmn2AddFeature<BaseElement> {
/** The add feature delegate. */
protected AbstractBpmn2AddFeature<BaseElement> addFeatureDelegate;
/**
* Instantiates a new {@code AddConnectionFeature} for custom connections.
*
* @param fp the Feature Provider
*/
public AddCustomConnectionFeature(IFeatureProvider fp) {
super(fp);
addFeatureDelegate = (AbstractBpmn2AddFeature) getFeatureContainer(fp).getAddFeature(fp);
Assert.isNotNull(addFeatureDelegate);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.func.IAdd#add(org.eclipse.graphiti.features.
* context.IAddContext)
*/
@Override
public PictogramElement add(IAddContext context) {
PictogramElement pe = addFeatureDelegate.add(context);
// make sure everyone knows that this PE is a custom task
if (pe != null)
FeatureSupport.setPropertyValue(pe, GraphitiConstants.CUSTOM_ELEMENT_ID, getId());
return pe;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.IBpmn2AddFeature#
* getBusinessObject(org.eclipse.graphiti.features.context.IAddContext)
*/
@Override
public BaseElement getBusinessObject(IAddContext context) {
// TODO Auto-generated method stub
return addFeatureDelegate.getBusinessObject(context);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.IBpmn2AddFeature#
* putBusinessObject(org.eclipse.graphiti.features.context.IAddContext,
* org.eclipse.emf.ecore.EObject)
*/
@Override
public void putBusinessObject(IAddContext context, BaseElement businessObject) {
addFeatureDelegate.putBusinessObject(context, businessObject);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.IBpmn2AddFeature#postExecute
* (org.eclipse.graphiti.IExecutionInfo)
*/
@Override
public void postExecute(IExecutionInfo executionInfo) {
addFeatureDelegate.postExecute(executionInfo);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.func.IAdd#canAdd(org.eclipse.graphiti.features
* .context.IAddContext)
*/
@Override
public boolean canAdd(IAddContext context) {
return addFeatureDelegate.canAdd(context);
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2AddFeature#getAddLabelFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public IAddFeature getAddLabelFeature(IFeatureProvider fp) {
// TODO Auto-generated method stub
return addFeatureDelegate.getAddLabelFeature(fp);
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2AddFeature#getHeight()
*/
@Override
public int getHeight(IAddContext context) {
return addFeatureDelegate.getHeight(context);
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2AddFeature#getWidth()
*/
@Override
public int getWidth(IAddContext context) {
return addFeatureDelegate.getWidth(context);
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2AddFeature#getBusinessObjectType()
*/
@Override
public Class getBusinessObjectType() {
return addFeatureDelegate.getBusinessObjectType();
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getUpdateFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public IUpdateFeature getUpdateFeature(IFeatureProvider fp) {
return getFeatureContainer(fp).getUpdateFeature(fp);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getDirectEditingFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public IDirectEditingFeature getDirectEditingFeature(IFeatureProvider fp) {
return getFeatureContainer(fp).getDirectEditingFeature(fp);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getLayoutFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public ILayoutFeature getLayoutFeature(IFeatureProvider fp) {
return getFeatureContainer(fp).getLayoutFeature(fp);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getRemoveFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public IRemoveFeature getRemoveFeature(IFeatureProvider fp) {
return getFeatureContainer(fp).getRemoveFeature(fp);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getDeleteFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public IDeleteFeature getDeleteFeature(IFeatureProvider fp) {
return getFeatureContainer(fp).getDeleteFeature(fp);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer
* #getCustomFeatures(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public ICustomFeature[] getCustomFeatures(IFeatureProvider fp) {
return getFeatureContainer(fp).getCustomFeatures(fp);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.bpmn2.modeler.core.features.IConnectionFeatureContainer#
* getReconnectionFeature(org.eclipse.graphiti.features.IFeatureProvider)
*/
@Override
public IReconnectionFeature getReconnectionFeature(IFeatureProvider fp) {
IConnectionFeatureContainer fc = (IConnectionFeatureContainer) getFeatureContainer(fp);
return fc.getReconnectionFeature(fp);
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.IConnectionFeatureContainer#getMoveConnectionDecoratorFeature(org.eclipse.graphiti.features.context.IMoveConnectionDecoratorContext)
*/
@Override
public IMoveConnectionDecoratorFeature getMoveConnectionDecoratorFeature(IFeatureProvider fp) {
// TODO Auto-generated method stub
return null;
}
}