summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorahaase2008-01-30 07:26:50 (EST)
committerahaase2008-01-30 07:26:50 (EST)
commitda88e1b69fea2de29941fea3dafe2d72f810ba9e (patch)
treee863e681382fae018782847217c9b7b0b763592d
parent6e978053be2da94ae2f01f4ac9fdad8259c2c0a9 (diff)
downloadorg.eclipse.xpand-da88e1b69fea2de29941fea3dafe2d72f810ba9e.zip
org.eclipse.xpand-da88e1b69fea2de29941fea3dafe2d72f810ba9e.tar.gz
org.eclipse.xpand-da88e1b69fea2de29941fea3dafe2d72f810ba9e.tar.bz2
Xtend and Xpand workflow components
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java32
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java140
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java (renamed from plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandWorkflowComponent.java)29
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java68
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendFacade.java132
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendComponent.java198
-rw-r--r--plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java1
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java17
8 files changed, 508 insertions, 109 deletions
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java
index 45b5b8b..9a5f837 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java
@@ -10,9 +10,16 @@ Contributors:
*/
package org.eclipse.xtend.middleend.old;
+import java.util.Collection;
+
import org.eclipse.internal.xtend.expression.parser.SyntaxConstants;
import org.eclipse.internal.xtend.xtend.XtendFile;
import org.eclipse.xpand2.XpandUtil;
+import org.eclipse.xtend.backend.common.BackendTypesystem;
+import org.eclipse.xtend.backend.types.CompositeTypesystem;
+import org.eclipse.xtend.backend.types.emf.EmfTypesystem;
+import org.eclipse.xtend.typesystem.MetaModel;
+import org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel;
/**
@@ -20,6 +27,31 @@ import org.eclipse.xpand2.XpandUtil;
* @author Arno Haase (http://www.haase-consulting.com)
*/
final class OldXtendHelper {
+ public static BackendTypesystem guessTypesystem (Collection<MetaModel> mms) {
+ boolean hasEmf = false;
+
+ for (MetaModel mm: mms) {
+ if (mm instanceof EmfRegistryMetaModel)
+ hasEmf = true;
+ }
+
+ final CompositeTypesystem result = new CompositeTypesystem ();
+ if (hasEmf)
+ result.register (new EmfTypesystem ());
+ //TODO register uml mm
+ //TODO replace this by adding "asBackendType" to the frontend types
+
+ return result;
+ }
+
+
+ public static String normalizedFileEncoding (String fileEncoding) {
+ if (fileEncoding == null)
+ return System.getProperty ("file.encoding");
+
+ return fileEncoding;
+ }
+
public static String normalizeXtendResourceName (String xtendName) {
xtendName = xtendName.replace (SyntaxConstants.NS_DELIM, "/");
if (xtendName.endsWith ("." + XtendFile.FILE_EXTENSION))
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java
index a51c93c..cb7d17c 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java
@@ -11,8 +11,6 @@ Contributors:
package org.eclipse.xtend.middleend.old;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
@@ -30,9 +28,11 @@ import org.eclipse.internal.xpand2.codeassist.XpandTokens;
import org.eclipse.internal.xpand2.parser.XpandParseFacade;
import org.eclipse.xpand2.XpandExecutionContext;
import org.eclipse.xpand2.XpandExecutionContextImpl;
+import org.eclipse.xpand2.output.FileHandle;
import org.eclipse.xpand2.output.Outlet;
import org.eclipse.xpand2.output.Output;
import org.eclipse.xpand2.output.OutputImpl;
+import org.eclipse.xpand2.output.PostProcessor;
import org.eclipse.xtend.backend.BackendFacade;
import org.eclipse.xtend.backend.common.BackendTypesystem;
import org.eclipse.xtend.backend.common.ExecutionContext;
@@ -46,11 +46,8 @@ import org.eclipse.xtend.backend.syslib.FileOutlet;
import org.eclipse.xtend.backend.syslib.InMemoryPostprocessor;
import org.eclipse.xtend.backend.syslib.SysLibNames;
import org.eclipse.xtend.backend.syslib.UriBasedPostprocessor;
-import org.eclipse.xtend.backend.types.CompositeTypesystem;
-import org.eclipse.xtend.backend.types.emf.EmfTypesystem;
import org.eclipse.xtend.expression.Variable;
import org.eclipse.xtend.typesystem.MetaModel;
-import org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel;
/**
@@ -66,6 +63,7 @@ public final class XpandBackendFacade {
/**
* This method executes Xpand code that is passed in as a string, script language style.<br>
+ * This method executes Xpand code that is passed in as a string, script language style.<br>
*
* There are two restrictions. Firstly, no DEFINEs are allowed - the string that is passed in must be a valid body for a DEFINE. Never
* mind the "parameters" - the "variables" parameter defines all variables that will be defined during execution. Use "this" as a
@@ -77,7 +75,25 @@ public final class XpandBackendFacade {
* Both the "variables" and "outlets" parameter may be null.
*/
public static Object executeStatement (String code, Collection<MetaModel> mms, Map<String, Object> variables, Collection <Outlet> outlets) {
- final BackendTypesystem ts = guessTypesystem(mms);
+ return executeStatement (code, null, mms, variables, outlets);
+ }
+
+ /**
+ * This method executes Xpand code that is passed in as a string, script language style.<br>
+ * This method executes Xpand code that is passed in as a string, script language style.<br>
+ *
+ * There are two restrictions. Firstly, no DEFINEs are allowed - the string that is passed in must be a valid body for a DEFINE. Never
+ * mind the "parameters" - the "variables" parameter defines all variables that will be defined during execution. Use "this" as a
+ * variable name to specify the variable that is implicitly bound as the "special" parameter passed to a definition.<br>
+ *
+ * Secondly, no IMPORT or EXTENSION statements are possible. So types must be referenced by their fully qualified names, and no calls
+ * to extensions are possible. Calls to other templates that are available as files are possible, just as you would expect.<br>
+ *
+ * Both the "variables" and "outlets" parameter may be null.
+ */
+ public static Object executeStatement (String code, String fileEncoding, Collection<MetaModel> mms, Map<String, Object> variables, Collection <Outlet> outlets) {
+ fileEncoding = OldXtendHelper.normalizedFileEncoding (fileEncoding);
+ final BackendTypesystem ts = OldXtendHelper.guessTypesystem (mms);
if (variables == null)
variables = new HashMap<String, Object> ();
@@ -88,7 +104,7 @@ public final class XpandBackendFacade {
final Statement[] statements = ((Definition) tpl.getDefinitions()[0]).getBody();
- XpandExecutionContext ctx = createOldExecutionContext (null, mms, outlets); // TODO fileEncoding
+ XpandExecutionContext ctx = createOldExecutionContext (fileEncoding, mms, outlets);
for (String varName: variables.keySet())
ctx = (XpandExecutionContext) ctx.cloneWithVariable (new Variable (varName, ctx.getType (variables.get (varName))));
@@ -114,23 +130,6 @@ public final class XpandBackendFacade {
return converted.evaluate (backendCtx);
}
-
- public static BackendTypesystem guessTypesystem (Collection<MetaModel> mms) {
- boolean hasEmf = false;
-
- for (MetaModel mm: mms) {
- if (mm instanceof EmfRegistryMetaModel)
- hasEmf = true;
- }
-
- final CompositeTypesystem result = new CompositeTypesystem ();
- if (hasEmf)
- result.register (new EmfTypesystem ());
- //TODO register uml mm
- //TODO replace this by adding "asBackendType" to the frontend types
-
- return result;
- }
public static void registerOutlets (ExecutionContext ctx, Collection<Outlet> outlets) {
for (Outlet oldOutlet: outlets) {
@@ -141,21 +140,98 @@ public final class XpandBackendFacade {
newOutlet.setFileEncoding (oldOutlet.getFileEncoding());
newOutlet.setOverwrite (oldOutlet.isOverwrite());
- // TODO register old postprocessors via adapters
+ for (PostProcessor pp: oldOutlet.postprocessors) {
+ newOutlet.register (new InMemoryPpAdapter (pp, oldOutlet));
+ newOutlet.register (new UriBasedPpAdapter (pp, oldOutlet));
+ }
final String outletName = (oldOutlet.getName() != null) ? oldOutlet.getName() : FileIoOperations.DEFAULT_OUTLET_NAME;
ctx.getFunctionDefContext ().invoke (ctx, SysLibNames.REGISTER_OUTLET, Arrays.asList (outletName, newOutlet));
}
}
- public static XpandBackendFacade createForFile (String xpandFilename, Collection<MetaModel> mms, Collection <Outlet> outlets) {
- return new XpandBackendFacade (xpandFilename, mms, outlets);
+ private static class InMemoryPpAdapter implements InMemoryPostprocessor {
+ private final PostProcessor _oldPp;
+ private final Outlet _outlet;
+
+ public InMemoryPpAdapter (PostProcessor oldPp, Outlet outlet) {
+ _oldPp = oldPp;
+ _outlet = outlet;
+ }
+
+ public CharSequence process (CharSequence unprocessed, String uri) {
+ final FileHandle fh = new FileHandleImpl (unprocessed, _outlet, new File (uri));
+ _oldPp.beforeWriteAndClose (fh);
+ return fh.getBuffer();
+ }
+ }
+
+ private static class FileHandleImpl implements FileHandle {
+ private CharSequence _buffer;
+ private final Outlet _outlet;
+ private final File _file;
+
+ public FileHandleImpl (CharSequence buffer, Outlet outlet, File file) {
+ _buffer = buffer;
+ _outlet = outlet;
+ _file = file;
+ }
+
+ public CharSequence getBuffer () {
+ return _buffer;
+ }
+
+ public String getFileEncoding () {
+ return _outlet.getFileEncoding();
+ }
+
+ public Outlet getOutlet () {
+ return _outlet;
+ }
+
+ public File getTargetFile () {
+ return _file;
+ }
+
+ public boolean isAppend () {
+ return _outlet.isAppend();
+ }
+
+ public boolean isOverwrite () {
+ return _outlet.isOverwrite();
+ }
+
+ public void setBuffer (CharSequence buffer) {
+ _buffer = buffer;
+ }
+
+ public void writeAndClose () {
+ throw new UnsupportedOperationException ();
+ }
+ }
+
+ private static class UriBasedPpAdapter implements UriBasedPostprocessor {
+ private final PostProcessor _oldPp;
+ private final Outlet _outlet;
+
+ public UriBasedPpAdapter (PostProcessor oldPp, Outlet outlet) {
+ _oldPp = oldPp;
+ _outlet = outlet;
+ }
+
+ public void process (String uri) {
+ final FileHandle fh = new FileHandleImpl ("", _outlet, new File (uri));
+ _oldPp.afterClose (fh);
+ }
+ }
+
+ public static XpandBackendFacade createForFile (String xpandFilename, String fileEncoding, Collection<MetaModel> mms, Collection <Outlet> outlets) {
+ return new XpandBackendFacade (xpandFilename, fileEncoding, mms, outlets);
}
private static XpandExecutionContext createOldExecutionContext (String fileEncoding, Collection<MetaModel> mms, Collection<Outlet> outlets) {
- if (fileEncoding == null)
- fileEncoding = System.getProperty ("file.encoding");
+ fileEncoding = OldXtendHelper.normalizedFileEncoding (fileEncoding);
final Output output = new OutputImpl ();
for (Outlet outlet: outlets)
@@ -170,11 +246,11 @@ public final class XpandBackendFacade {
return ctx;
}
- private XpandBackendFacade (String xpandFilename, Collection<MetaModel> mms, Collection <Outlet> outlets) {
+ private XpandBackendFacade (String xpandFilename, String fileEncoding, Collection<MetaModel> mms, Collection <Outlet> outlets) {
_xpandFile = OldXtendHelper.normalizeXpandResourceName (xpandFilename);
- _ts = guessTypesystem(mms);
+ _ts = OldXtendHelper.guessTypesystem (mms);
- final XpandExecutionContext ctx = createOldExecutionContext (null, mms, outlets);
+ final XpandExecutionContext ctx = createOldExecutionContext (fileEncoding, mms, outlets);
_extensions = new OldXtendRegistry (ctx, _ts);
_registry = new OldXpandRegistry (ctx, _ts, _extensions);
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandWorkflowComponent.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java
index ff6fb18..48244d2 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandWorkflowComponent.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java
@@ -30,6 +30,7 @@ import org.eclipse.xpand2.XpandExecutionContextImpl;
import org.eclipse.xpand2.output.Outlet;
import org.eclipse.xpand2.output.Output;
import org.eclipse.xpand2.output.OutputImpl;
+import org.eclipse.xpand2.output.PostProcessor;
import org.eclipse.xtend.expression.AbstractExpressionsUsingWorkflowComponent;
@@ -39,10 +40,9 @@ import org.eclipse.xtend.expression.AbstractExpressionsUsingWorkflowComponent;
*
* @author Arno Haase (http://www.haase-consulting.com)
*/
-public class XpandWorkflowComponent extends AbstractExpressionsUsingWorkflowComponent {
+public class XpandComponent extends AbstractExpressionsUsingWorkflowComponent {
//TODO genPath, srcPath
//TODO profiler
- //TODO beautifier
//TODO advice / AOP
private String _genPath = null;
@@ -52,9 +52,27 @@ public class XpandWorkflowComponent extends AbstractExpressionsUsingWorkflowComp
private String _fileEncoding = null;
private boolean _automaticHyphens = false;
private Output _output = null;
+
+ private List<PostProcessor> _postprocessors = new ArrayList <PostProcessor>();
private List<Outlet> _initializedOutlets = new ArrayList<Outlet> ();
+ public List<PostProcessor> getBeautifier() {
+ return _postprocessors;
+ }
+
+ public void addBeautifier (PostProcessor beautifier) {
+ _postprocessors.add (beautifier);
+ }
+
+ public List<PostProcessor> getPostprocessors() {
+ return _postprocessors;
+ }
+
+ public void addPostprocessor (PostProcessor postprocessor) {
+ _postprocessors.add (postprocessor);
+ }
+
public void setAutomaticHyphens(boolean automaticHyphens) {
this._automaticHyphens = automaticHyphens;
}
@@ -156,9 +174,14 @@ public class XpandWorkflowComponent extends AbstractExpressionsUsingWorkflowComp
result.add (new Outlet (false, _fileEncoding, "ONCE", false, _srcPath));
}
- for (Outlet o: result)
+ for (Outlet o: result) {
+ if (o.postprocessors.isEmpty())
+ for (PostProcessor pp: _postprocessors)
+ o.addPostprocessor (pp);
+
if (o.hasDefaultEncoding() && _fileEncoding!=null)
o.setFileEncoding(_fileEncoding);
+ }
}
return _initializedOutlets;
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java
deleted file mode 100644
index 8db461f..0000000
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Copyright (c) 2008 Arno Haase.
-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:
- Arno Haase - initial API and implementation
- */
-package org.eclipse.xtend.middleend.old;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipose.xtend.middleend.FunctionDefContextFactory;
-import org.eclipse.xtend.backend.common.BackendType;
-import org.eclipse.xtend.backend.common.BackendTypesystem;
-import org.eclipse.xtend.backend.common.FunctionDefContext;
-import org.eclipse.xtend.backend.common.NamedFunction;
-import org.eclipse.xtend.backend.functions.SourceDefinedFunction;
-import org.eclipse.xtend.backend.iface.BackendContributor;
-import org.eclipse.xtend.backend.types.CompositeTypesystem;
-import org.eclipse.xtend.expression.ExecutionContextImpl;
-import org.eclipse.xtend.typesystem.MetaModel;
-
-
-/**
- *
- * @author Arno Haase (http://www.haase-consulting.com)
- */
-public final class XtendBackendContributor implements BackendContributor {
- //TODO merge with XpandBackendFacade
- private final OldXtendRegistry _registry;
- private final String _xtendFile;
- private final BackendTypesystem _ts;
-
- public XtendBackendContributor (String xtendFile, Collection<MetaModel> mms, CompositeTypesystem ts) {
- _xtendFile = OldXtendHelper.normalizeXtendResourceName (xtendFile);
- _ts = ts;
-
- final ExecutionContextImpl ctx = new ExecutionContextImpl ();
- for (MetaModel mm: mms)
- ctx.registerMetaModel (mm);
- ctx.setFileEncoding("iso-8859-1"); //TODO really set the encoding
-
- //TODO redesign to allow reuse of the registry?
- _registry = new OldXtendRegistry ( ctx, ts);
- _registry.registerExtension(xtendFile);
- }
-
- public BackendType convertToType (List<String> segments) {
- return null;
- }
-
- public Collection<NamedFunction> getContributedFunctions () {
- return _registry.getContributedFunctions (_xtendFile);
- }
-
- public FunctionDefContext getFunctionDefContext () {
- if (getContributedFunctions().isEmpty())
- return new FunctionDefContextFactory(_ts).create();
-
- return ((SourceDefinedFunction) getContributedFunctions().iterator().next().getFunction()).getFunctionDefContext();
- }
-}
-
-
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendFacade.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendFacade.java
new file mode 100644
index 0000000..f6ffec2
--- /dev/null
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendFacade.java
@@ -0,0 +1,132 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.middleend.old;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipose.xtend.middleend.FunctionDefContextFactory;
+import org.eclipse.internal.xtend.expression.ast.Expression;
+import org.eclipse.internal.xtend.xtend.parser.ParseFacade;
+import org.eclipse.xtend.backend.BackendFacade;
+import org.eclipse.xtend.backend.common.BackendTypesystem;
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.common.FunctionDefContext;
+import org.eclipse.xtend.backend.common.NamedFunction;
+import org.eclipse.xtend.backend.functions.SourceDefinedFunction;
+import org.eclipse.xtend.expression.ExecutionContextImpl;
+import org.eclipse.xtend.expression.Variable;
+import org.eclipse.xtend.typesystem.MetaModel;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class XtendBackendFacade {
+ private final OldXtendRegistry _registry;
+ private final String _xtendFile;
+ private final BackendTypesystem _ts;
+
+
+ /**
+ * This method invokes a "stand alone" expression that knows nothing about any functions defined in files. It is useful for
+ * *very* simple use cases, and for testing purposes. <br>
+ *
+ * Both mms and localVars may be null.
+ */
+ public static Object evaluateExpression (String expression, Collection<MetaModel> mms, Map<String, Object> localVars) {
+ return evaluateExpression (expression, null, null, mms, localVars);
+ }
+
+ /**
+ * This method invokes an expression that may call functions from an Xtend file.<br>
+ *
+ * The fileEncoding may be null, in which case the platform's default encoding is used. Both mms and localVars may be null.
+ */
+ public static Object evaluateExpression (String expression, String initialXtendFileName, String fileEncoding, Collection<MetaModel> mms, Map<String, Object> localVars) {
+ if (localVars == null)
+ localVars = new HashMap<String, Object> ();
+ if (mms == null)
+ mms = new ArrayList<MetaModel> ();
+
+ final Expression oldAst = ParseFacade.expression (expression);
+
+
+ ExecutionContextImpl ctx = new ExecutionContextImpl ();
+ for (MetaModel mm: mms)
+ ctx.registerMetaModel (mm);
+ for (String varName: localVars.keySet())
+ ctx = (ExecutionContextImpl) ctx.cloneWithVariable (new Variable (varName, localVars.get (varName)));
+
+ final BackendTypesystem ts = OldXtendHelper.guessTypesystem (mms);
+ final TypeToBackendType typeConverter = new TypeToBackendType (ts, ctx);
+
+ final ExpressionBase newAst = new OldExpressionConverter (ctx, typeConverter, "<no file>").convert(oldAst);
+
+ final FunctionDefContext fdc = (initialXtendFileName != null) ? createForFile (initialXtendFileName, fileEncoding, mms).getFunctionDefContext() : new FunctionDefContextFactory (ts).create();
+ final ExecutionContext newCtx = BackendFacade.createExecutionContext (fdc, ts);
+ newCtx.getLocalVarContext().getLocalVars().putAll (localVars);
+
+ return newAst.evaluate (newCtx);
+ }
+
+ /**
+ * This function invokes a single Xtend function, returning the result. The fileEncoding may be null, in which case the platform's default file
+ * encoding is used.
+ */
+ public static Object invokeXtendFunction (String xtendFileName, String fileEncoding, Collection<MetaModel> mms, String functionName, Object... parameters) {
+ final XtendBackendFacade xbf = createForFile (xtendFileName, fileEncoding, mms);
+ final FunctionDefContext fdc = xbf.getFunctionDefContext();
+ final ExecutionContext ctx = BackendFacade.createExecutionContext (fdc, OldXtendHelper.guessTypesystem (mms));
+ return fdc.invoke (ctx, functionName, Arrays.asList (parameters));
+ }
+
+
+ public static XtendBackendFacade createForFile (String xtendFileName, String fileEncoding, Collection<MetaModel> mms) {
+ return new XtendBackendFacade (xtendFileName, fileEncoding, mms);
+ }
+
+ private XtendBackendFacade (String xtendFileName, String fileEncoding, Collection<MetaModel> mms) {
+ if (mms == null)
+ mms = new ArrayList<MetaModel> ();
+
+ fileEncoding = OldXtendHelper.normalizedFileEncoding (fileEncoding);
+ _xtendFile = OldXtendHelper.normalizeXtendResourceName (xtendFileName);
+ _ts = OldXtendHelper.guessTypesystem (mms);
+
+ final ExecutionContextImpl ctx = new ExecutionContextImpl ();
+ for (MetaModel mm: mms)
+ ctx.registerMetaModel (mm);
+ ctx.setFileEncoding (fileEncoding);
+
+ //TODO redesign to allow reuse of the registry?
+ _registry = new OldXtendRegistry ( ctx, _ts);
+ _registry.registerExtension (xtendFileName);
+ }
+
+ public Collection<NamedFunction> getContributedFunctions () {
+ return _registry.getContributedFunctions (_xtendFile);
+ }
+
+ public FunctionDefContext getFunctionDefContext () {
+ if (getContributedFunctions().isEmpty())
+ return new FunctionDefContextFactory(_ts).create();
+
+ return ((SourceDefinedFunction) getContributedFunctions().iterator().next().getFunction()).getFunctionDefContext();
+ }
+}
+
+
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendComponent.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendComponent.java
new file mode 100644
index 0000000..ca47419
--- /dev/null
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendComponent.java
@@ -0,0 +1,198 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.middleend.old;
+
+import java.io.InputStream;
+
+import org.eclipse.emf.mwe.core.WorkflowContext;
+import org.eclipse.emf.mwe.core.issues.Issues;
+import org.eclipse.emf.mwe.core.monitor.ProgressMonitor;
+import org.eclipse.emf.mwe.core.resources.ResourceLoaderFactory;
+import org.eclipse.internal.xtend.expression.parser.SyntaxConstants;
+import org.eclipse.internal.xtend.xtend.XtendFile;
+import org.eclipse.xtend.expression.AbstractExpressionsUsingWorkflowComponent;
+import org.eclipse.xtend.expression.ExecutionContext;
+import org.eclipse.xtend.expression.ExpressionFacade;
+import org.eclipse.xtend.expression.Variable;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class XtendComponent extends AbstractExpressionsUsingWorkflowComponent {
+
+// private final Log _log = LogFactory.getLog(getClass());
+
+
+// private List<String> extensionAdvices = new ArrayList<String>();
+//
+// public void addExtensionAdvice(String extensionAdvices) {
+// if ( !this.extensionAdvices.contains(extensionAdvices) )
+// this.extensionAdvices.add( extensionAdvices );
+// }
+
+ /** Stores the value of the 'invoke' property. Needed for error analysis. */
+ private String _invokeExpression;
+ String _extensionFile = null;
+ private String _expression = null;
+ private String _outputSlot = WorkflowContext.DEFAULT_SLOT;
+
+// private String collectProfileSummary = null;
+// private String verboseProfileFilename = null;
+//
+// public void setCollectProfileSummary (String c) {
+// collectProfileSummary = c;
+// }
+//
+// public void setVerboseProfileFilename (String f) {
+// verboseProfileFilename = f;
+// }
+
+
+ @Override
+ public String getLogMessage() {
+ return "executing '" + _invokeExpression + "'";
+ }
+
+ public void setInvoke (String invoke) {
+ _invokeExpression = invoke;
+ final int i = invoke.lastIndexOf (SyntaxConstants.NS_DELIM);
+ if (i != -1) {
+ _extensionFile = invoke.substring(0, i);
+ _expression = invoke.substring (i + SyntaxConstants.NS_DELIM.length());
+ }
+ else
+ _expression = invoke;
+ }
+
+ public void setOutputSlot (String outputSlot) {
+ _outputSlot = outputSlot;
+ }
+
+ @Override
+ public void invokeInternal2(final WorkflowContext ctx, final ProgressMonitor monitor, final Issues issues) {
+ if (! extensionFileExists ()) {
+ issues.addError ("Cannot find extension file: " + _extensionFile);
+ return;
+ }
+
+// OutputStream verboseProfileOutputStream = null;
+//
+// if (verboseProfileFilename != null) {
+// try {
+// verboseProfileOutputStream = new BufferedOutputStream (new FileOutputStream (verboseProfileFilename));
+// ProfileCollector.getInstance().setDetailedLoggingWriter(verboseProfileOutputStream);
+// }
+// catch (IOException exc) {
+// _log.warn("could not open profiling log file", exc);
+// }
+// }
+
+
+ ExecutionContext ec = getExecutionContext(ctx);
+
+// for (String advice : extensionAdvices) {
+// final String[] allAdvices = advice.split(",");
+// for (int i = 0; i < allAdvices.length; i++) {
+// final String string = allAdvices[i];
+// ec.registerExtensionAdvices(string.trim());
+// }
+// }
+//
+// ec = ec.cloneWithResource(new Resource() {
+// private String name = "noName";
+//
+// public String getFullyQualifiedName() {
+// return name;
+// }
+//
+// public void setFullyQualifiedName(final String fqn) {
+// name = fqn;
+// }
+//
+// public String[] getImportedNamespaces() {
+// return new String[0];
+// }
+//
+// public String[] getImportedExtensions() {
+// return new String[] { _extensionFile };
+// }
+// });
+ final String[] slots = ctx.getSlotNames();
+ for (int i = 0; i < slots.length; i++) {
+ ec = ec.cloneWithVariable(new Variable(slots[i], ctx.get(slots[i])));
+ }
+
+// if (monitor!=null) {
+// ec.setMonitor(monitor);
+// }
+
+ final Object result = new ExpressionFacade (ec).evaluate(_expression);
+ ctx.set (_outputSlot, result);
+
+// ProfileCollector.getInstance().finish();
+// if ("true".equalsIgnoreCase(this.collectProfileSummary)) {
+// _log.info ("profiling info: \n" + ProfileCollector.getInstance().toString());
+// }
+
+// if (verboseProfileOutputStream != null) {
+// try {
+// verboseProfileOutputStream.close ();
+// }
+// catch (IOException exc) {
+// _log.warn("problem closing profile log file", exc);
+// }
+// }
+ }
+
+ private boolean extensionFileExists() {
+ InputStream is = null;
+ try {
+ is = ResourceLoaderFactory.createResourceLoader().getResourceAsStream (_extensionFile.replace (SyntaxConstants.NS_DELIM, "/") + XtendFile.FILE_EXTENSION);
+ }
+ catch (Exception exc) {
+ // do nothing - an exception just means that the extension file does not exist
+ }
+ if (is != null) {
+ try {
+ is.close ();
+ }
+ catch (Exception e) {}
+ }
+ return is != null;
+ }
+
+ @Override
+ public void checkConfiguration (Issues issues) {
+ super.checkConfiguration (issues);
+
+ // Try to create detailed error message (see Bug#172567)
+ String compPrefix = getId()!=null ? getId()+": " : "";
+
+ if (_invokeExpression == null || _invokeExpression.trim().length()==0) {
+ issues.addError(compPrefix + "Property 'invoke' not specified.");
+ return;
+ }
+ if (_extensionFile == null) {
+ issues.addError (compPrefix + "Error parsing property 'invoke': Could not extract name of the extension file.");
+ return;
+ }
+ if (! extensionFileExists () || _expression == null) {
+ issues.addError (compPrefix + "Property 'invoke' not specified properly. Extension file '" + _extensionFile + "' not found.");
+ return;
+ }
+ if (_expression == null) {
+ issues.addError (compPrefix + "Error parsing property 'invoke': Could not extract the expression to invoke in extension file '" + _extensionFile + "'.");
+ return;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java b/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java
index 032e7f3..9a0b085 100644
--- a/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java
+++ b/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java
@@ -15,7 +15,6 @@ import java.util.List;
import org.eclipse.xtend.backend.common.BackendTypesystem;
import org.eclipse.xtend.backend.types.CompositeTypesystem;
import org.eclipse.xtend.backend.types.emf.EmfTypesystem;
-import org.eclipse.xtend.backend.types.java.GlobalJavaBeansTypesystem;
/**
diff --git a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
index 9f5005c..9000c40 100644
--- a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
+++ b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
@@ -24,8 +24,8 @@ import org.eclipse.xtend.backend.BackendFacade;
import org.eclipse.xtend.backend.common.ExecutionContext;
import org.eclipse.xtend.backend.types.CompositeTypesystem;
import org.eclipse.xtend.middleend.old.XpandBackendFacade;
-import org.eclipse.xtend.middleend.old.XpandWorkflowComponent;
-import org.eclipse.xtend.middleend.old.XtendBackendContributor;
+import org.eclipse.xtend.middleend.old.XpandComponent;
+import org.eclipse.xtend.middleend.old.XtendBackendFacade;
import org.eclipse.xtend.typesystem.MetaModel;
@@ -37,14 +37,14 @@ public class FirstAttempt {
final CompositeTypesystem ts = BackendTypesystemFactory.createWithoutUml();
{
- final XpandBackendFacade xp = XpandBackendFacade.createForFile ("org::eclipse::xtend::middleend::old::first::aTemplate", mms, new ArrayList<Outlet>());
+ final XpandBackendFacade xp = XpandBackendFacade.createForFile ("org::eclipse::xtend::middleend::old::first::aTemplate", "iso-8859-1", mms, new ArrayList<Outlet>());
final ExecutionContext ctx = BackendFacade.createExecutionContext (xp.getFunctionDefContext(), ts);
System.err.println (BackendFacade.invoke (ctx, "org/eclipse/xtend/middleend/old/first/aTemplate/greeting", Arrays.asList("Arno")));
}
{
- final XpandWorkflowComponent xwc = new XpandWorkflowComponent ();
+ final XpandComponent xwc = new XpandComponent ();
xwc.setExpand ("org::eclipse::xtend::middleend::old::first::WithFileOutput::WithFileOutput FOR toBeGreeted");
xwc.addOutlet (new Outlet (false, "iso-8859-1", null, true, "src-gen"));
@@ -54,7 +54,7 @@ public class FirstAttempt {
}
{
- final XtendBackendContributor bc = new XtendBackendContributor ("org::eclipse::xtend::middleend::old::first::first", mms, ts);
+ final XtendBackendFacade bc = XtendBackendFacade.createForFile ("org::eclipse::xtend::middleend::old::first::first", "iso-8859-1", mms);
final ExecutionContext ctx = BackendFacade.createExecutionContext (bc.getFunctionDefContext(), ts);
System.err.println (BackendFacade.invoke (ctx, "test", Arrays.asList ("Arno")));
@@ -67,5 +67,12 @@ public class FirstAttempt {
System.err.println (BackendFacade.invoke (ctx, "testPerson", Arrays.asList(p)));
}
+
+ {
+ System.err.println ("--");
+ System.err.println (XtendBackendFacade.invokeXtendFunction ("org::eclipse::xtend::middleend::old::first::first", null, mms, "test", "Arno"));
+ System.err.println (XtendBackendFacade.evaluateExpression ("1 + 2 + \"asdf\".length", null, null));
+ System.err.println (XtendBackendFacade.evaluateExpression ("1 + 2 + test(\"Arno\").length", "org::eclipse::xtend::middleend::old::first::first", null, mms, null));
+ }
}
}