Select Git revision
AbstractIntraRelationshipConstraintPattern.java
AbstractIntraRelationshipConstraintPattern.java 9.77 KiB
package relationship.intra_relationship_constraints;
import java.util.List;
import org.eclipse.graphiti.features.context.IAddContext;
import org.eclipse.graphiti.features.context.ICreateContext;
import org.eclipse.graphiti.features.context.IDeleteContext;
import org.eclipse.graphiti.features.context.impl.AddContext;
import org.eclipse.graphiti.features.context.impl.DeleteContext;
import org.eclipse.graphiti.features.context.impl.MultiDeleteInfo;
import org.eclipse.graphiti.mm.algorithms.Polyline;
import org.eclipse.graphiti.mm.algorithms.Text;
import org.eclipse.graphiti.mm.algorithms.styles.LineStyle;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.framed.iorm.model.Model;
import org.framed.iorm.model.OrmFactory;
import org.framed.iorm.model.Relation;
import org.framed.iorm.model.Type;
import org.framed.iorm.ui.FRaMEDShapePattern;
import org.framed.iorm.ui.UIUtil;
import org.framed.iorm.ui.editPolicy.EditPolicyService;
import org.framed.iorm.ui.palette.FeaturePaletteDescriptor;
import org.framed.iorm.ui.palette.PaletteCategory;
import org.framed.iorm.ui.palette.PaletteView;
import org.framed.iorm.ui.palette.ViewVisibility;
/**
* This is the abstract super class of the patterns for intra relationship contraints. It collects similiar operations
* and attributes of the patterns {@link AcyclicConstraintPattern}, {@link CyclicConstraintPattern},
* {@link IrreflexiveConstraintPattern}, {@link ReflexiveConstraintPattern} and {@link TotalConstraintPattern}.
* <p>
* This is implemented as shape pattern instead of a connection pattern since its easier for the user to click on a relationship to
* add a constraint. This would not be able if a connection pattern would be used. As a developer this solution is also preferred as
* this way already provides the relationship to add the constraint to. Otherwise the relationship has to be searched and more code
* would be needed.
* @author Kevin Kassin
*/
public abstract class AbstractIntraRelationshipConstraintPattern extends FRaMEDShapePattern {
/**
* the object to get names, ids and so on for this feature
*/
private final Literals literals = new Literals();
/**
* the feature palette descriptor manages the palette visibility, see {@link FeaturePaletteDescriptor}
*/
private final FeaturePaletteDescriptor spec_FPD = new FeaturePaletteDescriptor(
PaletteCategory.CONSTRAINTS_CATEGORY,
ViewVisibility.COMPARTMENT_VIEW) {
@Override
public boolean featureExpression(List<String> framedFeatureNames, PaletteView paletteView) {
return framedFeatureNames.contains("Intra_Relationship_Constraints");
} };
/**
* Class constructor
*/
public AbstractIntraRelationshipConstraintPattern() {
super();
FPD = spec_FPD;
ICON_IMG_PATH = literals.ICON_IMG_PATH;
}
/**
* checks if pattern is applicable for a given business object
* @return true, if the business object is a {@link org.framed.iorm.model.Relation} of the right type
*/
@Override
public boolean isMainBusinessObjectApplicable(Object mainBusinessObject) {
if(mainBusinessObject instanceof Relation) {
Relation relation = (Relation) mainBusinessObject;
if(relation.getType() == Type.ACYCLIC ||
relation.getType() == Type.CYCLIC ||
relation.getType() == Type.REFLEXIVE ||
relation.getType() == Type.IRREFLEXIVE ||
relation.getType() == Type.TOTAL)
return true;
}
return false;
}
/**
* checks if pattern is applicable for a given pictogram element
* @return true, if business object of the pictogram element is a {@link org.framed.iorm.model.Relation} of the right type
*/
@Override
protected boolean isPatternControlled(PictogramElement pictogramElement) {
return isMainBusinessObjectApplicable(this.getBusinessObjectForPictogramElement(pictogramElement));
}
/**
* checks if pattern is applicable for a given pictogram element
* @return true, if the business object of the pictogram element is a {@link org.framed.iorm.model.Relation} of the right type
*/
@Override
protected boolean isPatternRoot(PictogramElement pictogramElement) {
return isMainBusinessObjectApplicable(this.getBusinessObjectForPictogramElement(pictogramElement));
}
//add feature
//~~~~~~~~~~~
/**
* calculates if the intra relationship constraint can be added to the relationship
* <p>
* returns true if:<br>
* (1) the new business object is a {@link org.framed.iorm.model.Relation} of the right type
* @return if the intra relationship constraint can be added
*/
public boolean canAddIntraRelationshipConstraint(IAddContext addContext, Type type) {
if(addContext.getNewObject() instanceof Relation) {
Relation relation = (Relation) addContext.getNewObject();
if(relation.getType() == type) {
return EditPolicyService.getHandler(this.getDiagram()).canAdd(addContext, type);
} }
return false;
}
/**
* adds the graphical representation of an intra relationship constraint in the relationship and changes the visual
* appearance of the relationship if it didn't had an intra relationship constraint before
* <p>
* @param addContext the context which has a reference to the relationship to add the constraint to
* @param type the type of the constraint to add
* @return the connection decorator with the constraints name added
*/
public PictogramElement addIntraRelationshipConstraint(IAddContext addContext, Type type) {
Connection targetConnection = addContext.getTargetConnection();
Relation targetRelation = (Relation) getBusinessObjectForPictogramElement(targetConnection);
Polyline poyline = (Polyline) targetConnection.getGraphicsAlgorithm();
((Relation) addContext.getNewObject()).getReferencedRelation().add(targetRelation);
int numberOfReferencedRelations = targetRelation.getReferencedRelation().size();
poyline.setLineStyle(LineStyle.DASH);
ConnectionDecorator constraintName =
pictogramElementCreateService.createConnectionDecorator(targetConnection, true, 0.5, true);
Text nameText = graphicAlgorithmService.createText(constraintName, type.getName().toLowerCase());
nameText.setForeground(manageColor(literals.COLOR_CONSTRAINT_TEXT));
graphicAlgorithmService.setLocation(nameText, literals.DISTANCE_FROM_CONNECTION_LINE, (numberOfReferencedRelations-1)*literals.HEIGHT_INTRAREL_CONSTRAINT);
UIUtil.setShape_IdValue(constraintName, literals.SHAPE_ID_INTRA_REL_CON_NAME_DECORATOR);
link(constraintName, addContext.getNewObject());
return constraintName;
}
//create feature
//~~~~~~~~~~~~~~
/**
* calculates if a intra relationship constraint can be created
* <p>
* returns true if the clicked on pictogram element belongs to a relationship
* @return if inheritance can be added
*/
@Override
public boolean canCreate(ICreateContext createContext) {
Connection targetConnection = createContext.getTargetConnection();
if(targetConnection != null) {
Object m = getBusinessObjectForPictogramElement(targetConnection);
if(m instanceof Relation && ((Relation) m).getType() == Type.RELATIONSHIP) { //TODO: Create EditPolicy rule for this case
return EditPolicyService.getHandler(this.getDiagram()).canCreate(createContext, this.getModelType());
}
}
return false;
}
/**
* creates the business object of an intra relationship constraint of the given type
* @param createContext the context which has a reference to the relationship to add the constraint to
* @param type the type of the constraint to add to
* @param aircp the sub class calling this operation
* @return the created business object
*/
public Object[] createIntraRelationshipConstraint(ICreateContext createContext, Type type, AbstractIntraRelationshipConstraintPattern aircp) { //TODO: Ask Kevin why this fails
Connection targetConnection = createContext.getTargetConnection();
Relation targetRelation = (Relation) getBusinessObjectForPictogramElement(targetConnection);
Anchor sourceAnchor = targetConnection.getStart(),
targetAnchor = targetConnection.getEnd();
Relation newIntraRelCon = OrmFactory.eINSTANCE.createRelation();
newIntraRelCon.setType(type);
Model model = targetRelation.getContainer();
model.getElements().add(newIntraRelCon);
newIntraRelCon.setContainer(model);
newIntraRelCon.setSource(UIUtil.getModelElementForAnchor(sourceAnchor));
newIntraRelCon.setTarget(UIUtil.getModelElementForAnchor(targetAnchor));
targetRelation.getReferencedRelation().add(newIntraRelCon);
AddContext addContext = new AddContext();
addContext.setNewObject(newIntraRelCon);
addContext.setTargetConnection(targetConnection);
if(aircp.canAdd(addContext)) {
aircp.add(addContext); //FIXME: ?
}
return new Object[] { newIntraRelCon };
}
//delete feature
//~~~~~~~~~~~~~~
/**
* disables the "Are you sure?" message when intra relationship constraints and changes the visual appearance of the
* relation if it does not longer has a intra relationship constraint after the execution of delete
*/
@Override
public void delete(IDeleteContext deleteContext) {
Connection targetConnection = ((ConnectionDecorator) deleteContext.getPictogramElement()).getConnection();
Relation targetRelation = (Relation) getBusinessObjectForPictogramElement(targetConnection);
if(targetRelation.getReferencedRelation().size() == 1) {
Polyline poyline = (Polyline) targetConnection.getGraphicsAlgorithm();
poyline.setLineStyle(LineStyle.SOLID);
}
((DeleteContext) deleteContext).setMultiDeleteInfo(new MultiDeleteInfo(false, false, 0));
super.delete(deleteContext);
}
}