/******************************************************************************* * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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: * committers of openArchitectureWare - initial API and implementation *******************************************************************************/ package org.eclipse.internal.xpand2.ast; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.internal.xtend.expression.ast.Expression; import org.eclipse.internal.xtend.expression.ast.Identifier; import org.eclipse.internal.xtend.util.Pair; import org.eclipse.xpand2.XpandExecutionContext; import org.eclipse.xpand2.XpandExecutionContextImpl; import org.eclipse.xpand2.output.InsertionPointSupport; import org.eclipse.xpand2.output.VetoException; import org.eclipse.xtend.expression.AnalysationIssue; import org.eclipse.xtend.expression.EvaluationException; import org.eclipse.xtend.expression.ExecutionContext; import org.eclipse.xtend.expression.Variable; import org.eclipse.xtend.typesystem.Type; /** * * * * @author Sven Efftinge (http://www.efftinge.de) * */ public class FileStatement extends StatementWithBody { private static final Log LOG = LogFactory.getLog(FileStatement.class); private Expression fileNameExpression; private Identifier outletNameIdentifier; public FileStatement(final Expression fileName, final Statement[] body, final Identifier mode) { super(body); this.fileNameExpression = fileName; this.outletNameIdentifier = mode; } public Expression getTargetFileName() { return fileNameExpression; } public Identifier getMode() { return outletNameIdentifier; } public String getOutletName() { if (outletNameIdentifier == null) return null; return outletNameIdentifier.getValue(); } @Override public void analyzeInternal(XpandExecutionContext ctx, final Set<AnalysationIssue> issues) { final Type result = getTargetFileName().analyze(ctx, issues); ctx = (XpandExecutionContext) ctx.cloneWithVariable(new Variable("FILENAME", result)); if (!ctx.getStringType().isAssignableFrom(result)) { issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "String expected!", getTargetFileName())); } for (int i = 0; i < body.length; i++) { body[i].analyze(ctx, issues); } } @Override public void evaluateInternal(XpandExecutionContext ctx) { final Object result = getFilename(ctx); String fileName = result.toString(); final String outletName = getOutletName(); ctx = (XpandExecutionContext) ctx.cloneWithVariable(new Variable("FILENAME", result)); try { ctx.getOutput().openFile(fileName, outletName); for (int i = 0; i < body.length; i++) { body[i].evaluate(ctx); } for (Pair<XpandExecutionContextImpl,Statement> deferredStatement : ((XpandExecutionContextImpl)ctx).getDeferredStatements()) { Statement stmt = deferredStatement.getSecond(); if (!(ctx.getOutput() instanceof InsertionPointSupport)) { throw new IllegalStateException ("Output does not support insertion points."); } ((InsertionPointSupport)ctx.getOutput()).activateInsertionPoint(stmt); stmt.evaluate(deferredStatement.getFirst()); ((InsertionPointSupport)ctx.getOutput()).deactivateInsertionPoint(stmt); } ctx.getOutput().closeFile(); } catch (VetoException e) { if (LOG.isDebugEnabled()) { LOG.debug("Generation of file '"+fileName+"' on outlet '"+outletName+"' skipped due to veto."); } } } @Override public String getNameString(ExecutionContext context) { return "FILE"; } private Object getFilename(XpandExecutionContext ctx) { final Object result = getTargetFileName().evaluate(ctx); if (result == null) throw new EvaluationException("Nullevaluation", getTargetFileName(), ctx); return result; } }