/**
* Copyright (c) 2012-2016 Marsha Chechik, Alessio Di Sandro, Michalis Famelis,
* Rick Salay.
* 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:
* Alessio Di Sandro - Implementation.
*/
package edu.toronto.cs.se.mmint;
import java.util.Map;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.RegistryFactory;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import edu.toronto.cs.se.mmint.extensions.ExtensionPointType;
import edu.toronto.cs.se.mmint.mid.EMFInfo;
import edu.toronto.cs.se.mmint.mid.ExtendibleElement;
import edu.toronto.cs.se.mmint.mid.ExtendibleElementConstraint;
import edu.toronto.cs.se.mmint.mid.GenericElement;
import edu.toronto.cs.se.mmint.mid.MIDFactory;
import edu.toronto.cs.se.mmint.mid.Model;
import edu.toronto.cs.se.mmint.mid.ModelElement;
import edu.toronto.cs.se.mmint.mid.ModelEndpoint;
import edu.toronto.cs.se.mmint.mid.ModelOrigin;
import edu.toronto.cs.se.mmint.mid.editor.Editor;
import edu.toronto.cs.se.mmint.mid.editor.EditorFactory;
import edu.toronto.cs.se.mmint.mid.operator.GenericEndpoint;
import edu.toronto.cs.se.mmint.mid.operator.Operator;
import edu.toronto.cs.se.mmint.mid.operator.OperatorConstraint;
import edu.toronto.cs.se.mmint.mid.operator.OperatorConstraintParameter;
import edu.toronto.cs.se.mmint.mid.operator.OperatorConstraintRule;
import edu.toronto.cs.se.mmint.mid.operator.OperatorFactory;
import edu.toronto.cs.se.mmint.mid.operator.OperatorPackage;
import edu.toronto.cs.se.mmint.mid.relationship.Mapping;
import edu.toronto.cs.se.mmint.mid.relationship.MappingReference;
import edu.toronto.cs.se.mmint.mid.relationship.ModelElementEndpoint;
import edu.toronto.cs.se.mmint.mid.relationship.ModelElementEndpointReference;
import edu.toronto.cs.se.mmint.mid.relationship.ModelElementReference;
import edu.toronto.cs.se.mmint.mid.relationship.ModelEndpointReference;
import edu.toronto.cs.se.mmint.mid.relationship.ModelRel;
import edu.toronto.cs.se.mmint.mid.relationship.RelationshipFactory;
import edu.toronto.cs.se.mmint.mid.utils.MIDRegistry;
import edu.toronto.cs.se.mmint.mid.utils.MIDTypeFactory;
/**
* The factory to create/modify/remove "heavy" types, i.e. types from
* extensions.
*
* @author Alessio Di Sandro
*
*/
public class MIDHeavyTypeFactory extends MIDTypeFactory {
/**
* Gets the supertype of a new type from the repository.
*
* @param newType
* The new type for which the supertype has to be got.
* @param newTypeUri
* The uri of the new type.
* @param typeUri
* The uri of the supertype of the new type, null if the root uri should be used instead.
* @return The supertype of the new type, null if the new type is the root type.
*/
protected static @Nullable <T extends ExtendibleElement> T getSupertype(@NonNull T newType, @NonNull String newTypeUri, @Nullable String typeUri) {
T type = null;
String rootUri = MIDTypeHierarchy.getRootTypeUri(newType);
if (typeUri == null && !newTypeUri.equals(rootUri)) {
typeUri = rootUri;
}
if (typeUri != null) {
type = MIDTypeRegistry.getType(typeUri);
}
return type;
}
/**
* Gets the supertype of a new type from the repository, when there is no root type.
*
* @param newType
* The new type for which the supertype has to be got.
* @param newTypeUri
* The uri of the new type.
* @param typeUri
* The uri of the supertype of the new type, null if the new type has no supertype.
* @return The supertype of the new type, null if the new type has no supertype.
*/
protected static @Nullable <T extends ExtendibleElement> T getSupertypeWithoutRoot(@NonNull T newType, @NonNull String newTypeUri, @Nullable String typeUri) {
return (typeUri == null) ?
null :
getSupertype(newType, newTypeUri, typeUri);
}
/**
* Adds a "heavy" type to the repository.
*
* @param newType
* The new type to be added.
* @param type
* The supertype of the new type, null if the new type has no supertype.
* @param newTypeUri
* The uri of the new type.
* @param newTypeName
* The name of the new type.
* @throws MMINTException
* If the uri of the new type is already registered in the
* repository.
*/
protected static void addHeavyType(@NonNull ExtendibleElement newType, @Nullable ExtendibleElement type, @NonNull String newTypeUri, @NonNull String newTypeName) throws MMINTException {
addType(newType, type, newTypeUri, newTypeName, MMINT.cachedTypeMID);
newType.setDynamic(false);
}
/**
* Adds a "heavy" generic type to the repository.
*
* @param newType
* The new type to be added.
* @param type
* The supertype of the new type, null if the new type has no supertype.
* @param newTypeUri
* The uri of the new type.
* @param newTypeName
* The name of the new type.
* @param isAbstract
* True if the new type is abstract, false otherwise.
* @throws MMINTException
* If the uri of the new type is already registered in the repository.
*/
protected static void addHeavyGenericType(@NonNull GenericElement newType, @Nullable GenericElement type, @NonNull String newTypeUri, @NonNull String newTypeName, boolean isAbstract) throws MMINTException {
newType.setAbstract(isAbstract);
addType(newType, type, newTypeUri, newTypeName, MMINT.cachedTypeMID);
}
/**
* Adds a "heavy" model type to the repository.
*
* @param newModelType
* The new model type to be added.
* @param newModelTypeUri
* The uri of the new model type.
* @param modelTypeUri
* The uri of the supertype of the new model type, null if the
* root model type should be used as supertype instead.
* @param newModelTypeName
* The name of the new model type.
* @param isAbstract
* True if the new model type is abstract, false otherwise.
* @throws MMINTException
* If the package of the new model type is not registered
* through a org.eclipse.emf.ecore.generated_package extension,
* or if the uri of the new model type is already registered in
* the repository.
*/
protected void addHeavyModelType(Model newModelType, String newModelTypeUri, String modelTypeUri, String newModelTypeName, boolean isAbstract) throws MMINTException {
EPackage modelPackage = EPackage.Registry.INSTANCE.getEPackage(newModelTypeUri);
if (modelPackage == null) {
throw new MMINTException("EPackage for URI " + newModelTypeUri + " is not registered");
}
Model modelType = getSupertype(newModelType, newModelTypeUri, modelTypeUri);
addHeavyGenericType(newModelType, modelType, newModelTypeUri, newModelTypeName, isAbstract);
MIDTypeFactory.addModelType(newModelType, MMINT.cachedTypeMID);
newModelType.setOrigin(ModelOrigin.IMPORTED);
String modelPackageName = (modelType == null) ?
MIDTypeFactory.ECORE_REFLECTIVE_FILE_EXTENSION : // root model type
modelPackage.getName();
newModelType.setFileExtension(modelPackageName);
// possibly register file extension to load resources
Map<String, Object> resourceMap = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap();
if (!resourceMap.containsKey(modelPackageName)) {
resourceMap.put(modelPackageName, new XMIResourceFactoryImpl());
}
}
/**
* Adds a "heavy" model relationship type to the repository.
*
* @param newModelRelType
* The new model relationship type to be added.
* @param newModelRelTypeUri
* The uri of the new model relationship type.
* @param modelRelTypeUri
* The uri of the supertype of the new model relationship type,
* null if the root model relationship type should be used as
* supertype.
* @param newModelRelTypeName
* The name of the new model relationship type.
* @param isAbstract
* True if the new model relationship type is abstract, false
* otherwise.
* @throws MMINTException
* If the package of the new model relationship type is not
* registered through a org.eclipse.emf.ecore.generated_package
* extension, or if the uri of the new model relationship type
* is already registered in the repository.
*/
protected void addHeavyModelRelType(ModelRel newModelRelType, String newModelRelTypeUri, String modelRelTypeUri, String newModelRelTypeName, boolean isAbstract) throws MMINTException {
if (MMINT.ROOT_MODEL_URI.equals(modelRelTypeUri)) { // root ModelRel's supertype
addHeavyModelType(newModelRelType, newModelRelTypeUri, modelRelTypeUri, newModelRelTypeName, isAbstract);
}
else {
ModelRel modelRelType = getSupertype(newModelRelType, newModelRelTypeUri, modelRelTypeUri);
addHeavyModelType(newModelRelType, newModelRelTypeUri, modelRelTypeUri, newModelRelTypeName, isAbstract);
addModelRelType(newModelRelType, modelRelType);
}
}
/**
* Adds a "heavy" model type endpoint (for an operator type) to the Type MID.
*
* @param newModelTypeEndpoint
* The new model type endpoint to be added.
* @param newModelTypeEndpointUri
* The uri of the new model type endpoint.
* @param modelTypeEndpointUri
* The uri of the supertype of the new model type endpoint, null if the new model type endpoint has no
* supertype.
* @param newModelTypeEndpointName
* The name of the new model type endpoint.
* @param targetModelType
* The new model type that is the target of the new model type endpoint.
* @param containerOperatorType
* The operator type that will contain the new model type endpoint.
* @param containerFeatureName
* The name of the feature in the operator type that will contain the new model type endpoint.
* @throws MMINTException
* If the uri of the new model type endpoint is already registered in the Type MID.
*/
protected void addHeavyModelTypeEndpoint(@NonNull ModelEndpoint newModelTypeEndpoint, @NonNull String newModelTypeEndpointUri, @Nullable String modelTypeEndpointUri, @NonNull String newModelTypeEndpointName, @NonNull Model targetModelType, @NonNull Operator containerOperatorType, @NonNull String containerFeatureName) throws MMINTException {
ModelEndpoint modelTypeEndpoint = getSupertypeWithoutRoot(newModelTypeEndpoint, newModelTypeEndpointUri, modelTypeEndpointUri);
addHeavyType(newModelTypeEndpoint, modelTypeEndpoint, newModelTypeEndpointUri, newModelTypeEndpointName);
addModelTypeEndpoint(newModelTypeEndpoint, targetModelType, containerOperatorType, containerFeatureName);
}
/**
* Adds a "heavy" generic type endpoint to the Type MID.
*
* @param newGenericTypeEndpoint
* The new generic type endpoint to be added.
* @param newGenericTypeEndpointUri
* The uri of the new generic type endpoint.
* @param genericTypeEndpointUri
* The uri of the supertype of the new generic type endpoint, null if the new generic type endpoint has
* no supertype.
* @param newGenericTypeEndpointName
* The name of the new generic type endpoint.
* @param targetGenericType
* The new generic type that is the target of the new generic type endpoint.
* @param containerOperatorType
* The operator type that will contain the new generic type endpoint.
* @throws MMINTException
* If the uri of the new generic type endpoint is already registered in the Type MID.
*/
protected void addHeavyGenericTypeEndpoint(@NonNull GenericEndpoint newGenericTypeEndpoint, @NonNull String newGenericTypeEndpointUri, @Nullable String genericTypeEndpointUri, @NonNull String newGenericTypeEndpointName, @NonNull GenericElement targetGenericType, @NonNull Operator containerOperatorType) throws MMINTException {
GenericEndpoint modelTypeEndpoint = getSupertypeWithoutRoot(newGenericTypeEndpoint, newGenericTypeEndpointUri, genericTypeEndpointUri);
addHeavyType(newGenericTypeEndpoint, modelTypeEndpoint, newGenericTypeEndpointUri, newGenericTypeEndpointName);
addTypeEndpoint(newGenericTypeEndpoint, targetGenericType);
containerOperatorType.getGenerics().add(newGenericTypeEndpoint);
}
/**
* Adds a "heavy" model type endpoint and a reference to it to the
* repository.
*
* @param newModelTypeEndpoint
* The new model type endpoint to be added.
* @param newModelTypeEndpointUri
* The uri of the new model type endpoint.
* @param modelTypeEndpointUri
* The uri of the supertype of the new model type endpoint, null
* if the root model type endpoint should be used as supertype.
* @param newModelTypeEndpointName
* The name of the new model type endpoint.
* @param targetModelType
* The new model type that is the target of the new model type
* endpoint.
* @param isBinarySrc
* (Only for a binary model relationship type container) True if
* the target model type is the source in the binary model
* relationship type container, false otherwise.
* @param containerModelRelType
* The model relationship type that will contain the new model
* type endpoint.
* @return The created reference to the new model type endpoint.
* @throws MMINTException
* If the uri of the new model type endpoint is already
* registered in the repository.
*/
protected @NonNull ModelEndpointReference addHeavyModelTypeEndpointAndModelTypeEndpointReference(@NonNull ModelEndpoint newModelTypeEndpoint, @NonNull String newModelTypeEndpointUri, @Nullable String modelTypeEndpointUri, @NonNull String newModelTypeEndpointName, @NonNull Model targetModelType, boolean isBinarySrc, @NonNull ModelRel containerModelRelType) throws MMINTException {
ModelEndpoint modelTypeEndpoint = getSupertype(newModelTypeEndpoint, newModelTypeEndpointUri, modelTypeEndpointUri);
addHeavyType(newModelTypeEndpoint, modelTypeEndpoint, newModelTypeEndpointUri, newModelTypeEndpointName);
addModelTypeEndpoint(newModelTypeEndpoint, targetModelType, isBinarySrc, containerModelRelType);
ModelEndpointReference newModelTypeEndpointRef = newModelTypeEndpoint.createTypeReference(true, containerModelRelType);
return newModelTypeEndpointRef;
}
/**
* Adds a "heavy" mapping type and a reference to it to the repository.
*
* @param newMappingType
* The new mapping type to be added.
* @param newMappingTypeUri
* The uri of the new mapping type.
* @param mappingTypeUri
* The uri of the supertype of the new mapping type, null if the
* root mapping type should be used as supertype.
* @param newMappingTypeName
* The name of the new mapping type.
* @param containerModelRelType
* The model relationship type that will contain the new mapping
* type.
* @return The created reference to the new mapping type.
* @throws MMINTException
* If the uri of the new mapping type is already registered in
* the repository.
*/
protected @NonNull MappingReference addHeavyMappingTypeAndMappingTypeReference(@NonNull Mapping newMappingType, @NonNull String newMappingTypeUri, @Nullable String mappingTypeUri, @NonNull String newMappingTypeName, @NonNull ModelRel containerModelRelType) throws MMINTException {
Mapping mappingType = getSupertype(newMappingType, newMappingTypeUri, mappingTypeUri);
addHeavyType(newMappingType, mappingType, newMappingTypeUri, newMappingTypeName);
addMappingType(newMappingType, mappingType, containerModelRelType);
MappingReference mappingTypeRef = MIDRegistry.getReference(mappingTypeUri, containerModelRelType.getMappingRefs());
MappingReference newMappingTypeRef = newMappingType.createTypeReference(mappingTypeRef, true, containerModelRelType);
return newMappingTypeRef;
}
/**
* Creates and adds a "heavy" constraint to a type.
* @param constraintLanguage
* The language of the constraint.
* @param constraintImplementation
* The implementation of the constraint.
* @param constrainedType
* The new type to be constrained.
*/
public ExtendibleElementConstraint createHeavyTypeConstraint(@NonNull String constraintLanguage, @NonNull String constraintImplementation, @NonNull ExtendibleElement constrainedType) {
ExtendibleElementConstraint newTypeConstraint = (constrainedType instanceof Operator) ?
OperatorFactory.eINSTANCE.createOperatorConstraint() :
MIDFactory.eINSTANCE.createExtendibleElementConstraint();
MIDTypeFactory.addTypeConstraint(newTypeConstraint, constraintLanguage, constraintImplementation, constrainedType);
return newTypeConstraint;
}
/**
* Creates and adds a "heavy" model type to the repository.
*
* @param extensionType
* The extension info for the new model type.
* @return The created model type.
* @throws MMINTException
* If the package of the new model type is not registered
* through a org.eclipse.emf.ecore.generated_package extension,
* or if the uri of the new model type is already registered in
* the repository.
*/
public Model createHeavyModelType(@NonNull ExtensionPointType extensionType) throws MMINTException {
Model newModelType = (extensionType.getNewType() == null) ?
MIDFactory.eINSTANCE.createModel() :
(Model) extensionType.getNewType();
this.addHeavyModelType(newModelType, extensionType.getUri(), extensionType.getSupertypeUri(), extensionType.getName(), extensionType.isAbstract());
return newModelType;
}
/**
* Creates and adds a "heavy" model element type to the repository.
*
* @param extensionType
* The extension info for the new model element type.
* @param eInfo
* The EMF info of the new model element type.
* @param modelType
* The model type that will contain the new model element type.
* @return The created model element type.
* @throws MMINTException
* If the uri of the new model element type is already
* registered in the repository.
*/
public ModelElement createHeavyModelElementType(ExtensionPointType extensionType, EMFInfo eInfo, Model modelType) throws MMINTException {
ModelElement newModelElemType = (extensionType.getNewType() == null) ?
MIDFactory.eINSTANCE.createModelElement() :
(ModelElement) extensionType.getNewType();
ModelElement modelElemType = getSupertype(newModelElemType, extensionType.getUri(), extensionType.getSupertypeUri());
addHeavyType(newModelElemType, modelElemType, extensionType.getUri(), extensionType.getName());
addModelElementType(newModelElemType, eInfo, modelType);
return newModelElemType;
}
/**
* Creates and adds a "heavy" model relationship type to the repository.
*
* @param extensionType
* The extension info for the new model relationship type.
* @param isBinary
* True if the new model relationship type is binary, false
* otherwise.
* @return The created model relationship type.
* @throws MMINTException
* If the package of the new model relationship type is not
* registered through a org.eclipse.emf.ecore.generated_package
* extension, or if the uri of the new model relationship type
* is already registered in the repository.
*/
public @NonNull ModelRel createHeavyModelRelType(@NonNull ExtensionPointType extensionType, boolean isBinary) throws MMINTException {
ModelRel newModelRelType;
if (extensionType.getNewType() == null) {
newModelRelType = (isBinary) ?
RelationshipFactory.eINSTANCE.createBinaryModelRel() :
RelationshipFactory.eINSTANCE.createModelRel();
}
else {
newModelRelType = (ModelRel) extensionType.getNewType();
}
addHeavyModelRelType(newModelRelType, extensionType.getUri(), extensionType.getSupertypeUri(), extensionType.getName(), extensionType.isAbstract());
return newModelRelType;
}
/**
* Creates and adds a "heavy" model type endpoint and a reference to it to the Type MID (variant for model
* relationship types).
*
* @param extensionType
* The extension info for the new model type endpoint.
* @param targetModelType
* The model type that is the target of the new model type endpoint.
* @param isBinarySrc
* (Only for a binary model relationship type container) True if the target model type is the source in
* the binary model relationship type container, false otherwise.
* @param containerModelRelType
* The model relationship type that will contain the new model type endpoint.
* @return The created reference to the new model type endpoint.
* @throws MMINTException
* If the uri of the new model type endpoint is already registered in the repository.
*/
public @NonNull ModelEndpointReference createHeavyModelTypeEndpointAndModelTypeEndpointReference(@NonNull ExtensionPointType extensionType, @NonNull Model targetModelType, boolean isBinarySrc, @NonNull ModelRel containerModelRelType) throws MMINTException {
ModelEndpoint newModelTypeEndpoint = (extensionType.getNewType() == null) ?
MIDFactory.eINSTANCE.createModelEndpoint() :
(ModelEndpoint) extensionType.getNewType();
ModelEndpointReference newModelTypeEndpointRef = addHeavyModelTypeEndpointAndModelTypeEndpointReference(newModelTypeEndpoint, extensionType.getUri(), extensionType.getSupertypeUri(), extensionType.getName(), targetModelType, isBinarySrc, containerModelRelType);
return newModelTypeEndpointRef;
}
/**
* Creates and adds a "heavy" model type endpoint to the Type MID (variant for operator types).
*
* @param extensionType
* The extension info for the new model type endpoint.
* @param targetModelType
* The model type that is the target of the new model type endpoint.
* @param containerOperatorType
* The operator type that will contain the new model type endpoint.
* @param containerFeatureName
* The name of the feature in the operator type that will contain the new model type endpoint.
* @return The created model type endpoint.
* @throws MMINTException
* If the uri of the new model type endpoint is already registered in the Type MID.
*/
public @NonNull ModelEndpoint createHeavyModelTypeEndpoint(@NonNull ExtensionPointType extensionType, @NonNull Model targetModelType, @NonNull Operator containerOperatorType, @NonNull String containerFeatureName) throws MMINTException {
ModelEndpoint newModelTypeEndpoint = (extensionType.getNewType() == null) ?
MIDFactory.eINSTANCE.createModelEndpoint() :
(ModelEndpoint) extensionType.getNewType();
//TODO MMINT[USABILITY] Put into default uri creator function
String newModelTypeEndpointUri = (extensionType.getUri() == null) ?
containerOperatorType.getUri() + MMINT.URI_SEPARATOR + extensionType.getName() :
extensionType.getUri();
addHeavyModelTypeEndpoint(newModelTypeEndpoint, newModelTypeEndpointUri, extensionType.getSupertypeUri(), extensionType.getName(), targetModelType, containerOperatorType, containerFeatureName);
return newModelTypeEndpoint;
}
/**
* Creates and adds a "heavy" generic type endpoint to the Type MID.
*
* @param extensionType
* The extension info for the new generic type endpoint.
* @param targetGenericType
* The generic type that is the target of the new generic type endpoint.
* @param containerOperatorType
* The operator type that will contain the new generic type endpoint.
* @return The created generic type endpoint.
* @throws MMINTException
* If the uri of the new generic type endpoint is already registered in the Type MID.
*/
public @NonNull GenericEndpoint createHeavyGenericTypeEndpoint(@NonNull ExtensionPointType extensionType, @NonNull GenericElement targetGenericType, @NonNull Operator containerOperatorType) throws MMINTException {
GenericEndpoint newGenericTypeEndpoint = (extensionType.getNewType() == null) ?
OperatorFactory.eINSTANCE.createGenericEndpoint() :
(GenericEndpoint) extensionType.getNewType();
String newGenericTypeEndpointUri = (extensionType.getUri() == null) ?
containerOperatorType.getUri() + MMINT.URI_SEPARATOR + extensionType.getName() :
extensionType.getUri();
addHeavyGenericTypeEndpoint(newGenericTypeEndpoint, newGenericTypeEndpointUri, extensionType.getSupertypeUri(), extensionType.getName(), targetGenericType, containerOperatorType);
return newGenericTypeEndpoint;
}
/**
* Creates and adds a "heavy" mapping type and a reference to it to the
* repository.
*
* @param extensionType
* The extension info for the new mapping type.
* @param isBinary
* True if the new mapping type is binary, false otherwise.
* @param containerModelRelType
* The model relationship type that will contain the new mapping
* type.
* @return The created reference to the new mapping type.
* @throws MMINTException
* If the uri of the new mapping type is already registered in
* the repository.
*/
public @NonNull MappingReference createHeavyMappingTypeAndMappingTypeReference(@NonNull ExtensionPointType extensionType, boolean isBinary, @NonNull ModelRel containerModelRelType) throws MMINTException {
Mapping newMappingType;
if (extensionType.getNewType() == null) {
newMappingType = (isBinary) ?
RelationshipFactory.eINSTANCE.createBinaryMapping() :
RelationshipFactory.eINSTANCE.createMapping();
}
else {
newMappingType = (Mapping) extensionType.getNewType();
}
MappingReference newMappingTypeRef = this.addHeavyMappingTypeAndMappingTypeReference(newMappingType, extensionType.getUri(), extensionType.getSupertypeUri(), extensionType.getName(), containerModelRelType);
return newMappingTypeRef;
}
/**
* Creates and adds a "heavy" model element type endpoint and a reference to
* it to the repository.
*
* @param extensionType
* The extension info for the new model element type endpoint.
* @param targetModelElemTypeRef
* The new reference to the new model element type that is the
* target of the new model element type endpoint.
* @param isBinarySrc
* (Only for a binary mapping type container) True if the model
* element type endpoint is the source in the binary mapping type
* container, false otherwise.
* @param containerMappingTypeRef
* The reference to the mapping type that will contain the new model
* element type endpoint.
* @return The created reference to the new model element type endpoint.
* @throws MMINTException
* If the uri of the new model element type endpoint is already
* registered in the repository.
*/
public ModelElementEndpointReference createHeavyModelElementTypeEndpointAndModelElementTypeEndpointReference(ExtensionPointType extensionType, ModelElementReference targetModelElemTypeRef, boolean isBinarySrc, MappingReference containerMappingTypeRef) throws MMINTException {
ModelElementEndpoint newModelElemTypeEndpoint = (extensionType.getNewType() == null) ?
RelationshipFactory.eINSTANCE.createModelElementEndpoint() :
(ModelElementEndpoint) extensionType.getNewType();
Mapping containerMappingType = containerMappingTypeRef.getObject();
newModelElemTypeEndpoint.setTarget(targetModelElemTypeRef.getObject()); // needed to get the right root uri
ModelElementEndpoint modelElemTypeEndpoint = getSupertype(newModelElemTypeEndpoint, extensionType.getUri(), extensionType.getSupertypeUri());
addHeavyType(newModelElemTypeEndpoint, modelElemTypeEndpoint, extensionType.getUri(), extensionType.getName());
addModelElementTypeEndpoint(newModelElemTypeEndpoint, targetModelElemTypeRef.getObject(), containerMappingType);
ModelElementEndpointReference modelElemTypeEndpointRef = null;
if (modelElemTypeEndpoint != null) { // may be root
MappingReference newMappingTypeRefSuper = MIDRegistry.getReference(((Mapping) modelElemTypeEndpoint.eContainer()).getUri(), ((ModelRel) containerMappingTypeRef.eContainer()).getMappingRefs());
if (newMappingTypeRefSuper != null) {
modelElemTypeEndpointRef = MIDRegistry.getReference(modelElemTypeEndpoint.getUri(), newMappingTypeRefSuper.getModelElemEndpointRefs());
}
}
ModelElementEndpointReference newModelElemTypeEndpointRef = newModelElemTypeEndpoint.createTypeReference(modelElemTypeEndpointRef, targetModelElemTypeRef, true, isBinarySrc, containerMappingTypeRef);
addModelElementTypeEndpointReference(newModelElemTypeEndpointRef, containerMappingType);
// copy from supertype
Mapping mappingTypeSuper = containerMappingType.getSupertype();
if (mappingTypeSuper != null && !MIDTypeHierarchy.isRootType(mappingTypeSuper)) {
for (ModelElementEndpointReference modelElemTypeEndpointRefSuper : mappingTypeSuper.getModelElemEndpointRefs()) {
addModelElementTypeEndpointReference(modelElemTypeEndpointRefSuper, containerMappingType);
}
}
return newModelElemTypeEndpointRef;
}
/**
* Creates and adds a "heavy" editor type to the repository.
*
* @param extensionType
* The extension info for the new editor type.
* @param modelTypeUri
* The uri of the model type handled by the new editor type.
* @param editorId
* The id of the corresponding Eclipse editor.
* @param wizardId
* The wizard id of the corresponding Eclipse editor.
* @param wizardDialogClassName
* The fully qualified name of a Java class that handles the
* creation of the model type through the new editor type.
* @param isDiagram
* True if the new editor type is a diagram, false otherwise.
* @return The created editor type.
* @throws MMINTException
* If the uri of the new editor type is already registered in
* the repository.
*/
public Editor createHeavyEditorType(ExtensionPointType extensionType, String modelTypeUri, String editorId, String wizardId, String wizardDialogClassName, boolean isDiagram) throws MMINTException {
Editor newEditorType;
if (extensionType.getNewType() == null) {
newEditorType = (isDiagram) ?
EditorFactory.eINSTANCE.createDiagram() :
EditorFactory.eINSTANCE.createEditor();
}
else {
newEditorType = (Editor) extensionType.getNewType();
}
Editor editorType = getSupertype(newEditorType, extensionType.getUri(), extensionType.getSupertypeUri());
addHeavyType(newEditorType, editorType, extensionType.getUri(), extensionType.getName());
addEditorType(newEditorType, modelTypeUri, editorId, wizardId, wizardDialogClassName, MMINT.cachedTypeMID);
//TODO MMINT[MISC] this can be optimized to run once instead of for each editor, if needed
IExtensionRegistry registry = RegistryFactory.getRegistry();
if (registry != null) {
IConfigurationElement[] config = registry.getConfigurationElementsFor(MMINT.ECLIPSE_EDITORS_EXT_POINT);
for (IConfigurationElement elem : config) {
if (elem.getAttribute(MMINT.ECLIPSE_EDITORS_ATTR_ID).equals(editorId)) {
String fileExtensions = elem.getAttribute(MMINT.ECLIPSE_EDITORS_ATTR_EXTENSIONS);
if (fileExtensions != null) {
for (String fileExtension : fileExtensions.split(",")) {
newEditorType.getFileExtensions().add(fileExtension);
}
}
break;
}
}
}
return newEditorType;
}
/**
* Adds a "heavy" editor type for a model type.
*
* @param editorType
* The editor type.
* @param modelTypeUri
* The uri of the model type handled by the editor type.
*/
public static void addHeavyModelTypeEditor(Editor editorType, String modelTypeUri) {
Model modelType = MIDTypeRegistry.getType(modelTypeUri);
if (modelType != null) {
addModelTypeEditor(editorType, modelType);
editorType.getFileExtensions().add(modelType.getFileExtension());
}
}
/**
* Adds all registered "heavy" editor types for a model type.
*
* @param modelType
* The model type handled by the editor types.
*/
public static void createHeavyModelTypeEditors(Model modelType) {
for (Editor editorType : MIDTypeRegistry.getEditorTypes()) {
if (editorType.getModelUri().equals(modelType.getUri())) {
addModelTypeEditor(editorType, modelType);
editorType.getFileExtensions().add(modelType.getFileExtension());
}
}
}
/**
* Creates and adds a "heavy" operator type to the repository.
*
* @param extensionType
* The extension info for the new operator type.
* @return The created operator type.
* @throws MMINTException
* If the operator implementation is missing, or if the uri of
* the new operator type is already registered in the
* repository.
*/
public @NonNull Operator createHeavyOperatorType(@NonNull ExtensionPointType extensionType) throws MMINTException {
if (extensionType.getNewType() == null) {
throw new MMINTException("Missing operator implementation for " + extensionType.getName());
}
Operator newOperatorType = (Operator) extensionType.getNewType();
Operator operatorType = getSupertypeWithoutRoot(newOperatorType, extensionType.getUri(), extensionType.getSupertypeUri());
addHeavyGenericType(newOperatorType, operatorType, extensionType.getUri(), extensionType.getName(), extensionType.isAbstract());
addOperatorType(newOperatorType, MMINT.cachedTypeMID);
return newOperatorType;
}
public @NonNull OperatorConstraintRule createHeavyOperatorTypeConstraintRule(@NonNull OperatorConstraint constraint, @NonNull ModelEndpoint modelRelTypeEndpoint) throws MMINTException {
OperatorConstraintRule newConstraintRule = OperatorFactory.eINSTANCE.createOperatorConstraintRule();
MIDTypeFactory.addOperatorTypeConstraintRule(newConstraintRule, constraint, modelRelTypeEndpoint);
this.createHeavyOperatorTypeConstraintRuleEndpoint(
newConstraintRule,
modelRelTypeEndpoint,
-1,
OperatorPackage.eINSTANCE.getOperatorConstraintRule_OutputModelRel().getName());
return newConstraintRule;
}
public @NonNull OperatorConstraintParameter createHeavyOperatorTypeConstraintRuleEndpoint(@NonNull OperatorConstraintRule constraintRule, @NonNull ModelEndpoint modelTypeEndpoint, int endpointIndex, String ruleFeatureName) throws MMINTException {
ModelEndpointReference modelTypeEndpointRef = RelationshipFactory.eINSTANCE.createModelEndpointReference();
MIDTypeFactory.addTypeReference(modelTypeEndpointRef, modelTypeEndpoint, null, false, false);
OperatorConstraintParameter newConstraintRuleParam = OperatorFactory.eINSTANCE.createOperatorConstraintParameter();
MIDTypeFactory.addOperatorTypeConstraintRuleEndpoint(
newConstraintRuleParam,
constraintRule,
modelTypeEndpointRef,
endpointIndex,
ruleFeatureName);
return newConstraintRuleParam;
}
}