blob: d16957a270103f2681684a9386e78e7ef1455003 [file] [log] [blame]
/*******************************************************************************
* 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.features;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.IDirectEditingContext;
import org.eclipse.graphiti.features.impl.AbstractDirectEditingFeature;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.Text;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.ogee.designer.factories.ArtifactFactory;
import org.eclipse.ogee.designer.factories.ShapesFactory;
import org.eclipse.ogee.designer.utils.ArtifactUtil;
import org.eclipse.ogee.designer.utils.AssociationUtil;
import org.eclipse.ogee.designer.utils.ODataShapeUtil;
import org.eclipse.ogee.designer.utils.PropertyUtil;
import org.eclipse.ogee.model.odata.Association;
import org.eclipse.ogee.model.odata.EDMXReference;
import org.eclipse.ogee.model.odata.EntitySet;
import org.eclipse.ogee.model.odata.EntityType;
import org.eclipse.ogee.model.odata.Role;
import org.eclipse.ogee.model.odata.Schema;
/**
* This class will provide the editing functionality on name elements of an
* entity if it is of of type referenced entity
*
*/
public class ODataReferencedEntityDirectEditingFeature extends
AbstractDirectEditingFeature {
private static final String EMPTY_STRING = "";//$NON-NLS-1$
private List<EntityType> referencedEntities = null;
private ArtifactFactory artifactFactory = null;
/**
* Constructor
*
* @param fp
* Feature provider instance is passed
* @param artifactfactory
* Artifact factory instance is passed
* @param shapesFactory
* Shapes factory instance is passed
*/
public ODataReferencedEntityDirectEditingFeature(IFeatureProvider fp,
ArtifactFactory artifactfactory, ShapesFactory shapesFactory) {
super(fp);
this.artifactFactory = artifactfactory;
}
/**
* Specifies the field type. Text field, Combo Box, etc.
*/
@Override
public int getEditingType() {
return TYPE_DROPDOWN_READ_ONLY;
}
/**
* Returns the value of the text which the field currently has
*
* @return String the current field value
*/
@Override
public String getInitialValue(IDirectEditingContext context) {
PictogramElement pe = context.getPictogramElement();
Object obj = getBusinessObjectForPictogramElement(pe);
String initialName = EMPTY_STRING;
if (ArtifactUtil.isReferencedEntityType(obj)) {
initialName = ArtifactUtil.getArtifactDisplayName(artifactFactory,
(EntityType) obj);
} else {
initialName = ArtifactUtil.getInitialName(obj);
}
return initialName != null ? initialName : EMPTY_STRING;
}
/**
* Populates the given combo boxes for the return type
*/
@Override
public String[] getPossibleValues(IDirectEditingContext context) {
PictogramElement pe = context.getPictogramElement();
Object obj = getBusinessObjectForPictogramElement(pe);
Schema parentSchema = ArtifactUtil.getParentSchema((EObject) obj);
referencedEntities = ArtifactUtil.getReferencedEntities(parentSchema);
List<String> entityNames = new ArrayList<String>();
EntityType entityType = null;
for (int i = 0; i < referencedEntities.size(); i++) {
entityType = referencedEntities.get(i);
entityNames.add(ArtifactUtil.getArtifactDisplayName(
artifactFactory, entityType));
}
return entityNames.toArray(new String[entityNames.size()]);
}
/**
* Returns if the field can be directly edited in the UI
*
* @param context
* IDirectEditingContext instance
* @return boolean true if the field is editable
*/
@Override
public boolean canDirectEdit(IDirectEditingContext context) {
GraphicsAlgorithm ga = context.getGraphicsAlgorithm();
String id = PropertyUtil.getID(ga.getPictogramElement());
return (PropertyUtil.REFERENCED_ENTITY_NAME.equals(id))
&& ga instanceof Text;
}
/**
* Sets the new value to the UI and the object Also makes the corresponding
* changes to other elements
*
* @param context
* IDirectEditingContext instance
*/
@Override
public void setValue(String value, IDirectEditingContext context) {
PictogramElement pe = context.getPictogramElement();
Object obj = getBusinessObjectForPictogramElement(pe);
if (ArtifactUtil.isReferencedEntityType(obj)) {
Schema referencedSchema = getSchema(value);
List<EntityType> referencedEntitiesInSchema = referencedSchema
.getEntityTypes();
if (referencedEntitiesInSchema != null) {
EntityType entityType = null;
String entityName = null;
for (int i = 0; i < referencedEntitiesInSchema.size(); i++) {
entityType = referencedEntitiesInSchema.get(i);
if (value != null && value.length() > 0) {
if (value.lastIndexOf(".") != -1) { //$NON-NLS-1$
entityName = value
.substring(value.lastIndexOf(".") + 1); //$NON-NLS-1$
if (entityName.equals(entityType.getName())) {
updateReferencedObjects(pe, entityType);
}
}
}
}
}
}
// Update the UI
ODataShapeUtil.updatePictogramElement(pe, getFeatureProvider());
}
private Schema getSchema(String value) {
String schemaName = null;
if (value != null && value.length() > 0) {
if (value.lastIndexOf(".") != -1) {//$NON-NLS-1$
schemaName = value.substring(0, value.lastIndexOf("."));//$NON-NLS-1$
}
}
List<EDMXReference> references = ArtifactUtil
.getReferencedSchemas(artifactFactory.getSchema());
EList<Schema> schemata = null;
String alias = null;
for (EDMXReference edmxReference : references) {
schemata = edmxReference.getReferencedEDMX().getDataService()
.getSchemata();
for (Schema schema : schemata) {
alias = ArtifactUtil.getAliasName(artifactFactory.getSchema(),
schema);
if (alias != null && alias.length() > 0) {
if (schemaName.equals(alias)) {
return schema;
}
} else {
return null;
}
}
}
return null;
}
private void updateReferencedObjects(PictogramElement pe,
EntityType entityType) {
PictogramElement topContainer = ODataShapeUtil.getTopContainer(pe);
EntityType previousEntity = (EntityType) getBusinessObjectForPictogramElement(topContainer);
link(topContainer, entityType);
link(pe, entityType);
updateEntitySets(topContainer, previousEntity, entityType);
updateAssociations(topContainer, previousEntity, entityType);
}
private void updateAssociations(PictogramElement topContainer,
EntityType previousEntity, EntityType entityType) {
List<Connection> allConnections = AssociationUtil
.getAllAssociations((ContainerShape) topContainer);
for (Connection connection : allConnections) {
if (connection.getEnd().eContainer() == topContainer) {
Association association = (Association) getBusinessObjectForPictogramElement(connection);
EList<Role> ends = association.getEnds();
for (Role role : ends) {
if (role.getType() == previousEntity) {
role.setType(entityType);
}
}
AssociationUtil.refreshAssociationNamesForEntity(entityType,
(ContainerShape) topContainer, getFeatureProvider(),
previousEntity.getName(), entityType.getName());
}
}
}
private void updateEntitySets(PictogramElement topContainer,
EntityType previousEntityType, EntityType newEntityType) {
EList<Shape> children = ((ContainerShape) topContainer).getChildren();
for (Shape shape : children) {
if (PropertyUtil.ENTITYSET_RECTANGLE.equals(PropertyUtil
.getID(shape))) {
EList<Shape> entitySetShapes = ((ContainerShape) shape)
.getChildren();
for (Shape entitySetShape : entitySetShapes) {
Object businessObject = getBusinessObjectForPictogramElement(entitySetShape);
if (businessObject instanceof EntitySet) {
((EntitySet) businessObject).setType(newEntityType);
}
}
}
Object businessObject = getBusinessObjectForPictogramElement(shape);
if (businessObject == previousEntityType) {
link(shape, newEntityType);
}
if (shape instanceof ContainerShape) {
EList<Shape> subChildren = ((ContainerShape) shape)
.getChildren();
for (Shape childShape : subChildren) {
businessObject = getBusinessObjectForPictogramElement(childShape);
if (businessObject == previousEntityType) {
link(childShape, newEntityType);
}
}
}
}
}
}