#16 Output Configurations with Xbase
Feb 11, 2013 |
9 minutes |
Xbase
In this episode I demonstrate, how to use different output configurations (also called outlets) with Xbase and ModelInferrer.
- Download:
- source code Project Files in Zip (332 KB)
- mp4 Full Size H.264 Video (23.3 MB)
- m4v Smaller H.264 Video (13.3 MB)
- webm Full Size VP8 Video (13.5 MB)
- ogv Full Size Theora Video (33.5 MB)
Defining multiple output configurations
MyOutputConfigurationProvider.java
import static org.eclipse.xtext.xbase.lib.CollectionLiterals.newHashSet;
import java.util.Set;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IOutputConfigurationProvider;
import org.eclipse.xtext.generator.OutputConfiguration;
public class MyOutputConfigurationProvider implements IOutputConfigurationProvider {
public static final String GEN_ONCE_OUTPUT = "gen-once";
/**
* @return a set of {@link OutputConfiguration} available for the generator
*/
public Set<OutputConfiguration> getOutputConfigurations() {
OutputConfiguration defaultOutput = new OutputConfiguration(IFileSystemAccess.DEFAULT_OUTPUT);
defaultOutput.setDescription("Output Folder");
defaultOutput.setOutputDirectory("./src-gen");
defaultOutput.setOverrideExistingResources(true);
defaultOutput.setCreateOutputDirectory(true);
defaultOutput.setCleanUpDerivedResources(true);
defaultOutput.setSetDerivedProperty(true);
OutputConfiguration readonlyOutput = new OutputConfiguration(GEN_ONCE_OUTPUT);
readonlyOutput.setDescription("Read-only Output Folder");
readonlyOutput.setOutputDirectory("./src");
readonlyOutput.setOverrideExistingResources(false);
readonlyOutput.setCreateOutputDirectory(true);
readonlyOutput.setCleanUpDerivedResources(false);
readonlyOutput.setSetDerivedProperty(false);
return newHashSet(defaultOutput, readonlyOutput);
}
}
import static org.eclipse.xtext.xbase.lib.CollectionLiterals.newHashSet; import java.util.Set; import org.eclipse.xtext.generator.IFileSystemAccess; import org.eclipse.xtext.generator.IOutputConfigurationProvider; import org.eclipse.xtext.generator.OutputConfiguration; public class MyOutputConfigurationProvider implements IOutputConfigurationProvider { public static final String GEN_ONCE_OUTPUT = "gen-once"; /** * @return a set of {@link OutputConfiguration} available for the generator */ public Set<OutputConfiguration> getOutputConfigurations() { OutputConfiguration defaultOutput = new OutputConfiguration(IFileSystemAccess.DEFAULT_OUTPUT); defaultOutput.setDescription("Output Folder"); defaultOutput.setOutputDirectory("./src-gen"); defaultOutput.setOverrideExistingResources(true); defaultOutput.setCreateOutputDirectory(true); defaultOutput.setCleanUpDerivedResources(true); defaultOutput.setSetDerivedProperty(true); OutputConfiguration readonlyOutput = new OutputConfiguration(GEN_ONCE_OUTPUT); readonlyOutput.setDescription("Read-only Output Folder"); readonlyOutput.setOutputDirectory("./src"); readonlyOutput.setOverrideExistingResources(false); readonlyOutput.setCreateOutputDirectory(true); readonlyOutput.setCleanUpDerivedResources(false); readonlyOutput.setSetDerivedProperty(false); return newHashSet(defaultOutput, readonlyOutput); } }
MyDslRuntimeModule.java
public class MyDslRuntimeModule extends org.xtext.example.mydsl.AbstractMyDslRuntimeModule {
@Override
public void configure(Binder binder) {
super.configure(binder);
binder.bind(IOutputConfigurationProvider.class)
.to(MyOutputConfigurationProvider.class)
.in(Singleton.class);
}
}
public class MyDslRuntimeModule extends org.xtext.example.mydsl.AbstractMyDslRuntimeModule { @Override public void configure(Binder binder) { super.configure(binder); binder.bind(IOutputConfigurationProvider.class) .to(MyOutputConfigurationProvider.class) .in(Singleton.class); } }
Defining custom EMF-adapter
OutputConfigurationAdapter.java
import org.eclipse.emf.common.notify.*;
public class OutputConfigurationAdapter implements Adapter {
private String outputConfigurationName;
public OutputConfigurationAdapter(String outputConfigurationName) {
this.outputConfigurationName = outputConfigurationName;
}
public String getOutputConfigurationName() {
return outputConfigurationName;
}
@Override
public void notifyChanged(Notification notification) {}
@Override
public Notifier getTarget() {
return null;
}
@Override
public void setTarget(Notifier newTarget) {}
@Override
public boolean isAdapterForType(Object type) {
return false;
}
}
import org.eclipse.emf.common.notify.*; public class OutputConfigurationAdapter implements Adapter { private String outputConfigurationName; public OutputConfigurationAdapter(String outputConfigurationName) { this.outputConfigurationName = outputConfigurationName; } public String getOutputConfigurationName() { return outputConfigurationName; } @Override public void notifyChanged(Notification notification) {} @Override public Notifier getTarget() { return null; } @Override public void setTarget(Notifier newTarget) {} @Override public boolean isAdapterForType(Object type) { return false; } }
Marking Java EMF-elements using custom adapter
MyDslJvmModelInferrer.xtend
...
val myGreetingImpl = element.toClass("my.company.greeting.MyGreetingsImpl")
myGreetingImpl.eAdapters.add(new OutputConfigurationAdapter(
MyOutputConfigurationProvider::GEN_ONCE_OUTPUT
))
...
... val myGreetingImpl = element.toClass("my.company.greeting.MyGreetingsImpl") myGreetingImpl.eAdapters.add(new OutputConfigurationAdapter( MyOutputConfigurationProvider::GEN_ONCE_OUTPUT )) ...
Wrapping IFileSystemAccess
SingleOutputConfigurationFileSystemAccess.java
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.generator.*;
public class SingleOutputConfigurationFileSystemAccess implements
IFileSystemAccess, IFileSystemAccessExtension,
IFileSystemAccessExtension2 {
protected IFileSystemAccess fsa;
protected String outputConfigurationName;
protected SingleOutputConfigurationFileSystemAccess(IFileSystemAccess fsa,
String outputConfigurationName) {
this.fsa = fsa;
this.outputConfigurationName = outputConfigurationName;
}
@Override
public void generateFile(String fileName, CharSequence contents) {
fsa.generateFile(fileName, outputConfigurationName, contents);
}
@Override
public void generateFile(String fileName, String outputConfiguration, CharSequence contents) {
fsa.generateFile(fileName, outputConfigurationName, contents);
}
@Override
public void deleteFile(String fileName) {
deleteFile(fileName, outputConfigurationName);
}
@Override
public void deleteFile(String fileName,
String ignoredOutputConfigurationName) {
((IFileSystemAccessExtension) fsa).deleteFile(fileName, outputConfigurationName);
}
@Override
public URI getURI(String fileName, String outputConfiguration) {
return ((IFileSystemAccessExtension2) fsa).getURI(fileName, outputConfigurationName);
}
@Override
public URI getURI(String fileName) {
return ((IFileSystemAccessExtension2) fsa).getURI(fileName, outputConfigurationName);
}
}
import org.eclipse.emf.common.util.URI; import org.eclipse.xtext.generator.*; public class SingleOutputConfigurationFileSystemAccess implements IFileSystemAccess, IFileSystemAccessExtension, IFileSystemAccessExtension2 { protected IFileSystemAccess fsa; protected String outputConfigurationName; protected SingleOutputConfigurationFileSystemAccess(IFileSystemAccess fsa, String outputConfigurationName) { this.fsa = fsa; this.outputConfigurationName = outputConfigurationName; } @Override public void generateFile(String fileName, CharSequence contents) { fsa.generateFile(fileName, outputConfigurationName, contents); } @Override public void generateFile(String fileName, String outputConfiguration, CharSequence contents) { fsa.generateFile(fileName, outputConfigurationName, contents); } @Override public void deleteFile(String fileName) { deleteFile(fileName, outputConfigurationName); } @Override public void deleteFile(String fileName, String ignoredOutputConfigurationName) { ((IFileSystemAccessExtension) fsa).deleteFile(fileName, outputConfigurationName); } @Override public URI getURI(String fileName, String outputConfiguration) { return ((IFileSystemAccessExtension2) fsa).getURI(fileName, outputConfigurationName); } @Override public URI getURI(String fileName) { return ((IFileSystemAccessExtension2) fsa).getURI(fileName, outputConfigurationName); } }
Detecting custom EMF-adapter and set the output configuration
OutputConfigurationAwaredGenerator.java
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.xbase.compiler.JvmModelGenerator;
@SuppressWarnings("restriction")
public class OutputConfigurationAwaredGenerator extends JvmModelGenerator {
@Override
public void doGenerate(Resource input, IFileSystemAccess fsa) {
EList<EObject> _contents = input.getContents();
for (final EObject obj : _contents) {
String outputConfiguration = null;
for (Adapter adapter : obj.eAdapters()) {
if (adapter instanceof OutputConfigurationAdapter) {
outputConfiguration = ((OutputConfigurationAdapter) adapter).getOutputConfigurationName();
break;
}
}
if (outputConfiguration == null) {
this.internalDoGenerate(obj, fsa);
} else {
this.internalDoGenerate(obj, new SingleOutputConfigurationFileSystemAccess(fsa, outputConfiguration));
}
}
}
}
import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.generator.IFileSystemAccess; import org.eclipse.xtext.xbase.compiler.JvmModelGenerator; @SuppressWarnings("restriction") public class OutputConfigurationAwaredGenerator extends JvmModelGenerator { @Override public void doGenerate(Resource input, IFileSystemAccess fsa) { EList<EObject> _contents = input.getContents(); for (final EObject obj : _contents) { String outputConfiguration = null; for (Adapter adapter : obj.eAdapters()) { if (adapter instanceof OutputConfigurationAdapter) { outputConfiguration = ((OutputConfigurationAdapter) adapter).getOutputConfigurationName(); break; } } if (outputConfiguration == null) { this.internalDoGenerate(obj, fsa); } else { this.internalDoGenerate(obj, new SingleOutputConfigurationFileSystemAccess(fsa, outputConfiguration)); } } } }
MyDslRuntimeModule.java
public class MyDslRuntimeModule extends org.xtext.example.mydsl.AbstractMyDslRuntimeModule {
@Override
public void configure(Binder binder) {
...
}
@Override
public Class<? extends IGenerator> bindIGenerator() {
return OutputConfigurationAwaredGenerator.class;
}
}
public class MyDslRuntimeModule extends org.xtext.example.mydsl.AbstractMyDslRuntimeModule { @Override public void configure(Binder binder) { ... } @Override public Class<? extends IGenerator> bindIGenerator() { return OutputConfigurationAwaredGenerator.class; } }