/* Copyright (C) 2010 by Claas Wilke (claaswilke@gmx.net) This file is part of the OCL2 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.standardlibrary; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.dresdenocl.testsuite._abstract.AbstractDresdenOclTest; import org.dresdenocl.essentialocl.standardlibrary.OclAny; import org.dresdenocl.essentialocl.standardlibrary.OclBoolean; import org.dresdenocl.essentialocl.standardlibrary.OclCollection; import org.dresdenocl.essentialocl.standardlibrary.OclInteger; import org.dresdenocl.essentialocl.standardlibrary.OclType; import org.dresdenocl.facade.Ocl2ForEclipseFacade; import org.dresdenocl.interpreter.IInterpretationResult; import org.dresdenocl.interpreter.test.OclInterpreterTestPlugin; import org.dresdenocl.model.IModel; import org.dresdenocl.model.ModelAccessException; import org.dresdenocl.modelinstance.IModelInstance; import org.dresdenocl.modelinstancetype.types.IModelInstanceObject; import org.dresdenocl.parser.ParseException; import org.dresdenocl.pivotmodel.Constraint; import org.dresdenocl.pivotmodel.Feature; import org.dresdenocl.pivotmodel.Type; /** * <p> * Abstract implementation for test class to test code generation of standard * library operations. * </p> * * @author Claas Wilke */ public abstract class AbstractInterpreterTest extends AbstractDresdenOclTest { /** The name of a test {@link IModelInstance} for this test suite. */ protected static final String INSTANCE1_NAME = "package1/Instance1"; /** The name of a test {@link IModelInstance} for this test suite. */ protected static final String INSTANCE2_NAME = "package1/Instance2"; /** The name of a test {@link IModelInstance} for this test suite. */ protected static final String INSTANCE3_NAME = "package1/Instance3"; /** The name of a test {@link IModelInstance} for this test suite. */ protected static final String INSTANCE4_NAME = "package1/Instance4"; /** The name of a test {@link IModelInstance} for this test suite. */ protected static final String INSTANCE5_NAME = "package1/Instance5"; /** The name of a test {@link IModel} for this test suite. */ protected static final String MODEL1_NAME = "package1/Model1"; /** The name of a test {@link IModel} for this test suite. */ protected static final String MODEL2_NAME = "package1/Model2"; /** * <p> * Returns the file object for a given path relative to the plug-in's * directory. * </p> * * @param path * The path of the resource. * @return The found {@link File} object. * @throws IOException */ private static File getFile(String path) throws IOException { return AbstractDresdenOclTest.getFile(path, OclInterpreterTestPlugin.PLUGIN_ID); } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is an * {@link OclCollection} of a given size. * </p> * * @param expectedSize * The expectedSize of the collection. * @param result * The {@link IInterpretationResult} to be checked. */ @SuppressWarnings("unchecked") protected void assertIsCollectionOfSize(Integer expectedSize, IInterpretationResult result) { assertFalse("Result was invalid: " + result.getResult().getInvalidReason(), result.getResult() .oclIsInvalid().isTrue()); assertFalse("Result was undefined: " + result.getResult().getUndefinedReason(), result.getResult() .oclIsUndefined().isTrue()); if (result.getResult() instanceof OclCollection<?>) { OclCollection<OclAny> oclCollection; oclCollection = (OclCollection<OclAny>) result.getResult(); OclInteger size; size = oclCollection.size(); assertEquals(new Long(expectedSize), size.getModelInstanceInteger() .getLong()); } else { fail("Result was not a collection."); } } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is * equal to a given {@link Object}. * </p> * * @param expected * The expected {@link Object}. * @param result * The {@link IInterpretationResult} to be checked. */ protected void assertIsEqual(Object expected, IInterpretationResult result) { assertFalse(result.getResult().oclIsInvalid().isTrue()); assertFalse(result.getResult().oclIsUndefined().isTrue()); if (result.getResult() instanceof OclInteger) { OclInteger oclInteger; oclInteger = (OclInteger) result.getResult(); assertTrue(expected instanceof Number); assertEquals(new Long(((Number) expected).longValue()), oclInteger .getModelInstanceInteger().getLong()); } else { fail("Comparison not implemented yet."); } } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is * <code>false</code>. * </p> * * @param result * The {@link IInterpretationResult} to be checked. */ protected void assertIsFalse(IInterpretationResult result) { assertFalse(result.getResult().oclIsInvalid().isTrue()); assertFalse(result.getResult().oclIsUndefined().isTrue()); assertTrue(result.getResult() instanceof OclBoolean); assertFalse(((OclBoolean) result.getResult()).isTrue()); } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is * <code>invalid</code>. * </p> * * @param result * The {@link IInterpretationResult} to be checked. */ protected void assertIsInvalid(IInterpretationResult result) { assertTrue(result.getResult().oclIsInvalid().isTrue()); } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is not * <code>invalid</code>. * </p> * * @param result * The {@link IInterpretationResult} to be checked. */ protected void assertIsNotInvalid(IInterpretationResult result) { Throwable throwable = result.getResult().getInvalidReason(); String msg = ""; if (throwable != null && throwable.getMessage() != null) msg = throwable.getMessage(); // no else. assertFalse(msg, result.getResult().oclIsInvalid().isTrue()); } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is of * a given Type. * </p> * * @param expectedType * The expected {@link Type} of the {@link IInterpretationResult} * . * @param result * The {@link IInterpretationResult} to be checked. */ protected void assertIsOfType(Type expectedType, IInterpretationResult result) { assertFalse(result.getResult().oclIsInvalid().isTrue()); assertFalse(result.getResult().oclIsUndefined().isTrue()); OclType<?> oclType = result.getResult().oclType(); if (oclType.oclIsInvalid().isTrue() || oclType.oclIsUndefined().isTrue()) { fail("OclType was invalid or undefined."); } else if (!expectedType.conformsTo(oclType.getType())) { fail("ExpectedType was '" + expectedType.getName() + "' but was '" + oclType.getType().getName() + "'."); } } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is * <code>true</code>. * </p> * * @param result * The {@link IInterpretationResult} to be checked. */ protected void assertIsTrue(IInterpretationResult result) { assertFalse(result.getResult().oclIsInvalid().isTrue()); assertFalse(result.getResult().oclIsUndefined().isTrue()); assertTrue(result.getResult() instanceof OclBoolean); assertTrue(((OclBoolean) result.getResult()).isTrue()); } /** * <p> * Helper method to assert that a given {@link IInterpretationResult} is * <code>undefined</code>. * </p> * * @param result * The {@link IInterpretationResult} to be checked. */ protected void assertIsUndefined(IInterpretationResult result) { assertFalse(result.getResult().oclIsInvalid().isTrue()); assertTrue(result.getResult().oclIsUndefined().isTrue()); } /** * <p> * Interprets all {@link Constraint}s contained in a given constraint file * for all {@link IModelInstanceObject}s of a given {@link Type}'s name of a * given {@link IModelInstance}. * * @param modelName * The name of the Java {@link IModel} file (by its name relative * to the <code>bin</code> directory). * @param constraintName * The name of the constraint file (by its name relative to the * <code>resources/constraints</code> directory). * @param instanceName * The name of the Java {@link IModelInstance} provider file * (relative to the <code>bin</code> directory) * @param typeName * The name of the {@link Type} whose * {@link IModelInstanceObject}s shall be interpreted. * @return * @throws IllegalArgumentException * @throws ModelAccessException * @throws ParseException */ protected List<IInterpretationResult> interpretConstraintsForInstance( String modelName, String constraintName, String instanceName, List<String> typeName) throws IllegalArgumentException, ModelAccessException, ParseException { assertNotNull(modelName); assertNotNull(constraintName); assertNotNull(instanceName); assertNotNull(typeName); assertTrue(typeName.size() >= 1); List<IInterpretationResult> result; /* Load the model. */ File modelFile; try { modelFile = AbstractInterpreterTest.getFile("target/classes/" + modelName + ".class"); } catch (IOException e) { throw new ModelAccessException(e.getMessage(), e); } IModel model; model = Ocl2ForEclipseFacade.getModel(modelFile, Ocl2ForEclipseFacade.JAVA_META_MODEL); assertNotNull(model); /* Find the type for the IMIObjects to test. */ Type objectType; objectType = model.findType(typeName); assertNotNull(objectType); /* Parse the constraint. */ File constraintFile; try { constraintFile = AbstractInterpreterTest .getFile("resources/constraints/" + constraintName + ".ocl"); } catch (IOException e) { throw new ModelAccessException(e.getMessage(), e); } List<Constraint> parsedConstraints; parsedConstraints = Ocl2ForEclipseFacade.parseConstraints( constraintFile, model, true); assertNotNull(parsedConstraints); assertTrue(parsedConstraints.size() >= 1); /* Load or get the instance. */ File instanceFile; try { instanceFile = AbstractInterpreterTest.getFile("target/classes/" + instanceName + ".class"); } catch (IOException e) { throw new ModelAccessException(e.getMessage(), e); } IModelInstance modelInstance; modelInstance = Ocl2ForEclipseFacade.getModelInstance(instanceFile, model, Ocl2ForEclipseFacade.JAVA_MODEL_INSTANCE_TYPE); /* Find the IMIObject(s) to test. */ Set<IModelInstanceObject> imiObjects; imiObjects = modelInstance.getAllInstances(objectType); assertNotNull(imiObjects); assertNotNull(modelInstance); /* Interpret the constraints. */ result = new ArrayList<IInterpretationResult>(); List<Constraint> staticConstraints = new ArrayList<Constraint>(); for (Constraint constraint : parsedConstraints) { switch (constraint.getKind()) { case DEFINITION: if (constraint.getDefinedFeature().isStatic()) { staticConstraints.add(constraint); } break; case DERIVED: case INITIAL: case BODY: if (((Feature) constraint.getConstrainedElement().iterator() .next()).isStatic()) { staticConstraints.add(constraint); } break; // no default; } } // end for. parsedConstraints.removeAll(staticConstraints); result.addAll(Ocl2ForEclipseFacade.interpretConstraints( staticConstraints, modelInstance, null)); for (IModelInstanceObject imiObject : imiObjects) { result.addAll(Ocl2ForEclipseFacade.interpretConstraints( parsedConstraints, modelInstance, imiObject)); } // end for. /* Remove the constraints from the model. */ model.removeConstraints(parsedConstraints); return result; } }