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 ARFFx.ARFFxPackage; import 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; } }