/******************************************************************************* * Copyright (c) 2015-2016 Obeo, Inria * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * William Piers <william.piers@obeo.fr> * Philippe Merle <philippe.merle@inria.fr> *******************************************************************************/ package org.occiware.clouddesigner.occi.emfgen; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EModelElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.XMIResource; import org.occiware.clouddesigner.occi.Attribute; import org.occiware.clouddesigner.occi.Extension; import org.occiware.clouddesigner.occi.Kind; import org.occiware.clouddesigner.occi.OCCIRegistry; import org.occiware.clouddesigner.occi.util.Occi2Ecore; public final class ConverterUtils { public static String readFileAsString(File file) throws IOException { byte[] buffer = new byte[(int) file.length()]; BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file)); stream.read(buffer); String res = new String(buffer); stream.close(); return res; } public static void writeStringToFile(File file, String content) throws IOException { BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file)); stream.write(content.getBytes()); stream.close(); } public static EObject getRootElement(ResourceSet resourceSet, String path) { Resource resource = resourceSet.getResource(URI.createURI(path), true); EcoreUtil.resolveAll(resource); return resource.getContents().get(0); } public static void save(ResourceSet resourceSet, EObject rootElement, String path) throws IOException { Resource resource = resourceSet.createResource(URI.createURI(path)); resource.getContents().add(rootElement); Map<String, String> options = new HashMap<String, String>(); options.put(XMIResource.OPTION_ENCODING, "UTF-8"); resource.save(options); } public static String formatName(String name) { String temp = name.replaceAll(" ", "_"); if (temp.startsWith("occi.")) { String[] split = temp.split("\\."); temp = split[split.length - 1]; } return temp; } public static String toU1Case(String temp) { temp = temp.substring(0, 1).toUpperCase() + temp.substring(1); return temp; } /** * Get the Ecore package associated to a given OCCI object. * @param occiObject the given OCCI object. * @return the associated Ecore package. */ public static EPackage getEPackage(EObject occiObject) { Extension extension = ((Extension)occiObject.eContainer()); String uri = OCCIRegistry.getInstance().getFileURI(extension.getScheme()); // we must use platform:/plugin URI to enable genmodels uri = uri.replaceAll(".occie", ".ecore"); // special case for core uri = uri.replaceAll("model/Core.ecore", "model/OCCI.ecore"); EPackage p = (EPackage) occiObject.eResource().getResourceSet().getResource(URI.createURI(uri), true).getContents().get(0); return p; } public static EClass getMappedEClass(Kind kind) { return (EClass) ConverterUtils.getEPackage(kind).getEClassifier(ConverterUtils.toU1Case(kind.getTerm())); } public static Collection<Attribute> getAllAttributes(Kind kind) { List<Attribute> res = new ArrayList<Attribute>(); res.addAll(kind.getAttributes()); if (kind.getParent() != null) { res.addAll(getAllAttributes(kind.getParent())); } return res; } public static void persistMetamodel(ResourceSet resourceSet, EPackage generated, String path) throws IOException { if (new File(path).exists()) { EPackage existing = (EPackage) ConverterUtils.getRootElement(resourceSet, "file:/" + path); for (Iterator<EObject> iterator = existing.eAllContents(); iterator.hasNext();) { EObject eo = iterator.next(); if (eo instanceof EAnnotation && isOCLRelated((EAnnotation) eo)) { EModelElement existingContainer = (EModelElement) eo.eContainer(); EModelElement generatedContainer = (EModelElement) getGeneratedElement(generated, existingContainer); if (generatedContainer == null) { throw new RuntimeException("Unable to find " + existingContainer + " to reattach " + eo + " " + ((EAnnotation) eo).getEAnnotations()); } else { generatedContainer.getEAnnotations().add((EAnnotation) EcoreUtil.copy(eo)); } } } } ConverterUtils.save(resourceSet, generated, "file:/" + path); } private static EObject getGeneratedElement(EObject generatedRoot, EObject existing) { if (areEquivalent(generatedRoot, existing)) { return generatedRoot; } for (Iterator<EObject> iterator = generatedRoot.eAllContents(); iterator.hasNext();) { EObject generated = iterator.next(); if (areEquivalent(generated, existing)) { return generated; } } return null; } private static boolean areEquivalent(EObject generated, EObject existing) { if (generated.eClass().equals(existing.eClass())) { boolean allAttributeMatch = true; for (EAttribute ea : existing.eClass().getEAllAttributes()) { Object existingValue = String.valueOf(existing.eGet(ea)); Object generatedValue = String.valueOf(generated.eGet(ea)); allAttributeMatch = allAttributeMatch && ((existingValue == null && generatedValue == null) || existingValue.equals(generatedValue)); } if (allAttributeMatch) { return true; } } return false; } private static boolean isOCLRelated(EAnnotation annotation) { return annotation.getSource().equals("http://www.eclipse.org/emf/2002/Ecore") || annotation.getSource().equals("http://www.eclipse.org/OCL/Import") || annotation.getSource().equals("http://www.eclipse.org/emf/2002/Ecore/OCL/Pivot"); } }