/*
Copyright (C) 2010 by Claas Wilke (claaswilke@gmx.net)
This file is part of the Facade of Dresden OCL2 for Eclipse.
Dresden OCL2 for Eclipse is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your option)
any later version.
Dresden OCL2 for Eclipse is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
for more details.
You should have received a copy of the GNU Lesser General Public License along
with Dresden OCL2 for Eclipse. If not, see <http://www.gnu.org/licenses/>.
*/
package org.dresdenocl.facade;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.dresdenocl.metrics.OclMetrics;
import org.dresdenocl.metrics.metric.Metric;
import org.eclipse.emf.common.util.URI;
import org.dresdenocl.interpreter.IInterpretationResult;
import org.dresdenocl.interpreter.IOclInterpreter;
import org.dresdenocl.interpreter.OclInterpreterPlugin;
import org.dresdenocl.language.ocl.resource.ocl.Ocl22Parser;
import org.dresdenocl.metamodels.ecore.EcoreMetamodelPlugin;
import org.dresdenocl.metamodels.java.JavaMetaModelPlugin;
import org.dresdenocl.metamodels.uml2.UML2MetamodelPlugin;
import org.dresdenocl.metamodels.xsd.XSDMetamodelPlugin;
import org.dresdenocl.model.IModel;
import org.dresdenocl.model.ModelAccessException;
import org.dresdenocl.model.metamodel.IMetamodel;
import org.dresdenocl.modelbus.ModelBusPlugin;
import org.dresdenocl.modelinstance.IModelInstance;
import org.dresdenocl.modelinstance.IModelInstanceType;
import org.dresdenocl.modelinstancetype.ecore.EcoreModelInstanceTypePlugin;
import org.dresdenocl.modelinstancetype.java.JavaModelInstanceTypePlugin;
import org.dresdenocl.modelinstancetype.types.IModelInstanceElement;
import org.dresdenocl.modelinstancetype.types.IModelInstanceObject;
import org.dresdenocl.modelinstancetype.xml.XmlModelInstanceTypePlugin;
import org.dresdenocl.parser.ParseException;
import org.dresdenocl.pivotmodel.Constraint;
import org.dresdenocl.pivotmodel.ConstraintKind;
import org.dresdenocl.pivotmodel.Operation;
import org.dresdenocl.pivotmodel.Parameter;
import org.dresdenocl.pivotmodel.Type;
import org.dresdenocl.tools.codegen.declarativ.IOcl2DeclSettings;
import org.dresdenocl.tools.codegen.declarativ.Ocl2DeclCodeFactory;
import org.dresdenocl.tools.codegen.declarativ.ocl2sql.IOcl2Sql;
import org.dresdenocl.tools.codegen.declarativ.ocl2sql.Ocl2SQLFactory;
import org.dresdenocl.tools.codegen.exception.Ocl2CodeException;
import org.dresdenocl.tools.codegen.ocl2java.IOcl2Java;
import org.dresdenocl.tools.codegen.ocl2java.IOcl2JavaSettings;
import org.dresdenocl.tools.codegen.ocl2java.Ocl2JavaFactory;
import org.dresdenocl.tools.template.ITemplateGroup;
import org.dresdenocl.tools.template.TemplatePlugin;
import org.dresdenocl.tools.template.exception.TemplateException;
import org.dresdenocl.tools.transformation.ITransformation;
import org.dresdenocl.tools.transformation.TransformationFactory;
import org.dresdenocl.tools.transformation.TransformationPlugin;
import org.dresdenocl.tools.transformation.impl.Tuple;
/**
* <p>
* This is a <i>Facade</i> that provides access to all main services of Dresden
* OCL2 for Eclipse. The use of this Facade is easy but it depends on all
* bundles of Dresden OCL2 for Eclipse. If you want to use only some services
* you probably should implement your own Facade.
* </p>
*
* @author Claas Wilke
*/
public class Ocl2ForEclipseFacade {
/** The ID of the EMF Ecore {@link IMetamodel}. */
public final static String ECORE_META_MODEL = EcoreMetamodelPlugin.ID;
/** The ID of the EMF Ecore {@link IModelInstanceType}. */
public final static String ECORE_MODEL_INSTANCE_TYPE = EcoreModelInstanceTypePlugin.PLUGIN_ID;
/** The ID of the reflective Java {@link IMetamodel}. */
public final static String JAVA_META_MODEL = JavaMetaModelPlugin.ID;
/** The ID of the Java {@link IModelInstanceType}. */
public final static String JAVA_MODEL_INSTANCE_TYPE = JavaModelInstanceTypePlugin.PLUGIN_ID;
/** The ID of the Eclipse MDT UML2 {@link IMetamodel}. */
public final static String UML2_MetaModel = UML2MetamodelPlugin.ID;
/** The ID of the XML Schema (XSD) {@link IMetamodel}. */
public final static String XSD_META_MODEL = XSDMetamodelPlugin.ID;
/** The ID of the XML {@link IModelInstanceType}. */
public final static String XML_MODEL_INSTANCE_TYPE = XmlModelInstanceTypePlugin.PLUGIN_ID;
/**
* Cached interpreters for interpretation. They are stored in a
* {@link WeakHashMap}. If an {@link IModelInstance} becomes garbage, its
* {@link IOclInterpreter} becomes garbage as well.
*/
private static Map<IModelInstance, IOclInterpreter> cachedInterpreters = new WeakHashMap<IModelInstance, IOclInterpreter>();
/** The {@link IOcl2Java} representing the Java/AspectJ code generator. */
private static IOcl2Java javaCodeGenerator = null;
/** The {@link IOcl2Sql} representing the Java/AspectJ code generator. */
private static IOcl2Sql sqlCodeGenerator = null;
/**
* <p>
* Generates the AspectJ code for a given {@link List} of {@link Constraint}
* s and a given {@link IOcl22CodeSettings}.
* </p>
*
* @param constraints
* The {@link Constraint}s used for code generation.
* @param settings
* The {@link IOcl22CodeSettings} used for code generation (can
* be <code>null</code> if default settings shall be used).
* @return The generated AspectJ code as a set of {@link String}s.
* @throws IllegalArgumentException
* Thrown if the {@link List} of {@link Constraint}s is empty or
* <code>null</code>.
* @throws Ocl22CodeException
*/
public static List<String> generateAspectJCode(
List<Constraint> constraints, IOcl2JavaSettings settings)
throws IllegalArgumentException, Ocl2CodeException {
if (constraints == null || constraints.size() == 0) {
throw new IllegalArgumentException(
"The list of constraints must not be emtpy.");
}
// no else.
if (javaCodeGenerator == null) {
javaCodeGenerator = Ocl2JavaFactory.getInstance()
.createJavaCodeGenerator();
}
// no else.
javaCodeGenerator.resetEnvironment();
if (settings != null) {
javaCodeGenerator.setSettings(settings);
}
else {
/* Necessary to replace possibly altered settings. */
javaCodeGenerator.setSettings(Ocl2JavaFactory.getInstance()
.createJavaCodeGeneratorSettings());
}
return javaCodeGenerator.transformInstrumentationCode(constraints);
}
/**
* <p>
* Generates the AspectJ code for a given {@link Constraint} and a given
* {@link IOcl22CodeSettings}.
* </p>
*
* @param constraint
* The {@link Constraint} used for code generation.
* @param settings
* The {@link IOcl22CodeSettings} used for code generation (can
* be <code>null</code> if default settings shall be used).
* @return The generated AspectJ code as a {@link String}s.
* @throws IllegalArgumentException
* Thrown if the {@link List} of {@link Constraint}s is empty or
* <code>null</code>.
* @throws Ocl22CodeException
*/
public static String generateAspectJCode(Constraint constraint,
IOcl2JavaSettings settings) throws IllegalArgumentException,
Ocl2CodeException {
if (constraint == null) {
throw new IllegalArgumentException(
"The constraint must not be null.");
}
// no else.
List<Constraint> constraints;
constraints = new ArrayList<Constraint>();
constraints.add(constraint);
return generateAspectJCode(constraints, settings).get(0);
}
/**
* <p>
* Generates the Java fragment code for a given {@link List} of
* {@link Constraint}s and a given {@link IOcl22CodeSettings}.
* </p>
*
* @param constraints
* The {@link Constraint}s used for code generation.
* @param settings
* The {@link IOcl22CodeSettings} used for code generation (can
* be <code>null</code> if default settings shall be used).
* @return The generated fragments as a set of {@link String}s.
* @throws IllegalArgumentException
* Thrown if the {@link List} of {@link Constraint}s is empty or
* <code>null</code>.
* @throws Ocl22CodeException
*/
public static List<String> generateJavaFragmentCode(
List<Constraint> constraints, IOcl2JavaSettings settings)
throws IllegalArgumentException, Ocl2CodeException {
if (constraints == null || constraints.size() == 0) {
throw new IllegalArgumentException(
"The list of constraints must not be emtpy.");
}
// no else.
if (javaCodeGenerator == null) {
javaCodeGenerator = Ocl2JavaFactory.getInstance()
.createJavaCodeGenerator();
}
// no else.
javaCodeGenerator.resetEnvironment();
if (settings != null) {
javaCodeGenerator.setSettings(settings);
}
else {
/* Necessary to replace possibly altered settings. */
javaCodeGenerator.setSettings(Ocl2JavaFactory.getInstance()
.createJavaCodeGeneratorSettings());
}
return javaCodeGenerator.transformFragmentCode(constraints);
}
/**
* <p>
* Generates the Java fragment code for a given {@link Constraint} and a
* given {@link IOcl22CodeSettings}.
* </p>
*
* @param constraint
* The {@link Constraint} used for code generation.
* @param settings
* The {@link IOcl22CodeSettings} used for code generation (can
* be <code>null</code> if default settings shall be used).
* @return The generated fragment as a {@link String}s.
* @throws IllegalArgumentException
* Thrown if the {@link List} of {@link Constraint}s is empty or
* <code>null</code>.
* @throws Ocl22CodeException
*/
public static String generateJavaFragmentCode(Constraint constraint,
IOcl2JavaSettings settings) throws IllegalArgumentException,
Ocl2CodeException {
if (constraint == null) {
throw new IllegalArgumentException(
"The constraint must not be null.");
}
// no else.
List<Constraint> constraints;
constraints = new ArrayList<Constraint>();
constraints.add(constraint);
return generateJavaFragmentCode(constraints, settings).get(0);
}
/**
* <p>
* Returns an {@link IOcl22CodeSettings} instance to configure Java or
* AspectJ code generation.
* </p>
*
* @return An {@link IOcl22CodeSettings} instance to configure Java or
* AspectJ code generation.
*/
public static IOcl2JavaSettings getJavaCodeGeneratorSettings() {
return Ocl2JavaFactory.getInstance().createJavaCodeGeneratorSettings();
}
/**
* <p>
* Generates the SQL code for a given {@link List} of {@link Constraint} s
* and a given {@link IOcl2DeclSettings}.
* </p>
*
* @param constraints
* The {@link Constraint}s used for code generation.
* @param settings
* The {@link IOcl2DeclSettings} used for code generation (can be
* <code>null</code> if default settings shall be used).
* @param model
* The {@link IModel} for code generation
* @return The generated SQL code as a set of {@link String}s.
* @throws IllegalArgumentException
* Thrown if the {@link List} of {@link Constraint}s is empty or
* <code>null</code>.
* @throws Ocl2CodeException
*/
public static List<String> generateSQLCode(List<Constraint> constraints,
IOcl2DeclSettings settings, IModel model)
throws IllegalArgumentException, Ocl2CodeException {
if (constraints == null || constraints.size() == 0) {
throw new IllegalArgumentException(
"The list of constraints must not be emtpy.");
}
// no else.
if (sqlCodeGenerator == null) {
sqlCodeGenerator = Ocl2SQLFactory.getInstance()
.createSQLCodeGenerator();
}
// no else.
sqlCodeGenerator.resetEnvironment();
if (settings != null) {
sqlCodeGenerator.setSettings(settings);
}
else {
/* Necessary to replace possibly altered settings. */
sqlCodeGenerator.setSettings(getDeclCodeGeneratorSettings());
}
sqlCodeGenerator.setInputModel(model);
return sqlCodeGenerator.transformFragmentCode(constraints);
}
/**
* <p>
* Generates the SQL code for a given {@link Constraint} and a given
* {@link IOcl2DeclSettings}.
* </p>
*
* @param constraint
* The {@link Constraint} used for code generation.
* @param settings
* The {@link IOcl2DeclSettings} used for code generation (can be
* <code>null</code> if default settings shall be used).
* @param model
* The {@link IModel} for code generation
* @return The generated SQL code as a {@link String}s.
* @throws IllegalArgumentException
* Thrown if the {@link List} of {@link Constraint}s is empty or
* <code>null</code>.
* @throws Ocl2CodeException
*/
public static String generateSQLCode(Constraint constraint,
IOcl2DeclSettings settings, IModel model)
throws IllegalArgumentException, Ocl2CodeException {
if (constraint == null) {
throw new IllegalArgumentException(
"The constraint must not be null.");
}
// no else.
List<Constraint> constraints;
constraints = new ArrayList<Constraint>();
constraints.add(constraint);
return generateSQLCode(constraints, settings, model).get(0);
}
/**
* <p>
* Returns an {@link IOcl2DeclSettings} instance to configure SQL code
* generation.
* </p>
*
* @return An {@link IOcl2DeclSettings} instance to configure SQL code
* generation.
*/
public static IOcl2DeclSettings getDeclCodeGeneratorSettings() {
return Ocl2DeclCodeFactory.getInstance().createOcl2DeclCodeSettings();
}
/**
* <p>
* Return an {@link ITemplateGroup} instance with template for code
* generation.
* </p>
*
* @param templateGroupName
* The name of template group
* @return a instance of the template group or <i>null</i> if there no
* template group with the name
* @throws TemplateException
*/
public static ITemplateGroup getTemplateGroup(String templateGroupName)
throws TemplateException {
return TemplatePlugin.getTemplateGroupRegistry().getTemplateGroup(
templateGroupName);
}
/**
* <p>
* Return a list with the names of transformation.
* </P>
*
* @return the list with names.
*/
public static List<String> getTransformationList() {
return TransformationPlugin.getTransformationRegistry()
.getTransformationList();
}
/**
* <p>
* Returns a name list of transformation which transform a in_type to a
* out_type. The settings of transformation must implements the
* IOcl2DeclSettings.
* </p>
*
* @param in_type
* the type of transformation input
* @param out_type
* the type of transformation output
* @return the list with names
*/
public static List<String> getTransformation(Class<?> in_type,
Class<?> out_type) {
return TransformationPlugin.getTransformationRegistry()
.getTransformationList(in_type, out_type,
IOcl2DeclSettings.class);
}
/**
* <p>
* Returns an {@link ITransformation} instance with the parameters.
* </p>
*
* @param transId
* the name of the transformation
* @param modelIn
* the type of the transformation input
* @param modelOut
* the type of the transformation output
* @param settings
* the settings of the transformation
* @param modelInName
* the input name of the transformation
* @param modelOutName
* the output name of the transformation
* @return a new instance of {@link ITransformation} or <i>null</i> if there
* no transformation with the parameters.
*/
public static <I, S, O> ITransformation<I, S, O> getTransformation(
String transId, Class<I> modelIn, Class<O> modelOut,
Class<S> settings, String modelInName, String modelOutName) {
return TransformationFactory.getInstance().getTransformation(transId,
modelIn, modelOut, settings, modelInName, modelOutName);
}
/**
* <p>
* Returns an {@link ITransformation} instance with the parameters.
* </p>
*
* @param transId
* the name of the transformation
* @param modelIn
* the type of the transformation input
* @param modelOut1
* the type of the first element of the output tuple
* @param modelOut2
* the type of the second element of the output tuple
* @param settings
* the settings of the transformation
* @param modelInName
* the input name of the transformation
* @param modelOutName
* the output name of the transformation
* @return a new instance of {@link ITransformation} or <i>null</i> if there
* no transformation with the parameters.
*/
public static <I, S, O1, O2> ITransformation<I, S, Tuple<O1, O2>> getParallelTransformation(
String transId, Class<I> modelIn, Class<O1> modelOut1,
Class<O2> modelOut2, Class<S> settings, String modelInName,
String modelOutName) {
return TransformationFactory.getInstance().getParallelTransformation(
transId, modelIn, modelOut1, modelOut2, settings, modelInName,
modelOutName);
}
/**
* <p>
* Returns the {@link IMetamodel} for a given ID or throws an
* {@link IllegalArgumentException} if the given ID does not exists.
* </p>
*
* @param id
* The ID of the {@link IMetamodel} that shall be returned. Use
* the provided constants, if the id of the {@link IMetamodel} is
* unknown.
* @return The {@link IMetamodel} of the given id.
* @throws IllegalArgumentException
* Thrown if the given ID does not exists.
*/
public static IMetamodel getMetaModel(String id)
throws IllegalArgumentException {
if (id == null) {
throw new IllegalArgumentException(
"Parameter 'id' must not be null.");
}
// no else.
IMetamodel result;
result = ModelBusPlugin.getMetamodelRegistry().getMetamodel(id);
if (result == null) {
throw new IllegalArgumentException("A MetaModel for the given id '"
+ id + "' does not exist.");
}
// no else.
return result;
}
/**
* <p>
* Returns a {@link Set} containing all {@link IMetamodel}s of Dresden OCL2
* for Eclipse.
* </p>
*/
public static Set<IMetamodel> getMetaModels() {
return new HashSet<IMetamodel>(Arrays.asList(ModelBusPlugin
.getMetamodelRegistry().getMetamodels()));
}
/**
* Computes a {@link Metric} object containing metrics for a given
* {@link Constraint}.
*
* @param constraint
* The {@link Constraint} for which the {@link Metric} object
* shall be computed.
* @return A {@link Metric} object containing metrics for the given
* {@link Constraint}.
*/
public static Metric getMetrics(Constraint constraint) {
return OclMetrics.computeMetric(constraint);
}
/**
* Computes a {@link Metric} object containing metrics for a given
* {@link Constraint}.
*
* @param constraint
* The {@link Constraint} for which the {@link Metric} object
* shall be computed.
* @return A {@link Metric} object containing metrics for the given
* {@link Constraint}.
*/
public static Metric getMetrics(IModel model) {
try {
return OclMetrics.computeMetric(model.getConstraints());
} catch (ModelAccessException e) {
throw new IllegalStateException(
"Exception during computation of metric for the given model.",
e);
}
}
/**
* <p>
* Loads and returns an {@link IModel} for a given {@link File} and a given
* {@link IMetamodel}.
* </p>
*
* @param file
* The {@link File} that shall be loaded.
* @param metaModel
* The {@link IMetamodel} of the {@link IModel}.
* @return The loaded {@link IModel}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModel getModel(File file, IMetamodel metaModel)
throws ModelAccessException, IllegalArgumentException {
if (file == null) {
throw new IllegalArgumentException(
"Parameter 'file' must not be null.");
}
else if (metaModel == null) {
throw new IllegalArgumentException(
"Parameter 'metaModel' must not be null.");
}
// no else.
/* Probably add the MetaModel. */
if (!getMetaModels().contains(metaModel)) {
ModelBusPlugin.getMetamodelRegistry().addMetamodel(metaModel);
}
// no else.
IModel result;
result = metaModel.getModelProvider().getModel(file);
return result;
}
/**
* <p>
* Loads and returns an {@link IModel} for a given {@link File} and a given
* {@link IMetamodel}'s.
* </p>
*
* @param file
* The {@link File} of the file that shall be loaded.
* @param metaModelID
* The ID of {@link IMetamodel} of the {@link IModel}.
* @return The loaded {@link IModel}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid or the given ID does not
* identify an {@link IMetamodel}.
*/
public static IModel getModel(File file, String metaModelID)
throws ModelAccessException, IllegalArgumentException {
if (file == null) {
throw new IllegalArgumentException(
"Parameter 'file' must not be null.");
}
else if (metaModelID == null) {
throw new IllegalArgumentException(
"Parameter 'metaModelID' must not be null.");
}
// no else.
IModel result;
result = getMetaModel(metaModelID).getModelProvider().getModel(file);
return result;
}
/**
* <p>
* Loads and returns an {@link IModel} for a given location and a given
* {@link IMetamodel}.
* </p>
*
* @param location
* The location of the file that shall be loaded.
* @param metaModel
* The {@link IMetamodel} of the {@link IModel}.
* @return The loaded {@link IModel}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModel getModel(URL location, IMetamodel metaModel)
throws ModelAccessException, IllegalArgumentException {
if (location == null) {
throw new IllegalArgumentException(
"Parameter 'location' must not be null.");
}
else if (metaModel == null) {
throw new IllegalArgumentException(
"Parameter 'metaModel' must not be null.");
}
// no else.
/* Probably add the MetaModel. */
if (!getMetaModels().contains(metaModel)) {
ModelBusPlugin.getMetamodelRegistry().addMetamodel(metaModel);
}
// no else.
IModel result;
result = metaModel.getModelProvider().getModel(location);
return result;
}
/**
* <p>
* Loads and returns an {@link IModel} for a given location and a given
* {@link IMetamodel}'s.
* </p>
*
* @param location
* The location of the file that shall be loaded.
* @param metaModelID
* The ID of {@link IMetamodel} of the {@link IModel}.
* @return The loaded {@link IModel}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid or the given ID does not
* identify an {@link IMetamodel}.
*/
public static IModel getModel(URL location, String metaModelID)
throws ModelAccessException, IllegalArgumentException {
if (location == null) {
throw new IllegalArgumentException(
"Parameter 'location' must not be null.");
}
else if (metaModelID == null) {
throw new IllegalArgumentException(
"Parameter 'metaModelID' must not be null.");
}
// no else.
IModel result;
result = getMetaModel(metaModelID).getModelProvider()
.getModel(location);
return result;
}
/**
* <p>
* Creates and returns an empty {@link IModelInstance} for a given
* {@link IModel} and a given {@link IModelInstanceType}.
* </p>
*
* @param model
* The {@link IModel} of the {@link IModelInstance}.
* @param modelInstanceType
* The {@link IModelInstanceType} of the {@link IModelInstance}.
* @return The created empty {@link IModelInstance}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModelInstance getEmptyModelInstance(IModel model,
IModelInstanceType modelInstanceType) throws ModelAccessException,
IllegalArgumentException {
if (model == null) {
throw new IllegalArgumentException(
"Parameter 'model' must not be null.");
}
else if (modelInstanceType == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstanceType' must not be null.");
}
// no else.
/* Probably add the ModelInstanceType. */
if (!getModelInstanceTypes().contains(modelInstanceType)) {
ModelBusPlugin.getModelInstanceTypeRegistry().addModelInstanceType(
modelInstanceType);
}
// no else.
IModelInstance result;
result = modelInstanceType.getModelInstanceProvider()
.createEmptyModelInstance(model);
return result;
}
/**
* <p>
* Creates and returns an empty {@link IModelInstance} for a given
* {@link IModel} and a given {@link IModelInstanceType}'s ID.
* </p>
*
* @param model
* The {@link IModel} of the {@link IModelInstance}.
* @param modelInstanceTypeID
* The id of the {@link IModelInstanceType} of the
* {@link IModelInstance}.
* @return The created empty {@link IModelInstance}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModelInstance getEmptyModelInstance(IModel model,
String modelInstanceTypeID) throws ModelAccessException,
IllegalArgumentException {
if (model == null) {
throw new IllegalArgumentException(
"Parameter 'model' must not be null.");
}
// no else.
IModelInstanceType modelInstanceType;
modelInstanceType = getModelInstanceType(modelInstanceTypeID);
IModelInstance result;
result = modelInstanceType.getModelInstanceProvider()
.createEmptyModelInstance(model);
return result;
}
/**
* <p>
* Loads and returns an {@link IModelInstance} for a given {@link File}, a
* given {@link IModel} and a given {@link IModelInstanceType}.
* </p>
*
* @param file
* The {@link File} that shall be loaded.
* @param model
* The {@link IModel} of the {@link IModelInstance}.
* @param modelInstanceType
* The {@link IModelInstanceType} of the {@link IModelInstance}.
* @return The loaded {@link IModelInstance}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModelInstance getModelInstance(File file, IModel model,
IModelInstanceType modelInstanceType) throws ModelAccessException,
IllegalArgumentException {
if (file == null) {
throw new IllegalArgumentException(
"Parameter 'file' must not be null.");
}
else if (model == null) {
throw new IllegalArgumentException(
"Parameter 'model' must not be null.");
}
else if (modelInstanceType == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstanceType' must not be null.");
}
// no else.
/* Probably add the ModelInstanceType. */
if (!getModelInstanceTypes().contains(modelInstanceType)) {
ModelBusPlugin.getModelInstanceTypeRegistry().addModelInstanceType(
modelInstanceType);
}
// no else.
IModelInstance result;
result = modelInstanceType.getModelInstanceProvider().getModelInstance(
file, model);
return result;
}
/**
* <p>
* Loads and returns an {@link IModelInstance} for a given {@link File}, a
* given {@link IModel} and a given ID of a {@link IModelInstanceType}.
* </p>
*
* @param file
* The {@link File} that shall be loaded.
* @param model
* The {@link IModel} of the {@link IModelInstance}.
* @param modelInstanceTypeID
* The id of the {@link IModelInstanceType} of the
* {@link IModelInstance}.
* @return The loaded {@link IModelInstance}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModelInstance getModelInstance(File file, IModel model,
String modelInstanceTypeID) throws ModelAccessException,
IllegalArgumentException {
if (file == null) {
throw new IllegalArgumentException(
"Parameter 'file' must not be null.");
}
else if (model == null) {
throw new IllegalArgumentException(
"Parameter 'model' must not be null.");
}
// no else.
IModelInstanceType modelInstanceType;
modelInstanceType = getModelInstanceType(modelInstanceTypeID);
IModelInstance result;
result = modelInstanceType.getModelInstanceProvider().getModelInstance(
file, model);
return result;
}
/**
* <p>
* Loads and returns an {@link IModelInstance} for a given location, a given
* {@link IModel} and a given {@link IModelInstanceType}.
* </p>
*
* @param location
* The location of the {@link File} that shall be loaded.
* @param model
* The {@link IModel} of the {@link IModelInstance}.
* @param modelInstanceType
* The {@link IModelInstanceType} of the {@link IModelInstance}.
* @return The loaded {@link IModelInstance}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModelInstance getModelInstance(URL location, IModel model,
IModelInstanceType modelInstanceType) throws ModelAccessException,
IllegalArgumentException {
if (location == null) {
throw new IllegalArgumentException(
"Parameter 'location' must not be null.");
}
else if (model == null) {
throw new IllegalArgumentException(
"Parameter 'model' must not be null.");
}
else if (modelInstanceType == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstanceType' must not be null.");
}
// no else.
/* Probably add the ModelInstanceType. */
if (!getModelInstanceTypes().contains(modelInstanceType)) {
ModelBusPlugin.getModelInstanceTypeRegistry().addModelInstanceType(
modelInstanceType);
}
// no else.
IModelInstance result;
result = modelInstanceType.getModelInstanceProvider().getModelInstance(
location, model);
return result;
}
/**
* <p>
* Loads and returns an {@link IModelInstance} for a given location, a given
* {@link IModel} and a given ID of a {@link IModelInstanceType}.
* </p>
*
* @param location
* The location of the {@link File} that shall be loaded.
* @param model
* The {@link IModel} of the {@link IModelInstance}.
* @param modelInstanceTypeID
* The id of the {@link IModelInstanceType} of the
* {@link IModelInstance}.
* @return The loaded {@link IModelInstance}.
* @throws ModelAccessException
* Thrown, if the given location can not be loaded.
* @throws IllegalArgumentException
* Thrown if the parameters are invalid.
*/
public static IModelInstance getModelInstance(URL location, IModel model,
String modelInstanceTypeID) throws ModelAccessException,
IllegalArgumentException {
if (location == null) {
throw new IllegalArgumentException(
"Parameter 'location' must not be null.");
}
else if (model == null) {
throw new IllegalArgumentException(
"Parameter 'model' must not be null.");
}
IModelInstanceType modelInstanceType;
modelInstanceType = getModelInstanceType(modelInstanceTypeID);
IModelInstance result;
result = modelInstanceType.getModelInstanceProvider().getModelInstance(
location, model);
return result;
}
/**
* <p>
* Returns a {@link Set} containing all {@link IModelInstanceType}s of
* Dresden OCL2 for Eclipse.
* </p>
*/
public static Set<IModelInstanceType> getModelInstanceTypes() {
return new HashSet<IModelInstanceType>(Arrays.asList(ModelBusPlugin
.getModelInstanceTypeRegistry().getModelInstanceTypes()));
}
/**
* <p>
* Returns the {@link IModelInstanceType} for a given ID or throws an
* {@link IllegalArgumentException} if the given ID does not exists.
* </p>
*
* @param id
* The ID of the {@link IModelInstanceType} that shall be
* returned. Use the provided constants, if the id of the
* {@link IModelInstanceType} is unknown.
* @return The {@link IModelInstanceType} of the given id.
* @throws IllegalArgumentException
* Thrown if the given ID does not exists.
*/
public static IModelInstanceType getModelInstanceType(String id)
throws IllegalArgumentException {
if (id == null) {
throw new IllegalArgumentException(
"Parameter 'id' must not be null.");
}
// no else.
IModelInstanceType result;
result = ModelBusPlugin.getModelInstanceTypeRegistry()
.getModelInstanceType(id);
if (result == null) {
throw new IllegalArgumentException(
"A ModelInstanceType for the given id '" + id
+ "' does not exist.");
}
// no else.
return result;
}
/**
* <p>
* Interpret the given {@link Constraint} for the given
* {@link IModelInstanceElement}.
* </p>
*
* @param constraint
* The {@link Constraint} to be interpreted.
* @param modelInstance
* The {@link IModelInstance} the {@link IModelInstanceElement}
* belongs to.
* @param modelInstanceElement
* The {@link IModelInstanceElement} representing the current
* object. Can be <code>null</code> if none of the given
* {@link Constraint}s requires an {@link IModelInstanceObject}
* as context, i.e. all of the are defined in a static context
* (static def, or body/derive/init on static feature).
*
* @return The {@link IInterpretationResult} of the interpretation or
* <code>null</code> if the given {@link Constraint} cannot be
* checked for the given {@link IModelInstanceElement} (wrong
* {@link Type} of {@link IModelInstanceElement}).
* @throws IllegalArgumentException
* Thrown, if at least one parameter is invalid.
* @throws ModelAccessException
* Thrown, if the given {@link IModelInstance} is in an invalid
* state.
*/
public static IInterpretationResult interpretConstraint(
Constraint constraint, IModelInstance modelInstance,
IModelInstanceElement modelInstanceElement)
throws IllegalArgumentException, ModelAccessException {
if (constraint == null) {
throw new IllegalArgumentException(
"Parameter 'constraint' must not be null.");
}
else if (modelInstance == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstance' must not be null.");
}
// no else.
IInterpretationResult result;
IOclInterpreter interpreter;
/* Create or use a cached interpreter. */
if (cachedInterpreters.containsKey(modelInstance)) {
interpreter = cachedInterpreters.get(modelInstance);
}
else {
interpreter = OclInterpreterPlugin.createInterpreter(modelInstance);
cachedInterpreters.put(modelInstance, interpreter);
}
result = interpreter.interpretConstraint(constraint,
modelInstanceElement);
return result;
}
/**
* <p>
* Interprets a given {@link Collection} of {@link Constraint} for the given
* {@link IModelInstanceElement}.
* </p>
*
* @param constraints
* The {@link Constraint}s to be interpreted.
* @param modelInstance
* The {@link IModelInstance} the {@link IModelInstanceElement}
* belongs to.
* @param modelInstanceElement
* The {@link IModelInstanceElement} representing the current
* object. Can be <code>null</code> if none of the given
* {@link Constraint}s requires an {@link IModelInstanceObject}
* as context, i.e. all of the are defined in a static context
* (static def, or body/derive/init on static feature).
*
* @return A {@link List} containing the {@link IInterpretationResult} of
* the interpretation as {@link OclRoot}s.
* @throws IllegalArgumentException
* Thrown, if at least one parameter is invalid.
* @throws ModelAccessException
* Thrown, if the given {@link IModelInstance} is in an invalid
* state.
*/
public static List<IInterpretationResult> interpretConstraints(
Collection<Constraint> constraints, IModelInstance modelInstance,
IModelInstanceElement modelInstanceElement)
throws IllegalArgumentException, ModelAccessException {
if (constraints == null) {
throw new IllegalArgumentException(
"Parameter 'constraints' must not be null.");
}
// no else.
List<IInterpretationResult> result;
result = new ArrayList<IInterpretationResult>();
for (Constraint constraint : constraints) {
IInterpretationResult aResult;
aResult = interpretConstraint(constraint, modelInstance,
modelInstanceElement);
if (aResult != null) {
result.add(aResult);
}
// no else.
}
// end for.
return result;
}
/**
* <p>
* Interprets its given postconditions for a given {@link Operation}.
* </p>
*
* <p>
* <strong>Please be aware, that some postconditions must be prepared before
* their constrained {@link Operation} is invoked to save some values such
* as <code>@pre</code> values!</strong> Use the method
* {@link Ocl2ForEclipseFacade#preparePostConditions(IModelInstance, IModelInstanceElement, Operation, IModelInstanceElement[], Collection)}
* to prepare postconditions.
* </p>
*
* @param modelInstance
* The {@link IModelInstance} the {@link IModelInstanceElement}
* belongs to.
* @param modelInstanceElement
* The {@link IModelInstanceElement} on that the
* {@link Operation} shall be invoked.
* @param operation
* The {@link Operation} that shall be invoked.
* @param parameters
* The values of the {@link Operation}'s {@link Parameter}s as a
* {@link List} of {@link IModelInstanceElement} values.
* @param resultValue
* The result of the {@link Operation}'s invocation or
* <code>null</code> if no result has been returned (e.g., a void
* {@link Operation}).
* @param postConditions
* The postconditions that shall be interpreted.
* <b>Attention:</b> if this {@link Collection} contains
* {@link Constraint}s of the {@link ConstraintKind} that is
* different than {@link ConstraintKind#POSTCONDITION} they will
* not be interpreted.
* @return A {@link List} of {@link IInterpretationResult}s.
* @throws IllegalArgumentException
* Thrown, if at least one parameter is invalid.
*/
public static List<IInterpretationResult> interpretPostConditions(
IModelInstance modelInstance,
IModelInstanceElement modelInstanceElement, Operation operation,
List<IModelInstanceElement> parameters,
IModelInstanceElement resultValue,
Collection<Constraint> postConditions)
throws IllegalArgumentException {
if (modelInstance == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstance' must not be null.");
}
else if (modelInstanceElement == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstanceElement' must not be null.");
}
else if (operation == null) {
throw new IllegalArgumentException(
"Parameter 'operation' must not be null.");
}
else if (parameters == null) {
throw new IllegalArgumentException(
"Parameter 'parameters' must not be null.");
}
else if (postConditions == null) {
throw new IllegalArgumentException(
"Parameter 'postConditions' must not be null.");
}
// no else.
List<IInterpretationResult> result;
IOclInterpreter interpreter;
/* Create or use a cached interpreter. */
if (cachedInterpreters.containsKey(modelInstance)) {
interpreter = cachedInterpreters.get(modelInstance);
}
else {
interpreter = OclInterpreterPlugin.createInterpreter(modelInstance);
cachedInterpreters.put(modelInstance, interpreter);
}
result = interpreter.interpretPostConditions(modelInstanceElement,
operation, parameters.toArray(new IModelInstanceElement[0]),
resultValue, postConditions);
return result;
}
/**
* <p>
* Interprets its given preconditions for a given {@link Operation}.
* </p>
*
* @param modelInstance
* The {@link IModelInstance} the {@link IModelInstanceElement}
* belongs to.
* @param modelInstanceElement
* The {@link IModelInstanceElement} on that the
* {@link Operation} shall be invoked.
* @param operation
* The {@link Operation} that shall be invoked.
* @param parameters
* The values of the {@link Operation}'s {@link Parameter}s as a
* {@link List} of {@link IModelInstanceElement} values.
* @param preConditions
* The preconditions that shall be interpreted. <b>Attention:</b>
* if this {@link Collection} contains {@link Constraint}s of the
* {@link ConstraintKind} that is different than
* {@link ConstraintKind#PRECONDITION} they will not be
* interpreted.
* @return A {@link List} of {@link IInterpretationResult}s.
* @throws IllegalArgumentException
* Thrown, if at least one parameter is invalid.
*/
public static List<IInterpretationResult> interpretPreConditions(
IModelInstance modelInstance,
IModelInstanceElement modelInstanceElement, Operation operation,
List<IModelInstanceElement> parameters,
Collection<Constraint> preConditions)
throws IllegalArgumentException {
if (modelInstance == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstance' must not be null.");
}
else if (modelInstanceElement == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstanceElement' must not be null.");
}
else if (operation == null) {
throw new IllegalArgumentException(
"Parameter 'operation' must not be null.");
}
else if (parameters == null) {
throw new IllegalArgumentException(
"Parameter 'parameters' must not be null.");
}
else if (preConditions == null) {
throw new IllegalArgumentException(
"Parameter 'preConditions' must not be null.");
}
// no else.
List<IInterpretationResult> result;
IOclInterpreter interpreter;
/* Create or use a cached interpreter. */
if (cachedInterpreters.containsKey(modelInstance)) {
interpreter = cachedInterpreters.get(modelInstance);
}
else {
interpreter = OclInterpreterPlugin.createInterpreter(modelInstance);
cachedInterpreters.put(modelInstance, interpreter);
}
result = interpreter.interpretPreConditions(modelInstanceElement,
operation, parameters.toArray(new IModelInstanceElement[0]),
preConditions);
return result;
}
/**
* <p>
* Removes a {@link IModel model}.
* </p>
*
* @param model
* The {@link IModel} that shall be removed.
*
* @return <code>true</code> if the given {@link IModel} has been removed.
* @throws IllegalArgumentException
* Thrown, if the given parameter is invalid.
*/
public static boolean removeModel(IModel model)
throws IllegalArgumentException {
return ModelBusPlugin.getModelRegistry().removeModel(model);
}
/**
* <p>
* Removes a {@link IModelInstance}.
* </p>
*
* @param modelInstance
* The {@link IModelInstance} that shall be removed.
*
* @return <code>true</code> if the given {@link IModelInstance} has been
* removed.
* @throws IllegalArgumentException
* Thrown, if the given parameter is invalid.
*/
public static boolean removeModelInstance(IModelInstance modelInstance)
throws IllegalArgumentException {
return ModelBusPlugin.getModelInstanceRegistry().removeModelInstance(
modelInstance);
}
/**
* <p>
* Parses a {@link List} of OCL {@link Constraint}s that are provided by a
* given {@link File}.
* </p>
*
* @param file
* The {@link File} providing the {@link File} or Stream to be
* parsed.
* @param model
* The {@link IModel} for which the {@link Constraint}s shall be
* parsed.
* @param addToModel
* Indicates whether or not the parsed {@link Constraint}s, its
* defined fields and functions to the given {@link IModel}.
* @return The parsed {@link Constraint}s as a {@link List}.
* @throws ParseException
* Thrown, if the parsing fails.
* @throws IllegalArgumentException
* Thrown, if at least one parameter is invalid.
*/
public static List<Constraint> parseConstraints(File file, IModel model,
boolean addToModel) throws ParseException, IllegalArgumentException {
if (file == null) {
throw new IllegalAccessError("Parameter 'file' must not be null.");
}
// no else.
URI uri = URI.createFileURI(file.getAbsolutePath());
return parseConstraints(uri, model, addToModel);
}
/**
* <p>
* Parses a {@link List} of OCL {@link Constraint}s that are provided by a
* given {@link URL}.
* </p>
*
* @param location
* The {@link URL} providing the {@link File} or Stream to be
* parsed.
* @param model
* The {@link IModel} for which the {@link Constraint}s shall be
* parsed.
* @param addToModel
* Indicates whether or not the parsed {@link Constraint}s, its
* defined fields and functions to the given {@link IModel}.
* @return The parsed {@link Constraint}s as a {@link List}.
* @throws ParseException
* Thrown, if the parsing fails.
* @throws IllegalArgumentException
* Thrown, if at least one parameter is invalid.
*/
public static List<Constraint> parseConstraints(URL location, IModel model,
boolean addToModel) throws ParseException, IllegalArgumentException {
if (location == null) {
throw new IllegalArgumentException(
"Parameter 'location' must not be null.");
}
// no else.
return parseConstraints(URI.createFileURI(location.getFile()), model,
addToModel);
}
public static List<Constraint> parseConstraints(URI uri, IModel model,
boolean addToModel) throws ParseException, IllegalArgumentException {
if (uri == null)
throw new IllegalArgumentException(
"Parameter 'uri' must not be null.");
// no else.
if (model == null)
throw new IllegalArgumentException(
"Parameter 'model' must not be null.");
// no else.
return Ocl22Parser.INSTANCE.doParse(model, uri, addToModel);
}
/**
* <p>
* Prepares a given {@link Collection} of postconditions for a given
* {@link Operation}.
* </p>
*
* @param modelInstance
* The {@link IModelInstance} the {@link IModelInstanceElement}
* belongs to.
* @param modelInstanceElement
* The {@link IModelInstanceElement} on that the
* {@link Operation} shall be invoked.
* @param operation
* The {@link Operation} that shall be invoked.
* @param parameters
* The values of the {@link Operation}'s {@link Parameter}s as a
* {@link List} of {@link IModelInstanceElement} values.
* @param postConditions
* The postconditions that shall be prepared. <b>Attention:</b>
* if this {@link Collection} contains {@link Constraint}s of the
* {@link ConstraintKind} that is different than
* {@link ConstraintKind#POSTCONDITION} they will not be
* prepared.
*/
public static void preparePostConditions(IModelInstance modelInstance,
IModelInstanceElement modelInstanceElement, Operation operation,
List<IModelInstanceElement> parameters,
Collection<Constraint> postConditions) {
if (modelInstance == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstance' must not be null.");
}
else if (modelInstanceElement == null) {
throw new IllegalArgumentException(
"Parameter 'modelInstanceElement' must not be null.");
}
else if (operation == null) {
throw new IllegalArgumentException(
"Parameter 'operation' must not be null.");
}
else if (parameters == null) {
throw new IllegalArgumentException(
"Parameter 'parameters' must not be null.");
}
else if (postConditions == null) {
throw new IllegalArgumentException(
"Parameter 'postConditions' must not be null.");
}
// no else.
IOclInterpreter interpreter;
/* Create or use a cached interpreter. */
if (cachedInterpreters.containsKey(modelInstance)) {
interpreter = cachedInterpreters.get(modelInstance);
}
else {
interpreter = OclInterpreterPlugin.createInterpreter(modelInstance);
cachedInterpreters.put(modelInstance, interpreter);
}
interpreter.preparePostConditions(modelInstanceElement, operation,
parameters.toArray(new IModelInstanceElement[0]),
postConditions);
}
}