| /******************************************************************************* |
| * 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 Innar Made |
| ******************************************************************************/ |
| package org.eclipse.bpmn2.modeler.ui.diagram; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| |
| import org.eclipse.bpmn2.AdHocSubProcess; |
| import org.eclipse.bpmn2.Association; |
| import org.eclipse.bpmn2.BoundaryEvent; |
| import org.eclipse.bpmn2.BusinessRuleTask; |
| import org.eclipse.bpmn2.CallActivity; |
| import org.eclipse.bpmn2.CallChoreography; |
| import org.eclipse.bpmn2.CallConversation; |
| import org.eclipse.bpmn2.CancelEventDefinition; |
| import org.eclipse.bpmn2.ChoreographyTask; |
| import org.eclipse.bpmn2.CompensateEventDefinition; |
| import org.eclipse.bpmn2.ComplexGateway; |
| import org.eclipse.bpmn2.ConditionalEventDefinition; |
| import org.eclipse.bpmn2.Conversation; |
| import org.eclipse.bpmn2.ConversationLink; |
| import org.eclipse.bpmn2.DataAssociation; |
| import org.eclipse.bpmn2.DataInput; |
| import org.eclipse.bpmn2.DataObject; |
| import org.eclipse.bpmn2.DataObjectReference; |
| import org.eclipse.bpmn2.DataOutput; |
| import org.eclipse.bpmn2.DataStoreReference; |
| import org.eclipse.bpmn2.EndEvent; |
| import org.eclipse.bpmn2.ErrorEventDefinition; |
| import org.eclipse.bpmn2.EscalationEventDefinition; |
| import org.eclipse.bpmn2.EventBasedGateway; |
| import org.eclipse.bpmn2.ExclusiveGateway; |
| import org.eclipse.bpmn2.GlobalBusinessRuleTask; |
| import org.eclipse.bpmn2.GlobalManualTask; |
| import org.eclipse.bpmn2.GlobalScriptTask; |
| import org.eclipse.bpmn2.GlobalTask; |
| import org.eclipse.bpmn2.GlobalUserTask; |
| import org.eclipse.bpmn2.Group; |
| import org.eclipse.bpmn2.InclusiveGateway; |
| import org.eclipse.bpmn2.IntermediateCatchEvent; |
| import org.eclipse.bpmn2.IntermediateThrowEvent; |
| import org.eclipse.bpmn2.Lane; |
| import org.eclipse.bpmn2.LinkEventDefinition; |
| import org.eclipse.bpmn2.ManualTask; |
| import org.eclipse.bpmn2.Message; |
| import org.eclipse.bpmn2.MessageEventDefinition; |
| import org.eclipse.bpmn2.MessageFlow; |
| import org.eclipse.bpmn2.ParallelGateway; |
| import org.eclipse.bpmn2.Participant; |
| import org.eclipse.bpmn2.ReceiveTask; |
| import org.eclipse.bpmn2.ScriptTask; |
| import org.eclipse.bpmn2.SendTask; |
| import org.eclipse.bpmn2.SequenceFlow; |
| import org.eclipse.bpmn2.ServiceTask; |
| import org.eclipse.bpmn2.SignalEventDefinition; |
| import org.eclipse.bpmn2.StartEvent; |
| import org.eclipse.bpmn2.SubChoreography; |
| import org.eclipse.bpmn2.SubConversation; |
| import org.eclipse.bpmn2.SubProcess; |
| import org.eclipse.bpmn2.Task; |
| import org.eclipse.bpmn2.TerminateEventDefinition; |
| import org.eclipse.bpmn2.TextAnnotation; |
| import org.eclipse.bpmn2.TimerEventDefinition; |
| import org.eclipse.bpmn2.Transaction; |
| import org.eclipse.bpmn2.UserTask; |
| 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.di.DIImport; |
| import org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2AddFeature; |
| import org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2CreateConnectionFeature; |
| import org.eclipse.bpmn2.modeler.core.features.AbstractBpmn2CreateFeature; |
| import org.eclipse.bpmn2.modeler.core.features.BPMNDiagramFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.CustomConnectionFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.CustomElementFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.CustomShapeFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.CustomShapeFeatureContainer.CreateCustomShapeFeature; |
| import org.eclipse.bpmn2.modeler.core.features.DefaultCopyBPMNElementFeature; |
| import org.eclipse.bpmn2.modeler.core.features.DefaultDeleteBPMNShapeFeature; |
| import org.eclipse.bpmn2.modeler.core.features.DefaultPasteBPMNElementFeature; |
| import org.eclipse.bpmn2.modeler.core.features.DefaultRemoveBPMNShapeFeature; |
| import org.eclipse.bpmn2.modeler.core.features.GraphitiConstants; |
| import org.eclipse.bpmn2.modeler.core.features.IBpmn2FeatureProvider; |
| import org.eclipse.bpmn2.modeler.core.features.IConnectionFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.ICustomElementFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.IFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.IShapeFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.features.bendpoint.AddBendpointFeature; |
| import org.eclipse.bpmn2.modeler.core.features.bendpoint.MoveBendpointFeature; |
| import org.eclipse.bpmn2.modeler.core.features.bendpoint.RemoveBendpointFeature; |
| import org.eclipse.bpmn2.modeler.core.features.flow.AbstractCreateFlowFeature; |
| import org.eclipse.bpmn2.modeler.core.features.label.LabelFeatureContainer; |
| import org.eclipse.bpmn2.modeler.core.runtime.CustomTaskDescriptor; |
| import org.eclipse.bpmn2.modeler.core.runtime.FeatureContainerDescriptor; |
| import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime; |
| import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil; |
| import org.eclipse.bpmn2.modeler.ui.editor.DefaultBPMN2Editor; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.AdHocSubProcessFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.SubProcessFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.TransactionFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.BusinessRuleTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.ManualTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.ReceiveTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.ScriptTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.SendTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.ServiceTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.TaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.activity.task.UserTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.artifact.GroupFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.artifact.TextAnnotationFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.callactivity.CallActivityFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.callactivity.CallGlobalBusinessRuleTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.callactivity.CallGlobalManualTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.callactivity.CallGlobalScriptTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.callactivity.CallGlobalTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.callactivity.CallGlobalUserTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.choreography.CallChoreographyFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographyMessageLinkFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographyTaskFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.choreography.SubChoreographyFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.conversation.CallConversationFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.conversation.ConversationFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.conversation.ConversationLinkFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.conversation.SubConversationFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.data.DataInputFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.data.DataObjectFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.data.DataObjectReferenceFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.data.DataOutputFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.data.DataStoreReferenceFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.data.MessageFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.BoundaryEventFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.EndEventFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.IntermediateCatchEventFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.IntermediateThrowEventFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.StartEventFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.CancelEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.CompensateEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.ConditionalEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.ErrorEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.EscalationEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.LinkEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.MessageEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.SignalEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.TerminateEventDefinitionFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.event.definitions.TimerEventDefinitionContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.flow.AssociationFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.flow.DataAssociationFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.flow.MessageFlowFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.flow.SequenceFlowFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.gateway.ComplexGatewayFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.gateway.EventBasedGatewayFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.gateway.ExclusiveGatewayFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.gateway.InclusiveGatewayFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.gateway.ParallelGatewayFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.lane.LaneFeatureContainer; |
| import org.eclipse.bpmn2.modeler.ui.features.participant.ParticipantFeatureContainer; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.graphiti.dt.IDiagramTypeProvider; |
| import org.eclipse.graphiti.features.IAddBendpointFeature; |
| import org.eclipse.graphiti.features.IAddFeature; |
| import org.eclipse.graphiti.features.ICopyFeature; |
| import org.eclipse.graphiti.features.ICreateConnectionFeature; |
| import org.eclipse.graphiti.features.ICreateFeature; |
| import org.eclipse.graphiti.features.IDeleteFeature; |
| import org.eclipse.graphiti.features.IDirectEditingFeature; |
| import org.eclipse.graphiti.features.IFeature; |
| import org.eclipse.graphiti.features.ILayoutFeature; |
| import org.eclipse.graphiti.features.IMoveBendpointFeature; |
| import org.eclipse.graphiti.features.IMoveConnectionDecoratorFeature; |
| import org.eclipse.graphiti.features.IMoveShapeFeature; |
| import org.eclipse.graphiti.features.IPasteFeature; |
| import org.eclipse.graphiti.features.IReason; |
| import org.eclipse.graphiti.features.IReconnectionFeature; |
| import org.eclipse.graphiti.features.IRemoveBendpointFeature; |
| import org.eclipse.graphiti.features.IRemoveFeature; |
| import org.eclipse.graphiti.features.IResizeShapeFeature; |
| import org.eclipse.graphiti.features.IUpdateFeature; |
| import org.eclipse.graphiti.features.context.IAddBendpointContext; |
| import org.eclipse.graphiti.features.context.IAddContext; |
| import org.eclipse.graphiti.features.context.IContext; |
| import org.eclipse.graphiti.features.context.ICopyContext; |
| import org.eclipse.graphiti.features.context.ICustomContext; |
| import org.eclipse.graphiti.features.context.IDeleteContext; |
| import org.eclipse.graphiti.features.context.IDirectEditingContext; |
| import org.eclipse.graphiti.features.context.ILayoutContext; |
| import org.eclipse.graphiti.features.context.IMoveBendpointContext; |
| import org.eclipse.graphiti.features.context.IMoveConnectionDecoratorContext; |
| import org.eclipse.graphiti.features.context.IMoveShapeContext; |
| import org.eclipse.graphiti.features.context.IPasteContext; |
| import org.eclipse.graphiti.features.context.IPictogramElementContext; |
| import org.eclipse.graphiti.features.context.IReconnectionContext; |
| import org.eclipse.graphiti.features.context.IRemoveBendpointContext; |
| import org.eclipse.graphiti.features.context.IRemoveContext; |
| import org.eclipse.graphiti.features.context.IResizeShapeContext; |
| import org.eclipse.graphiti.features.context.IUpdateContext; |
| import org.eclipse.graphiti.features.custom.ICustomFeature; |
| import org.eclipse.graphiti.features.impl.Reason; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.platform.IDiagramBehavior; |
| import org.eclipse.graphiti.services.Graphiti; |
| import org.eclipse.graphiti.ui.features.DefaultFeatureProvider; |
| |
| /** |
| * Determines what kinds of business objects can be added to a diagram. |
| * |
| * @author imeikas |
| * |
| */ |
| @SuppressWarnings("rawtypes") |
| public class BPMN2FeatureProvider extends DefaultFeatureProvider implements IBpmn2FeatureProvider { |
| |
| private LinkedHashMap<Class,IFeatureContainer> containers; |
| private LinkedHashMap<String,ICustomElementFeatureContainer> customTaskContainers; |
| private ICreateFeature[] createFeatures; |
| private ICreateConnectionFeature[] createConnectionFeatures; |
| private HashMap<Class,IFeature> mapBusinessObjectClassToCreateFeature = new HashMap<Class,IFeature>(); |
| private DefaultCopyBPMNElementFeature defaultCopyFeature = new DefaultCopyBPMNElementFeature(this); |
| private DefaultPasteBPMNElementFeature defaultPasteFeature = new DefaultPasteBPMNElementFeature(this); |
| |
| public BPMN2FeatureProvider(IDiagramTypeProvider dtp) { |
| super(dtp); |
| } |
| |
| private void initializeFeatureContainers() { |
| containers = new LinkedHashMap<Class,IFeatureContainer>(); |
| containers.put(Group.class,new GroupFeatureContainer()); |
| containers.put(DataObject.class,new DataObjectFeatureContainer()); |
| containers.put(DataObjectReference.class,new DataObjectReferenceFeatureContainer()); |
| containers.put(DataStoreReference.class,new DataStoreReferenceFeatureContainer()); |
| containers.put(DataInput.class,new DataInputFeatureContainer()); |
| containers.put(DataOutput.class,new DataOutputFeatureContainer()); |
| containers.put(Message.class,new MessageFeatureContainer()); |
| containers.put(StartEvent.class,new StartEventFeatureContainer()); |
| containers.put(EndEvent.class,new EndEventFeatureContainer()); |
| containers.put(IntermediateCatchEvent.class,new IntermediateCatchEventFeatureContainer()); |
| containers.put(IntermediateThrowEvent.class,new IntermediateThrowEventFeatureContainer()); |
| containers.put(BoundaryEvent.class,new BoundaryEventFeatureContainer()); |
| containers.put(Task.class,new TaskFeatureContainer()); |
| containers.put(ScriptTask.class,new ScriptTaskFeatureContainer()); |
| containers.put(ServiceTask.class,new ServiceTaskFeatureContainer()); |
| containers.put(UserTask.class,new UserTaskFeatureContainer()); |
| containers.put(ManualTask.class,new ManualTaskFeatureContainer()); |
| containers.put(BusinessRuleTask.class,new BusinessRuleTaskFeatureContainer()); |
| containers.put(SendTask.class,new SendTaskFeatureContainer()); |
| containers.put(ReceiveTask.class,new ReceiveTaskFeatureContainer()); |
| containers.put(ChoreographyTask.class,new ChoreographyTaskFeatureContainer()); |
| containers.put(ExclusiveGateway.class,new ExclusiveGatewayFeatureContainer()); |
| containers.put(InclusiveGateway.class,new InclusiveGatewayFeatureContainer()); |
| containers.put(ParallelGateway.class,new ParallelGatewayFeatureContainer()); |
| containers.put(EventBasedGateway.class,new EventBasedGatewayFeatureContainer()); |
| containers.put(ComplexGateway.class,new ComplexGatewayFeatureContainer()); |
| containers.put(AdHocSubProcess.class,new AdHocSubProcessFeatureContainer()); |
| containers.put(CallActivity.class,new CallActivityFeatureContainer()); |
| containers.put(GlobalTask.class,new CallGlobalTaskFeatureContainer()); |
| containers.put(GlobalBusinessRuleTask.class,new CallGlobalBusinessRuleTaskFeatureContainer()); |
| containers.put(GlobalManualTask.class,new CallGlobalManualTaskFeatureContainer()); |
| containers.put(GlobalScriptTask.class,new CallGlobalScriptTaskFeatureContainer()); |
| containers.put(GlobalUserTask.class,new CallGlobalUserTaskFeatureContainer()); |
| containers.put(Transaction.class,new TransactionFeatureContainer()); |
| containers.put(SubProcess.class,new SubProcessFeatureContainer()); |
| containers.put(ConditionalEventDefinition.class,new ConditionalEventDefinitionContainer()); |
| containers.put(MessageEventDefinition.class,new MessageEventDefinitionContainer()); |
| containers.put(TimerEventDefinition.class,new TimerEventDefinitionContainer()); |
| containers.put(SignalEventDefinition.class,new SignalEventDefinitionContainer()); |
| containers.put(EscalationEventDefinition.class,new EscalationEventDefinitionContainer()); |
| containers.put(CompensateEventDefinition.class,new CompensateEventDefinitionContainer()); |
| containers.put(LinkEventDefinition.class,new LinkEventDefinitionContainer()); |
| containers.put(ErrorEventDefinition.class,new ErrorEventDefinitionContainer()); |
| containers.put(CancelEventDefinition.class,new CancelEventDefinitionContainer()); |
| containers.put(TerminateEventDefinition.class,new TerminateEventDefinitionFeatureContainer()); |
| containers.put(SequenceFlow.class,new SequenceFlowFeatureContainer()); |
| containers.put(MessageFlow.class,new MessageFlowFeatureContainer()); |
| containers.put(Association.class,new AssociationFeatureContainer()); |
| containers.put(Conversation.class,new ConversationFeatureContainer()); |
| containers.put(SubConversation.class,new SubConversationFeatureContainer()); |
| containers.put(CallConversation.class,new CallConversationFeatureContainer()); |
| containers.put(ConversationLink.class,new ConversationLinkFeatureContainer()); |
| containers.put(DataAssociation.class,new DataAssociationFeatureContainer()); |
| containers.put(SubChoreography.class,new SubChoreographyFeatureContainer()); |
| containers.put(CallChoreography.class,new CallChoreographyFeatureContainer()); |
| containers.put(Participant.class,new ParticipantFeatureContainer()); |
| containers.put(Lane.class,new LaneFeatureContainer()); |
| containers.put(TextAnnotation.class,new TextAnnotationFeatureContainer()); |
| containers.put(BPMNDiagram.class,new BPMNDiagramFeatureContainer()); |
| // these have no BPMN2 element equivalents |
| containers.put(ChoreographyMessageLinkFeatureContainer.class,new ChoreographyMessageLinkFeatureContainer()); |
| containers.put(LabelFeatureContainer.class,new LabelFeatureContainer()); |
| } |
| |
| public void addFeatureContainer(String id, ICustomElementFeatureContainer fc) throws Exception { |
| |
| if (customTaskContainers==null) { |
| customTaskContainers = new LinkedHashMap<String,ICustomElementFeatureContainer>(); |
| } |
| customTaskContainers.put(id,fc); |
| updateFeatureLists(); |
| } |
| |
| public void init() { |
| updateFeatureLists(); |
| } |
| |
| private void updateFeatureLists() { |
| |
| initializeFeatureContainers(); |
| |
| // Collect all of the <featureContainerDelegate> extensions defined by the current TargetRuntime |
| // and replace the ones in our list of FeatureContainers |
| IDiagramBehavior diagramBehavior = getDiagramTypeProvider().getDiagramBehavior(); |
| TargetRuntime rt = diagramBehavior != null ? TargetRuntime.getRuntime(diagramBehavior) : TargetRuntime.getDefaultRuntime(); |
| for (FeatureContainerDescriptor fcd : rt.getFeatureContainerDescriptors()) { |
| IFeatureContainer fc = fcd.getFeatureContainer(); |
| if (fc instanceof IConnectionFeatureContainer) { |
| ICreateConnectionFeature createConnectionFeature = ((IConnectionFeatureContainer)fc) |
| .getCreateConnectionFeature(this); |
| if (createConnectionFeature!=null) { |
| containers.put(fcd.getType(), fc); |
| } |
| } |
| if (fc instanceof IShapeFeatureContainer) { |
| ICreateFeature createFeature = ((IShapeFeatureContainer)fc).getCreateFeature(this); |
| if (createFeature != null) { |
| containers.put(fcd.getType(), fc); |
| } |
| } |
| } |
| |
| // build the list of CreateFeatures from our new list of all FeatureContainers |
| List<ICreateFeature> createFeaturesList = new ArrayList<ICreateFeature>(); |
| List<ICreateConnectionFeature> createConnectionFeatureList = new ArrayList<ICreateConnectionFeature>(); |
| |
| for (IFeatureContainer fc : containers.values()) { |
| if (fc instanceof IConnectionFeatureContainer) { |
| ICreateConnectionFeature createConnectionFeature = ((IConnectionFeatureContainer) fc) |
| .getCreateConnectionFeature(this); |
| if (createConnectionFeature != null) { |
| createConnectionFeatureList.add(createConnectionFeature); |
| } |
| } |
| if (fc instanceof IShapeFeatureContainer) { |
| ICreateFeature createFeature = ((IShapeFeatureContainer) fc).getCreateFeature(this); |
| if (createFeature != null) { |
| createFeaturesList.add(createFeature); |
| } |
| } |
| } |
| if (customTaskContainers!=null) { |
| for (IFeatureContainer fc : customTaskContainers.values()) { |
| if (fc instanceof IConnectionFeatureContainer) { |
| ICreateConnectionFeature createConnectionFeature = ((IConnectionFeatureContainer) fc) |
| .getCreateConnectionFeature(this); |
| if (createConnectionFeature != null) { |
| createConnectionFeatureList.add(createConnectionFeature); |
| } |
| } |
| if (fc instanceof IShapeFeatureContainer) { |
| ICreateFeature createFeature = ((IShapeFeatureContainer) fc).getCreateFeature(this); |
| if (createFeature != null) { |
| createFeaturesList.add(createFeature); |
| } |
| } |
| } |
| } |
| |
| createFeatures = createFeaturesList.toArray(new ICreateFeature[createFeaturesList.size()]); |
| createConnectionFeatures = createConnectionFeatureList |
| .toArray(new ICreateConnectionFeature[createConnectionFeatureList.size()]); |
| |
| mapBusinessObjectClassToCreateFeature.clear(); |
| for (IFeature cf : createFeatures) { |
| if (cf instanceof AbstractBpmn2CreateFeature) { |
| if (cf instanceof CreateCustomShapeFeature) { |
| continue; |
| } |
| AbstractBpmn2CreateFeature acf = (AbstractBpmn2CreateFeature)cf; |
| mapBusinessObjectClassToCreateFeature.put(acf.getFeatureClass().getInstanceClass(), cf); |
| } |
| } |
| for (IFeature cf : createConnectionFeatures) { |
| if (cf instanceof AbstractCreateFlowFeature) { |
| AbstractBpmn2CreateConnectionFeature acf = (AbstractBpmn2CreateConnectionFeature)cf; |
| mapBusinessObjectClassToCreateFeature.put(acf.getFeatureClass().getInstanceClass(), cf); |
| } |
| } |
| } |
| |
| private EObject getApplyObject(IContext context) { |
| if (context instanceof IAddContext) { |
| Object object = ((IAddContext) context).getNewObject(); |
| if (object instanceof EObject) |
| return (EObject)object; |
| } else if (context instanceof IPictogramElementContext) { |
| return BusinessObjectUtil.getFirstElementOfType( |
| (((IPictogramElementContext) context).getPictogramElement()), EObject.class); |
| } else if (context instanceof IReconnectionContext) { |
| return BusinessObjectUtil.getFirstElementOfType( |
| (((IReconnectionContext) context).getConnection()), EObject.class); |
| } |
| return null; |
| } |
| |
| public IFeatureContainer getFeatureContainer(Class clazz) { |
| return containers.get(clazz); |
| } |
| |
| public IFeatureContainer getFeatureContainer(IContext context) { |
| |
| // The special LabelFeatureContainer is used to add labels to figures that were |
| // added within the given IContext |
| // LabelFeatureContainer lfc = (LabelFeatureContainer) containers.get(LabelFeatureContainer.class); |
| // if (lfc.getApplyObject(context)!=null) |
| // return lfc; |
| |
| TargetRuntime rt = getTargetRuntime(); |
| EObject object = getApplyObject(context); |
| if (object!=null) { |
| FeatureContainerDescriptor fcd = rt.getFeatureContainer(object.eClass()); |
| if (fcd!=null) |
| return fcd.getFeatureContainer(); |
| } |
| |
| Object id = CustomElementFeatureContainer.getId(context); |
| for (IFeatureContainer container : containers.values()) { |
| if (id!=null && !(container instanceof ICustomElementFeatureContainer)) |
| continue; |
| Object o = container.getApplyObject(context); |
| if (o != null && container.canApplyTo(o)) { |
| return container; |
| } |
| } |
| if (id!=null) { |
| for (CustomTaskDescriptor ct : rt.getCustomTaskDescriptors()) { |
| if (id.equals(ct.getId())) { |
| ICustomElementFeatureContainer container = (ICustomElementFeatureContainer)ct.getFeatureContainer(); |
| return container; |
| } |
| } |
| } |
| // last chance: check custom task feature containers |
| if (customTaskContainers!=null) { |
| if (id!=null) { |
| IFeatureContainer container = customTaskContainers.get(id); |
| if (container!=null && container.getApplyObject(context)!=null) |
| return container; |
| } |
| else { |
| for (IFeatureContainer container : customTaskContainers.values()) { |
| if (container.getApplyObject(context)!=null) |
| return container; |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public IAddFeature getAddFeature(IAddContext context) { |
| // only here do we need to search all of the Custom Task extensions to check if |
| // the newObject (in AddContext) is a Custom Task. This is because of a chicken/egg |
| // problem during DIImport: the Custom Task feature containers are not added to |
| // the toolpalette until AFTER the file is loaded (in DIImport) and getAddFeature() |
| // is called during file loading. |
| Object id = CustomElementFeatureContainer.getId(context); |
| if (id!=null) { |
| TargetRuntime rt = getTargetRuntime(); |
| for (CustomTaskDescriptor ct : rt.getCustomTaskDescriptors()) { |
| if (id.equals(ct.getId())) { |
| ICustomElementFeatureContainer container = (ICustomElementFeatureContainer)ct.getFeatureContainer(); |
| return container.getAddFeature(this); |
| } |
| } |
| } |
| |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container!=null) { |
| IAddFeature feature = container.getAddFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getAddFeature(context); |
| } |
| |
| @Override |
| public ICreateFeature[] getCreateFeatures() { |
| return createFeatures; |
| } |
| |
| @Override |
| public IUpdateFeature getUpdateFeature(IUpdateContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container!=null) { |
| IUpdateFeature feature = container.getUpdateFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getUpdateFeature(context); |
| } |
| |
| @Override |
| public ICreateConnectionFeature[] getCreateConnectionFeatures() { |
| return createConnectionFeatures; |
| } |
| |
| @Override |
| public IDirectEditingFeature getDirectEditingFeature(IDirectEditingContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container!=null) { |
| IDirectEditingFeature feature = container.getDirectEditingFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getDirectEditingFeature(context); |
| } |
| |
| @Override |
| public ILayoutFeature getLayoutFeature(ILayoutContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container!=null) { |
| ILayoutFeature feature = container.getLayoutFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getLayoutFeature(context); |
| } |
| |
| @Override |
| public IMoveShapeFeature getMoveShapeFeature(IMoveShapeContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container instanceof IShapeFeatureContainer) { |
| IMoveShapeFeature feature = ((IShapeFeatureContainer)container).getMoveFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getMoveShapeFeature(context); |
| } |
| |
| @Override |
| public IMoveConnectionDecoratorFeature getMoveConnectionDecoratorFeature(IMoveConnectionDecoratorContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container instanceof IConnectionFeatureContainer) { |
| IMoveConnectionDecoratorFeature feature = ((IConnectionFeatureContainer)container).getMoveConnectionDecoratorFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getMoveConnectionDecoratorFeature(context); |
| } |
| |
| @Override |
| public IResizeShapeFeature getResizeShapeFeature(IResizeShapeContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container instanceof IShapeFeatureContainer) { |
| IResizeShapeFeature feature = ((IShapeFeatureContainer)container).getResizeFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getResizeShapeFeature(context); |
| } |
| |
| @Override |
| public IAddBendpointFeature getAddBendpointFeature(IAddBendpointContext context) { |
| return new AddBendpointFeature(this); |
| } |
| |
| @Override |
| public IMoveBendpointFeature getMoveBendpointFeature(IMoveBendpointContext context) { |
| return new MoveBendpointFeature(this); |
| } |
| |
| @Override |
| public IRemoveBendpointFeature getRemoveBendpointFeature(IRemoveBendpointContext context) { |
| return new RemoveBendpointFeature(this); |
| } |
| |
| @Override |
| public IReconnectionFeature getReconnectionFeature(IReconnectionContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container instanceof IConnectionFeatureContainer) { |
| IReconnectionFeature feature = ((IConnectionFeatureContainer)container).getReconnectionFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return super.getReconnectionFeature(context); |
| } |
| |
| @Override |
| public IDeleteFeature getDeleteFeature(IDeleteContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container!=null) { |
| IDeleteFeature feature = container.getDeleteFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return new DefaultDeleteBPMNShapeFeature(this); |
| } |
| |
| @Override |
| public IRemoveFeature getRemoveFeature(IRemoveContext context) { |
| IFeatureContainer container = getFeatureContainer(context); |
| if (container!=null) { |
| IRemoveFeature feature = container.getRemoveFeature(this); |
| if (feature != null) |
| return feature; |
| } |
| return new DefaultRemoveBPMNShapeFeature(this); |
| } |
| |
| |
| @Override |
| public ICustomFeature[] getCustomFeatures(ICustomContext context) { |
| List<ICustomFeature> list = new ArrayList<ICustomFeature>(); |
| |
| TargetRuntime rt = getTargetRuntime(); |
| String id = CustomElementFeatureContainer.getId(context); |
| if (id!=null) { |
| for (CustomTaskDescriptor ct : rt.getCustomTaskDescriptors()) { |
| ICustomElementFeatureContainer ctf = ct.getFeatureContainer(); |
| if (ctf!=null && id.equals(ctf.getId())) { |
| ICustomFeature[] cfa = ctf.getCustomFeatures(this); |
| if (cfa!=null) { |
| for (ICustomFeature cf : cfa) { |
| if (cf.isAvailable(context)) { |
| boolean found = false; |
| for (ICustomFeature cfl : list) { |
| if (cfl.getClass() == cf.getClass()) { |
| found = true; |
| break; |
| } |
| } |
| if (!found) |
| list.add(cf); |
| } |
| } |
| } |
| } |
| } |
| } |
| else { |
| for (IFeatureContainer fc : containers.values()) { |
| Object o = fc.getApplyObject(context); |
| if (o!=null && fc.canApplyTo(o)) { |
| ICustomFeature[] cfa = fc.getCustomFeatures(this); |
| if (cfa!=null) { |
| for (ICustomFeature cf : cfa) { |
| boolean found = false; |
| for (ICustomFeature cfl : list) { |
| if (cfl.getClass() == cf.getClass()) { |
| found = true; |
| break; |
| } |
| } |
| if (!found) |
| list.add(cf); |
| } |
| } |
| } |
| } |
| } |
| |
| // list.add(new ValidateModelFeature(this)); |
| return list.toArray(new ICustomFeature[list.size()]); |
| } |
| |
| // TODO: move this to the adapter registry |
| public IFeature getCreateFeatureForPictogramElement(PictogramElement pe) { |
| if (pe!=null) { |
| String id = Graphiti.getPeService().getPropertyValue(pe,GraphitiConstants.CUSTOM_ELEMENT_ID); |
| if (id!=null) { |
| for (IFeatureContainer container : containers.values()) { |
| if (container instanceof ICustomElementFeatureContainer) { |
| ICustomElementFeatureContainer ctf = (ICustomElementFeatureContainer)container; |
| if (id.equals(ctf.getId())) { |
| if (ctf instanceof CustomShapeFeatureContainer) |
| return ((CustomShapeFeatureContainer)ctf).getCreateFeature(this); |
| else if (ctf instanceof CustomConnectionFeatureContainer) |
| return ((CustomConnectionFeatureContainer)ctf).getCreateConnectionFeature(this); |
| } |
| } |
| } |
| } |
| |
| EObject be = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(pe); |
| return getCreateFeatureForBusinessObject(be); |
| } |
| return null; |
| } |
| |
| public IFeature getCreateFeatureForBusinessObject(Object be) { |
| IFeature feature = null; |
| if (be!=null) { |
| Class[] ifs = be.getClass().getInterfaces(); |
| for (int i=0; i<ifs.length && feature==null; ++i) { |
| feature = mapBusinessObjectClassToCreateFeature.get(ifs[i]); |
| } |
| } |
| return feature; |
| } |
| |
| public IFeature getCreateFeatureForBusinessObject(Class clazz) { |
| return mapBusinessObjectClassToCreateFeature.get(clazz); |
| } |
| |
| public void link(PictogramElement element, Object[] objects) { |
| if (element.getLink()==null) { |
| super.link(element, objects); |
| } |
| else { |
| for (Object o : objects) { |
| if (o instanceof EObject && !element.getLink().getBusinessObjects().contains(o)) { |
| element.getLink().getBusinessObjects().add((EObject) o); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public ICopyFeature getCopyFeature(ICopyContext context) { |
| // TODO: COPY-PASTE enable this once copy-paste functionality is working |
| if (defaultCopyFeature.canCopy(context)) |
| return defaultCopyFeature; |
| return null; |
| } |
| |
| @Override |
| public IPasteFeature getPasteFeature(IPasteContext context) { |
| // TODO: COPY-PASTE enable this once copy-paste functionality is working |
| if (defaultPasteFeature.canPaste(context)) |
| return defaultPasteFeature; |
| return null; |
| } |
| |
| @Override |
| public IReason canAdd(IAddContext context) { |
| IReason reason = super.canAdd(context); |
| EObject object = (EObject) context.getNewObject(); |
| TargetRuntime rt = TargetRuntime.getRuntime(object); |
| LifecycleEvent event = new LifecycleEvent(EventType.PICTOGRAMELEMENT_CAN_ADD, this, context, object, rt); |
| event.doit = reason.toBoolean(); |
| LifecycleEvent.notify(event); |
| if (event.doit != reason.toBoolean()) |
| reason = (event.doit ? Reason.createTrueReason() : Reason.createFalseReason()); |
| return reason; |
| } |
| |
| @Override |
| public IReason updateNeeded(IUpdateContext context) { |
| IReason reason = super.updateNeeded(context); |
| PictogramElement pe = context.getPictogramElement(); |
| TargetRuntime rt = TargetRuntime.getRuntime(pe); |
| LifecycleEvent event = new LifecycleEvent(EventType.PICTOGRAMELEMENT_UPDATE_NEEDED, this, context, pe, rt); |
| event.doit = reason.toBoolean(); |
| LifecycleEvent.notify(event); |
| if (event.doit != reason.toBoolean()) |
| reason = (event.doit ? Reason.createTrueReason() : Reason.createFalseReason()); |
| return reason; |
| } |
| |
| @Override |
| public IReason canUpdate(IUpdateContext context) { |
| IReason reason = super.canUpdate(context); |
| PictogramElement pe = context.getPictogramElement(); |
| TargetRuntime rt = TargetRuntime.getRuntime(pe); |
| LifecycleEvent event = new LifecycleEvent(EventType.PICTOGRAMELEMENT_CAN_UPDATE, this, context, pe, rt); |
| event.doit = reason.toBoolean(); |
| LifecycleEvent.notify(event); |
| if (event.doit != reason.toBoolean()) |
| reason = (event.doit ? Reason.createTrueReason() : Reason.createFalseReason()); |
| return reason; |
| } |
| |
| @Override |
| public IReason canLayout(ILayoutContext context) { |
| IReason reason = super.canLayout(context); |
| PictogramElement pe = context.getPictogramElement(); |
| TargetRuntime rt = TargetRuntime.getRuntime(pe); |
| LifecycleEvent event = new LifecycleEvent(EventType.PICTOGRAMELEMENT_CAN_LAYOUT, this, context, pe, rt); |
| event.doit = reason.toBoolean(); |
| LifecycleEvent.notify(event); |
| if (event.doit != reason.toBoolean()) |
| reason = (event.doit ? Reason.createTrueReason() : Reason.createFalseReason()); |
| return reason; |
| } |
| |
| @Override |
| public PictogramElement addIfPossible(IAddContext context) { |
| IAddFeature addElementFeature = getAddFeature(context); |
| PictogramElement pe = super.addIfPossible(context); |
| if (pe!=null) { |
| PictogramElement le = null; |
| if (addElementFeature instanceof AbstractBpmn2AddFeature) { |
| context.putProperty(GraphitiConstants.PICTOGRAM_ELEMENT, pe); |
| IAddFeature addLabelFeature = ((AbstractBpmn2AddFeature)addElementFeature).getAddLabelFeature(this); |
| if (addLabelFeature!=null && addLabelFeature.canAdd(context)) { |
| le = addLabelFeature.add(context); |
| } |
| } |
| |
| TargetRuntime rt = TargetRuntime.getRuntime(pe); |
| List<PictogramElement> pes = new ArrayList<PictogramElement>(); |
| LifecycleEvent.notify(new LifecycleEvent(EventType.PICTOGRAMELEMENT_ADDED, this, context, pe, rt)); |
| |
| if (le!=null) { |
| ((AbstractBpmn2AddFeature)addElementFeature).updatePictogramElement(context, pe); |
| if (!DIImport.isImporting(context)) { |
| context.putProperty(GraphitiConstants.INITIAL_UPDATE, Boolean.TRUE); |
| ((AbstractBpmn2AddFeature)addElementFeature).layoutPictogramElement(context, pe); |
| } |
| } |
| } |
| return pe; |
| } |
| |
| /** |
| * returns the target runtime for the current editor |
| * |
| * @return |
| */ |
| protected TargetRuntime getTargetRuntime() { |
| DefaultBPMN2Editor editor = (DefaultBPMN2Editor)getDiagramTypeProvider().getDiagramBehavior().getDiagramContainer(); |
| return editor.getTargetRuntime(); |
| } |
| } |