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><packageName>.syntaxtree</code> and
45 * <code>visitorPackageName</code> = <code><packageName>.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><pre></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>**/*.jtb</code> and <code>**/*.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 }