View Javadoc

1   package org.codehaus.mojo.javacc;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file 
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing, 
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
17   * KIND, either express or implied.  See the License for the 
18   * specific language governing permissions and limitations 
19   * under the License.
20   */
21  
22  import java.io.File;
23  
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.MojoFailureException;
26  
27  /**
28   * Parses a JTB file and transforms it into source files for an AST and a JavaCC grammar file which automatically builds
29   * the AST.<br/><br/><strong>Note:</strong> <a href="http://compilers.cs.ucla.edu/jtb/">JTB</a> requires Java 1.5
30   * or higher. This goal will not work with earlier versions of the JRE.
31   * 
32   * @goal jtb
33   * @phase generate-sources
34   * @since 2.2
35   * @deprecated As of version 2.4, use the <code>jtb-javacc</code> goal instead.
36   * @author Gregory Kick (gk5885@kickstyle.net)
37   * @version $Id: JTBMojo.java 7743 2008-09-28 15:22:44Z bentmann $
38   */
39  public class JTBMojo
40      extends AbstractPreprocessorMojo
41  {
42  
43      /**
44       * This option is short for <code>nodePackageName</code> = <code>&lt;packageName&gt;.syntaxtree</code> and
45       * <code>visitorPackageName</code> = <code>&lt;packageName&gt;.visitor</code>. Note that this option takes
46       * precedence over <code>nodePackageName</code> and <code>visitorPackageName</code> if specified.
47       * 
48       * @parameter expression="${package}"
49       */
50      private String packageName;
51  
52      /**
53       * This option specifies the package for the generated AST nodes. This value may use a leading asterisk to reference
54       * the package of the corresponding parser. For example, if the parser package is <code>org.apache</code> and this
55       * parameter is set to <code>*.demo</code>, the tree node classes will be located in the package
56       * <code>org.apache.demo</code>. Default value is <code>*.syntaxtree</code>.
57       * 
58       * @parameter expression="${nodePackageName}"
59       */
60      private String nodePackageName;
61  
62      /**
63       * This option specifies the package for the generated visitors. This value may use a leading asterisk to reference
64       * the package of the corresponding parser. For example, if the parser package is <code>org.apache</code> and this
65       * parameter is set to <code>*.demo</code>, the visitor classes will be located in the package
66       * <code>org.apache.demo</code>. Default value is <code>*.visitor</code>.
67       * 
68       * @parameter expression="${visitorPackageName}"
69       */
70      private String visitorPackageName;
71  
72      /**
73       * If <code>true</code>, JTB will suppress its semantic error checking. Default value is <code>false</code>.
74       * 
75       * @parameter expression="${supressErrorChecking}"
76       */
77      private Boolean supressErrorChecking;
78  
79      /**
80       * If <code>true</code>, all generated comments will be wrapped in <code>&lt;pre&gt;</code> tags so that they
81       * are formatted correctly in API docs. Default value is <code>false</code>.
82       * 
83       * @parameter expression="${javadocFriendlyComments}"
84       */
85      private Boolean javadocFriendlyComments;
86  
87      /**
88       * Setting this option to <code>true</code> causes JTB to generate field names that reflect the structure of the
89       * tree instead of generic names like <code>f0</code>, <code>f1</code> etc. Default value is <code>false</code>.
90       * 
91       * @parameter expression="${descriptiveFieldNames}"
92       */
93      private Boolean descriptiveFieldNames;
94  
95      /**
96       * The qualified name of a user-defined class from which all AST nodes will inherit. By default, AST nodes will
97       * inherit from the generated class <code>Node</code>.
98       * 
99       * @parameter expression="${nodeParentClass}"
100      */
101     private String nodeParentClass;
102 
103     /**
104      * If <code>true</code>, all nodes will contain fields for its parent node. Default value is <code>false</code>.
105      * 
106      * @parameter expression="${parentPointers}"
107      */
108     private Boolean parentPointers;
109 
110     /**
111      * If <code>true</code>, JTB will include JavaCC "special tokens" in the AST. Default value is <code>false</code>.
112      * 
113      * @parameter expression="${specialTokens}"
114      */
115     private Boolean specialTokens;
116 
117     /**
118      * If <code>true</code>, JTB will generate the following files to support the Schema programming language:
119      * <ul>
120      * <li>Scheme records representing the grammar.</li>
121      * <li>A Scheme tree building visitor.</li>
122      * </ul>
123      * Default value is <code>false</code>.
124      * 
125      * @parameter expression="${scheme}"
126      */
127     private Boolean scheme;
128 
129     /**
130      * If <code>true</code>, JTB will generate a syntax tree dumping visitor. Default value is <code>false</code>.
131      * 
132      * @parameter expression="${printer}"
133      */
134     private Boolean printer;
135 
136     /**
137      * The directory where the JavaCC grammar files (<code>*.jtb</code>) are located. It will be recursively scanned
138      * for input files to pass to JTB.
139      * 
140      * @parameter expression="${sourceDirectory}" default-value="${basedir}/src/main/jtb"
141      */
142     private File sourceDirectory;
143 
144     /**
145      * The directory where the output Java files will be located.
146      * 
147      * @parameter expression="${outputDirectory}" default-value="${project.build.directory}/generated-sources/jtb"
148      */
149     private File outputDirectory;
150 
151     /**
152      * The directory to store the processed input files for later detection of stale sources.
153      * 
154      * @parameter expression="${timestampDirectory}"
155      *            default-value="${project.build.directory}/generated-sources/jtb-timestamp"
156      */
157     private File timestampDirectory;
158 
159     /**
160      * The granularity in milliseconds of the last modification date for testing whether a source needs recompilation.
161      * 
162      * @parameter expression="${lastModGranularityMs}" default-value="0"
163      */
164     private int staleMillis;
165 
166     /**
167      * A set of Ant-like inclusion patterns used to select files from the source directory for processing. By default,
168      * the patterns <code>**&#47;*.jtb</code> and <code>**&#47;*.JTB</code> are used to select grammar files.
169      * 
170      * @parameter
171      */
172     private String[] includes;
173 
174     /**
175      * A set of Ant-like exclusion patterns used to prevent certain files from being processed. By default, this set is
176      * empty such that no files are excluded.
177      * 
178      * @parameter
179      */
180     private String[] excludes;
181 
182     /**
183      * {@inheritDoc}
184      */
185     protected File getSourceDirectory()
186     {
187         return this.sourceDirectory;
188     }
189 
190     /**
191      * {@inheritDoc}
192      */
193     protected String[] getIncludes()
194     {
195         if ( this.includes != null )
196         {
197             return this.includes;
198         }
199         else
200         {
201             return new String[] { "**/*.jtb", "**/*.JTB" };
202         }
203     }
204 
205     /**
206      * {@inheritDoc}
207      */
208     protected String[] getExcludes()
209     {
210         return this.excludes;
211     }
212 
213     /**
214      * {@inheritDoc}
215      */
216     protected File getOutputDirectory()
217     {
218         return this.outputDirectory;
219     }
220 
221     /**
222      * {@inheritDoc}
223      */
224     protected File getTimestampDirectory()
225     {
226         return this.timestampDirectory;
227     }
228 
229     /**
230      * {@inheritDoc}
231      */
232     protected int getStaleMillis()
233     {
234         return this.staleMillis;
235     }
236 
237     /**
238      * {@inheritDoc}
239      */
240     protected void processGrammar( GrammarInfo grammarInfo )
241         throws MojoExecutionException, MojoFailureException
242     {
243         File jtbFile = grammarInfo.getGrammarFile();
244         File jjDirectory = new File( getOutputDirectory(), grammarInfo.getParserDirectory() );
245 
246         String nodePackage = grammarInfo.resolvePackageName( getNodePackageName() );
247         File nodeDirectory = new File( getOutputDirectory(), nodePackage.replace( '.', File.separatorChar ) );
248 
249         String visitorPackage = grammarInfo.resolvePackageName( getVisitorPackageName() );
250         File visitorDirectory = new File( getOutputDirectory(), visitorPackage.replace( '.', File.separatorChar ) );
251 
252         // generate final grammar file and the node/visitor files
253         JTB jtb = newJTB();
254         jtb.setInputFile( jtbFile );
255         jtb.setOutputDirectory( jjDirectory );
256         jtb.setNodeDirectory( nodeDirectory );
257         jtb.setVisitorDirectory( visitorDirectory );
258         jtb.setNodePackageName( nodePackage );
259         jtb.setVisitorPackageName( visitorPackage );
260         jtb.run();
261 
262         // create timestamp file
263         createTimestamp( grammarInfo );
264     }
265 
266     /**
267      * Gets the effective package name for the AST node files.
268      * 
269      * @return The effective package name for the AST node files, never <code>null</code>.
270      */
271     private String getNodePackageName()
272     {
273         if ( this.packageName != null )
274         {
275             return this.packageName + ".syntaxtree";
276         }
277         else if ( this.nodePackageName != null )
278         {
279             return this.nodePackageName;
280         }
281         else
282         {
283             return "*.syntaxtree";
284         }
285     }
286 
287     /**
288      * Gets the effective package name for the visitor files.
289      * 
290      * @return The effective package name for the visitor files, never <code>null</code>.
291      */
292     private String getVisitorPackageName()
293     {
294         if ( this.packageName != null )
295         {
296             return this.packageName + ".visitor";
297         }
298         else if ( this.visitorPackageName != null )
299         {
300             return this.visitorPackageName;
301         }
302         else
303         {
304             return "*.visitor";
305         }
306     }
307 
308     /**
309      * Creates a new facade to invoke JTB. Most options for the invocation are derived from the current values of the
310      * corresponding mojo parameters. The caller is responsible to set the input file, output directories and packages
311      * on the returned facade.
312      * 
313      * @return The facade for the tool invocation, never <code>null</code>.
314      */
315     private JTB newJTB()
316     {
317         JTB jtb = new JTB();
318         jtb.setLog( getLog() );
319         jtb.setDescriptiveFieldNames( this.descriptiveFieldNames );
320         jtb.setJavadocFriendlyComments( this.javadocFriendlyComments );
321         jtb.setNodeParentClass( this.nodeParentClass );
322         jtb.setParentPointers( this.parentPointers );
323         jtb.setPrinter( this.printer );
324         jtb.setScheme( this.scheme );
325         jtb.setSpecialTokens( this.specialTokens );
326         jtb.setSupressErrorChecking( this.supressErrorChecking );
327         return jtb;
328     }
329 
330 }