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