001: /*
002: * transformica 2
003: * Code generator
004: * Copyright (C) 2004 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.pavelvlasov.com/pv/content/menu.show@id=products.transformica.html
021: * e-Mail: support@hammurapi.biz
022: */
023: package biz.hammurapi.transformica.bnf;
024:
025: import java.io.File;
026: import java.io.FileNotFoundException;
027: import java.io.FileReader;
028:
029: import org.apache.tools.ant.BuildException;
030: import org.apache.tools.ant.types.Path;
031: import org.mesopotamia.MesopotamiaException;
032: import org.mesopotamia.util.BnfModel;
033:
034: import biz.hammurapi.transformica.TransformSession;
035: import biz.hammurapi.transformica.TransformTask;
036: import biz.hammurapi.util.Visitable;
037:
038: /**
039: * Transforms BNF file into multiple files. Transformations are defined by nested channel elements.
040: * Velocity template engine is used for code generation. Current bnf element (model or rule definition) is accessible through 'element' context object,
041: * 'session' context object of type biz.hammurapi.transformica.TransformSession gives access to current Ant project and provides
042: * methods to include other templates or channels and to store information.
043: * <section name="Example" suppress-description="yes">
044: <pre>
045: <taskdef name="bnftransform" classname="biz.hammurapi.transformica.bnf.BnfTask"><br/>
046: <tab/><classpath><br/>
047: <tab/><tab/><fileset dir="lib" includes="*.jar"/><br/>
048: <tab/></classpath><br/>
049: </taskdef><br/>
050: <br/>
051: <bnftransform file="java.bnf"><br/>
052: <tab/><channel <br/>
053: <tab/><tab/>outputDir="generated"<br/>
054: <tab/><tab/>type="RuleDefinition" <br/>
055: <tab/><tab/>template="templates/LanguageElement.java"<br/>
056: <tab/><tab/>fileNameTemplate='$${element.name}.java' <br/>
057: <tab/>><br/>
058: <tab/></channel><br/>
059: </bnftransform><br/>
060: </pre></section>
061: * @ant.element name="jseltransform"
062: * @author Pavel Vlasov
063: */
064: public class BnfTask extends TransformTask {
065:
066: /**
067: * Defines transformation channel.
068: * @ant.required
069: * @return
070: */
071: public BnfChannel createBnfChannel() {
072: BnfChannel ret = new BnfChannel(session);
073: channels.add(ret);
074: return ret;
075: }
076:
077: protected Visitable getModel(TransformSession session)
078: throws BuildException {
079: try {
080: return new BnfModel(new FileReader(file),
081: className == null ? null : Class.forName(className));
082: } catch (MesopotamiaException e) {
083: throw new BuildException("Can't load file: "
084: + file.getAbsolutePath() + ", " + e, e);
085: } catch (FileNotFoundException e) {
086: throw new BuildException("Can't load file: "
087: + file.getAbsolutePath() + ", " + e, e);
088: } catch (ClassNotFoundException e) {
089: throw new BuildException("Can't load class: " + className
090: + ", " + e, e);
091: }
092: }
093:
094: /**
095: * Classpath for loading classes
096: * @ant:non-required
097: */
098: private Path classPath;
099: private File file;
100: private String className;
101:
102: public void setClassPath(Path classPath) {
103: if (this .classPath == null) {
104: this .classPath = classPath;
105: } else {
106: this .classPath.append(classPath);
107: }
108: }
109:
110: /**
111: * Maybe creates a nested classpath element.
112: * @ant:non-required
113: */
114: public Path createClasspath() {
115: if (classPath == null) {
116: classPath = new Path(project);
117: }
118: return classPath.createPath();
119: }
120:
121: /**
122: * Source file.
123: * @ant.required
124: */
125: public void setFile(File file) {
126: this .file = file;
127: }
128:
129: /**
130: * Token types class to validate token names
131: * @param className
132: * @ant.non-required
133: */
134: public void setTokenTypesClass(String className) {
135: this.className = className;
136: }
137: }
|