001/*
002// $Id: //open/util/resgen/src/org/eigenbase/xom/XOMGenTask.java#4 $
003// Package org.eigenbase.xom is an XML Object Mapper.
004// Copyright (C) 2005-2007 The Eigenbase Project
005// Copyright (C) 2005-2007 Disruptive Tech
006// Copyright (C) 2005-2007 LucidEra, Inc.
007// Portions Copyright (C) 2002-2007 Kana Software, Inc. and others.
008//
009// This library is free software; you can redistribute it and/or modify it
010// under the terms of the GNU Lesser General Public License as published by the
011// Free Software Foundation; either version 2 of the License, or (at your
012// option) any later version approved by The Eigenbase Project.
013//
014// This library is distributed in the hope that it will be useful,
015// but WITHOUT ANY WARRANTY; without even the implied warranty of
016// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017// GNU Lesser General Public License for more details.
018//
019// You should have received a copy of the GNU Lesser General Public License
020// along with this library; if not, write to the Free Software
021// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022//
023// jhyde, 1 April, 2002
024*/
025package org.eigenbase.xom;
026
027import org.apache.tools.ant.BuildException;
028import org.apache.tools.ant.Task;
029
030import java.io.File;
031import java.io.IOException;
032
033/**
034 * <code>XOMGenTask</code> is an ANT task with which to invoke {@link
035 * MetaGenerator}.
036 *
037 * @author jhyde
038 * @since 1 April, 2002
039 * @version $Id: //open/util/resgen/src/org/eigenbase/xom/XOMGenTask.java#4 $
040 *
041 * <hr/>
042 *
043 * <h2><a name="XOMGen">XOMGen</a></h2>
044 * <h3>Description</h3>
045 * <p>
046 *   Invokes the {@link MetaGenerator}.
047 * </p>
048 * <p>
049 *   This task only invokes XOMGen if the grammar file is newer than the
050 *   generated Java files.
051 * </p>
052 *
053 * <h3>Parameters</h3>
054 * <table border="1" cellpadding="2" cellspacing="0">
055 *   <tr>
056 *     <td valign="top"><b>Attribute</b></td>
057 *     <td valign="top"><b>Description</b></td>
058 *     <td align="center" valign="top"><b>Required</b></td>
059 *   </tr>
060 *   <tr>
061 *     <td valign="top"><a name="model">model</a></td>
062 *     <td valign="top">The name of the XML file which holds the XOM
063 *       model.</td>
064 *     <td valign="top" align="center">Yes</td>
065 *   </tr>
066 *   <tr>
067 *     <td valign="top"><a name="destdir">destdir</a></td>
068 *     <td valign="top">The name of the output directory. Default is the
069 *       current directory.</td>
070 *     <td valign="top" align="center">No</td>
071 *   </tr>
072 *   <tr>
073 *     <td valign="top"><a name="classname">classname</a></td>
074 *     <td valign="top">The full name of the class to generate.</td>
075 *     <td valign="top" align="center">Yes</td>
076 *   </tr>
077 *   <tr>
078 *     <td valign="top"><a name="dtdname">dtdname</a></td>
079 *     <td valign="top">The name of the DTD file to generate. The path may be
080 *       either absolute, or relative to <code>destdir</code>.</td>
081 *     <td valign="top" align="center">Yes</td>
082 *   </tr>
083 * </table>
084 *
085 * <h3>Example</h3>
086 * <blockquote><pre>&lt;xomgen
087 *     model=&quot;src/org/eigenbase/xom/Meta.xml&quot;
088 *     destdir=&quot;src&quot;
089 *     classname=&quot;org.eigenbase.xom.MetaDef&quot;/&gt;</pre></blockquote>
090 * <p>
091 *   This invokes XOMGen on the model file
092 *   <code>src/org/eigenbase/xom/Meta.xml</code>, and generates
093 *   <code>src/org/eigenbase/xom/MetaDef.java</code> and
094 *   <code>src/org/eigenbase/xom/meta.dtd</code>.
095 * </p>
096 *
097 * <hr/>
098 **/
099public class XOMGenTask extends Task {
100    String modelFileName;
101    String destDir;
102    String dtdFileName;
103    String className;
104
105    public XOMGenTask()
106    {}
107
108    public void execute() throws BuildException {
109        try {
110            if (modelFileName == null) {
111                throw new BuildException("You must specify model.");
112            }
113            if (className == null) {
114                throw new BuildException("You must specify className.");
115            }
116
117            File projectBase = getProject().getBaseDir();
118            File destinationDirectory;
119            if (destDir == null) {
120                destinationDirectory = projectBase;
121            } else {
122                destinationDirectory = new File(projectBase, destDir);
123            }
124            if (!destinationDirectory.exists()) {
125                throw new BuildException(
126                    "Destination directory doesn't exist: " +
127                        destinationDirectory.toString());
128            }
129
130            File modelFile = new File(projectBase, modelFileName);
131            File classFile = classNameToFile(destinationDirectory, className);
132            File outputDir = classFile.getParentFile();
133            File dtdFile = new File(outputDir, dtdFileName);
134
135            if (modelFile.exists() &&
136                classFile.exists() &&
137                dtdFile.exists()) {
138                long modelStamp = modelFile.lastModified(),
139                    classStamp = classFile.lastModified(),
140                    dtdStamp = dtdFile.lastModified();
141                if (classStamp > modelStamp &&
142                    dtdStamp > modelStamp) {
143                    // files are up to date
144                    return;
145                }
146            }
147
148            final boolean testMode = false;
149            MetaGenerator generator = new MetaGenerator(
150                modelFile.toString(), testMode, className);
151            generator.writeFiles(destinationDirectory.toString(), dtdFileName);
152            generator.writeOutputs();
153        } catch (XOMException e) {
154            throw new BuildException("Generation of model failed: " + e);
155        } catch (IOException e) {
156            throw new BuildException("Generation of model failed: " + e);
157        }
158    }
159
160    // ------------------------------------------------------------------------
161    // ANT attribute methods
162
163    /** See parameter <code><a href="#model">model</a></code>. **/
164    public void setModel(String model) {
165        this.modelFileName = model;
166    }
167
168    /** See parameter <code><a href="#destdir">destdir</a></code>. **/
169    public void setDestdir(String destdir) {
170        this.destDir = destdir;
171    }
172
173    /** See parameter <code><a href="#classname">classname</a></code>. **/
174    public void setClassname(String classname) {
175        this.className = classname;
176    }
177
178    /** See parameter <code><a href="#dtdname">dtdname</a></code>. **/
179    public void setDtdname(String dtdname) {
180        this.dtdFileName = dtdname;
181    }
182
183    // ------------------------------------------------------------------------
184
185    /**
186     * Creates the File that a java class will live in. For example,
187     * <code>makeJavaFileName("com.myproj", "MyClass")</code> returns
188     * "com/myproj/MyClass.java".
189     **/
190    static File classNameToFile(File dir, String className) {
191        char fileSep = System.getProperty("file.separator").charAt(0); // e.g. '/'
192
193        String relativePath = className.replace('.', fileSep) + ".java";
194
195        if (dir == null) {
196            return new File(relativePath);
197        } else {
198            return new File(dir, relativePath);
199        }
200    }
201
202}
203
204
205// End XOMGenTask.java