View Javadoc
1   /*
2    * Copyright 2005 Edward Kuns
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  package org.castor.xmlctf.compiler;
15  
16  import java.io.File;
17  import java.util.HashSet;
18  
19  import org.apache.tools.ant.BuildException;
20  import org.apache.tools.ant.Project;
21  import org.apache.tools.ant.taskdefs.Javac;
22  import org.apache.tools.ant.types.Path;
23  import org.castor.xmlctf.XMLTestCase;
24  import org.castor.xmlctf.util.FileServices;
25  
26  /**
27   * Compiles a directory tree, recursively. This class is built around the use of the ANT JAVAC task.
28   */
29  public class AntJavaCompiler implements Compiler {
30    /** A Set of directories to ignore. */
31    private static final HashSet IGNORE_DIRS = new HashSet();
32  
33    static {
34      IGNORE_DIRS.add(FileServices.CVS);
35      IGNORE_DIRS.add(FileServices.SVN);
36      IGNORE_DIRS.add("org");
37      IGNORE_DIRS.add("com");
38      IGNORE_DIRS.add("net");
39    }
40  
41    private final File _baseDirectory;
42    private final File _outputDirectory;
43  
44    private String _javaVersion = null;
45    private Javac _compiler;
46  
47    /**
48     * Creates a compiler for a given directory.
49     *
50     * @param baseDirectory The directory that holds the files to be compiled.
51     */
52    public AntJavaCompiler(final File baseDirectory) {
53      if (baseDirectory == null) {
54        throw new IllegalArgumentException("'baseDirectory' must not be null.");
55      }
56      _baseDirectory = baseDirectory;
57      _outputDirectory = baseDirectory;
58    }
59  
60    /**
61     * Sets the Java source version the current test will be using.
62     * 
63     * @param javaSourceVersion The Java Source version to be used.
64     */
65    public void setJavaSourceVersion(final float javaSourceVersion) {
66      float srcVersion = javaSourceVersion;
67      if (javaSourceVersion >= 5F && javaSourceVersion < 10F) {
68        srcVersion = 1.0F + (javaSourceVersion / 10F);
69      }
70      _javaVersion = "" + srcVersion;
71    }
72  
73    /**
74     * Compiles the content of a directory. Throws a <code>CompilationException</code> if the build
75     * fails.
76     */
77    public void compileDirectory() {
78      _compiler = makeCompiler(_baseDirectory, _outputDirectory);
79      compileDirectory(_baseDirectory, _outputDirectory);
80    }
81  
82    /**
83     * Creates and returns a Ant Javac compiler.
84     * 
85     * @param srcDir Source directory for compiation.
86     * @param destDir Destination directory for compilation.
87     *
88     * @return Ant Javac compiler
89     */
90    private Javac makeCompiler(final File srcDir, final File destDir) {
91      Project project = new Project();
92      project.init();
93      project.setBasedir(srcDir.getAbsolutePath());
94  
95      Javac compiler = new Javac();
96      compiler.setProject(project);
97      compiler.setDestdir(destDir.getAbsoluteFile());
98      compiler.setOptimize(false);
99      compiler.setDebug(true);
100     compiler.setDebugLevel("lines,vars,source");
101     compiler.setIncludejavaruntime(true);
102     if (XMLTestCase._verbose) {
103       compiler.setListfiles(true);
104       compiler.setVerbose(true);
105     } else {
106       compiler.setNowarn(true);
107     }
108     if (_javaVersion != null) {
109       compiler.setSource(_javaVersion);
110     }
111     Path classpath = compiler.createClasspath();
112     classpath.setPath(System.getProperty("java.class.path"));
113     classpath.add(new Path(project, destDir.getAbsolutePath()));
114     compiler.setClasspath(classpath);
115     return compiler;
116   }
117 
118   /**
119    * Compiles a directory tree. Throws a <code>CompilationException</code> if build fails.
120    *
121    * @param srcDir Source directory holding the files to be compiled.
122    * @param destDir Destination directory to put the compiled classes in.
123    */
124   private void compileDirectory(final File srcDir, final File destDir) {
125     File[] entries = srcDir.listFiles();
126     for (int i = 0; i < entries.length; i++) {
127       File entry = entries[i];
128       if (entry.isDirectory() && !IGNORE_DIRS.contains(entry.getName())) {
129         compileDirectory(entry, destDir);
130       }
131     }
132     entries = null;
133 
134     try {
135       Path srcPath = _compiler.createSrc();
136       srcPath.setLocation(destDir);
137       _compiler.setSrcdir(srcPath);
138       _compiler.execute();
139     } catch (BuildException ex) {
140       throw new CompilationException("Problem compiling directory " + srcDir, ex);
141     }
142   }
143 
144 }