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    */
025    package org.eigenbase.xom;
026    
027    import org.apache.tools.ant.BuildException;
028    import org.apache.tools.ant.Task;
029    
030    import java.io.File;
031    import 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     **/
099    public 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