KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > util > JythoncAntTask


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2002 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "The Jakarta Project", "Ant", and "Apache Software
27  * Foundation" must not be used to endorse or promote products derived
28  * from this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */

54 //package org.apache.tools.ant.taskdefs.optional.python;
55
package org.python.util;
56
57 import org.apache.tools.ant.taskdefs.MatchingTask;
58 import org.apache.tools.ant.BuildException;
59 import org.apache.tools.ant.taskdefs.Java;
60 import org.apache.tools.ant.types.Path;
61 import org.apache.tools.ant.DirectoryScanner;
62
63 import java.io.File JavaDoc;
64
65 /**
66  * Jythonc is a Python compiler into Java Bytecode. So you can
67  * call your python code from Java, and call you java code from
68  * Python, create bean, servlet...
69  *
70  * <p>
71  *
72  * The task is a directory based task, so attributes like <b>includes="*.py"</b> and
73  * <b>excludes="broken.py"</b> can be used to control the files pulled in. By default,
74  * all *.py files from the project folder down are included in the command.
75  *
76  * @author Cyrille Morvan - cmorvan@ingenosya.com - Ingenosya France
77  * @version 1.0
78  */

79 public class JythoncAntTask extends MatchingTask {
80
81   protected static final String JavaDoc JYTHONC_PY = "Tools/jythonc/jythonc.py";
82   protected static final String JavaDoc JYTHON_CLASS = "org.python.util.jython";
83
84   /**
85    * The classpath for the virtual machine.
86    */

87   protected Path classpath;
88
89   /**
90    * Put all compiled code into the named Java package.
91    */

92   protected String JavaDoc packageName;
93
94   /**
95    * Specifies a .jar file to create and put the results of
96    * the freeze into. Set the deep option to true.
97    */

98   protected File JavaDoc jarFile;
99
100   /**
101    * the compiler.
102    */

103   protected File JavaDoc jythoncpy;
104
105   /**
106    * Compile all Python dependencies of the module. This is
107    * used for creating applets.
108    */

109   protected boolean deep;
110
111   /**
112    * Include the core Jython libraries (about 130K).
113    * Needed for applets since Netscape doesn't yet support
114    * multiple archives.
115    */

116   protected boolean core;
117
118   /**
119    * Include all of the Jython libraries (everything in core + compiler and
120    * parser).
121    */

122   protected boolean all;
123
124   /**
125    * Include Java dependencies from this list of packages. Default is
126    * org.python.modules and org.apache.oro.text.regex.
127    */

128   protected String JavaDoc addpackages;
129
130   /**
131    * Compile into jarfile, including the correct manifest for the bean.
132    */

133   protected File JavaDoc jarFileBean;
134
135   /**
136    * Don't include any of these modules in compilation. This is a
137    * comma-separated list of modules.
138    */

139   protected String JavaDoc skipModule;
140
141   /**
142    * Compiler name.
143    */

144   protected String JavaDoc compiler;
145
146   /**
147    * Use a different compiler than `standard' javac. If this is set to "NONE"
148    * then compile ends with the generation of the Java source file.
149    * Alternatively, you can set the property python.jythonc.compiler in the
150    * registry.
151    */

152   protected String JavaDoc compileropts;
153
154   /**
155    * Options passed directly to the Java compiler. Alternatively, you can set
156    * the property python.jythonc.compileropts in the registry.
157    */

158   protected String JavaDoc falsenames;
159
160   /**
161    * Path to jython directory.
162    */

163   protected File JavaDoc jythonHome;
164
165   /**
166    * Destination, build directory.
167    */

168   protected File JavaDoc destDir;
169
170   /**
171    * Source directory.
172    */

173   protected File JavaDoc srcDir;
174
175   /**
176    * Specify the working directory where the generated Java source code is
177    * placed. Default is "./jpywork"
178    */

179   protected File JavaDoc workdir;
180
181   /**
182    * aditionnals args.
183    */

184   protected String JavaDoc extraArgs;
185
186   /**
187    * constructor set up the search pattern
188    */

189   public JythoncAntTask() {
190     setIncludes("**/*.py");
191   }
192
193   /**
194    * Add a classpath. Used to handle the nested classpath
195    * element.
196    * @return A Path object representing the classpath to be used.
197    */

198   public Path createClasspath() {
199     if(classpath == null) {
200       classpath = new Path(this.getProject());
201     }
202     return classpath.createPath();
203   }
204
205   /**
206    * Sets the classpath field.
207    * @param aClasspath A Path object representing the "classpath" attribute.
208    */

209   public void setClasspath(Path aClasspath) {
210     classpath = aClasspath;
211   }
212
213   /**
214    * Put all compiled code into the named Java package.
215    * @param aString the packake name.
216    */

217   public void setPackage(String JavaDoc aString) {
218     packageName = aString;
219   }
220
221   /**
222    * Specifies a .jar file to create and put the results of
223    * the freeze into. Set the deep option to true.
224    */

225   public void setJar(File JavaDoc aJarFile) {
226     jarFile = aJarFile;
227     deep = true;
228   }
229
230   /**
231    * Include the core Jython libraries (about 130K).
232    * Needed for applets since Netscape doesn't yet support
233    * multiple archives. Set the deep option to true.
234    */

235   public void setCore(boolean aValue) {
236     core = aValue;
237     deep = true;
238   }
239
240   /**
241    * Include all of the Jython libraries (everything in core + compiler and
242    * parser). Set the deep option to true.
243    */

244   public void setAll(boolean aValue) {
245     all = aValue;
246     deep = true;
247   }
248
249   /**
250    * Compile into jarfile, including the correct manifest for the bean.
251    */

252   public void setBean(File JavaDoc aJarFileBean) {
253     jarFileBean = aJarFileBean;
254   }
255
256   /**
257    * Don't include any of these modules in compilation. This is a
258    * comma-separated list of modules.
259    */

260   public void setSkip(String JavaDoc aValue) {
261     skipModule = aValue;
262   }
263
264   /**
265    * Compile all Python dependencies of the module. This is
266    * used for creating applets.
267    */

268   public void setDeep(boolean aValue) {
269     deep = aValue;
270   }
271
272
273   /**
274    * Include Java dependencies from this list of packages. Default is
275    * org.python.modules and org.apache.oro.text.regex.
276    */

277   public void setAddpackages(String JavaDoc aValue) {
278     addpackages = aValue;
279   }
280
281   /**
282    * Specify the working directory where the generated Java source code is
283    * placed. Default is "./jpywork"
284    */

285   public void setWorkdir(File JavaDoc aValue) {
286     if( aValue.exists() ) {
287       if( ! aValue.isDirectory() ) {
288         throw new BuildException( "Workdir ("+ aValue + ") is not a directory" );
289       }
290     } else {
291       aValue.mkdirs();
292     }
293     workdir = aValue;
294   }
295
296   /**
297    * Set the compiler.
298    */

299   public void setCompiler(String JavaDoc aCompiler) {
300     compiler = aCompiler;
301   }
302
303   /**
304    * Options passed directly to the Java compiler. Alternatively, you can set
305    * the property python.jythonc.compileropts in the registry.
306    */

307   public void setCompileropts(String JavaDoc aValue) {
308     compileropts = aValue;
309   }
310
311   /**
312    * A comma-separated list of names that are always false. Can be used to
313    * short-circuit if clauses.
314    */

315   public void setFalsenames(String JavaDoc aValue) {
316     falsenames = aValue;
317   }
318
319   /**
320    * Jython home directory.
321    */

322   public void setHome(File JavaDoc aFile) {
323     jythonHome = aFile;
324   }
325
326   /**
327    * Home for the source.
328    */

329   public void setSrcdir(File JavaDoc aFile) {
330     srcDir = aFile;
331   }
332
333   /**
334    * Home for the destination (build).
335    */

336   public void setDestdir(File JavaDoc aFile) {
337     destDir = aFile;
338   }
339
340   /**
341    * Change the default Python compiler.
342    */

343   public void setJythoncpy(File JavaDoc aValue) {
344     jythoncpy = aValue;
345   }
346
347   /**
348    * sets some additional args to send to jythonc.
349    */

350   public void setArgs(String JavaDoc aValue) {
351     extraArgs = aValue;
352   }
353
354   /**
355    * get the compiler option, null if none.
356    */

357   public String JavaDoc getCompilerOptions() {
358     StringBuffer JavaDoc aStringBuffer = new StringBuffer JavaDoc();
359     if( destDir != null ) {
360       aStringBuffer.append("-d \"");
361       aStringBuffer.append( destDir );
362       aStringBuffer.append("\"");
363
364       createClasspath().setLocation(destDir);
365       destDir.mkdirs();
366     }
367     if( compileropts != null ) {
368       aStringBuffer.append(compileropts);
369     }
370     if( aStringBuffer.length() == 0 ) {
371       return null;
372     } else {
373       return aStringBuffer.toString();
374     }
375   }
376
377   /**
378    * Get the path to the jython home (or python home)
379    */

380   public File JavaDoc getPythonHome() {
381     if(jythonHome == null ) {
382       String JavaDoc aPythonHome = getProject().getProperty("python.home");
383       if(aPythonHome == null ) {
384         throw new BuildException("No python.home or home specified");
385       }
386       jythonHome = new File JavaDoc(aPythonHome);
387     }
388     return jythonHome;
389   }
390
391   /**
392    * Get the path to the jython compiler file (in python).
393    */

394   public File JavaDoc getJythoncPY() {
395     if(jythoncpy == null ) {
396       return new File JavaDoc(getPythonHome(),JYTHONC_PY);
397     }
398     return jythoncpy;
399   }
400
401
402   /**
403    * Exectute the compiler.
404    */

405   public void execute() {
406     try {
407       Java javaTask = null;
408
409       javaTask = (Java)getProject().createTask("java");
410       javaTask.setTaskName("jythonc");
411
412       javaTask.setClassname( JYTHON_CLASS );
413
414       javaTask.createJvmarg().setValue( "-Dpython.home=" + getPythonHome() );
415
416       // classpath
417
File JavaDoc aJythonJarFile = new File JavaDoc(getPythonHome(), "jython.jar" );
418       createClasspath().setLocation(aJythonJarFile);
419
420       javaTask.setClasspath(classpath);
421
422       // jythonc file
423
javaTask.createArg().setFile( getJythoncPY() );
424
425       if( packageName != null ) {
426         javaTask.createArg().setValue("--package");
427         javaTask.createArg().setValue(packageName);
428       }
429
430       if( jarFile != null ) {
431         javaTask.createArg().setValue( "--jar" );
432         javaTask.createArg().setFile( jarFile );
433       }
434
435       if(deep) {
436         javaTask.createArg().setValue( "--deep" );
437       }
438
439       if(core) {
440         javaTask.createArg().setValue( "--core" );
441       }
442
443       if(all) {
444         javaTask.createArg().setValue( "--all" );
445       }
446
447       if( jarFileBean != null ) {
448         javaTask.createArg().setValue( "--bean" );
449         javaTask.createArg().setFile( jarFileBean );
450       }
451
452       if( addpackages != null ) {
453         javaTask.createArg().setValue( "--addpackages " );
454         javaTask.createArg().setValue( addpackages );
455       }
456
457       if( workdir != null ) {
458         javaTask.createArg().setValue( "--workdir " );
459         javaTask.createArg().setFile( workdir );
460       }
461
462       if( skipModule != null ) {
463         javaTask.createArg().setValue("--skip");
464         javaTask.createArg().setValue(skipModule);
465       }
466
467       // --compiler
468
if( compiler == null ) {
469         // try to use the compiler specified by build.compiler. Right now we are
470
// just going to allow Jikes
471
String JavaDoc buildCompiler = getProject().getProperty("build.compiler");
472         if (buildCompiler != null && buildCompiler.equals("jikes")) {
473             javaTask.createArg().setValue("--compiler");
474             javaTask.createArg().setValue("jikes");
475         }
476       } else {
477         javaTask.createArg().setValue("--compiler");
478         javaTask.createArg().setValue(compiler);
479       }
480
481       String JavaDoc aCompilerOpts = getCompilerOptions();
482       if( aCompilerOpts != null ) {
483         javaTask.createArg().setValue("--compileropts");
484         javaTask.createArg().setValue(aCompilerOpts);
485       }
486
487       if( falsenames != null ) {
488         javaTask.createArg().setValue("--falsenames");
489         javaTask.createArg().setValue(falsenames);
490       }
491
492       if( extraArgs != null ) {
493         javaTask.createArg().setLine(extraArgs);
494       }
495
496       //get dependencies list.
497
if( srcDir == null ) {
498         srcDir = project.resolveFile(".");
499       }
500       DirectoryScanner scanner = super.getDirectoryScanner(srcDir);
501       String JavaDoc[] dependencies = scanner.getIncludedFiles();
502       log("compiling " + dependencies.length + " file" +
503                          ((dependencies.length == 1)?"":"s"));
504       String JavaDoc baseDir = scanner.getBasedir().toString() + File.separator;
505       //add to the command
506
for (int i = 0; i < dependencies.length; i++) {
507           String JavaDoc targetFile = dependencies[i];
508           javaTask.createArg().setValue(baseDir + targetFile);
509       }
510
511       // change the location directory
512
javaTask.setDir(srcDir);
513       javaTask.setFork(true);
514       if (javaTask.executeJava() != 0) {
515           throw new BuildException("jythonc reported an error");
516       }
517     } catch (Exception JavaDoc e) {
518         // Have to catch this because of the semantics of calling main()
519
String JavaDoc msg = "Exception while calling " + JYTHON_CLASS + ". Details: " + e.toString();
520         throw new BuildException(msg, e);
521     }
522   }
523 }
524
525
Popular Tags