View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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      // Tag interface
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                      // it's more recent, skip.
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 }