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 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26
27 import org.codehaus.plexus.util.FileUtils;
28 import org.codehaus.plexus.util.StringUtils;
29
30 /**
31 * Provides a facade for the mojos to invoke JJTree.
32 *
33 * @author Benjamin Bentmann
34 * @version $Id: JJTree.java 10603 2009-09-06 15:05:08Z bentmann $
35 * @see <a href="https://javacc.dev.java.net/doc/JJTree.html">JJTree Reference</a>
36 */
37 class JJTree
38 extends ToolFacade
39 {
40
41 /**
42 * The input grammar.
43 */
44 private File inputFile;
45
46 /**
47 * The option OUTPUT_DIRECTORY.
48 */
49 private File outputDirectory;
50
51 /**
52 * The option GRAMMAR_ENCODING.
53 */
54 private String grammarEncoding;
55
56 /**
57 * The option JDK_VERSION.
58 */
59 private String jdkVersion;
60
61 /**
62 * The option STATIC.
63 */
64 private Boolean isStatic;
65
66 /**
67 * The option BUILD_NODE_FILES.
68 */
69 private Boolean buildNodeFiles;
70
71 /**
72 * The option MULTI.
73 */
74 private Boolean multi;
75
76 /**
77 * The option NODE_DEFAULT_VOID.
78 */
79 private Boolean nodeDefaultVoid;
80
81 /**
82 * The option NODE_CLASS.
83 */
84 private String nodeClass;
85
86 /**
87 * The option NODE_FACTORY.
88 */
89 private String nodeFactory;
90
91 /**
92 * The option NODE_PACKAGE.
93 */
94 private String nodePackage;
95
96 /**
97 * The option NODE_PREFIX.
98 */
99 private String nodePrefix;
100
101 /**
102 * The option NODE_SCOPE_HOOK.
103 */
104 private Boolean nodeScopeHook;
105
106 /**
107 * The option NODE_USES_PARSER.
108 */
109 private Boolean nodeUsesParser;
110
111 /**
112 * The option TRACK_TOKENS.
113 */
114 private Boolean trackTokens;
115
116 /**
117 * The option VISITOR.
118 */
119 private Boolean visitor;
120
121 /**
122 * The option VISITOR_DATA_TYPE.
123 */
124 private String visitorDataType;
125
126 /**
127 * The option VISITOR_RETURN_TYPE.
128 */
129 private String visitorReturnType;
130
131 /**
132 * The option VISITOR_EXCEPTION.
133 */
134 private String visitorException;
135
136 /**
137 * Sets the absolute path to the grammar file to pass into JJTree for preprocessing.
138 *
139 * @param value The absolute path to the grammar file to pass into JJTree for preprocessing.
140 */
141 public void setInputFile( File value )
142 {
143 if ( value != null && !value.isAbsolute() )
144 {
145 throw new IllegalArgumentException( "path is not absolute: " + value );
146 }
147 this.inputFile = value;
148 }
149
150 /**
151 * Sets the absolute path to the output directory.
152 *
153 * @param value The absolute path to the output directory for the generated grammar file. If this directory does not
154 * exist yet, it is created. Note that this path should already include the desired package hierarchy
155 * because JJTree will not append the required sub directories automatically.
156 */
157 public void setOutputDirectory( File value )
158 {
159 if ( value != null && !value.isAbsolute() )
160 {
161 throw new IllegalArgumentException( "path is not absolute: " + value );
162 }
163 this.outputDirectory = value;
164 }
165
166 /**
167 * Gets the absolute path to the enhanced grammar file generated by JJTree.
168 *
169 * @return The absolute path to the enhanced grammar file generated by JJTree or <code>null</code> if either the
170 * input file or the output directory have not been set.
171 */
172 public File getOutputFile()
173 {
174 File outputFile = null;
175 if ( this.outputDirectory != null && this.inputFile != null )
176 {
177 String fileName = FileUtils.removeExtension( this.inputFile.getName() ) + ".jj";
178 outputFile = new File( this.outputDirectory, fileName );
179 }
180 return outputFile;
181 }
182
183 /**
184 * Sets the option GRAMMAR_ENCODING.
185 *
186 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
187 */
188 public void setGrammarEncoding( String value )
189 {
190 this.grammarEncoding = value;
191 }
192
193 /**
194 * Sets the option JDK_VERSION.
195 *
196 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
197 */
198 public void setJdkVersion( String value )
199 {
200 this.jdkVersion = value;
201 }
202
203 /**
204 * Sets the option STATIC.
205 *
206 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
207 */
208 public void setStatic( Boolean value )
209 {
210 this.isStatic = value;
211 }
212
213 /**
214 * Sets the option value BUILD_NODE_FILES.
215 *
216 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
217 */
218 public void setBuildNodeFiles( Boolean value )
219 {
220 this.buildNodeFiles = value;
221 }
222
223 /**
224 * Sets the option value MULTI.
225 *
226 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
227 */
228 public void setMulti( Boolean value )
229 {
230 this.multi = value;
231 }
232
233 /**
234 * Sets the option value NODE_DEFAULT_VOID.
235 *
236 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
237 */
238 public void setNodeDefaultVoid( Boolean value )
239 {
240 this.nodeDefaultVoid = value;
241 }
242
243 /**
244 * Sets the option value NODE_CLASS.
245 *
246 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
247 */
248 public void setNodeClass( String value )
249 {
250 this.nodeClass = value;
251 }
252
253 /**
254 * Sets the option value NODE_FACTORY.
255 *
256 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
257 */
258 public void setNodeFactory( String value )
259 {
260 this.nodeFactory = value;
261 }
262
263 /**
264 * Sets the option value NODE_PACKAGE.
265 *
266 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
267 */
268 public void setNodePackage( String value )
269 {
270 this.nodePackage = value;
271 }
272
273 /**
274 * Sets the option value NODE_PREFIX.
275 *
276 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
277 */
278 public void setNodePrefix( String value )
279 {
280 this.nodePrefix = value;
281 }
282
283 /**
284 * Sets the option value NODE_SCOPE_HOOK.
285 *
286 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
287 */
288 public void setNodeScopeHook( Boolean value )
289 {
290 this.nodeScopeHook = value;
291 }
292
293 /**
294 * Sets the option value NODE_USES_PARSER.
295 *
296 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
297 */
298 public void setNodeUsesParser( Boolean value )
299 {
300 this.nodeUsesParser = value;
301 }
302
303 /**
304 * Sets the option value TRACK_TOKENS.
305 *
306 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
307 */
308 public void setTrackTokens( Boolean value )
309 {
310 this.trackTokens = value;
311 }
312
313 /**
314 * Sets the option value VISITOR.
315 *
316 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
317 */
318 public void setVisitor( Boolean value )
319 {
320 this.visitor = value;
321 }
322
323 /**
324 * Sets the option value VISITOR_DATA_TYPE.
325 *
326 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
327 */
328 public void setVisitorDataType( String value )
329 {
330 this.visitorDataType = value;
331 }
332
333 /**
334 * Sets the option value VISITOR_RETURN_TYPE.
335 *
336 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
337 */
338 public void setVisitorReturnType( String value )
339 {
340 this.visitorReturnType = value;
341 }
342
343 /**
344 * Sets the option value VISITOR_EXCEPTION.
345 *
346 * @param value The option value, may be <code>null</code> to use the value provided in the grammar or the default.
347 */
348 public void setVisitorException( String value )
349 {
350 this.visitorException = value;
351 }
352
353 /**
354 * {@inheritDoc}
355 */
356 protected int execute()
357 throws Exception
358 {
359 String[] args = generateArguments();
360
361 if ( this.outputDirectory != null && !this.outputDirectory.exists() )
362 {
363 this.outputDirectory.mkdirs();
364 }
365
366 org.javacc.jjtree.JJTree jjtree = new org.javacc.jjtree.JJTree();
367 return jjtree.main( args );
368 }
369
370 /**
371 * Assembles the command line arguments for the invocation of JJTree according to the configuration.<br/><br/>
372 * <strong>Note:</strong> To prevent conflicts with JavaCC options that might be set directly in the grammar file,
373 * only those parameters that have been explicitly set are passed on the command line.
374 *
375 * @return A string array that represents the arguments to use for JJTree.
376 */
377 private String[] generateArguments()
378 {
379 List argsList = new ArrayList();
380
381 if ( StringUtils.isNotEmpty( this.grammarEncoding ) )
382 {
383 argsList.add( "-GRAMMAR_ENCODING=" + this.grammarEncoding );
384 }
385
386 if ( StringUtils.isNotEmpty( jdkVersion ) )
387 {
388 argsList.add( "-JDK_VERSION=" + this.jdkVersion );
389 }
390
391 if ( this.buildNodeFiles != null )
392 {
393 argsList.add( "-BUILD_NODE_FILES=" + this.buildNodeFiles );
394 }
395
396 if ( this.multi != null )
397 {
398 argsList.add( "-MULTI=" + this.multi );
399 }
400
401 if ( this.nodeDefaultVoid != null )
402 {
403 argsList.add( "-NODE_DEFAULT_VOID=" + this.nodeDefaultVoid );
404 }
405
406 if ( StringUtils.isNotEmpty( this.nodeClass ) )
407 {
408 argsList.add( "-NODE_CLASS=" + this.nodeClass );
409 }
410
411 if ( StringUtils.isNotEmpty( this.nodeFactory ) )
412 {
413 argsList.add( "-NODE_FACTORY=" + this.nodeFactory );
414 }
415
416 if ( StringUtils.isNotEmpty( this.nodePackage ) )
417 {
418 argsList.add( "-NODE_PACKAGE=" + this.nodePackage );
419 }
420
421 if ( StringUtils.isNotEmpty( this.nodePrefix ) )
422 {
423 argsList.add( "-NODE_PREFIX=" + this.nodePrefix );
424 }
425
426 if ( this.nodeScopeHook != null )
427 {
428 argsList.add( "-NODE_SCOPE_HOOK=" + this.nodeScopeHook );
429 }
430
431 if ( this.nodeUsesParser != null )
432 {
433 argsList.add( "-NODE_USES_PARSER=" + this.nodeUsesParser );
434 }
435
436 if ( this.isStatic != null )
437 {
438 argsList.add( "-STATIC=" + this.isStatic );
439 }
440
441 if ( this.trackTokens != null )
442 {
443 argsList.add( "-TRACK_TOKENS=" + this.trackTokens );
444 }
445
446 if ( this.visitor != null )
447 {
448 argsList.add( "-VISITOR=" + this.visitor );
449 }
450
451 if ( StringUtils.isNotEmpty( this.visitorDataType ) )
452 {
453 argsList.add( "-VISITOR_DATA_TYPE=" + this.visitorDataType );
454 }
455
456 if ( StringUtils.isNotEmpty( this.visitorReturnType ) )
457 {
458 argsList.add( "-VISITOR_RETURN_TYPE=" + this.visitorReturnType );
459 }
460
461 if ( StringUtils.isNotEmpty( this.visitorException ) )
462 {
463 argsList.add( "-VISITOR_EXCEPTION=" + this.visitorException );
464 }
465
466 if ( this.outputDirectory != null )
467 {
468 argsList.add( "-OUTPUT_DIRECTORY=" + this.outputDirectory.getAbsolutePath() );
469 }
470
471 if ( this.inputFile != null )
472 {
473 argsList.add( this.inputFile.getAbsolutePath() );
474 }
475
476 return (String[]) argsList.toArray( new String[argsList.size()] );
477 }
478
479 /**
480 * Gets a string representation of the command line arguments.
481 *
482 * @return A string representation of the command line arguments.
483 */
484 public String toString()
485 {
486 return Arrays.asList( generateArguments() ).toString();
487 }
488
489 }