blob: 6885719556f051050d6e7bfc235ee56e15ab5873 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 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:
* Freddy Allilaire (INRIA) - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.atl.service.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.m2m.atl.drivers.emf4atl.ASMEMFModelElement;
import org.eclipse.m2m.atl.drivers.emf4atl.EMFModelLoader;
import org.eclipse.m2m.atl.drivers.emf4atl.tcs.extractor.TCSExtractor;
import org.eclipse.m2m.atl.drivers.emf4atl.tcs.injector.TCSInjector;
import org.eclipse.m2m.atl.engine.MarkerMaker;
import org.eclipse.m2m.atl.engine.extractors.xml.XMLExtractor;
import org.eclipse.m2m.atl.engine.vm.AtlModelHandler;
import org.eclipse.m2m.atl.engine.vm.ModelLoader;
import org.eclipse.m2m.atl.engine.vm.nativelib.ASMEnumLiteral;
import org.eclipse.m2m.atl.engine.vm.nativelib.ASMModel;
import org.eclipse.m2m.atl.service.core.exception.ServiceException;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
/**
* This class provides a set of util methods.
*
* @author <a href="mailto:freddy.allilaire@obeo.fr">Freddy Allilaire</a>
*/
public final class ServiceTransformationUtil {
/** XML Extractor name. */
public static final String XML_EXTRACTOR = "XML"; //$NON-NLS-1$
/** XMI Extractor name. */
public static final String XMI_EXTRACTOR = "XMI"; //$NON-NLS-1$
/** EBNF Extractor name. */
public static final String EBNF_EXTRACTOR = "EBNF"; //$NON-NLS-1$
private ServiceTransformationUtil() {
super();
}
/**
* Returns the URL of a given ASM file.
*
* @param filePath
* the ASM file path
* @param pluginId
* the plugin id
* @return the URL of a given ASM file.
* @throws ServiceException
*/
public static URL getURLFromASMFile(String filePath, String pluginId) throws ServiceException {
URL tPlatform = Platform.getBundle(pluginId).getEntry(filePath);
try {
return FileLocator.toFileURL(tPlatform);
} catch (IOException e) {
throw new ServiceException(IStatus.CANCEL, e);
}
}
/**
* Loads a model.
*
* @param modelName
* the model name
* @param metamodel
* the metamodel
* @param ml
* the model loader
* @param path
* the model path
* @param nsUri
* the model uri
* @param isM3
* true if the metamodel is a metametamodel
* @param inWorkspace
* true if the model is in workspace
* @param pluginId
* the plugin id
* @return the model
* @throws IOException
*/
public static ASMModel loadModel(String modelName, ASMModel metamodel, ModelLoader ml, String path,
String nsUri, boolean isM3, boolean inWorkspace, String pluginId) throws ServiceException, IOException {
ASMModel ret = null;
if (ml instanceof EMFModelLoader) {
final EMFModelLoader emfml = (EMFModelLoader)ml;
if (isM3) {
ret = emfml.getMOF();
} else if (nsUri != null && !nsUri.equals("")) { //$NON-NLS-1$
// TODO delete pre-string 'uri:'
ret = emfml.loadModel(modelName, metamodel, "uri:" + nsUri); //$NON-NLS-1$
} else if (inWorkspace) {
ret = emfml.loadModel(modelName, metamodel, URI.createPlatformResourceURI(path, true));
} else {
try {
Bundle bundle = Platform.getBundle(pluginId);
if (bundle == null) {
throw new ServiceException(IStatus.ERROR, ServiceMessages.getString(
"ServiceTransformationUtil.0", new Object[] {pluginId})); //$NON-NLS-1$
}
URL urlFile = bundle.getEntry(path);
if (urlFile == null) {
throw new ServiceException(IStatus.ERROR, ServiceMessages.getString(
"ServiceTransformationUtil.1", new Object[] {path, pluginId})); //$NON-NLS-1$
}
InputStream in = urlFile.openStream();
ret = emfml.loadModel(modelName, metamodel, in);
} catch (IOException e) {
throw new ServiceException(IStatus.ERROR, e);
}
}
} else {
throw new ServiceException(IStatus.CANCEL, ServiceMessages
.getString("ServiceTransformationUtil.2")); //$NON-NLS-1$
}
return ret;
}
/**
* Process the XML extraction.
*
* @param model
* the model to extract
* @param path
* the path where to extract
*/
public static void xmlExtraction(final ASMModel model, String path) {
try {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path));
PipedInputStream in = new PipedInputStream();
final OutputStream out = new PipedOutputStream(in);
final Map parameters = Collections.EMPTY_MAP;
final XMLExtractor xmle = new XMLExtractor();
Thread th = new Thread() {
public void run() {
try {
xmle.extract(model, out, parameters);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
};
th.start();
if (file.exists()) {
file.setContents(in, IFile.FORCE, null);
} else {
file.create(in, IFile.FORCE, null);
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
}
}
/**
* Process the EBNF extraction.
*
* @param model
* the model to extract
* @param path
* the path where to extract
* @param params
* the extractor parameters
*/
public static void ebnfExtraction(final ASMModel model, String path, Map params) {
try {
PipedInputStream in = new PipedInputStream();
final OutputStream out = new PipedOutputStream(in);
final TCSExtractor ebnfe = new TCSExtractor();
final AtlModelHandler amh = AtlModelHandler.getDefault(AtlModelHandler.AMH_EMF);
final ModelLoader ml = amh.createModelLoader();
ASMModel tcs = loadModel(
"TCS", ml.getMOF(), ml, "resources/TCS.ecore", null, false, false, //$NON-NLS-1$ //$NON-NLS-2$
"org.eclipse.m2m.atl.service.core"); //$NON-NLS-1$
Map tempParam = new HashMap();
tempParam
.put(
"format", loadModel("model.tcs", tcs, ml, (String)params.get("path"), null, false, false, (String)params.get("pluginId"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
for (Iterator it = params.keySet().iterator(); it.hasNext();) {
String paramName = (String)it.next();
String paramType = (String)ebnfe.getParameterTypes().get(paramName);
if (paramType != null && paramType.equals("String")) { //$NON-NLS-1$
tempParam.put(paramName, params.get(paramName));
}
}
final Map parameters = tempParam;
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path));
Thread th = new Thread() {
public void run() {
try {
ebnfe.extract(model, out, parameters);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
};
th.start();
if (file.exists()) {
file.setContents(in, IFile.FORCE, null);
} else {
file.create(in, IFile.FORCE, null);
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
}
}
/**
* Process the injection.
*
* @param name
* the model nama
* @param filePath
* the path where to inject
* @param metamodel
* the metamodel
* @param params
* the injection parameters
* @param parserPath
* the parser
* @param metamodelName
* the metamodel name
* @param pluginId
* the plugin id
* @return the model
*/
public static ASMModel ebnfInjection(String name, String filePath, ASMModel metamodel,
Map params, String parserPath, String metamodelName, String pluginId) {
try {
InputStream in = Platform.getBundle(pluginId).getEntry(filePath).openStream();
final AtlModelHandler amh = AtlModelHandler.getHandler(metamodel);
final ModelLoader ml = amh.createModelLoader();
final ASMModel model = ml.newModel(name, "model.xmi", metamodel); //$NON-NLS-1$
final TCSInjector inj = new TCSInjector();
final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
final JarClassLoader loader = createLoader(pluginId, parserPath, oldCl);
final Class lexer = loader.loadClass2("org.eclipse.gmt.tcs.injector." + metamodelName + "Lexer", true); //$NON-NLS-1$ //$NON-NLS-2$
final Class parser = loader
.loadClass2("org.eclipse.gmt.tcs.injector." + metamodelName + "Parser", true); //$NON-NLS-1$ //$NON-NLS-2$
Map injParams = new HashMap();
injParams.put("name", metamodelName); //$NON-NLS-1$
injParams.put("lexerClass", lexer); //$NON-NLS-1$
injParams.put("parserClass", parser); //$NON-NLS-1$
inj.inject(model, in, injParams);
in.close();
return model;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
System.err.println(e1);
}
return null;
}
private static JarClassLoader createLoader(String pluginId, String parserPath, ClassLoader parent) {
try {
URL url = Platform.getBundle(pluginId).getEntry("/"); //$NON-NLS-1$
String urlString = url.toString();
LinkedList list = new LinkedList();
String requires = (String)Platform.getBundle(pluginId).getHeaders().get(
Constants.BUNDLE_CLASSPATH);
if (requires == null) {
requires = parserPath;
} else if (requires.indexOf(parserPath) == -1) {
requires += "," + parserPath; //$NON-NLS-1$
}
ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, requires);
for (int i = 0; i < elements.length; i++) {
ManifestElement element = elements[i];
String libPathStr = element.getValue();
String libUrlStr = urlString + libPathStr;
URL libUrl = new URL(libUrlStr);
list.add(libUrl);
}
URL[] libUrls = (URL[])list.toArray(new URL[list.size()]);
return new JarClassLoader(libUrls, parent);
} catch (BundleException e) {
e.printStackTrace();
} catch (MalformedURLException mue) {
mue.printStackTrace();
}
return null;
}
/**
* Applies markers on a file.
*
* @param path
* the path where to apply
* @param pbs
* the problem model to apply
* @return errors count
* @throws CoreException
*/
public static int applyMarkers(String path, ASMModel pbs) throws CoreException {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path));
MarkerMaker markerMaker = new MarkerMaker();
int nbErrors = 0;
Collection pbsc = pbs.getElementsByType("Problem"); //$NON-NLS-1$
EObject[] pbsa = new EObject[pbsc.size()];
int k = 0;
for (Iterator i = pbsc.iterator(); i.hasNext();) {
ASMEMFModelElement ame = (ASMEMFModelElement)i.next();
pbsa[k] = ame.getObject();
if ("error".equals(((ASMEnumLiteral)ame.get(null, "severity")).getName())) { //$NON-NLS-1$ //$NON-NLS-2$
nbErrors++;
}
k++;
}
markerMaker.resetPbmMarkers(file, pbsa);
return nbErrors;
}
}