/* 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.standardlibrary.java.test.tests; import java.io.File; import java.io.IOException; import org.dresdenocl.testsuite._abstract.AbstractDresdenOclTest; import org.dresdenocl.essentialocl.EssentialOclPlugin; import org.dresdenocl.essentialocl.standardlibrary.factory.IStandardLibraryFactory; import org.dresdenocl.essentialocl.types.OclLibrary; import org.dresdenocl.examples.royalandloyal.Customer; import org.dresdenocl.examples.royalandloyal.CustomerCard; import org.dresdenocl.examples.royalandloyal.Date; import org.dresdenocl.examples.royalandloyal.LoyaltyAccount; import org.dresdenocl.examples.royalandloyal.LoyaltyProgram; import org.dresdenocl.examples.royalandloyal.ProgramPartner; import org.dresdenocl.metamodels.uml2.UML2MetamodelPlugin; import org.dresdenocl.model.IModel; import org.dresdenocl.model.IModelRegistry; import org.dresdenocl.model.ModelAccessException; import org.dresdenocl.model.ModelConstants; import org.dresdenocl.model.metamodel.IMetamodel; import org.dresdenocl.modelbus.ModelBusPlugin; import org.dresdenocl.modelinstance.IModelInstance; import org.dresdenocl.modelinstance.IModelInstanceProvider; import org.dresdenocl.modelinstance.IModelInstanceRegistry; import org.dresdenocl.modelinstancetype.exception.OperationNotFoundException; import org.dresdenocl.modelinstancetype.exception.TypeNotFoundInModelException; import org.dresdenocl.modelinstancetype.java.internal.provider.JavaModelInstanceProvider; import org.dresdenocl.modelinstancetype.types.IModelInstanceElement; import org.dresdenocl.pivotmodel.Operation; import org.dresdenocl.standardlibrary.java.JavaStandardlibraryPlugin; /** * <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 * @author Michael Thiele */ public class TestPerformer { /** * The qualified Name of the package that contains the {@link Class}es used * for testing. */ public static String QUALIFIED_NAME_MODEL_PACKAGE = ModelConstants.ROOT_PACKAGE_NAME + "::org::dresdenocl::examples::royalandloyal"; /** The qualified Name of {@link Customer}. */ public static String QUALIFIED_NAME_CUSTOMER = QUALIFIED_NAME_MODEL_PACKAGE + "::Customer"; /** The qualified Name of {@link CustomerCard}. */ public static String QUALIFIED_NAME_CUSTOMER_CARD = QUALIFIED_NAME_MODEL_PACKAGE + "::CustomerCard"; /** The qualified Name of {@link Date}. */ public static String QUALIFIED_NAME_DATE = QUALIFIED_NAME_MODEL_PACKAGE + "::Date"; /** The qualified Name of {@link LoyaltyAccount}. */ public static String QUALIFIED_NAME_LOYALTY_ACCOUNT = QUALIFIED_NAME_MODEL_PACKAGE + "::LoyaltyAccount"; /** The qualified Name of {@link LoyaltyProgram}. */ public static String QUALIFIED_NAME_LOYALTY_PROGRAM = QUALIFIED_NAME_MODEL_PACKAGE + "::LoyaltyProgram"; /** The qualified Name of {@link LoyaltyProgram}. */ public static String QUALIFIED_NAME_MEMBERSHIP = QUALIFIED_NAME_MODEL_PACKAGE + "::Membership"; /** The qualified Name of {@link ProgramPartner}. */ public static String QUALIFIED_NAME_PROGRAM_PARTNER = QUALIFIED_NAME_MODEL_PACKAGE + "::ProgramPartner"; /** The package of the UML2 meta model. */ private final static String META_MODEL = UML2MetamodelPlugin.ID; /** 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"; /** The standard library factory to create OclAny and sub-types. */ protected IStandardLibraryFactory myStandardLibraryFactory = JavaStandardlibraryPlugin .getStandardLibraryFactory(); /** Contains the UML2 meta model. */ protected IMetamodel myMetaModel = null; /** Contains the loaded UML2 model. */ protected IModel myModel = null; /** Contains the loaded UML2 model instance. */ protected IModelInstance myModelInstance = null; private static TestPerformer instance = null; /** * <p> * Creates a new TestPerformer. * </p> */ private TestPerformer() { super(); this.init(); } public static TestPerformer getInstance() { if (instance == null) instance = new TestPerformer(); return instance; } /** * Returns the {@link IStandardLibraryFactory} used for creating Standard * Library types. * * @return the {@link IStandardLibraryFactory} used for creating Standard * Library types */ public IStandardLibraryFactory getSLFactory() { return myStandardLibraryFactory; } /** * Returns the {@link OclLibrary}. * * @return the {@link OclLibrary} */ public OclLibrary getOclLibrary() { return EssentialOclPlugin.getOclLibraryProvider().getOclLibrary(); } /** * <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}. */ public IModelInstanceElement addModelObject(Object object) { IModelInstanceElement result; try { result = myModelInstance.addModelInstanceElement(object); } // FIXME: Shouldn't there be a better way of handling this exception? catch (TypeNotFoundInModelException e) { result = null; } return result; } /** * <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. */ private void init() throws RuntimeException { /* Try to load model and meta model. */ try { this.myMetaModel = ModelBusPlugin.getMetamodelRegistry() .getMetamodel(META_MODEL); if (myMetaModel == null) { throw new RuntimeException( "Unable to load meta model during test."); } // no else. /* 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()); } } // TODO JavaDoc; regard parameter types as well? public Operation findOperation(IModelInstanceElement imiElement, String name) throws OperationNotFoundException { for (Operation ownedOperation : imiElement.getType() .getOwnedOperation()) { if (ownedOperation.getName().equals(name)) { return ownedOperation; } } throw new OperationNotFoundException("Cannot find operation " + name + " on " + imiElement); } /** * <p> * Resets the environment ({@link IModel} and {@link IModelInstance} used by * this {@link TestPerformer} and reinitializes it. Used to remove new * defined or initialized {@link IModelInstanceElement}s from the * {@link IModel}. * </p> * * @throws ModelAccessException */ public void reset() throws ModelAccessException { /* Remove all loaded models. */ ModelBusPlugin.getModelRegistry().dispose(); this.myModel = null; this.myModelInstance = null; this.init(); } /** * <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); IModelRegistry modelRegistry; this.myModel = this.myMetaModel.getModelProvider().getModel( modelFile); modelRegistry = ModelBusPlugin.getModelRegistry(); modelRegistry.addModel(myModel); modelRegistry.setActiveModel(myModel); } 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. */ IModelInstanceProvider modelInstanceProvider = new JavaModelInstanceProvider(); this.myModelInstance = modelInstanceProvider .createEmptyModelInstance(this.myModel); /* * Add the successfully loaded model instance to the model instance * registry. */ IModelInstanceRegistry modelInstanceRegistry; modelInstanceRegistry = ModelBusPlugin.getModelInstanceRegistry(); modelInstanceRegistry.addModelInstance(this.myModelInstance); modelInstanceRegistry.setActiveModelInstance(myModel, this.myModelInstance); } else { throw new RuntimeException( "No model found to load a model instance."); } } }