/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.customization.properties.generation.generators; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.m2m.qvt.oml.BasicModelExtent; import org.eclipse.m2m.qvt.oml.ExecutionContextImpl; import org.eclipse.m2m.qvt.oml.ExecutionDiagnostic; import org.eclipse.m2m.qvt.oml.ModelExtent; import org.eclipse.m2m.qvt.oml.TransformationExecutor; import org.eclipse.m2m.qvt.oml.util.WriterLog; import org.eclipse.papyrus.customization.properties.generation.Activator; import org.eclipse.papyrus.views.properties.contexts.Context; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; /** * An Abstract generator based on QVTO transformations. * Subclasses should specify the .qvto file and ModelExtents, as well as the * SWT widgets allowing the user to chose the input models. * * @author Camille Letavernier */ public abstract class AbstractQVTGenerator implements IGenerator, Listener { /** * The Contexts created by the transformation. */ protected List<Context> generatedContexts; /** * The output ModelExtent */ protected ModelExtent out; private Set<Listener> listeners = new HashSet<Listener>(); public List<Context> generate(URI targetURI) { URI transformationURI = getTransformationURI(); TransformationExecutor executor = new TransformationExecutor(transformationURI); Diagnostic diagnostic = executor.loadTransformation(); if(diagnostic.getSeverity() != Diagnostic.OK) { Activator.log.warn("Cannot load the transformation : " + transformationURI); return generatedContexts = null; } List<ModelExtent> extents = getModelExtents(); ExecutionContextImpl context = new ExecutionContextImpl(); context.setConfigProperty("keepModeling", true); //$NON-NLS-1$ context.setLog(new WriterLog(new OutputStreamWriter(System.out))); ExecutionDiagnostic result = executor.execute(context, extents.toArray(new ModelExtent[0])); if(result.getSeverity() == org.eclipse.emf.common.util.Diagnostic.OK) { List<EObject> outObjects = getOutContextExtent().getContents(); Object objectResult = outObjects.get(0); if(!(objectResult instanceof Context)) { return null; } ResourceSet resourceSet = new ResourceSetImpl(); Resource contextResource = resourceSet.createResource(targetURI); contextResource.getContents().addAll(outObjects); return generatedContexts = getContexts(outObjects); } else { IStatus status = BasicDiagnostic.toIStatus(result); Activator.log.warn(String.format("%s : %s", status.getPlugin(), status.getMessage())); } return generatedContexts = null; } /** * @return the list of in/out/inout ModelExtents (including the OutContextExtent) * Implementors should ensure they add the outContextExtent to the list. */ abstract protected List<ModelExtent> getModelExtents(); /** * @return the ModelExtent containing the generated context */ protected ModelExtent getOutContextExtent() { if(out == null) { out = new BasicModelExtent(); } return out; } /** * @return the URI of the QVTO transformation file. */ abstract protected URI getTransformationURI(); /** * Loads the EObject from the given URI. * * @param uri * The URI from which the EObject is loaded * @return * The loaded EObject, or null if an error occured * @throws IOException * If the URI isn't a valid EObject */ protected EObject loadEMFModel(URI uri) throws IOException { ResourceSet resourceSet = new ResourceSetImpl(); try { Resource resource = resourceSet.getResource(uri, true); if(resource != null) { if(!resource.getContents().isEmpty()) { return resource.getContents().get(0); } } } catch (Exception ex) { throw new IOException(ex.toString()); } return null; } public void addListener(Listener listener) { listeners.add(listener); } public void handleEvent(Event event) { for(Listener listener : listeners) { listener.handleEvent(event); } } /** * Return the generated Context from a list of EObjects * * @param outObjects * The list of EObjects from which the context will be retrieved * @return * The main generated context */ protected List<Context> getContexts(List<EObject> outObjects) { List<Context> result = new LinkedList<Context>(); for(Object objectResult : outObjects) { if(objectResult instanceof Context) { result.add((Context)objectResult); } } return result; } }