// Copyright 2015 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.cpdp.decentApp; import java.io.File; import java.net.URISyntaxException; import java.util.HashMap; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.epsilon.common.util.StringProperties; import org.eclipse.epsilon.emc.emf.EmfModel; import org.eclipse.epsilon.emc.emf.InMemoryEmfModel; import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException; import org.eclipse.epsilon.eol.models.IModel; import de.ugoe.cs.cpdp.decentApp.models.arffx.ARFFxPackage; import de.ugoe.cs.cpdp.decentApp.models.decent.DECENTPackage; /** * Class for handling decent and arffx model files. * * @author Philip Makedonski, Fabian Trautsch * */ public class DECENTEpsilonModelHandler { private HashMap metaModelCache = new HashMap<>(); private boolean useDECENTBinary = false; private boolean useARFFxBinary = false; public static String metaPath = "./decent/models/"; /** * Returns the decent model as IModel instance * * @param decentModelLocation * location of the decent model file * @param read * indicates if the model should be read from * @param write * indicates if data should be written in the model * @return EmFModel (IModel) instance from the decent model, which was loaded * @throws Exception */ public IModel getDECENTModel(String decentModelLocation, boolean read, boolean write) throws Exception { EmfModel model; if (isUseDECENTBinary()) { unregisterMetaModels(""); if (!read) { new File(decentModelLocation).delete(); new File(decentModelLocation + "bin").delete(); } DECENTResourceTool tool = new DECENTResourceTool(); if (new File(decentModelLocation).exists() && !new File(decentModelLocation + "bin").exists()) { Resource resource = tool.loadResourceFromXMI(decentModelLocation, "decent", DECENTPackage.eINSTANCE); tool.storeBinaryResourceContents(resource.getContents(), decentModelLocation + "bin", "decentbin"); } Resource resourceBin = tool.loadResourceFromBinary(decentModelLocation + "bin", "decentbin", DECENTPackage.eINSTANCE); // alternative pattern // model = createInMemoryEmfModel("DECENT", resourceLocation, // "../DECENT.Meta/model/DECENTv3.ecore", read, write, resourceBin, // DECENTPackage.eINSTANCE); // restoreMetaModels(); // NOTE: Adding the package is essential as otherwise epsilon breaks model = new InMemoryEmfModel("DECENT", resourceBin, DECENTPackage.eINSTANCE); model.setStoredOnDisposal(write); model.setReadOnLoad(read); model.setCachingEnabled(true); restoreMetaModels(); } else { model = createEmfModel("DECENT", decentModelLocation, metaPath + "DECENTv3.ecore", read, write); } return model; } /** * Converts the decent model to a binary form * * @param location * of the decent model file */ public void convertDECENTModelToBinary(String location) { unregisterMetaModels(""); DECENTResourceTool tool = new DECENTResourceTool(); Resource resource = tool.loadResourceFromXMI(location + "/model.decent", "decent", DECENTPackage.eINSTANCE); tool.storeBinaryResourceContents(resource.getContents(), location + "/model.decent" + "bin", "decentbin"); restoreMetaModels(); } /** * Converts the decent model to a xmi form * * @param location * of the decent model file */ public void convertDECENTModelToXMI(String location) { unregisterMetaModels(""); DECENTResourceTool tool = new DECENTResourceTool(); Resource resource = tool.loadResourceFromBinary(location + "/model.decentbin", "decentbin", DECENTPackage.eINSTANCE); restoreMetaModels(); tool.storeResourceContents(resource.getContents(), location + "/model.decent", "decent"); } /** * Returns the arffx model as IModel instance * * @param arffxModelLocation * location of the arffx model file * @param read * indicates if the model should be read from * @param write * indicates if data should be written in the model * @return EmFModel (IModel) instance from the arffx model, which was loaded * @throws Exception */ public IModel getARFFxModel(String arffxModelLocation, boolean read, boolean write) throws Exception { EmfModel model; if (isUseARFFxBinary()) { unregisterMetaModels(""); if (!read) { new File(arffxModelLocation).delete(); new File(arffxModelLocation + "bin").delete(); } ARFFxResourceTool tool = new ARFFxResourceTool(); if (new File(arffxModelLocation).exists() && !new File(arffxModelLocation + "bin").exists()) { Resource resource = tool.loadResourceFromXMI(arffxModelLocation, "arffx", ARFFxPackage.eINSTANCE); tool.storeBinaryResourceContents(resource.getContents(), arffxModelLocation + "bin", "arffxbin"); } Resource resourceBin = tool.loadResourceFromBinary(arffxModelLocation + "bin", "arffxbin", ARFFxPackage.eINSTANCE); // alternative pattern // model = createInMemoryEmfModel("DECENT", resourceLocation, // "../DECENT.Meta/model/DECENTv3.ecore", read, write, resourceBin, // DECENTPackage.eINSTANCE); // restoreMetaModels(); // NOTE: Adding the package is essential as otherwise epsilon breaks model = new InMemoryEmfModel("ARFFx", resourceBin, ARFFxPackage.eINSTANCE); // model.getModelImpl().getURI().toFileString() model.setStoredOnDisposal(write); model.setReadOnLoad(read); model.setCachingEnabled(true); restoreMetaModels(); } else { model = createEmfModel("ARFFx", arffxModelLocation, metaPath + "ARFFx.ecore", read, write); } return model; } /** * Converts an arffx model to a binary version * * @param location * of the arffx model */ public void convertARFFxModelToBinary(String location) { unregisterMetaModels(""); ARFFxResourceTool tool = new ARFFxResourceTool(); Resource resource = tool.loadResourceFromXMI(location + "/model.arffx", "arffx", ARFFxPackage.eINSTANCE); tool.storeBinaryResourceContents(resource.getContents(), location + "/model.arffx" + "bin", "arffxbin"); restoreMetaModels(); } /** * Converts an arffx model to xmi * * @param location * of the arffx model */ public void convertARFFxModelToXMI(String location) { unregisterMetaModels(""); ARFFxResourceTool tool = new ARFFxResourceTool(); Resource resource = tool.loadResourceFromBinary(location + "/model.arffxbin", "arffxbin", DECENTPackage.eINSTANCE); restoreMetaModels(); tool.storeResourceContents(resource.getContents(), location + "/model.arffx", "arffx"); } /** * Returns the log model as IModel instance * * @param logModelLocation * location of the log model file * @param read * indicates if the model should be read from * @param write * indicates if data should be written in the model * @return EmFModel (IModel) instance from the log model, which was loaded * @throws Exception */ public IModel getLOGModel(String logModelLocation, boolean read, boolean write) throws Exception { if (!new File(logModelLocation).exists()) { read = false; } IModel model = createEmfModel("LOG", logModelLocation, metaPath + "LOG.ecore", read, write); System.setProperty("epsilon.logFileAvailable", "true"); return model; } /** * Creates an EMF Model * * @param name * of the emf model * @param model * name of the model * @param metamodel * name of the metamodel * @param readOnLoad * indicates if the model should be read on load * @param storeOnDisposal * indicates if the model should be stored on disposal * @return * @throws EolModelLoadingException * @throws URISyntaxException */ @SuppressWarnings("deprecation") protected EmfModel createEmfModel(String name, String model, String metamodel, boolean readOnLoad, boolean storeOnDisposal) throws EolModelLoadingException, URISyntaxException { EmfModel emfModel = new EmfModel(); StringProperties properties = new StringProperties(); properties.put(EmfModel.PROPERTY_NAME, name); properties.put(EmfModel.PROPERTY_ALIASES, name); properties.put(EmfModel.PROPERTY_FILE_BASED_METAMODEL_URI, "file:/" + getFile(metamodel).getAbsolutePath()); properties.put(EmfModel.PROPERTY_MODEL_URI, "file:/" + getFile(model).getAbsolutePath()); properties.put(EmfModel.PROPERTY_IS_METAMODEL_FILE_BASED, "true"); properties.put(EmfModel.PROPERTY_READONLOAD, readOnLoad + ""); properties.put(EmfModel.PROPERTY_CACHED, "true"); properties.put(EmfModel.PROPERTY_STOREONDISPOSAL, storeOnDisposal + ""); emfModel.load(properties, ""); // System.out.println(emfModel.allContents()); return emfModel; } /** * Returns a new File instance from the given filename * * @param fileName * of the file * @return * @throws URISyntaxException */ public File getFile(String fileName) throws URISyntaxException { ; return new File(fileName); } /** * Restores the metamodels, so that they are registered in the EPackage registry */ private void restoreMetaModels() { for (String key : metaModelCache.keySet()) { EPackage.Registry.INSTANCE.put(key, metaModelCache.get(key)); }; } /** * Unregister the metamodels from the EPackage registry * * @param filter * for filtering out certain instances */ private void unregisterMetaModels(String filter) { for (String key : EPackage.Registry.INSTANCE.keySet()) { if (key.contains(filter)) { metaModelCache.put(key, EPackage.Registry.INSTANCE.get(key)); } }; for (String key : metaModelCache.keySet()) { EPackage.Registry.INSTANCE.remove(key); }; } /** * Returns true if decent binary model is used * * @return */ public boolean isUseDECENTBinary() { return useDECENTBinary; } /** * Sets the boolean which indicates, if the decent binary model is used * * @param useDECENTBinary */ public void setUseDECENTBinary(boolean useDECENTBinary) { this.useDECENTBinary = useDECENTBinary; } /** * Returns true if arffx binary model is used * * @return */ public boolean isUseARFFxBinary() { return useARFFxBinary; } /** * Sets the boolean which indicates, if the arffx binary model is used * * @param useARFFxBinary */ public void setUseARFFxBinary(boolean useARFFxBinary) { this.useARFFxBinary = useARFFxBinary; } }