1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jelly.tags.antlr;
18
19 import org.apache.commons.jelly.XMLOutput;
20 import org.apache.commons.jelly.TagSupport;
21 import org.apache.commons.jelly.MissingAttributeException;
22 import org.apache.commons.jelly.JellyTagException;
23
24 import antlr.Tool;
25
26 import java.io.File;
27 import java.io.FileReader;
28 import java.io.BufferedReader;
29 import java.security.Permission;
30 import java.util.List;
31 import java.util.ArrayList;
32 import java.util.Iterator;
33
34 public class AntlrTag extends TagSupport
35 {
36 private List grammars;
37 private File outputDir;
38
39 public AntlrTag()
40 {
41 this.grammars = new ArrayList( 1 );
42 }
43
44
45
46
47
48 /***
49 * Evaluate the body to register all the various goals and pre/post conditions
50 * then run all the current targets
51 */
52 public void doTag(final XMLOutput output) throws MissingAttributeException, JellyTagException
53 {
54 if ( this.outputDir == null )
55 {
56 throw new MissingAttributeException( "outputDir" );
57 }
58
59 invokeBody( output );
60
61 Iterator grammarIter = this.grammars.iterator();
62 String eachGrammar = null;
63
64 String sourceDir = (String) getContext().getVariable( "maven.antlr.src.dir" );
65 File grammar = null;
66
67 while ( grammarIter.hasNext() )
68 {
69 eachGrammar = ((String) grammarIter.next()).trim();
70
71 grammar = new File( sourceDir,
72 eachGrammar );
73
74 File generated = getGeneratedFile( grammar.getPath() );
75
76 if ( generated.exists() )
77 {
78 if ( generated.lastModified() > grammar.lastModified() )
79 {
80
81 return;
82 }
83 }
84
85 if ( ! generated.getParentFile().exists() )
86 {
87 generated.getParentFile().mkdirs();
88 }
89
90 String[] args = new String[]
91 {
92 "-o",
93 generated.getParentFile().getPath(),
94 grammar.getPath(),
95 };
96
97 SecurityManager oldSm = System.getSecurityManager();
98
99 System.setSecurityManager( NoExitSecurityManager.INSTANCE );
100
101 try
102 {
103 Tool.main( args );
104 }
105 catch (SecurityException e)
106 {
107 if ( ! e.getMessage().equals( "exitVM-0" ) )
108 {
109 throw new JellyTagException( e );
110 }
111 }
112 finally
113 {
114 System.setSecurityManager( oldSm );
115 }
116 }
117 }
118
119 protected File getGeneratedFile(String grammar) throws JellyTagException
120 {
121 File grammarFile = new File( grammar );
122
123 String generatedFileName = null;
124
125 String className = null;
126 String packageName = "";
127
128 try {
129
130 BufferedReader in = new BufferedReader(new FileReader(grammar));
131
132 String line;
133 while ((line = in.readLine()) != null) {
134 line = line.trim();
135 int extendsIndex = line.indexOf(" extends ");
136 if (line.startsWith("class ") && extendsIndex > -1) {
137 generatedFileName = line.substring(6, extendsIndex).trim();
138 break;
139 }
140 else if ( line.startsWith( "package" ) ) {
141 packageName = line.substring( 8 ).trim();
142 }
143 }
144 in.close();
145 } catch (Exception e) {
146 throw new JellyTagException("Unable to determine generated class",
147 e);
148 }
149 if (generatedFileName == null) {
150 return null;
151 }
152
153 File genFile = null;
154
155 if ( "".equals( packageName ) )
156 {
157 genFile = new File( getOutputDir(),
158 generatedFileName + ".java" );
159 }
160 else
161 {
162 String packagePath = packageName.replace( '.',
163 File.separatorChar );
164
165 packagePath = packagePath.replace( ';',
166 File.separatorChar );
167
168 genFile = new File( new File( getOutputDir(), packagePath),
169 generatedFileName + ".java" );
170 }
171
172 return genFile;
173 }
174
175 void addGrammar(String grammar)
176 {
177 this.grammars.add( grammar );
178 }
179
180 public void setOutputDir(File outputDir)
181 {
182 this.outputDir = outputDir;
183 }
184
185 public File getOutputDir()
186 {
187 return this.outputDir;
188 }
189 }
190
191 class NoExitSecurityManager extends SecurityManager
192 {
193 static final NoExitSecurityManager INSTANCE = new NoExitSecurityManager();
194
195 private NoExitSecurityManager()
196 {
197 }
198
199 public void checkPermission(Permission permission)
200 {
201 }
202
203 public void checkExit(int status)
204 {
205 throw new SecurityException( "exitVM-" + status );
206 }
207 }