1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.castor.xmlctf.compiler;
17
18 import java.io.File;
19 import java.lang.reflect.Method;
20 import java.util.ArrayList;
21 import java.util.HashSet;
22 import java.util.List;
23
24 import org.castor.xmlctf.XMLTestCase;
25 import org.castor.xmlctf.util.FileServices;
26
27
28
29
30
31
32
33
34
35
36
37 public class SunJavaCompiler implements Compiler {
38
39 private static final int COMPILATION_SUCCESS = 0;
40 private static final int COMPILATION_ERROR = 1;
41 private static final int COMPILATION_CMDERR = 2;
42 private static final int COMPILATION_SYSERR = 3;
43 private static final int COMPILATION_ABNORMAL = 4;
44
45 private static final String COMPILE_CLASSNAME = "com.sun.tools.javac.Main";
46 private static final String COMPILE_METHODNAME = "compile";
47 private static final Class[] COMPILE_PARAMTYPE = new Class[] {String[].class};
48
49 private static final HashSet IGNORE_DIRS = new HashSet();
50
51 private static Method _compileMethod = null;
52 private static boolean _initialized = false;
53
54 private static final float JAVA_VERSION = Float.parseFloat(System.getProperty("java.specification.version"));
55
56 private String _javaVersion = null;
57
58 private final File _baseDirectory;
59 private final File _outputDirectory;
60
61
62
63
64
65 public SunJavaCompiler(final File baseDirectory) {
66 if (baseDirectory == null) {
67 throw new IllegalArgumentException("'baseDirectory' must not be null.");
68 }
69 _baseDirectory = baseDirectory;
70 _outputDirectory = baseDirectory;
71
72 if (!_initialized) { initialize(); }
73 }
74
75
76
77
78
79 public void setJavaSourceVersion(final float javaSourceVersion) {
80 float srcVersion = javaSourceVersion;
81 if (javaSourceVersion >= 5F && javaSourceVersion < 10F) {
82 srcVersion = 1.0F + (javaSourceVersion / 10F);
83 }
84 _javaVersion = "" + srcVersion;
85 }
86
87
88
89
90 private void initialize() {
91 IGNORE_DIRS.add(FileServices.CVS);
92 IGNORE_DIRS.add(FileServices.SVN);
93
94 try {
95 ClassLoader loader = this.getClass().getClassLoader();
96 Class cls = loader.loadClass(COMPILE_CLASSNAME);
97 _compileMethod = cls.getMethod(COMPILE_METHODNAME, COMPILE_PARAMTYPE);
98 } catch (Exception ex) {
99 IllegalStateException ise = new IllegalStateException("Failed to find compile method.");
100 ise.initCause(ex);
101 throw ise;
102 }
103
104 _initialized = true;
105 }
106
107
108
109
110
111 public void compileDirectory() {
112 List filesList = findSourceFiles(_baseDirectory);
113 if (filesList.size() > 0) {
114 filesList.addAll(0, getCompileArguments(_baseDirectory, _outputDirectory));
115
116 String[] args = new String[filesList.size()];
117 args = (String[]) filesList.toArray(args);
118
119 int status;
120 try {
121 Object result = _compileMethod.invoke(null, new Object[] {args});
122 status = ((Integer) result).intValue();
123 } catch (Exception ex) {
124 throw new IllegalStateException("Failed to call compile method.");
125 }
126
127 switch (status) {
128 case COMPILATION_SUCCESS: break;
129 case COMPILATION_ERROR: throw new CompilationException("Compile status: ERROR");
130 case COMPILATION_CMDERR: throw new CompilationException("Compile status: CMDERR");
131 case COMPILATION_SYSERR: throw new CompilationException("Compile status: SYSERR");
132 case COMPILATION_ABNORMAL: throw new CompilationException("Compile status: ABNORMAL");
133 default: throw new CompilationException("Compile status: Unknown");
134 }
135 } else {
136 throw new CompilationException("No files to compile: " + _baseDirectory);
137 }
138 }
139
140
141
142
143
144
145
146 private List getCompileArguments(final File srcDir, final File destDir) {
147 List args = new ArrayList();
148
149 args.add("-g");
150 if (JAVA_VERSION == 1.5F) {
151 args.add("-Xlint:unchecked");
152 }
153 if (XMLTestCase._verbose) {
154 args.add("-verbose");
155 } else {
156 args.add("-nowarn");
157 args.add("-Xmaxwarns");
158 args.add("0");
159 args.add("-Xmaxerrs");
160 args.add("5");
161 }
162 if (_javaVersion != null) {
163 args.add("-source");
164 args.add(_javaVersion);
165 }
166 args.add("-classpath");
167 String classPathOverriden = System.getProperty("xmlctf.classpath.override");
168 if (classPathOverriden != null) {
169 args.add(classPathOverriden + ";" + destDir.getAbsolutePath());
170 } else {
171 args.add(System.getProperty("java.class.path") + ";" + destDir.getAbsolutePath());
172 }
173 args.add("-d");
174 args.add(destDir.getAbsolutePath());
175 args.add("-sourcepath");
176 args.add(srcDir.getAbsolutePath());
177 return args;
178 }
179
180
181
182
183
184
185 private List findSourceFiles(final File srcDir) {
186 List files = new ArrayList();
187
188 File[] entries = srcDir.listFiles();
189 for (int i = 0; i < entries.length; i++) {
190 File entry = entries[i];
191 if (entry.getName().endsWith(".java")) {
192 files.add(entry.getAbsolutePath());
193 } else if (entry.isDirectory() && !IGNORE_DIRS.contains(entry.getName())) {
194 files.addAll(findSourceFiles(entry));
195 }
196 }
197
198 return files;
199 }
200
201 }