blob: c24ea42425d3e093c546597b02ab339ef244e0a0 [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: WorkspaceLanguage.java,v 1.9 2008/06/24 14:27:32 fjouault Exp $
*/
package org.eclipse.gmt.tcs.metadata.adhoc;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.gmt.tcs.metadata.AbstractLanguage;
import org.eclipse.gmt.tcs.metadata.Language;
import org.eclipse.gmt.tcs.metadata.LanguageSource;
import org.eclipse.gmt.tcs.metadata.ModelFactory;
import org.eclipse.m2m.atl.core.launch.ILauncher;
import org.eclipse.m2m.atl.dsls.DSLResourceProvider;
import org.eclipse.m2m.atl.dsls.textsource.IFileTextSource;
import org.eclipse.m2m.atl.dsls.textsource.TextSource;
import org.eclipse.m2m.atl.engine.vm.ASM;
import org.eclipse.m2m.atl.engine.vm.ASMXMLReader;
/**
*
* @author Frédéric Jouault
*/
public class WorkspaceLanguage extends AbstractLanguage implements Language, LanguageSource {
private static class ModelCacheFromIFile extends ModelCache {
private String metamodelName;
private URI metamodelURI;
private String modelName;
private IFile modelFile;
private long timestamp;
public ModelCacheFromIFile(String metamodelName, URI metamodelURI, String modelName, IFile modelFile) {
this.metamodelName = metamodelName;
this.metamodelURI = metamodelURI;
this.modelName = modelName;
this.modelFile = modelFile;
}
protected Object loadModel(ModelFactory factory) {
Object metamodel = factory.loadMetamodel(metamodelName, metamodelURI);
Object ret = null;
try {
ret = factory.loadModel(modelName + "-" + metamodelName, metamodel, modelFile.getContents());
this.timestamp = modelFile.getModificationStamp();
} catch (CoreException e) {
throw new RuntimeException(e);
}
return ret;
}
protected boolean shouldReload() {
return modelFile.getModificationStamp() != timestamp;
}
}
private static final String DEFAULT_PARSER_GENERATOR_NAME = "antlr3";
private IProject project;
private String name;
private String extension;
// TODO: properties timestamp
private long propertiesTimestamp;
private IFile propertiesFile;
private Properties properties;
private IFile editorFile;
private ModelCache editorCache;
private IFile outlineFile;
private ModelCache outlineCache;
private IFile ecoreFile;
private ModelCache metamodelCache;
private IFile compilerFile;
private IFile jarFile;
private IFile km3File;
private IFile annotationFile;
private IFile tcsFile;
private IFile antlrFile;
private IFile acgFile;
public WorkspaceLanguage(IProject project) {
this.project = project;
propertiesFile = project.getFile("build.properties");
if(!propertiesFile.exists()) {
throw new RuntimeException("Missing property file");
}
try {
properties = new Properties();
InputStream in = propertiesFile.getContents();
properties.load(in);
in.close();
propertiesTimestamp = propertiesFile.getModificationStamp();
} catch(IOException e) {
throw new RuntimeException("Error reading properties file", e);
} catch(CoreException e) {
throw new RuntimeException("Error reading properties file", e);
}
name = properties.getProperty("dsl.name");
extension = properties.getProperty("dsl.ext");
if(extension == null) {
throw new RuntimeException("Missing extension");
}
if(name == null) {
throw new RuntimeException("Missing name");
}
km3File = project.getFile("Metamodel/" + name + ".km3");
annotationFile = project.getFile("Metamodel/" + name + ".ann");
tcsFile = project.getFile("Syntax/" + name + ".tcs");
if(!km3File.exists()) {
throw new RuntimeException("Missing KM3 file");
}
if(!tcsFile.exists()) {
throw new RuntimeException("Missing TCS file");
}
editorFile = project.getFile("TGE/" + name + "-Editor.xmi");
editorCache = new ModelCacheFromIFile("Editor", DSLResourceProvider.getDefault().getResource("Editor/Metamodel/Editor.ecore").asEMFURI(), name, editorFile);
outlineFile = project.getFile("TGE/" + name + "-Outline.xmi");
outlineCache = new ModelCacheFromIFile("Outline", DSLResourceProvider.getDefault().getResource("Outline/Metamodel/Outline.ecore").asEMFURI(), name, outlineFile);
ecoreFile = project.getFile("Metamodel/" + name + ".ecore");
metamodelCache = new ModelCache() {
private long timestamp;
private String metamodelOverrideURI = properties.getProperty("override.metamodel.uri");
protected Object loadModel(ModelFactory factory) {
try {
Object location;
if(metamodelOverrideURI != null) {
location = URI.createURI(metamodelOverrideURI);
} else {
location = ecoreFile.getContents();
this.timestamp = ecoreFile.getModificationStamp();
}
Object ret = factory.loadMetamodel(name, location);
return ret;
} catch (CoreException e) {
throw new RuntimeException(e);
}
}
protected boolean shouldReload() {
String newMetamodelOverrideURI = getProperty("override.metamodel.uri");
if(metamodelOverrideURI != newMetamodelOverrideURI) {
metamodelOverrideURI = newMetamodelOverrideURI;
return true;
} else {
return ecoreFile.getModificationStamp() != timestamp;
}
}
};
antlrFile = project.getFile("Syntax/" + name + "_ANTLR3.g");
jarFile = project.getFile("Syntax/" + name + "-parser.jar");
acgFile = project.getFile("Compiler/" + name + ".acg");
compilerFile = project.getFile("Compiler/" + name + ".asm");
}
public Object getEditorModel(ModelFactory factory) {
return editorCache.getModel(factory);
}
public Object getOutlineModel(ModelFactory factory) {
return outlineCache.getModel(factory);
}
public Object getMetamodel(ModelFactory factory) {
return metamodelCache.getModel(factory);
}
public LanguageSource getSource() {
return this;
}
public String getExtension() {
return extension;
}
public String getName() {
return name;
}
public ASM getCompiler() {
ASM ret = null;
if(compilerFile != null && compilerFile.exists()) {
try {
ret = new ASMXMLReader().read(new BufferedInputStream(compilerFile.getContents()));
} catch (CoreException e) {
e.printStackTrace();
}
}
return ret;
}
public String getProperty(String key) {
if(propertiesFile.getModificationStamp() != propertiesTimestamp) {
properties = new Properties();
try {
properties.load(propertiesFile.getContents());
} catch (IOException e) {
throw new RuntimeException("Error reading properties file", e);
} catch (CoreException e) {
throw new RuntimeException("Error reading properties file", e);
}
propertiesTimestamp = propertiesFile.getModificationStamp();
if(!name.equals(properties.getProperty("dsl.name"))) {
throw new RuntimeException("Language name changed, restart Eclipse");
}
if(!extension.equals(properties.getProperty("dsl.ext"))) {
throw new RuntimeException("language extension changed, restart Eclipse");
}
}
return properties.getProperty(key);
}
public IFile getEditorFile() {
return editorFile;
}
public IFile getKM3SourceFile() {
return km3File;
}
public IFile getAnnotationSourceFile() {
return annotationFile;
}
public IFile getOutlineFile() {
return outlineFile;
}
public IFile getTCSSourceFile() {
return tcsFile;
}
public IFile getMetamodelFile() {
return ecoreFile;
}
public IFile getGrammarFile() {
return antlrFile;
}
public String getParserGenerator() {
String ret = getProperty("parser.generator.name");
if(ret == null) {
ret = DEFAULT_PARSER_GENERATOR_NAME;
}
return ret;
}
public IFile getParserFile() {
return jarFile;
}
public IFile getACGSourceFile() {
return acgFile;
}
public IFile getCompilerFile() {
return compilerFile;
}
private void addLibraries(ILauncher launcher, String propertyName) throws IOException {
String libNameAndPathsCSV = this.getProperty(propertyName);
if(libNameAndPathsCSV != null) {
String libNameAndPaths[] = libNameAndPathsCSV.split(",");
for(int i = 0 ; i < libNameAndPaths.length ; i++) {
String parts[] = libNameAndPaths[i].split("=");
launcher.addLibrary(parts[0], project.getFile(parts[1]).getLocationURI().toURL().openStream());
}
}
}
protected void addWFRLibraries(ILauncher launcher) throws IOException {
this.addLibraries(launcher, "wfr.libraries");
}
protected void addPreExtractLibraries(ILauncher launcher) throws IOException {
this.addLibraries(launcher, "pre-extract.libraries");
}
private IFile getFile(String path) {
return project.getFile(path);
}
private InputStream getASM(String path) throws IOException {
IFile wfrFile = getFile(path);
if(wfrFile.exists()) {
return wfrFile.getLocationURI().toURL().openStream();
} else {
return null;
}
}
protected boolean hasWFR() {
return this.getFile("WFR/" + name + ".asm").exists();
}
protected InputStream getWFR() throws IOException {
return this.getASM("WFR/" + name + ".asm");
}
protected boolean hasPreExtract() {
return this.getFile("WFR/PreExtract.asm").exists();
}
protected InputStream getPreExtract() throws IOException {
return this.getASM("WFR/PreExtract.asm");
}
protected void addExtractOptions(Map params) {
String opts = getProperty("extract.options");
if(opts != null) {
String optsParts[] = opts.split(",");
for(int i = 0 ; i < optsParts.length ; i++) {
String mapping[] = optsParts[i].split("=");
params.put(mapping[0], mapping[1]);
}
}
}
protected TextSource getTCS() {
return new IFileTextSource(tcsFile);
}
protected URL getJarURL() throws MalformedURLException {
return jarFile.getLocationURI().toURL();
}
}