| /******************************************************************************* |
| * Copyright (c) 2012-2014 SAP SE. |
| * All rights reserved. This program and the accompanying materials |
| * are 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: |
| * SAP SE - initial API and implementation and/or initial documentation |
| * |
| *******************************************************************************/ |
| package org.eclipse.ogee.designer.providers; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.eclipse.graphiti.dt.IDiagramTypeProvider; |
| 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.ILayoutFeature; |
| import org.eclipse.graphiti.features.IMoveConnectionDecoratorFeature; |
| import org.eclipse.graphiti.features.IMoveShapeFeature; |
| import org.eclipse.graphiti.features.IPasteFeature; |
| import org.eclipse.graphiti.features.IReconnectionFeature; |
| import org.eclipse.graphiti.features.IResizeShapeFeature; |
| import org.eclipse.graphiti.features.IUpdateFeature; |
| import org.eclipse.graphiti.features.context.IAddContext; |
| 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.IMoveConnectionDecoratorContext; |
| import org.eclipse.graphiti.features.context.IMoveShapeContext; |
| import org.eclipse.graphiti.features.context.IPasteContext; |
| import org.eclipse.graphiti.features.context.IReconnectionContext; |
| 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.mm.algorithms.Image; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.pattern.AddFeatureForPattern; |
| import org.eclipse.graphiti.pattern.DefaultFeatureProviderWithPatterns; |
| import org.eclipse.graphiti.platform.IDiagramContainer; |
| import org.eclipse.ogee.designer.ODataEditor; |
| import org.eclipse.ogee.designer.contexts.AddReferencedEntityContext; |
| import org.eclipse.ogee.designer.contexts.AssociationAddConnectionContext; |
| import org.eclipse.ogee.designer.contexts.LinkUsageContext; |
| import org.eclipse.ogee.designer.factories.ArtifactFactory; |
| import org.eclipse.ogee.designer.factories.ShapesFactory; |
| import org.eclipse.ogee.designer.features.ODataAddBiDirectionalAssociationFeature; |
| import org.eclipse.ogee.designer.features.ODataAddComplexPropertyFeature; |
| import org.eclipse.ogee.designer.features.ODataAddComplexTypeFeature; |
| import org.eclipse.ogee.designer.features.ODataAddEntitySetFeature; |
| import org.eclipse.ogee.designer.features.ODataAddEntityTypeFeature; |
| import org.eclipse.ogee.designer.features.ODataAddEnumMemberFeature; |
| import org.eclipse.ogee.designer.features.ODataAddEnumPropertyFeature; |
| import org.eclipse.ogee.designer.features.ODataAddFunctionImportFeature; |
| import org.eclipse.ogee.designer.features.ODataAddParameterFeature; |
| import org.eclipse.ogee.designer.features.ODataAddPropertyFeature; |
| import org.eclipse.ogee.designer.features.ODataAddReturnTypeFeature; |
| import org.eclipse.ogee.designer.features.ODataAddUniDirectionalAssociationFeature; |
| import org.eclipse.ogee.designer.features.ODataCommonLayoutFeature; |
| import org.eclipse.ogee.designer.features.ODataCopyFeature; |
| import org.eclipse.ogee.designer.features.ODataCreateBiDirectionalAssociationFeature; |
| import org.eclipse.ogee.designer.features.ODataCreateComplexTypeFeature; |
| import org.eclipse.ogee.designer.features.ODataCreateEntityTypeFeature; |
| import org.eclipse.ogee.designer.features.ODataCreateFunctionImportFeature; |
| import org.eclipse.ogee.designer.features.ODataCreateUniDirectionalAssociationFeature; |
| import org.eclipse.ogee.designer.features.ODataDeleteFeature; |
| import org.eclipse.ogee.designer.features.ODataDirectEditingFeature; |
| import org.eclipse.ogee.designer.features.ODataLinkUsageFeature; |
| import org.eclipse.ogee.designer.features.ODataPasteFeature; |
| import org.eclipse.ogee.designer.features.ODataReferencedEntityDirectEditingFeature; |
| import org.eclipse.ogee.designer.features.ODataResizeFeature; |
| import org.eclipse.ogee.designer.features.ODataReturnTypeDirectEditingFeature; |
| import org.eclipse.ogee.designer.features.ODataUpdateFeature; |
| import org.eclipse.ogee.designer.patterns.ReferenceEntityTypePattern; |
| import org.eclipse.ogee.designer.types.AssociationType; |
| import org.eclipse.ogee.designer.types.FunctionImportReturnType; |
| import org.eclipse.ogee.designer.utils.ArtifactUtil; |
| import org.eclipse.ogee.designer.utils.PropertyUtil; |
| import org.eclipse.ogee.model.odata.impl.AssociationImpl; |
| import org.eclipse.ogee.model.odata.impl.ComplexTypeImpl; |
| import org.eclipse.ogee.model.odata.impl.EntityTypeImpl; |
| import org.eclipse.ogee.model.odata.impl.FunctionImportImpl; |
| |
| /** |
| * |
| * All the patterns and Features will be registered in this feature provider |
| * class. |
| * |
| */ |
| public class ODataFeatureProvider extends DefaultFeatureProviderWithPatterns { |
| |
| /** |
| * ShapesFactory instance used to create all the shapes. |
| */ |
| private ShapesFactory shapesFactory; |
| |
| /** |
| * ArtifactFactory instance used to create all the Business objects. |
| */ |
| private ArtifactFactory artifactFactory; |
| |
| /** |
| * Initializing feature provider and Registers entity type pattern. |
| * |
| * @param dtp |
| */ |
| |
| private ReferenceEntityTypePattern referenceEntityTypePattern = null; |
| |
| public ODataFeatureProvider(IDiagramTypeProvider dtp) { |
| super(dtp); |
| // Create a new ShapesFactory. This will in turn create all the |
| // necessary shapes for the artifacts |
| this.shapesFactory = new ShapesFactory(this); |
| // New ArtifactFactory creates the necessary artifacts |
| this.artifactFactory = new ArtifactFactory(); |
| } |
| |
| /** |
| * Returns ArtifactFactory associated with this FeatureProvider |
| * |
| * @return ArtifactFactory |
| */ |
| public ArtifactFactory getArtifactFactory() { |
| return this.artifactFactory; |
| } |
| |
| /** |
| * Returns ShapesFactory associated with this FeatureProvider |
| * |
| * @return ShapesFactory |
| */ |
| public ShapesFactory getShapesFactory() { |
| return this.shapesFactory; |
| } |
| |
| /** |
| * Returns the IDirectEditingFeature |
| * |
| * @param context |
| * IDirectEditingContext instance |
| * @return IDirectEditingFeature |
| */ |
| @Override |
| public IDirectEditingFeature getDirectEditingFeature( |
| IDirectEditingContext context) { |
| |
| if (this.isReadOnlyModel()) { |
| return null; |
| } |
| // Pictogram element on which direct editing is invoked from the UI |
| PictogramElement pe = context.getPictogramElement(); |
| // Business object from the UI element |
| Object obj = getBusinessObjectForPictogramElement((PictogramElement) pe |
| .eContainer()); |
| |
| // Only enable editing on Entity name |
| if (ArtifactUtil.isEditable(obj)) { |
| if (ArtifactUtil.isFunctionImportReturnType(obj)) { |
| return new ODataReturnTypeDirectEditingFeature(this, |
| this.artifactFactory, this.shapesFactory); |
| } else if (ArtifactUtil.isEnumType(obj)) { |
| if (PropertyUtil.isEnumTypeName(pe)) { |
| return new ODataDirectEditingFeature(this, |
| this.artifactFactory, this.shapesFactory); |
| } |
| |
| } else if (ArtifactUtil.isReferencedEntityType(obj)) { |
| return new ODataReferencedEntityDirectEditingFeature(this, |
| this.artifactFactory, this.shapesFactory); |
| } |
| |
| return new ODataDirectEditingFeature(this, this.artifactFactory, |
| this.shapesFactory); |
| |
| } |
| return super.getDirectEditingFeature(context); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.graphiti.pattern.DefaultFeatureProviderWithPatterns# |
| * getUpdateFeature(org.eclipse.graphiti.features.context.IUpdateContext) |
| */ |
| /** |
| * |
| */ |
| @Override |
| public IUpdateFeature getUpdateFeature(IUpdateContext context) { |
| // Pictogram element on which direct editing is invoked from the UI |
| PictogramElement pe = context.getPictogramElement(); |
| |
| if (this.isReadOnlyModel()) { |
| |
| // This condition to update expand/Collapse Image |
| boolean isCollapsableImage = PropertyUtil.isTitle(pe) |
| && pe.getGraphicsAlgorithm() instanceof Image; |
| if (!isCollapsableImage) { |
| return null; |
| } |
| |
| } |
| |
| // Business object from the UI element |
| Object obj = getBusinessObjectForPictogramElement(pe); |
| if (ArtifactUtil.isEditable(obj) && PropertyUtil.canUpdate(pe)) { |
| return new ODataUpdateFeature(this); |
| } |
| return super.getUpdateFeature(context); |
| } |
| |
| /** |
| * AddProperty Feature is added to Custom Features List. This method will be |
| * called on creation of context menu. |
| */ |
| @Override |
| public ICustomFeature[] getCustomFeatures(ICustomContext context) { |
| |
| if (this.isReadOnlyModel()) { |
| return null; |
| } |
| ICustomFeature[] ret = super.getCustomFeatures(context); |
| List<ICustomFeature> retList = new ArrayList<ICustomFeature>(); |
| retList.addAll(Arrays.asList(ret)); |
| PictogramElement[] pictogramElements = context.getPictogramElements(); |
| if (pictogramElements != null && pictogramElements.length > 0) { |
| Object businessObject = getBusinessObjectForPictogramElement(pictogramElements[0]); |
| if (ArtifactUtil.isEntityType(businessObject)) { |
| retList.add(new ODataAddPropertyFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| // to add entity set from the context menu of entity type |
| retList.add(new ODataAddEntitySetFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| // to add complex type from the context menu of entity type |
| retList.add(new ODataAddComplexPropertyFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| // to add enum type from the context menu of entity type |
| retList.add(new ODataAddEnumPropertyFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| } else if (ArtifactUtil.isFunctionImport(businessObject)) { |
| |
| // to add parameter from the context menu of Function Import |
| retList.add(new ODataAddParameterFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| // to add return type from the context menu of Function Import |
| retList.add(new ODataAddReturnTypeFeature(this, |
| this.artifactFactory, this.shapesFactory, |
| FunctionImportReturnType.SIMPLE)); |
| // to add return type from the context menu of Function Import |
| retList.add(new ODataAddReturnTypeFeature(this, |
| this.artifactFactory, this.shapesFactory, |
| FunctionImportReturnType.COMPLEX)); |
| // to add return type from the context menu of Function Import |
| retList.add(new ODataAddReturnTypeFeature(this, |
| this.artifactFactory, this.shapesFactory, |
| FunctionImportReturnType.ENTITY)); |
| // to add return type from the context menu of Function Import |
| retList.add(new ODataAddReturnTypeFeature(this, |
| this.artifactFactory, this.shapesFactory, |
| FunctionImportReturnType.ENUM)); |
| } else if (ArtifactUtil.isComplexType(businessObject)) { |
| retList.add(new ODataAddPropertyFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| // to add complex type from the context menu of entity type |
| retList.add(new ODataAddComplexPropertyFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| // to add enum type from the context menu of entity type |
| retList.add(new ODataAddEnumPropertyFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| // to add complex type from the context menu of entity type |
| retList.add(new ODataLinkUsageFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| } else if (ArtifactUtil.isEnumType(businessObject)) { |
| retList.add(new ODataAddEnumMemberFeature(this, |
| this.artifactFactory, this.shapesFactory)); |
| |
| } |
| } |
| return retList.toArray(new ICustomFeature[] {}); |
| } |
| |
| @Override |
| public IMoveShapeFeature getMoveShapeFeature(IMoveShapeContext context) { |
| |
| if (!PropertyUtil.isMovableShape(context)) { |
| |
| return null; |
| } |
| return super.getMoveShapeFeature(context); |
| } |
| |
| @Override |
| public IDeleteFeature getDeleteFeature(IDeleteContext context) { |
| |
| if (context instanceof LinkUsageContext) { |
| LinkUsageContext lc = (LinkUsageContext) context; |
| if (lc.isDeletable()) { |
| return new ODataDeleteFeature(this); |
| } |
| } |
| return new ODataDeleteFeature(this); |
| } |
| |
| @Override |
| protected IDeleteFeature getDeleteFeatureAdditional(IDeleteContext context) { |
| |
| if (this.isReadOnlyModel()) { |
| return null; |
| } |
| return new ODataDeleteFeature(this); |
| } |
| |
| /** |
| * To restrict connection decorator moving (for multiplicity) |
| */ |
| @Override |
| public IMoveConnectionDecoratorFeature getMoveConnectionDecoratorFeature( |
| IMoveConnectionDecoratorContext context) { |
| return null; |
| } |
| |
| /** |
| * The following method checks if the current model is a read-only model. |
| * |
| * @return boolean |
| */ |
| public boolean isReadOnlyModel() { |
| |
| boolean isReadOnlyModel = false; |
| |
| final IDiagramContainer diagramEditor = this.getDiagramTypeProvider() |
| .getDiagramBehavior().getDiagramContainer(); |
| |
| if (diagramEditor instanceof ODataEditor) { |
| if (((ODataEditor) diagramEditor).isReadOnly()) { |
| isReadOnlyModel = true; |
| } |
| } |
| |
| return isReadOnlyModel; |
| } |
| |
| /** |
| * This is overridden so as to not allow movement of associations/links |
| * |
| */ |
| @Override |
| public IReconnectionFeature getReconnectionFeature( |
| IReconnectionContext context) { |
| return null; |
| } |
| |
| @Override |
| public IAddFeature getAddFeature(IAddContext context) { |
| if (context instanceof AddReferencedEntityContext) { |
| if (referenceEntityTypePattern != null) { |
| if (referenceEntityTypePattern.canAdd(context)) { |
| return new AddFeatureForPattern(this, |
| referenceEntityTypePattern); |
| } |
| } |
| } else if (context.getNewObject() instanceof EntityTypeImpl) { |
| return new ODataAddEntityTypeFeature(this, this.artifactFactory, |
| this.shapesFactory); |
| } else if (context.getNewObject() instanceof ComplexTypeImpl) { |
| return new ODataAddComplexTypeFeature(this, this.artifactFactory, |
| this.shapesFactory); |
| } else if (context.getNewObject() instanceof FunctionImportImpl) { |
| return new ODataAddFunctionImportFeature(this, |
| this.artifactFactory, this.shapesFactory); |
| } else if (context.getNewObject() instanceof AssociationImpl) { |
| AssociationType type = ((AssociationAddConnectionContext) context) |
| .getAssociationType(); |
| if (type == AssociationType.UNIDIR || type == AssociationType.NONE) { |
| return new ODataAddUniDirectionalAssociationFeature(this, |
| this.artifactFactory, this.shapesFactory); |
| } else if (type == AssociationType.BIDIR) { |
| return new ODataAddBiDirectionalAssociationFeature(this, |
| this.artifactFactory, this.shapesFactory); |
| } |
| } |
| return super.getAddFeature(context); |
| } |
| |
| @Override |
| public ICopyFeature getCopyFeature(ICopyContext context) { |
| return new ODataCopyFeature(this); |
| } |
| |
| @Override |
| public IPasteFeature getPasteFeature(IPasteContext context) { |
| return new ODataPasteFeature(this); |
| } |
| |
| @Override |
| public ICreateFeature[] getCreateFeatures() { |
| return new ICreateFeature[] { |
| new ODataCreateEntityTypeFeature(this, this.shapesFactory, |
| this.artifactFactory), |
| new ODataCreateComplexTypeFeature(this, this.shapesFactory, |
| this.artifactFactory), |
| new ODataCreateFunctionImportFeature(this, this.shapesFactory, |
| this.artifactFactory) }; |
| } |
| |
| @Override |
| public ILayoutFeature getLayoutFeature(ILayoutContext context) { |
| return new ODataCommonLayoutFeature(this); |
| } |
| |
| @Override |
| public IResizeShapeFeature getResizeShapeFeature(IResizeShapeContext context) { |
| |
| if (!PropertyUtil.isMovableShape(context)) { |
| |
| return null; |
| } |
| return new ODataResizeFeature(this); |
| } |
| |
| @Override |
| public ICreateConnectionFeature[] getCreateConnectionFeatures() { |
| |
| return new ICreateConnectionFeature[] { |
| new ODataCreateUniDirectionalAssociationFeature(this, |
| shapesFactory, artifactFactory), |
| new ODataCreateBiDirectionalAssociationFeature(this, |
| shapesFactory, artifactFactory) }; |
| } |
| |
| } |