/*
Copyright (C) 2009 by Claas Wilke (info@claaswilke.de)
This file is part of the OCL Interpreter Test Suite 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.interpreter.test.royalandloyal;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.dresdenocl.testsuite._abstract.AbstractDresdenOclTest;
import org.dresdenocl.facade.Ocl2ForEclipseFacade;
import org.dresdenocl.interpreter.IInterpretationResult;
import org.dresdenocl.model.IModel;
import org.dresdenocl.model.ModelAccessException;
import org.dresdenocl.modelinstance.IModelInstance;
import org.dresdenocl.modelinstancetype.exception.OperationNotFoundException;
import org.dresdenocl.modelinstancetype.exception.TypeNotFoundInModelException;
import org.dresdenocl.modelinstancetype.types.IModelInstanceElement;
import org.dresdenocl.parser.ParseException;
import org.dresdenocl.pivotmodel.Constraint;
import org.dresdenocl.pivotmodel.ConstraintKind;
import org.dresdenocl.pivotmodel.Operation;
/**
* <p>
* This class loads a given model file, a given model instance and given OCL
* files. Then it can be used to perform some interpreter tests.
* </p>
*
* @author Claas Wilke
*/
public class TestPerformer {
/** The package of the UML2 meta model. */
private final static String META_MODEL = Ocl2ForEclipseFacade.UML2_MetaModel;
/** The name of the bundle of the model file. */
private final static String MODEL_BUNDLE = "org.dresdenocl.examples.royalandloyal";
/** The path of the UML model file. */
private final static String MODEL_FILE = "model/royalandloyal.uml";
/** Contains the loaded UML2 model. */
protected IModel myModel = null;
/** Contains the loaded UML2 model instance. */
protected IModelInstance myModelInstance = null;
/**
* <p>
* Creates a new TestPerformer.
* </p>
*/
public TestPerformer() {
super();
this.init();
}
/**
* <p>
* Adapts a given {@link Object} as {@link IModelInstanceElement} and adds
* it to the {@link IModelInstance} under test.
* </p>
*
* @param object
* The {@link Object} that shall be adapted and added.
* @return The adapted {@link IModelInstanceElement}.
* @throws TypeNotFoundInModelException
*/
public IModelInstanceElement addModelObject(Object object)
throws TypeNotFoundInModelException {
IModelInstanceElement result;
result = myModelInstance.addModelInstanceElement(object);
return result;
}
/**
* <p>
* Searches for a {@link Operation} of a given {@link IModelInstanceElement}
* in its {@link IModel}.
* </p>
*
* @param imiElement
* The {@link IModelInstanceElement}.
* @param name
* The name of the {@link Operation}.
* @return The found {@link Operation}.
* @throws OperationNotFoundException
* Thrown, if the {@link Operation} has not been found.
*/
public Operation findOperation(IModelInstanceElement imiElement, String name)
throws OperationNotFoundException {
for (Operation ownedOperation : imiElement.getType()
.getOwnedOperation()) {
if (ownedOperation.getName().equals(name)) {
return ownedOperation;
}
// no else.
}
// end for.
throw new OperationNotFoundException("Cannot find operation " + name
+ " on " + imiElement);
}
/**
* <p>
* Initializes the {@link TestPerformer} after all required parameters are
* set.
* </p>
*
* @throws RuntimeException
* Is thrown if any error occurred while loading the model or
* the meta model.
*/
public void init() throws RuntimeException {
/* Try to load model and model instance. */
try {
/* Load the model. */
this.loadModel();
/* Load the model instance. */
this.loadModelInstance();
}
catch (Exception e) {
throw new RuntimeException(
"Unable to initialize the test. Reason: " + e.getMessage());
}
}
/**
* <p>
* Interprets a given {@link Constraint} for a given {@link List} of
* {@link IModelInstanceElement}s.
* </p>
*
* @param constrraint
* The {@link Constraint} that shall be interpreted.
* @param modelObjects
* The {@link IModelInstanceElement}s that shall be interpreted.
* @throws ModelAccessException
* @throws IllegalArgumentException
* @result A {@link List} containing the {@link IInterpretationResult}s of
* the interpretation.
*/
public List<IInterpretationResult> interpretConstraint(
Constraint constraint, List<IModelInstanceElement> modelObjects,
boolean removeConstraints) throws IllegalArgumentException,
ModelAccessException {
List<IInterpretationResult> result;
result = new ArrayList<IInterpretationResult>();
for (IModelInstanceElement modelObject : modelObjects) {
result.add(Ocl2ForEclipseFacade.interpretConstraint(constraint,
this.myModelInstance, modelObject));
}
// end for.
/* Probably remove all constraints are removed from the model. */
if (removeConstraints) {
this.myModel.removeAllConstraints();
}
// no else.
return result;
}
/**
* <p>
* Interprets a given {@link Constraint} of the
* {@link ConstraintKind#POSTCONDITION} for a given
* {@link IModelInstanceElement}.
* </p>
*
* @param constraint
* The {@link Constraint} that shall be interpreted.
* @param modelInstanceElements
* The {@link IModelInstanceElement} that shall be interpreted.
* @param operation
* The {@link Operation} whose postconditions shall be
* interpreted.
* @param parameters
* The parameter values of the {@link Operation} for which the
* postconditions shall be interpreted.
* @param resultValue
* The result of the {@link Operation}'s invocation for that the
* postconditions shall be interpreted.
* @param removeConstraints
* Indicates, whether or not all {@link Constraint} shall be
* removed from the {@link IModel} after this interpretation.
* @throws ModelAccessException
* @throws IllegalArgumentException
* @result The {@link IInterpretationResult} of the interpretation.
*/
public List<IInterpretationResult> interpretPostCondition(
Constraint constraint,
List<IModelInstanceElement> modelInstanceElements,
Operation operation, List<IModelInstanceElement> parameters,
IModelInstanceElement resultValue, boolean removeConstraints)
throws IllegalArgumentException, ModelAccessException {
List<IInterpretationResult> result;
result = new ArrayList<IInterpretationResult>();
List<Constraint> constraints;
constraints = new ArrayList<Constraint>();
constraints.add(constraint);
for (IModelInstanceElement modelInstanceElement : modelInstanceElements) {
result.addAll(Ocl2ForEclipseFacade.interpretPostConditions(
this.myModelInstance, modelInstanceElement, operation,
parameters, resultValue, constraints));
}
// end for.
/* Probably remove all constraints are removed from the model. */
if (removeConstraints) {
this.myModel.removeAllConstraints();
}
// no else.
return result;
}
/**
* <p>
* Interprets a given {@link Constraint} of the
* {@link ConstraintKind#PRECONDITION} for a given
* {@link IModelInstanceElement}.
* </p>
*
* @param constraint
* The {@link Constraint} that shall be interpreted.
* @param modelInstanceElements
* The {@link IModelInstanceElement} that shall be interpreted.
* @param operation
* The {@link Operation} whose preconditions shall be
* interpreted.
* @param parameters
* The parameter values of the {@link Operation} for which the
* preconditions shall be interpreted.
* @param removeConstraints
* Indicates, whether or not all {@link Constraint} shall be
* removed from the {@link IModel} after this interpretation.
* @throws ModelAccessException
* @throws IllegalArgumentException
* @result The {@link IInterpretationResult} of the interpretation.
*/
public List<IInterpretationResult> interpretPreCondition(
Constraint constraint,
List<IModelInstanceElement> modelInstanceElements,
Operation operation, List<IModelInstanceElement> parameters,
boolean removeConstraints) throws IllegalArgumentException,
ModelAccessException {
List<IInterpretationResult> result;
result = new ArrayList<IInterpretationResult>();
List<Constraint> constraints;
constraints = new ArrayList<Constraint>();
constraints.add(constraint);
for (IModelInstanceElement modelInstanceElement : modelInstanceElements) {
result.addAll(Ocl2ForEclipseFacade.interpretPreConditions(
this.myModelInstance, modelInstanceElement, operation,
parameters, constraints));
}
// end for.
/* Probably remove all constraints are removed from the model. */
if (removeConstraints) {
this.myModel.removeAllConstraints();
}
// no else.
return result;
}
/**
* <p>
* Parses the file <i>oclFileName</i> against the loaded UML model file. If
* an error occurred an CodeGenerationException will be thrown.
* </p>
*
* @param oclFileName
* The OCL file to be parsed.
* @return A {@link List} containing the parsed {@link Constraint}s.
* @throws ModelAccessException
* @throws ParseException
* @throws Ocl22JavaException
* Is thrown if any error occurs
*/
public List<Constraint> loadOCLFile(String oclFileName)
throws RuntimeException, ParseException, ModelAccessException {
try {
File oclFile = AbstractDresdenOclTest.getFile(oclFileName,
MODEL_BUNDLE);
return Ocl2ForEclipseFacade.parseConstraints(oclFile, this.myModel,
true);
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* <p>
* Prepares a given {@link Constraint} of the
* {@link ConstraintKind#POSTCONDITION} for a given
* {@link IModelInstanceElement} (necessary to store <code>@pre</code>
* values).
* </p>
*
* @param constraint
* The {@link Constraint} that shall be interpreted.
* @param modelInstanceElements
* The {@link IModelInstanceElement} that shall be interpreted.
* @param operation
* The {@link Operation} whose postconditions shall be
* interpreted.
* @param parameters
* The parameter values of the {@link Operation} for which the
* postconditions shall be interpreted.
* @throws ModelAccessException
* @throws IllegalArgumentException
* @result The {@link IInterpretationResult} of the interpretation.
*/
public List<IInterpretationResult> preparePostCondition(
Constraint constraint,
List<IModelInstanceElement> modelInstanceElements,
Operation operation, List<IModelInstanceElement> parameters)
throws IllegalArgumentException, ModelAccessException {
List<IInterpretationResult> result;
result = new ArrayList<IInterpretationResult>();
List<Constraint> constraints;
constraints = new ArrayList<Constraint>();
constraints.add(constraint);
for (IModelInstanceElement modelInstanceElement : modelInstanceElements) {
Ocl2ForEclipseFacade.preparePostConditions(this.myModelInstance,
modelInstanceElement, operation, parameters, constraints);
}
// end for.
return result;
}
/**
* <p>
* Loads the {@link IModel} used for testing.
* </p>
*
* @throws Ocl22JavaException
* Is thrown if the {@link IModel} cannot be initialized or the
* model file is not found.
*/
protected void loadModel() throws RuntimeException {
/* Check if the model has not already been loaded yet. */
if (!(this.myModel != null && this.myModel.getDisplayName().equals(
MODEL_FILE))) {
/* Try to load the model. */
try {
File modelFile = AbstractDresdenOclTest.getFile(MODEL_FILE,
MODEL_BUNDLE);
this.myModel = Ocl2ForEclipseFacade.getModel(modelFile,
META_MODEL);
}
catch (ModelAccessException e) {
throw new RuntimeException("The model could not be loaded. "
+ e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
// no else.
}
/**
* <p>
* Loads a new empty {@link IModelInstance} of the actual selected
* {@link IModel}.
* </p>
*
* @throws RuntimeException
* Thrown, if an error during {@link IModelInstance}
* initialization occurs.
*/
protected void loadModelInstance() throws RuntimeException {
/* Check if a model has been set yet. */
if (this.myModel != null) {
this.myModelInstance = null;
/* Load the model instance. */
try {
this.myModelInstance = Ocl2ForEclipseFacade
.getEmptyModelInstance(this.myModel,
Ocl2ForEclipseFacade.JAVA_MODEL_INSTANCE_TYPE);
}
catch (ModelAccessException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
else {
throw new RuntimeException(
"No model found to load a model instance.");
}
}
}