diff options
Diffstat (limited to 'plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java')
-rw-r--r-- | plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java new file mode 100644 index 00000000..48244d2c --- /dev/null +++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandComponent.java @@ -0,0 +1,238 @@ +/* +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.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +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.internal.xpand2.ast.Definition; +import org.eclipse.internal.xpand2.ast.ExpandStatement; +import org.eclipse.internal.xpand2.ast.Template; +import org.eclipse.internal.xpand2.codeassist.XpandTokens; +import org.eclipse.internal.xpand2.parser.XpandParseFacade; +import org.eclipse.internal.xtend.xtend.parser.ParseException; +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; + + +/** + * This workflow component executes an Xpand template based on the new backend implementation. It + * combines the steps of parsing and transforming the source files, and of invoking the script. + * + * @author Arno Haase (http://www.haase-consulting.com) + */ +public class XpandComponent extends AbstractExpressionsUsingWorkflowComponent { + //TODO genPath, srcPath + //TODO profiler + //TODO advice / AOP + + private String _genPath = null; + private String _srcPath = null; + + private String _expand = null; + 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; + } + + @Override + public String getLogMessage() { + return "generating '" + _expand + "' => directory '" + _genPath + "'"; + } + + public void setFileEncoding(final String fileEncoding) { + _fileEncoding = fileEncoding; + } + + public String getFileEncoding() { + return _fileEncoding; + } + + public void setExpand (String invoke) { + _expand = invoke; + } + + /** + * @deprecated use outlets instead + */ + @Deprecated + public void setGenPath(final String genPath) { + _genPath = fixPath(genPath); + } + + /** + * + * @deprecated use outlets instead + */ + @Deprecated + public void setSrcPath(final String srcPath) { + _srcPath = fixPath(srcPath); + } + + + private String fixPath(final String p) { + if (p.endsWith("\\")) + return p.replace('\\', '/'); + if (p.endsWith("/")) + return p; + return p + "/"; + } + + + @Override + protected void invokeInternal2 (WorkflowContext wfContext, ProgressMonitor monitor, Issues issues) { + + // set up the execution context + XpandExecutionContextImpl executionContext = new XpandExecutionContextImpl (getOutput(), null, getGlobalVars (wfContext), null, getNullEvaluationHandler()); + + if (_fileEncoding != null) + executionContext.setFileEncoding (_fileEncoding); + + final String code = XpandTokens.LT + "EXPAND " + _expand + XpandTokens.RT; + + final Map<String, Object> variables = new HashMap<String, Object> (); + for (String name: wfContext.getSlotNames()) + variables.put (name, wfContext.get (name)); + + XpandBackendFacade.executeStatement (code, metaModels, variables, outlets); + } + + private final List<Outlet> outlets = new ArrayList<Outlet>(); + + public void addOutlet (Outlet outlet) { + outlets.add(outlet); + } + + public void setOutput (Output output) { + _output = output; + } + + private Output getOutput () { + if (_output == null) { + // lazy initialization + OutputImpl out = new OutputImpl(); + out.setAutomaticHyphens (_automaticHyphens); + _output = out; + } + + return _output; + } + + + private List<Outlet> getInitializedOutlets() { + if (_initializedOutlets.isEmpty()) { + final List<Outlet> result = new ArrayList<Outlet> (outlets); + if (result.isEmpty()) { + if (_genPath != null) { // backward compatibility + result.add (new Outlet (false, _fileEncoding, null, true, _genPath)); + result.add (new Outlet (true, _fileEncoding, "APPEND", true, _genPath)); + } + + if (_srcPath != null) + result.add (new Outlet (false, _fileEncoding, "ONCE", false, _srcPath)); + } + + 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; + } + + + private ExpandStatement getStatement() { + Template tpl = XpandParseFacade.file (new StringReader(XpandTokens.LT + "DEFINE test FOR test" + XpandTokens.RT + XpandTokens.LT + "EXPAND " + _expand + XpandTokens.RT + XpandTokens.LT + "ENDDEFINE" + XpandTokens.RT), null); + ExpandStatement es = null; + try { + es = (ExpandStatement) ((Definition) tpl.getDefinitions()[0]).getBody()[1]; + } catch (final Exception e) { + log.error(e); + } + return es; + } + + @Override + public void checkConfiguration(final Issues issues) { + super.checkConfiguration(issues); + if (_genPath == null && getInitializedOutlets().isEmpty()) + issues.addError(this, "You need to configure at least one outlet!"); + + if ((_genPath != null || _srcPath != null) && !outlets.isEmpty()) + issues.addWarning(this, "'genPath' is ignored since you have specified outlets!"); + + int defaultOutlets = 0; + for (final Iterator<Outlet> iter = getInitializedOutlets().iterator(); iter.hasNext();) { + final Outlet o = iter.next(); + if (o.getName() == null) + defaultOutlets++; + } + + if (defaultOutlets > 1) + issues.addError(this, "Only one outlet can be the default outlet. Please specifiy a name for the other outlets!"); + else if (defaultOutlets == 0) + issues.addWarning(this, "No default outlet configured!"); + + if (_expand == null) + issues.addError(this, "property 'expand' not configured!"); + else { + try { + final ExpandStatement es = getStatement(); + if (es == null) { + issues.addError(this, "property 'expand' has wrong syntax!"); + } + } catch (ParseException e) { + issues.addError(this, "property 'expand' has wrong syntax : "+e.getMessage()); + } + } + } +} + + |