KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > controls > runtime > generator > AptTask


1 package org.apache.beehive.controls.runtime.generator;
2
3 /*
4  * Copyright 2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * $Header:$
19  */

20
21 import org.apache.tools.ant.BuildException;
22 import org.apache.tools.ant.DirectoryScanner;
23 import org.apache.tools.ant.taskdefs.Javac;
24 import org.apache.tools.ant.types.Commandline;
25 import org.apache.tools.ant.types.Path;
26 import org.apache.tools.ant.util.FileUtils;
27 import org.apache.tools.ant.util.GlobPatternMapper;
28 import org.apache.tools.ant.util.SourceFileScanner;
29
30 import java.io.File JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.util.StringTokenizer JavaDoc;
33 import java.util.Vector JavaDoc;
34
35 /**
36  * The AptTask class defines a custom ANT task for invoking APT-based code generation. It
37  * derives from the <javac> built-in task, so all of the attributes and nested elements of that
38  * task are supported, for source list selection, classpath selection, compiler arguments,
39  * etc. Each of these options will be passed onto APT for processing.
40  * <p>
41  * AptTask also adds some new attributes:
42  * <ul>
43  * <li>gendir - specifies the directory where temporary source files that are produced during
44  * generation will be kept.
45  * <li>srcExtensions - provides a comma-separated list of source file extensions that are
46  * considered valid input to APT. The default value is "*.java".
47  * <li>
48  */

49 public class AptTask extends Javac
50 {
51     /**
52      * The srcExtensions attribute can be set to a comma-separated list of source filename
53      * extensions that are considered to be valid inputs to APT processing.
54      * The default value is "*.java".
55      */

56     public void setSrcExtensions(String JavaDoc srcExts)
57     {
58         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(srcExts, ",");
59         while (tok.hasMoreTokens())
60             _srcExts.add(tok.nextToken());
61     }
62     
63     /**
64      * The srcExtensions attribute can be set to a comma-separated list of processor options
65      * (of the form <i>option</i> or <i>option</i><code>=</code><i>value</i>) to be passed to
66      * APT.
67      */

68     public void setProcessorOptions(String JavaDoc processorOptions)
69     {
70         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(processorOptions, ",");
71         while (tok.hasMoreTokens())
72             _processorOptions.add(tok.nextToken());
73     }
74
75     /**
76      * The gendir attribute specifies the name of the output directory for any files generated
77      * as a result of calling APT.
78      */

79     public void setGendir(File JavaDoc genDir)
80     {
81         _genDir = genDir;
82     }
83
84     /**
85      * The nocompile attribute disables compilation of the input source file list and any
86      * generated sources that are derived from them. The default value is 'false'.
87      */

88     public void setNocompile(boolean nocompile)
89     {
90         _nocompile = nocompile;
91     }
92
93     /**
94      * The compileByExtension attribute causes each input source extension to be compiled
95      * independently (and sequentially). This is useful when one type of extensio can
96      * possibly depend upon the generation output from another. The default value 'false'.
97      */

98     public void setCompileByExtension(boolean compileByExt)
99     {
100         _compileByExt = compileByExt;
101     }
102
103     /**
104      * Override the implementation of scanDir, to look for additional files based upon any
105      * specified source extensions
106      */

107     protected void scanDir(File JavaDoc srcDir, File JavaDoc destDir, String JavaDoc[] files, String JavaDoc ext)
108     {
109         // If no source path was specified, we effectively created one by adding the generation
110
// path. Because of this, we need to be sure and add all source dirs to the path too.
111
if (!_hasSourcepath)
112         {
113             Path srcPath = new Path(getProject());
114             srcPath.setLocation(srcDir);
115             Path sp = getSourcepath();
116             sp.append(srcPath);
117             setSourcepath(sp);
118         }
119
120         GlobPatternMapper m = new GlobPatternMapper();
121         m.setFrom(ext);
122         m.setTo("*.class");
123         SourceFileScanner sfs = new SourceFileScanner(this);
124         if (ext.equals("*.java"))
125         {
126             File JavaDoc[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
127             if (newFiles.length > 0)
128             {
129                 File JavaDoc[] newCompileList = new File JavaDoc[compileList.length + newFiles.length];
130                 System.arraycopy(compileList, 0, newCompileList, 0, compileList.length);
131                 System.arraycopy(newFiles, 0, newCompileList, compileList.length,
132                                  newFiles.length);
133                 compileList = newCompileList;
134             }
135         }
136         else
137         {
138             String JavaDoc [] newSources = sfs.restrict(files, srcDir, destDir, m);
139             int extLen = ext.length() - 1; // strip wildcard
140
if (newSources.length > 0)
141             {
142                 File JavaDoc[] newCompileList = new File JavaDoc[compileList.length + newSources.length];
143                 System.arraycopy(compileList, 0, newCompileList, 0, compileList.length);
144                 try
145                 {
146                     FileUtils fileUtils = FileUtils.newFileUtils();
147                     for (int j = 0; j < newSources.length; j++)
148                     {
149                         String JavaDoc toName =
150                             newSources[j].substring(0, newSources[j].length() - extLen) +
151                             ".java";
152                                                                
153                         File JavaDoc srcFile = new File JavaDoc(srcDir, newSources[j]);
154                         File JavaDoc dstFile = new File JavaDoc(_genDir, toName);
155                         fileUtils.copyFile(srcFile, dstFile, null, true, true);
156                         newCompileList[compileList.length + j] = dstFile;
157                     }
158                 }
159                 catch (IOException JavaDoc ioe)
160                 {
161                     throw new BuildException("Unable to copy " + ext + " file", ioe,
162                                              getLocation());
163                 }
164                 compileList = newCompileList;
165             }
166         }
167     }
168
169     public void execute() throws BuildException
170     {
171         // Ensure that the gendir attribute was specified
172
if (_genDir == null)
173             throw new BuildException("Missing genDir attribute: must be set to codegen output directory", getLocation());
174
175
176         // If no source extension specified, then just process .java files
177
if (_srcExts.size() == 0)
178             _srcExts.add("*.java");
179
180         // Save whether a user sourcepath was provided, and if so, the paths
181
String JavaDoc[] userSourcepaths = null;
182         _hasSourcepath = getSourcepath() != null;
183         if ( _hasSourcepath )
184             userSourcepaths = getSourcepath().list();
185
186         // The generation dir is always added to the source path for compilation
187
Path genPath = new Path(getProject());
188         genPath.setLocation(_genDir);
189         setSourcepath(genPath);
190         
191         // If the user sourcepath specifies subdirs underneath the srcdir, then we need to add
192
// the corresponding subdirs under the gendir to the source path for compilation.
193
// For example, if the user sourcepath is "<webapp-root>;<webapp-root>\WEB-INF\src",
194
// then the sourcepath for compilation should include "<gen-dir>;<gen-dir>\WEB-INF\src".
195
if ( _hasSourcepath )
196         {
197             String JavaDoc genDirPath = _genDir.getAbsolutePath();
198             String JavaDoc srcDirPath = (getSrcdir().list())[0]; // TODO: handle multiple srcdirs
199
for ( String JavaDoc p: userSourcepaths )
200             {
201                 if ( p.startsWith( srcDirPath ) && p.length() > srcDirPath.length() )
202                 {
203                     File JavaDoc genDirElem = new File JavaDoc( _genDir, p.substring( srcDirPath.length()+1 ));
204                     Path gp = new Path(getProject());
205                     gp.setLocation( genDirElem );
206                     setSourcepath(gp);
207                 }
208             }
209         }
210
211         //
212
// Select the executable (apt) and set fork = true
213
//
214
setExecutable("apt");
215         setFork(true);
216
217         //
218
// Specify the code generation output directory to APT
219
//
220
Commandline.Argument arg = createCompilerArg();
221         arg.setValue("-s");
222         arg = createCompilerArg();
223         arg.setFile(_genDir);
224
225         //add the -nocompile flag if set to true
226
if(_nocompile)
227         {
228             Commandline.Argument ncarg = createCompilerArg();
229             ncarg.setValue("-nocompile");
230         }
231         
232         //
233
// Add processor options.
234
//
235
for (Object JavaDoc i : _processorOptions)
236         {
237             Commandline.Argument optionArg = createCompilerArg();
238             optionArg.setValue("-A" + i);
239         }
240
241         checkParameters();
242         resetFileLists();
243
244         // Iterate through the list of input extensions, matching/dependency checking based
245
// upon the input list.
246
for (int j = 0; j < _srcExts.size(); j++)
247         {
248             String JavaDoc ext = (String JavaDoc)_srcExts.get(j);
249             Vector JavaDoc<File JavaDoc> inputFiles = new Vector JavaDoc<File JavaDoc>();
250
251             // scan source directories and dest directory to build up
252
// compile lists
253
String JavaDoc[] list = getSrcdir().list();
254             File JavaDoc destDir = getDestdir();
255             for (int i = 0; i < list.length; i++)
256             {
257                 File JavaDoc srcFile = getProject().resolveFile(list[i]);
258                 if (!srcFile.exists()) {
259                     throw new BuildException("srcdir \""
260                                          + srcFile.getPath()
261                                          + "\" does not exist!", getLocation());
262                 }
263
264                 //
265
// The base <javac> algorithm is tweaked here, to allow <src> elements
266
// to contain a list of files _or_ a list of directories to scan.
267
//
268
if (srcFile.isDirectory())
269                 {
270                     DirectoryScanner ds = this.getDirectoryScanner(srcFile);
271                     String JavaDoc[] files = ds.getIncludedFiles();
272                     scanDir(srcFile, destDir != null ? destDir : srcFile, files, ext);
273                 }
274                 else
275                 {
276                     //
277
// BUGBUG: Because these bypass scanning, they also bypass dependency chks :(
278
//
279
if (srcFile.getPath().endsWith(ext.substring(1)))
280                         inputFiles.add(srcFile);
281                 }
282             }
283
284             if (inputFiles.size() != 0)
285             {
286                 File JavaDoc[] newCompileList = new File JavaDoc[compileList.length + inputFiles.size()];
287                 inputFiles.toArray(newCompileList);
288                 System.arraycopy(compileList, 0, newCompileList, inputFiles.size(),
289                              compileList.length);
290                 compileList = newCompileList;
291             }
292
293             //
294
// If processing/compiling on a per-extension basis, then handle the current list,
295
// then reset the list fo files to compile before moving to the next extension
296
//
297
if (_compileByExt)
298             {
299                 compile();
300                 resetFileLists();
301             }
302         }
303
304         //
305
// If not processing on a per-extension basis, then compile the entire aggregated list
306
//
307
if (!_compileByExt)
308             compile();
309     }
310
311     protected boolean _nocompile = false;
312     protected boolean _compileByExt = false;
313     protected boolean _hasSourcepath;
314     protected File JavaDoc _genDir;
315     protected Vector JavaDoc/*<String>*/ _srcExts = new Vector JavaDoc/*<String>*/();
316     protected Vector JavaDoc/*<String>*/ _processorOptions = new Vector JavaDoc/*<String>*/();
317 }
318
Popular Tags