KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > compilers > DefaultCompilerAdapter


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs.compilers;
20
21 //Java5 style
22
//import static org.apache.tools.ant.util.StringUtils.LINE_SEP;
23

24 import java.io.File JavaDoc;
25 import java.io.FileWriter JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.PrintWriter JavaDoc;
28 import org.apache.tools.ant.BuildException;
29 import org.apache.tools.ant.Location;
30 import org.apache.tools.ant.Project;
31 import org.apache.tools.ant.taskdefs.Execute;
32 import org.apache.tools.ant.taskdefs.Javac;
33 import org.apache.tools.ant.taskdefs.LogStreamHandler;
34 import org.apache.tools.ant.types.Commandline;
35 import org.apache.tools.ant.types.Path;
36 import org.apache.tools.ant.util.FileUtils;
37 import org.apache.tools.ant.util.StringUtils;
38 import org.apache.tools.ant.util.JavaEnvUtils;
39 import org.apache.tools.ant.taskdefs.condition.Os;
40
41 /**
42  * This is the default implementation for the CompilerAdapter interface.
43  * Currently, this is a cut-and-paste of the original javac task.
44  *
45  * @since Ant 1.3
46  */

47 public abstract class DefaultCompilerAdapter implements CompilerAdapter {
48     // CheckStyle:VisibilityModifier OFF - bc
49

50     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
51
52     protected Path src;
53     protected File JavaDoc destDir;
54     protected String JavaDoc encoding;
55     protected boolean debug = false;
56     protected boolean optimize = false;
57     protected boolean deprecation = false;
58     protected boolean depend = false;
59     protected boolean verbose = false;
60     protected String JavaDoc target;
61     protected Path bootclasspath;
62     protected Path extdirs;
63     protected Path compileClasspath;
64     protected Path compileSourcepath;
65     protected Project project;
66     protected Location location;
67     protected boolean includeAntRuntime;
68     protected boolean includeJavaRuntime;
69     protected String JavaDoc memoryInitialSize;
70     protected String JavaDoc memoryMaximumSize;
71
72     protected File JavaDoc[] compileList;
73     protected Javac attributes;
74
75     //must keep for subclass BC, though unused:
76
// CheckStyle:ConstantNameCheck OFF - bc
77
protected static final String JavaDoc lSep = StringUtils.LINE_SEP;
78
79     // CheckStyle:ConstantNameCheck ON
80
// CheckStyle:VisibilityModifier ON
81

82     /**
83      * Set the Javac instance which contains the configured compilation
84      * attributes.
85      *
86      * @param attributes a configured Javac task.
87      */

88     public void setJavac(Javac attributes) {
89         this.attributes = attributes;
90         src = attributes.getSrcdir();
91         destDir = attributes.getDestdir();
92         encoding = attributes.getEncoding();
93         debug = attributes.getDebug();
94         optimize = attributes.getOptimize();
95         deprecation = attributes.getDeprecation();
96         depend = attributes.getDepend();
97         verbose = attributes.getVerbose();
98         target = attributes.getTarget();
99         bootclasspath = attributes.getBootclasspath();
100         extdirs = attributes.getExtdirs();
101         compileList = attributes.getFileList();
102         compileClasspath = attributes.getClasspath();
103         compileSourcepath = attributes.getSourcepath();
104         project = attributes.getProject();
105         location = attributes.getLocation();
106         includeAntRuntime = attributes.getIncludeantruntime();
107         includeJavaRuntime = attributes.getIncludejavaruntime();
108         memoryInitialSize = attributes.getMemoryInitialSize();
109         memoryMaximumSize = attributes.getMemoryMaximumSize();
110     }
111
112     /**
113      * Get the Javac task instance associated with this compiler adapter
114      *
115      * @return the configured Javac task instance used by this adapter.
116      */

117     public Javac getJavac() {
118         return attributes;
119     }
120
121     /**
122      * Get the project this compiler adapter was created in.
123      * @return the owner project
124      * @since Ant 1.6
125      */

126     protected Project getProject() {
127         return project;
128     }
129
130     /**
131      * Builds the compilation classpath.
132      * @return the compilation class path
133      */

134     protected Path getCompileClasspath() {
135         Path classpath = new Path(project);
136
137         // add dest dir to classpath so that previously compiled and
138
// untouched classes are on classpath
139

140         if (destDir != null) {
141             classpath.setLocation(destDir);
142         }
143
144         // Combine the build classpath with the system classpath, in an
145
// order determined by the value of build.sysclasspath
146

147         Path cp = compileClasspath;
148         if (cp == null) {
149             cp = new Path(project);
150         }
151         if (includeAntRuntime) {
152             classpath.addExisting(cp.concatSystemClasspath("last"));
153         } else {
154             classpath.addExisting(cp.concatSystemClasspath("ignore"));
155         }
156
157         if (includeJavaRuntime) {
158             classpath.addJavaRuntime();
159         }
160
161         return classpath;
162     }
163
164     /**
165      * Get the command line arguments for the switches.
166      * @param cmd the command line
167      * @return the command line
168      */

169     protected Commandline setupJavacCommandlineSwitches(Commandline cmd) {
170         return setupJavacCommandlineSwitches(cmd, false);
171     }
172
173     /**
174      * Does the command line argument processing common to classic and
175      * modern. Doesn't add the files to compile.
176      * @param cmd the command line
177      * @param useDebugLevel if true set set the debug level with the -g switch
178      * @return the command line
179      */

180     protected Commandline setupJavacCommandlineSwitches(Commandline cmd,
181                                                         boolean useDebugLevel) {
182         Path classpath = getCompileClasspath();
183         // For -sourcepath, use the "sourcepath" value if present.
184
// Otherwise default to the "srcdir" value.
185
Path sourcepath = null;
186         if (compileSourcepath != null) {
187             sourcepath = compileSourcepath;
188         } else {
189             sourcepath = src;
190         }
191
192         String JavaDoc memoryParameterPrefix = assumeJava11() ? "-J-" : "-J-X";
193         if (memoryInitialSize != null) {
194             if (!attributes.isForkedJavac()) {
195                 attributes.log("Since fork is false, ignoring "
196                                + "memoryInitialSize setting.",
197                                Project.MSG_WARN);
198             } else {
199                 cmd.createArgument().setValue(memoryParameterPrefix
200                                               + "ms" + memoryInitialSize);
201             }
202         }
203
204         if (memoryMaximumSize != null) {
205             if (!attributes.isForkedJavac()) {
206                 attributes.log("Since fork is false, ignoring "
207                                + "memoryMaximumSize setting.",
208                                Project.MSG_WARN);
209             } else {
210                 cmd.createArgument().setValue(memoryParameterPrefix
211                                               + "mx" + memoryMaximumSize);
212             }
213         }
214
215         if (attributes.getNowarn()) {
216             cmd.createArgument().setValue("-nowarn");
217         }
218
219         if (deprecation) {
220             cmd.createArgument().setValue("-deprecation");
221         }
222
223         if (destDir != null) {
224             cmd.createArgument().setValue("-d");
225             cmd.createArgument().setFile(destDir);
226         }
227
228         cmd.createArgument().setValue("-classpath");
229
230         // Just add "sourcepath" to classpath ( for JDK1.1 )
231
// as well as "bootclasspath" and "extdirs"
232
if (assumeJava11()) {
233             Path cp = new Path(project);
234
235             Path bp = getBootClassPath();
236             if (bp.size() > 0) {
237                 cp.append(bp);
238             }
239
240             if (extdirs != null) {
241                 cp.addExtdirs(extdirs);
242             }
243             cp.append(classpath);
244             cp.append(sourcepath);
245             cmd.createArgument().setPath(cp);
246         } else {
247             cmd.createArgument().setPath(classpath);
248             // If the buildfile specifies sourcepath="", then don't
249
// output any sourcepath.
250
if (sourcepath.size() > 0) {
251                 cmd.createArgument().setValue("-sourcepath");
252                 cmd.createArgument().setPath(sourcepath);
253             }
254             if (target != null) {
255                 cmd.createArgument().setValue("-target");
256                 cmd.createArgument().setValue(target);
257             }
258
259             Path bp = getBootClassPath();
260             if (bp.size() > 0) {
261                 cmd.createArgument().setValue("-bootclasspath");
262                 cmd.createArgument().setPath(bp);
263             }
264
265             if (extdirs != null && extdirs.size() > 0) {
266                 cmd.createArgument().setValue("-extdirs");
267                 cmd.createArgument().setPath(extdirs);
268             }
269         }
270
271         if (encoding != null) {
272             cmd.createArgument().setValue("-encoding");
273             cmd.createArgument().setValue(encoding);
274         }
275         if (debug) {
276             if (useDebugLevel && !assumeJava11()) {
277                 String JavaDoc debugLevel = attributes.getDebugLevel();
278                 if (debugLevel != null) {
279                     cmd.createArgument().setValue("-g:" + debugLevel);
280                 } else {
281                     cmd.createArgument().setValue("-g");
282                 }
283             } else {
284                 cmd.createArgument().setValue("-g");
285             }
286         } else if (getNoDebugArgument() != null) {
287             cmd.createArgument().setValue(getNoDebugArgument());
288         }
289         if (optimize) {
290             cmd.createArgument().setValue("-O");
291         }
292
293         if (depend) {
294             if (assumeJava11()) {
295                 cmd.createArgument().setValue("-depend");
296             } else if (assumeJava12()) {
297                 cmd.createArgument().setValue("-Xdepend");
298             } else {
299                 attributes.log("depend attribute is not supported by the "
300                                + "modern compiler", Project.MSG_WARN);
301             }
302         }
303
304         if (verbose) {
305             cmd.createArgument().setValue("-verbose");
306         }
307
308         addCurrentCompilerArgs(cmd);
309
310         return cmd;
311     }
312
313     /**
314      * Does the command line argument processing for modern. Doesn't
315      * add the files to compile.
316      * @param cmd the command line
317      * @return the command line
318      */

319     protected Commandline setupModernJavacCommandlineSwitches(Commandline cmd) {
320         setupJavacCommandlineSwitches(cmd, true);
321         if (attributes.getSource() != null && !assumeJava13()) {
322             cmd.createArgument().setValue("-source");
323             String JavaDoc source = attributes.getSource();
324             if ((assumeJava14() || assumeJava15())
325                 && (source.equals("1.1") || source.equals("1.2"))) {
326                 // support for -source 1.1 and -source 1.2 has been
327
// added with JDK 1.4.2 - and isn't present in 1.5.0 either
328
cmd.createArgument().setValue("1.3");
329             } else {
330                 cmd.createArgument().setValue(source);
331             }
332         } else if ((assumeJava15() || assumeJava16())
333                    && attributes.getTarget() != null) {
334             String JavaDoc t = attributes.getTarget();
335             if (t.equals("1.1") || t.equals("1.2") || t.equals("1.3")
336                 || t.equals("1.4")) {
337                 String JavaDoc s = t;
338                 if (t.equals("1.1")) {
339                     // 1.5.0 doesn't support -source 1.1
340
s = "1.2";
341                 }
342                 attributes.log("", Project.MSG_WARN);
343                 attributes.log(" WARNING", Project.MSG_WARN);
344                 attributes.log("", Project.MSG_WARN);
345                 attributes.log("The -source switch defaults to 1.5 in JDK 1.5 and 1.6.",
346                                Project.MSG_WARN);
347                 attributes.log("If you specify -target " + t
348                                + " you now must also specify -source " + s
349                                + ".", Project.MSG_WARN);
350                 attributes.log("Ant will implicitly add -source " + s
351                                + " for you. Please change your build file.",
352                                Project.MSG_WARN);
353                 cmd.createArgument().setValue("-source");
354                 cmd.createArgument().setValue(s);
355             }
356         }
357         return cmd;
358     }
359
360     /**
361      * Does the command line argument processing for modern and adds
362      * the files to compile as well.
363      * @return the command line
364      */

365     protected Commandline setupModernJavacCommand() {
366         Commandline cmd = new Commandline();
367         setupModernJavacCommandlineSwitches(cmd);
368
369         logAndAddFilesToCompile(cmd);
370         return cmd;
371     }
372
373     /**
374      * Set up the command line.
375      * @return the command line
376      */

377     protected Commandline setupJavacCommand() {
378         return setupJavacCommand(false);
379     }
380
381     /**
382      * Does the command line argument processing for classic and adds
383      * the files to compile as well.
384      * @param debugLevelCheck if true set the debug level with the -g switch
385      * @return the command line
386      */

387     protected Commandline setupJavacCommand(boolean debugLevelCheck) {
388         Commandline cmd = new Commandline();
389         setupJavacCommandlineSwitches(cmd, debugLevelCheck);
390         logAndAddFilesToCompile(cmd);
391         return cmd;
392     }
393
394     /**
395      * Logs the compilation parameters, adds the files to compile and logs the
396      * "niceSourceList"
397      * @param cmd the command line
398      */

399     protected void logAndAddFilesToCompile(Commandline cmd) {
400         attributes.log("Compilation " + cmd.describeArguments(),
401                        Project.MSG_VERBOSE);
402
403         StringBuffer JavaDoc niceSourceList = new StringBuffer JavaDoc("File");
404         if (compileList.length != 1) {
405             niceSourceList.append("s");
406         }
407         niceSourceList.append(" to be compiled:");
408
409         niceSourceList.append(StringUtils.LINE_SEP);
410
411         for (int i = 0; i < compileList.length; i++) {
412             String JavaDoc arg = compileList[i].getAbsolutePath();
413             cmd.createArgument().setValue(arg);
414             niceSourceList.append(" ");
415             niceSourceList.append(arg);
416             niceSourceList.append(StringUtils.LINE_SEP);
417         }
418
419         attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
420     }
421
422     /**
423      * Do the compile with the specified arguments.
424      * @param args - arguments to pass to process on command line
425      * @param firstFileName - index of the first source file in args,
426      * if the index is negative, no temporary file will ever be
427      * created, but this may hit the command line length limit on your
428      * system.
429      * @return the exit code of the compilation
430      */

431     protected int executeExternalCompile(String JavaDoc[] args, int firstFileName) {
432         return executeExternalCompile(args, firstFileName, true);
433     }
434
435     /**
436      * Do the compile with the specified arguments.
437      * @param args - arguments to pass to process on command line
438      * @param firstFileName - index of the first source file in args,
439      * if the index is negative, no temporary file will ever be
440      * created, but this may hit the command line length limit on your
441      * system.
442      * @param quoteFiles - if set to true, filenames containing
443      * spaces will be quoted when they appear in the external file.
444      * This is necessary when running JDK 1.4's javac and probably
445      * others.
446      * @return the exit code of the compilation
447      *
448      * @since Ant 1.6
449      */

450     protected int executeExternalCompile(String JavaDoc[] args, int firstFileName,
451                                          boolean quoteFiles) {
452         String JavaDoc[] commandArray = null;
453         File JavaDoc tmpFile = null;
454
455         try {
456             /*
457              * Many system have been reported to get into trouble with
458              * long command lines - no, not only Windows ;-).
459              *
460              * POSIX seems to define a lower limit of 4k, so use a temporary
461              * file if the total length of the command line exceeds this limit.
462              */

463             if (Commandline.toString(args).length() > 4096
464                 && firstFileName >= 0) {
465                 PrintWriter JavaDoc out = null;
466                 try {
467                     tmpFile = FILE_UTILS.createTempFile(
468                         "files", "", getJavac().getTempdir());
469                     tmpFile.deleteOnExit();
470                     out = new PrintWriter JavaDoc(new FileWriter JavaDoc(tmpFile));
471                     for (int i = firstFileName; i < args.length; i++) {
472                         if (quoteFiles && args[i].indexOf(" ") > -1) {
473                             args[i] = args[i].replace(File.separatorChar, '/');
474                             out.println("\"" + args[i] + "\"");
475                         } else {
476                             out.println(args[i]);
477                         }
478                     }
479                     out.flush();
480                     commandArray = new String JavaDoc[firstFileName + 1];
481                     System.arraycopy(args, 0, commandArray, 0, firstFileName);
482                     commandArray[firstFileName] = "@" + tmpFile;
483                 } catch (IOException JavaDoc e) {
484                     throw new BuildException("Error creating temporary file",
485                                              e, location);
486                 } finally {
487                     FileUtils.close(out);
488                 }
489             } else {
490                 commandArray = args;
491             }
492
493             try {
494                 Execute exe = new Execute(
495                                   new LogStreamHandler(attributes,
496                                                        Project.MSG_INFO,
497                                                        Project.MSG_WARN));
498                 if (Os.isFamily("openvms")) {
499                     //Use the VM launcher instead of shell launcher on VMS
500
//for java
501
exe.setVMLauncher(true);
502                 }
503                 exe.setAntRun(project);
504                 exe.setWorkingDirectory(project.getBaseDir());
505                 exe.setCommandline(commandArray);
506                 exe.execute();
507                 return exe.getExitValue();
508             } catch (IOException JavaDoc e) {
509                 throw new BuildException("Error running " + args[0]
510                         + " compiler", e, location);
511             }
512         } finally {
513             if (tmpFile != null) {
514                 tmpFile.delete();
515             }
516         }
517     }
518
519     /**
520      * Add extdirs to classpath
521      * @param classpath the classpath to use
522      * @deprecated since 1.5.x.
523      * Use org.apache.tools.ant.types.Path#addExtdirs instead.
524      */

525     protected void addExtdirsToClasspath(Path classpath) {
526         classpath.addExtdirs(extdirs);
527     }
528
529     /**
530      * Adds the command line arguments specific to the current implementation.
531      * @param cmd the command line to use
532      */

533     protected void addCurrentCompilerArgs(Commandline cmd) {
534         cmd.addArguments(getJavac().getCurrentCompilerArgs());
535     }
536
537     /**
538      * Shall we assume JDK 1.1 command line switches?
539      * @return true if jdk 1.1
540      * @since Ant 1.5
541      */

542     protected boolean assumeJava11() {
543         return "javac1.1".equals(attributes.getCompilerVersion());
544     }
545
546     /**
547      * Shall we assume JDK 1.2 command line switches?
548      * @return true if jdk 1.2
549      * @since Ant 1.5
550      */

551     protected boolean assumeJava12() {
552         return "javac1.2".equals(attributes.getCompilerVersion())
553             || ("classic".equals(attributes.getCompilerVersion())
554                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2))
555             || ("extJavac".equals(attributes.getCompilerVersion())
556                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2));
557     }
558
559     /**
560      * Shall we assume JDK 1.3 command line switches?
561      * @return true if jdk 1.3
562      * @since Ant 1.5
563      */

564     protected boolean assumeJava13() {
565         return "javac1.3".equals(attributes.getCompilerVersion())
566             || ("classic".equals(attributes.getCompilerVersion())
567                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3))
568             || ("modern".equals(attributes.getCompilerVersion())
569                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3))
570             || ("extJavac".equals(attributes.getCompilerVersion())
571                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3));
572     }
573
574     /**
575      * Shall we assume JDK 1.4 command line switches?
576      * @return true if jdk 1.4
577      * @since Ant 1.6.3
578      */

579     protected boolean assumeJava14() {
580         return "javac1.4".equals(attributes.getCompilerVersion())
581             || ("classic".equals(attributes.getCompilerVersion())
582                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4))
583             || ("modern".equals(attributes.getCompilerVersion())
584                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4))
585             || ("extJavac".equals(attributes.getCompilerVersion())
586                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4));
587     }
588
589     /**
590      * Shall we assume JDK 1.5 command line switches?
591      * @return true if JDK 1.5
592      * @since Ant 1.6.3
593      */

594     protected boolean assumeJava15() {
595         return "javac1.5".equals(attributes.getCompilerVersion())
596             || ("classic".equals(attributes.getCompilerVersion())
597                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5))
598             || ("modern".equals(attributes.getCompilerVersion())
599                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5))
600             || ("extJavac".equals(attributes.getCompilerVersion())
601                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5));
602     }
603
604     /**
605      * Shall we assume JDK 1.6 command line switches?
606      * @return true if JDK 1.6
607      * @since Ant 1.7
608      */

609     protected boolean assumeJava16() {
610         return "javac1.6".equals(attributes.getCompilerVersion())
611             || ("classic".equals(attributes.getCompilerVersion())
612                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6))
613             || ("modern".equals(attributes.getCompilerVersion())
614                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6))
615             || ("extJavac".equals(attributes.getCompilerVersion())
616                 && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6));
617     }
618
619     /**
620      * Combines a user specified bootclasspath with the system
621      * bootclasspath taking build.sysclasspath into account.
622      *
623      * @return a non-null Path instance that combines the user
624      * specified and the system bootclasspath.
625      */

626     protected Path getBootClassPath() {
627         Path bp = new Path(project);
628         if (bootclasspath != null) {
629             bp.append(bootclasspath);
630         }
631         return bp.concatSystemBootClasspath("ignore");
632     }
633
634     /**
635      * The argument the compiler wants to see if the debug attribute
636      * has been set to false.
637      *
638      * <p>A return value of <code>null</code> means no argument at all.</p>
639      *
640      * @return "-g:none" unless we expect to invoke a JDK 1.1 compiler.
641      *
642      * @since Ant 1.6.3
643      */

644     protected String JavaDoc getNoDebugArgument() {
645         return assumeJava11() ? null : "-g:none";
646     }
647 }
648
649
Popular Tags