blob: 25c08510732a4c42814df76f096f254bc7d82dee [file] [log] [blame]
/**
* Copyright (c) 2008 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:
* INRIA - initial API and implementation
*
* $Id: TCSBuilder.java,v 1.17 2008/07/03 14:38:28 fjouault Exp $
*/
package org.eclipse.gmt.tcs.builder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.gmt.tcs.builder.ct.ResourceLocator;
import org.eclipse.gmt.tcs.metadata.Language;
import org.eclipse.gmt.tcs.metadata.LanguageRegistry;
import org.eclipse.gmt.tcs.metadata.LanguageSource;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.core.builder.ProblemFactory;
import org.eclipse.jdt.internal.core.util.ResourceCompilationUnit;
import org.eclipse.m2m.atl.core.ATLCoreException;
import org.eclipse.m2m.atl.core.IExtractor;
import org.eclipse.m2m.atl.core.IModel;
import org.eclipse.m2m.atl.core.ModelFactory;
import org.eclipse.m2m.atl.core.emf.EMFModelFactory;
import org.eclipse.m2m.atl.core.service.CoreService;
import org.eclipse.m2m.atl.dsls.DSLResourceProvider;
import org.eclipse.m2m.atl.dsls.Resource;
import org.eclipse.m2m.atl.dsls.textsource.IFileTextSource;
import org.eclipse.m2m.atl.dsls.textsource.TextSource;
import org.eclipse.m2m.atl.engine.MarkerMaker;
import org.osgi.framework.Bundle;
/**
*
* @author Fr�d�ric Jouault
*
*/
public class TCSBuilder extends IncrementalProjectBuilder {
public static final String ID = "org.eclipse.gmt.tcs.builder.Builder";
private Map parserGenerators = new HashMap();;
public TCSBuilder() throws Exception {
}
private ResourceLocator rl;
// soft reference: to prevent from being retained, which causes a leak
// TODO: is the SoftReference itself leaked now?
private SoftReference ct = null;
private TCSBuilderCT getTCSBuilderCT() throws CoreException {
TCSBuilderCT ret = (ct == null) ? null : (TCSBuilderCT)ct.get();
final IProject ammaCore = ResourcesPlugin.getWorkspace().getRoot().getProject("AMMACore");
if((ret != null) && (ammaCore.exists())) {
IFile noChangeFile = ammaCore.getFile("NO_CHANGE.txt");
if(!noChangeFile.exists()) {
ret = null; // force reload of all models
noChangeFile.create(new ByteArrayInputStream("Remove this file to force the TCS builder to purge its cache and reload the AMMACore models (e.g., after updating from CVS, or changing a model).".getBytes()), true, null);
noChangeFile.setDerived(true);
}
}
if(ret == null) {
boolean canUseAMMACore = false;
if(ammaCore.exists()) {
IFile doNotUseFile = ammaCore.getFile("DO_NOT_USE.txt");
if(!doNotUseFile.exists()) {
canUseAMMACore = true;
}
}
final boolean useAMMACore = canUseAMMACore;
rl = new ResourceLocator() {
public Resource getResource(final String id) throws IOException {
if(useAMMACore) {
// Get resources from AMMACore project in workspace
return new Resource() {
public TextSource asTextSource() {
return new IFileTextSource(ammaCore.getFile(id));
}
public URI asEMFURI() {
return URI.createPlatformResourceURI(ammaCore.getFile(id).getFullPath().toString(), true);
}
public URL asURL() {
throw new RuntimeException("Conversion to URL unsupported");
}
};
} else {
return DSLResourceProvider.getDefault().getResource(id);
}
}
};
try {
ret = new TCSBuilderCT(rl);
ct = new SoftReference(ret);
} catch(IOException ioe) {
// setting exception (ie., last argument) to non-null value (i.e., ioe) prevents the error pop-up from opening
throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.OK, "error loading resources from AMMACore project", ioe));
} catch (ATLCoreException ace) {
// setting exception (ie., last argument) to non-null value (i.e., ace) prevents the error pop-up from opening
throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.OK, "error loading resources from AMMACore project", ace));
}
}
return ret;
}
// TODO: add 'if(monitor.isCanceled()) return null;' where appropriate
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
TCSBuilderCT ct = getTCSBuilderCT();
final IProject p = getProject();
Language ts = LanguageRegistry.getDefault().getLanguageFromSource(p);
if(ts == null) {
return null; // not a valid TCS project
}
LanguageSource tss = ts.getSource();
final String name = ts.getName();
IFile km3File = tss.getKM3SourceFile();
IFile tcsFile = tss.getTCSSourceFile();
IFile outlineFile = tss.getOutlineFile();
IFile editorFile = tss.getEditorFile();
IFile ecoreFile = tss.getMetamodelFile();
final IFile grammarFile = tss.getGrammarFile();
final IFile jarFile = tss.getParserFile();
IFile compilerSourceFile = tss.getACGSourceFile();
IFile compilerBinaryFile = tss.getCompilerFile();
try {
String ext = ts.getExtension();
boolean removeParserJavaSource = !"false".equals(tss.getProperty("syntax.jar.source.remove"));
boolean rebuildPlugin = false;
boolean isJavaProject = false;
ModelFactory mf = CoreService.getModelFactory(EMFModelFactory.MODEL_FACTORY_NAME);
IExtractor extractor = CoreService.getExtractor(mf.getDefaultExtractorName());
Map models = new HashMap();
models.put(ct.srckm3, new IFileTextSource(km3File));
models.put(ct.srctcs, new IFileTextSource(tcsFile));
models.put("problemReporter", new ProblemReporter() {
public boolean reportProblem(TextSource textSource, IModel problemModel) {
int nbErrors = 0;
try {
IFile file = ((IFileTextSource)textSource).getFile();
nbErrors = new MarkerMaker().applyMarkers(file, problemModel);
} catch (CoreException e) {
e.printStackTrace();
}
return nbErrors == 0;
}
});
if(tcsFile.getLocalTimeStamp() > editorFile.getLocalTimeStamp()) {
monitor.subTask("creating Editor model " + editorFile.getName());
IModel editorModel = (IModel)ct.getTarget(ct.tgteditor, models);
extractor.extract(editorModel,
URI.createPlatformResourceURI(
"/" + p.getName() + "/" + editorFile.getProjectRelativePath().toString(), true)
.toString());
p.getFolder("TGE").setDerived(true);
rebuildPlugin = true;
}
if(km3File.getLocalTimeStamp() > outlineFile.getLocalTimeStamp()) {
monitor.subTask("creating Outline model " + outlineFile.getName());
IModel outlineModel = (IModel)ct.getTarget(ct.tgtoutline, models);
extractor.extract(outlineModel,
URI.createPlatformResourceURI(
"/" + p.getName() + "/" + outlineFile.getProjectRelativePath().toString(), true)
.toString());
p.getFolder("TGE").setDerived(true);
rebuildPlugin = true;
}
if(km3File.getLocalTimeStamp() > ecoreFile.getLocalTimeStamp()) {
monitor.subTask("creating Ecore metamodel " + ecoreFile.getName());
IModel ecoreModel = (IModel)ct.getTarget(ct.tgtecore, models);
IFile annotationFile = tss.getAnnotationSourceFile();
if(annotationFile.exists()) {
models.put(ct.srcannotation, new IFileTextSource(annotationFile));
ecoreModel = (IModel)ct.getTarget(ct.tgtecorePlusAnnotations, models);
}
extractor.extract(ecoreModel,
URI.createPlatformResourceURI(
"/" + p.getName() + "/" + ecoreFile.getProjectRelativePath().toString(), true)
.toString());
rebuildPlugin = true;
}
if(compilerSourceFile.exists()) {
if(compilerSourceFile.getLocalTimeStamp() > compilerBinaryFile.getLocalTimeStamp()) {
monitor.subTask("compiling compiler to " + compilerBinaryFile.getName());
models.put(ct.srcacg, new IFileTextSource(compilerSourceFile));
int nbACGErrors = 0;
if(nbACGErrors == 0) {
TextSource asmFile = (TextSource)ct.getTarget(ct.tgtasm, models);
if (compilerBinaryFile.exists()) {
compilerBinaryFile.setContents(asmFile.openStream(), IFile.DERIVED, monitor);
} else {
compilerBinaryFile.create(asmFile.openStream(), IFile.DERIVED, monitor);
}
}
}
}
// TODO: improve TCS2Problem so that it is automatically invoked after injection (e.g., for TCS2Editor too)
// TODO: keep injection errors as well
// => possible solution to both problems: add a problem model to each getTarget request
// (possibly using a special id in the models Map)
if(
(km3File.getLocalTimeStamp() > grammarFile.getLocalTimeStamp()) ||
(tcsFile.getLocalTimeStamp() > grammarFile.getLocalTimeStamp())) {
monitor.subTask("creating grammar " + grammarFile.getName());
IModel tcsProblemModel = (IModel)ct.getTarget(ct.tgttcsproblem, models);
int nbTCSErrors = new MarkerMaker().applyMarkers(tcsFile, tcsProblemModel);
IModel km3ProblemModel = (IModel)ct.getTarget(ct.tgtkm3problem, models);
int nbKM3Errors = new MarkerMaker().applyMarkers(km3File, km3ProblemModel);
if((nbTCSErrors == 0) && (nbKM3Errors == 0)) {
TextSource grammarModel = (TextSource)ct.getTarget(ct.tgtgrammar, models);
if (grammarFile.exists()) {
grammarFile.setContents(grammarModel.openStream(), IFile.DERIVED, monitor);
} else {
grammarFile.create(grammarModel.openStream(), IFile.DERIVED, monitor);
}
}
}
String parserSourceFolderPathName = "Syntax/parser_src/";
if(grammarFile.getLocalTimeStamp() > jarFile.getLocalTimeStamp()) {
monitor.subTask("compiling grammar to jar " + jarFile.getName());
IFolder javaFilesPath = p.getFolder(parserSourceFolderPathName + "org/eclipse/gmt/tcs/injector/");
grammarFile.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
ParserGenerator parserGenerator = getParserGenerator(tss);
if(parserGenerator == null) {
throw new RuntimeException("Missing parser generator: " + tss.getParserGenerator() + " see http://wiki.eclipse.org/TCS/Language_Project#Installing_the_Required_Features");
}
parserGenerator.generate(
grammarFile.getRawLocation().toOSString(),
javaFilesPath.getRawLocation().toOSString(),
new ParserGeneratorErrorListener() {
public void addError(String message, int lineNumber,
int charStart, int charEnd) {
addMarker(grammarFile, IMarker.SEVERITY_ERROR, message, lineNumber, charStart, charEnd);
}
public void addInfo(String message, int lineNumber,
int charStart, int charEnd) {
addMarker(grammarFile, IMarker.SEVERITY_INFO, message, lineNumber, charStart, charEnd);
}
public void addWarning(String message, int lineNumber,
int charStart, int charEnd) {
addMarker(grammarFile, IMarker.SEVERITY_WARNING, message, lineNumber, charStart, charEnd);
}
});
IFolder syntaxFolder = p.getFolder("Syntax/");
syntaxFolder.refreshLocal(IFolder.DEPTH_INFINITE, null);
if(!isJavaProject) {
monitor.subTask("compiling parser and lexer to jar " + jarFile.getName());
try {
if(jarFile.exists())
jarFile.delete(true, monitor);
} catch(CoreException ce) {
// We tried to delete the jarFile, but it may be in use (e.g., by TGE).
// In this case, we can still overwrite it.
}
Manifest man = new Manifest();
man.getMainAttributes().putValue("Manifest-Version", "1.0");
final JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile.getLocation().toFile()), man);
final List errors = new ArrayList();
List classpath = new ArrayList();
populateClassPath(p, classpath);
INameEnvironment ne = new FileSystem((String[])classpath.toArray(new String[] {}), new String[0], "UTF-8");
CompilerOptions co = new CompilerOptions();
Map options = new HashMap();
options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
// Java code generated by the parser generator may contain unused imports that are not worth reporting
options.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE);
co.set(options);
ICompilerRequestor cr = new ICompilerRequestor() {
public void acceptResult(CompilationResult result) {
try {
// TODO: report errors
CategorizedProblem pbs[] = result.getProblems();
boolean hasError = false;
IFile javaFile = p.getParent().getFile(new Path(new String(result.getFileName())));
javaFile.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
if(pbs != null) {
for(int i = 0 ; i < pbs.length ; i++) {
CategorizedProblem pb = pbs[i];
System.out.println(pb);
if(pb.isError()) {
hasError |= true;
errors.add(pb);
addMarker(javaFile, IMarker.SEVERITY_ERROR, pb.getMessage(), pb.getSourceLineNumber(), pb.getSourceStart(), pb.getSourceEnd() + 1);
} else if(pb.isWarning()) {
addMarker(javaFile, IMarker.SEVERITY_WARNING, pb.getMessage(), pb.getSourceLineNumber(), pb.getSourceStart(), pb.getSourceEnd() + 1);
}
}
}
if(!hasError) {
ClassFile cfs[] = result.getClassFiles();
for(int i = 0 ; i < cfs.length ; i++) {
out.putNextEntry(new ZipEntry(new String(cfs[i].fileName()) + ".class"));
out.write(cfs[i].getBytes());
out.closeEntry();
}
}
} catch(IOException ioe) {
ioe.printStackTrace(System.out);
} catch (CoreException e) {
e.printStackTrace(System.out);
}
}
};
Compiler compiler = new Compiler(ne, DefaultErrorHandlingPolicies.proceedWithAllProblems(), co, cr, ProblemFactory.getProblemFactory(Locale.getDefault()));
syntaxFolder.refreshLocal(IFolder.DEPTH_INFINITE, null);
compiler.compile(new ICompilationUnit[] {
new ResourceCompilationUnit(javaFilesPath.getFile(name + "_ANTLR3Lexer.java")),
new ResourceCompilationUnit(javaFilesPath.getFile(name + "_ANTLR3Parser.java")),
});
syntaxFolder.refreshLocal(IFolder.DEPTH_INFINITE, null);
out.close();
IFolder parserSourceFolder = p.getFolder(parserSourceFolderPathName);
if(parserSourceFolder.exists()) {
parserSourceFolder.setDerived(true);
}
if(errors.isEmpty()) {
if(removeParserJavaSource) {
parserSourceFolder.delete(false, null);
}
} else {
jarFile.delete(true, null);
}
if(jarFile.exists()) {
jarFile.refreshLocal(IResource.DEPTH_ZERO, monitor);
jarFile.setDerived(true);
rebuildPlugin = true;
}
}
}
Map subst = new HashMap();
// subst.put("ammacore.path", "/AMMACore");
// subst.put("ammacore.metamodel.dir.name", "Metamodel");
subst.put("dsl.name", name);
subst.put("syntax.path", "/" + name + "/Syntax");
subst.put("syntax.tcs.filename", name + ".tcs");
subst.put("syntax.jar.filename", name + "-parser.jar");
subst.put("dsl.ext", ext);
// subst.put("tge.path", "/" + name + "/TGE");
subst.put("mm.location", "/" + name + "/Metamodel/" + name + ".ecore");
// subst.put("injector.path", "/" + name + "/injector.xml");
// subst.put("extractor.path", "/" + name + "/extractor.xml");
if("true".equals(tss.getProperty("scripts.ant.create"))) {
IFile injectorFile = p.getFile("injector.xml");
if(!injectorFile.exists()) {
injectorFile.create(new ByteArrayInputStream(getTemplate("templates/injector.xml", subst).getBytes()), true, null);
injectorFile.setDerived(true);
}
IFile extractorFile = p.getFile("extractor.xml");
if(!extractorFile.exists()) {
extractorFile.create(new ByteArrayInputStream(getTemplate("templates/extractor.xml", subst).getBytes()), true, null);
extractorFile.setDerived(true);
}
}
if(!isJavaProject) {
IFile pluginFile = p.getFile("plugin/org.eclipse.gmt.tcs.language." + name + ".jar");
if(!pluginFile.exists()) {
rebuildPlugin = true;
}
if("true".equals(tss.getProperty("plugin.create")) && rebuildPlugin) {
IFolder pluginFolder = p.getFolder("plugin");
if(!pluginFolder.exists()) {
pluginFolder.create(IFolder.DERIVED + IFolder.FORCE, true, monitor);
}
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(pluginFile.getRawLocation().toString()));
JarOutputStream jout = new JarOutputStream(out);
jout.putNextEntry(new ZipEntry("plugin.xml"));
jout.write(getTemplate("templates/plugin.xml", subst).getBytes());
jout.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
jout.write(getTemplate("templates/MANIFEST.MF", subst).getBytes());
jout.putNextEntry(new ZipEntry("resources/" + name + ".ecore"));
IModel ecoreModel = (IModel)ct.getTarget(ct.tgtecore, models);
extractor.extract(ecoreModel, jout, Collections.emptyMap());
jout.putNextEntry(new ZipEntry("resources/" + name + "-Editor.xmi"));
IModel editorModel = (IModel)ct.getTarget(ct.tgteditor, models);
extractor.extract(editorModel, jout, Collections.emptyMap());
jout.putNextEntry(new ZipEntry("resources/" + name + "-Outline.xmi"));
IModel outlineModel = (IModel)ct.getTarget(ct.tgtoutline, models);
extractor.extract(outlineModel, jout, Collections.emptyMap());
jout.putNextEntry(new ZipEntry("resources/" + name + "-TCS.xmi"));
IModel tcsModel = (IModel)ct.getTarget(ct.tgttcs, models);
extractor.extract(tcsModel, jout, Collections.emptyMap());
jout.putNextEntry(new ZipEntry("resources/" + name + "-parser.jar"));
BufferedInputStream in = new BufferedInputStream(jarFile.getContents());
int size;
byte buffer[] = new byte[1024];
while((size = in.read(buffer)) > 0) {
jout.write(buffer, 0, size);
}
in.close();
jout.close();
if(!pluginFile.exists()) {
pluginFile.refreshLocal(IResource.DEPTH_ZERO, monitor);
pluginFile.setDerived(true);
}
}
}
} catch(IOException ioe) {
ioe.printStackTrace(System.out);
} catch (ATLCoreException e) {
e.printStackTrace(System.out);
}
rl=null;ct=null;
return null;
}
private ParserGenerator getParserGenerator(LanguageSource tss) {
String parserGeneratorName = tss.getParserGenerator();
ParserGenerator ret = (ParserGenerator)parserGenerators.get(parserGeneratorName);
if(ret == null) {
IExtensionRegistry registry = Platform.getExtensionRegistry();
if (registry == null) {
throw new RuntimeException("Extension registry not found");
}
IExtensionPoint point = registry.getExtensionPoint("org.eclipse.gmt.tcs.builder.parserGenerator");//$NON-NLS-1$
IExtension[] extensions = point.getExtensions();
extensions: for(int i = 0 ; i < extensions.length ; i++) {
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
for(int j = 0 ; j < elements.length ; j++) {
try {
if(elements[j].getAttribute("name").equals(parserGeneratorName)) {//$NON-NLS-1$
ret = (ParserGenerator)elements[j].createExecutableExtension("class");
break extensions;
}
} catch (CoreException e){
throw new RuntimeException(e);
}
}
}
synchronized(parserGenerators) {
parserGenerators.put(parserGeneratorName, ret);
}
}
return ret;
}
private static void addMarker(IResource res, int severity, String description, int lineNumber, int charStart, int charEnd) {
try {
IMarker pbmMarker = res.createMarker(IMarker.PROBLEM);
pbmMarker.setAttribute(IMarker.SEVERITY, severity);
pbmMarker.setAttribute(IMarker.MESSAGE, description);
pbmMarker.setAttribute(IMarker.LINE_NUMBER, (lineNumber == -1) ? 1 : lineNumber);
pbmMarker.setAttribute(IMarker.CHAR_START, charStart);
pbmMarker.setAttribute(IMarker.CHAR_END, charEnd);
} catch(CoreException ce) {
ce.printStackTrace(System.err);
}
}
public static String getTemplate(String path, Map substitutions) throws IOException {
Bundle bundle = Activator.getDefault().getBundle();
URL templateURL = bundle.getResource("resources/" + path); //FileLocator.find(bundle, new Path("resources/" + path), Collections.EMPTY_MAP);
BufferedInputStream in = new BufferedInputStream(templateURL.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
int size;
byte buffer[] = new byte[1000];
while((size = in.read(buffer)) > 0) {
out.write(buffer, 0, size);
}
String ret = out.toString();
for(Iterator i = substitutions.keySet().iterator() ; i.hasNext() ; ) {
String key = (String)i.next();
String value = (String)substitutions.get(key);
ret = ret.replaceAll("\\$\\{" + key + "}", value);
}
return ret;
}
// private void createIfMissing(IFolder f, IProgressMonitor monitor) throws CoreException {
// if(!f.exists()) {
// createIfMissing((IFolder)f.getParent(), monitor);
// f.create(0,false, monitor);
// }
// }
private void populateClassPath(IProject project, List classpath) throws IOException {
// property: sun.boot.class.path
// According to JDT help: If no bootclasspath is specified, the compiler will infer it using the following system properties sun.boot.class.path, vm.boot.class.path or org.apache.harmony.boot.class.path in this order respectively.
// see example in org.eclipse.jdt.internal.compiler.batch.Main.handleBootclasspath([...])
classpath.add(System.getProperty("java.home") + "/lib/rt.jar");
Bundle bundle = org.eclipse.m2m.atl.dsls.Activator.getDefault().getBundle();
URL urlPlatform = bundle.getEntry("/");
URL localFileInPluginURL;
localFileInPluginURL = FileLocator.toFileURL(urlPlatform);
String atlEnginePath = localFileInPluginURL.getPath().toString();
classpath.add(atlEnginePath + "libraries/org.eclipse.gmt.tcs.injector.jar");
urlPlatform = Platform.getBundle("org.antlr.runtime").getEntry("/");
localFileInPluginURL = FileLocator.toFileURL(urlPlatform);
classpath.add(localFileInPluginURL.getPath().toString());
}
}