1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
|
|
22 |
|
package net.sf.infrared.tools.ant; |
23 |
|
|
24 |
|
import java.io.File; |
25 |
|
import java.io.IOException; |
26 |
|
import java.util.ArrayList; |
27 |
|
import java.util.Collections; |
28 |
|
import java.util.Iterator; |
29 |
|
import java.util.List; |
30 |
|
import net.sf.infrared.tools.util.JarHelper; |
31 |
|
import org.apache.commons.io.FileUtils; |
32 |
|
import org.apache.tools.ant.BuildException; |
33 |
|
import org.apache.tools.ant.DirectoryScanner; |
34 |
|
import org.apache.tools.ant.Project; |
35 |
|
import org.apache.tools.ant.types.PatternSet; |
36 |
|
|
37 |
|
|
38 |
|
|
39 |
|
|
40 |
|
|
41 |
|
public class ModuleType { |
42 |
0 |
private static String WEB_INF_CLASSES = "WEB-INF" + File.separator + "classes"; |
43 |
|
|
44 |
0 |
private static String WEB_INF_LIB = "WEB-INF" + File.separator + "lib"; |
45 |
|
|
46 |
|
private Project project; |
47 |
|
|
48 |
|
private String type; |
49 |
|
|
50 |
|
private String name; |
51 |
|
|
52 |
0 |
private PatternSet patterns = new PatternSet(); |
53 |
|
|
54 |
|
private File appDir; |
55 |
|
|
56 |
|
private DirectoryScanner ds; |
57 |
|
|
58 |
|
private File moduleDir; |
59 |
|
|
60 |
0 |
private List jarsToInstrument = new ArrayList(); |
61 |
|
|
62 |
0 |
private List classesToInstrument = new ArrayList(); |
63 |
|
|
64 |
0 |
private List packagesToInstrument = new ArrayList(); |
65 |
|
|
66 |
0 |
private boolean wasExploded = false; |
67 |
|
|
68 |
|
private Logger log; |
69 |
|
|
70 |
|
public void setLogger(Logger log) { |
71 |
0 |
this.log = log; |
72 |
0 |
} |
73 |
|
|
74 |
|
public Logger getLogger() { |
75 |
0 |
return this.log; |
76 |
|
} |
77 |
|
|
78 |
0 |
public ModuleType(Project project) { |
79 |
0 |
this.project = project; |
80 |
0 |
} |
81 |
|
|
82 |
|
public void setType(String type) { |
83 |
0 |
this.type = type; |
84 |
0 |
} |
85 |
|
|
86 |
|
public void setName(String name) { |
87 |
0 |
this.name = name; |
88 |
0 |
} |
89 |
|
|
90 |
|
public String getName() { |
91 |
0 |
return this.name; |
92 |
|
} |
93 |
|
|
94 |
|
public PatternSet.NameEntry createInclude() { |
95 |
0 |
return patterns.createInclude(); |
96 |
|
} |
97 |
|
|
98 |
|
public void setIncludes(String includes) { |
99 |
0 |
patterns.setIncludes(includes); |
100 |
0 |
} |
101 |
|
|
102 |
|
public PatternSet.NameEntry createExclude() { |
103 |
0 |
return patterns.createExclude(); |
104 |
|
} |
105 |
|
|
106 |
|
public void setExcludes(String excludes) { |
107 |
0 |
patterns.setExcludes(excludes); |
108 |
0 |
} |
109 |
|
|
110 |
|
public void setup(File dir) { |
111 |
0 |
setApplicationDir(dir); |
112 |
0 |
explodeIfNeeded(); |
113 |
0 |
setupDirectoryScanner(); |
114 |
0 |
findClassesAndJarsToInstrument(); |
115 |
0 |
} |
116 |
|
|
117 |
|
public List getApplicationClasspath() { |
118 |
0 |
List appClassPath = new ArrayList(); |
119 |
|
|
120 |
0 |
if ("war".equalsIgnoreCase(type)) { |
121 |
0 |
File web_inf = new File(moduleDir, "WEB-INF"); |
122 |
0 |
appClassPath.add(new File(web_inf, "classes")); |
123 |
0 |
File web_inf_lib = new File(web_inf, "lib"); |
124 |
0 |
appClassPath.addAll(FileUtils.listFiles(web_inf_lib, |
125 |
|
new String[] {"jar", "zip"}, false)); |
126 |
0 |
} else if ( ("jar".equalsIgnoreCase(type)) |
127 |
|
|| ("java".equalsIgnoreCase(type)) |
128 |
|
|| ("classes".equalsIgnoreCase(type)) |
129 |
|
|| ("ejb".equalsIgnoreCase(type))) { |
130 |
0 |
appClassPath.add(moduleDir); |
131 |
|
} |
132 |
|
|
133 |
0 |
return appClassPath; |
134 |
|
} |
135 |
|
|
136 |
|
public List getJarsToInstrument() { |
137 |
0 |
return jarsToInstrument; |
138 |
|
} |
139 |
|
|
140 |
|
public List getClassesToInstrument() { |
141 |
0 |
return classesToInstrument; |
142 |
|
} |
143 |
|
|
144 |
|
public List getPackagesToInstrument() { |
145 |
0 |
return packagesToInstrument; |
146 |
|
} |
147 |
|
|
148 |
|
public File getRootDir() { |
149 |
0 |
return moduleDir; |
150 |
|
} |
151 |
|
|
152 |
|
public void cleanup() { |
153 |
0 |
if (wasExploded) { |
154 |
0 |
File module = new File(getApplicationDir(), getName()); |
155 |
|
try { |
156 |
0 |
FileUtils.forceDelete(module); |
157 |
0 |
new JarHelper().jarDir(getModuleDir(), module); |
158 |
0 |
getLogger().verbose("\t[MODULE:"+ getName() + "] Archived backup " + |
159 |
|
getModuleDir().getAbsolutePath() + " to " + module.getAbsolutePath()); |
160 |
0 |
} catch (IOException ex) { |
161 |
0 |
throw new BuildException("Failed to rearchive " + getName() + |
162 |
|
" in " + getApplicationDir(), ex); |
163 |
0 |
} |
164 |
|
|
165 |
|
try { |
166 |
0 |
FileUtils.forceDelete(getModuleDir()); |
167 |
0 |
getLogger().verbose("\t[MODULE:"+ getName() + "] Deleted backup " + |
168 |
|
getModuleDir().getAbsolutePath()); |
169 |
0 |
} catch (IOException ex) { |
170 |
|
|
171 |
|
|
172 |
0 |
getLogger().error("Failed to delete temporary exploded directory " + |
173 |
|
getModuleDir().getAbsolutePath() + " in " + getApplicationDir()); |
174 |
0 |
} |
175 |
|
} |
176 |
0 |
} |
177 |
|
|
178 |
|
public void setApplicationDir(File dir) { |
179 |
0 |
this.appDir = dir; |
180 |
0 |
} |
181 |
|
|
182 |
|
public File getApplicationDir() { |
183 |
0 |
return this.appDir; |
184 |
|
} |
185 |
|
|
186 |
|
public File getModuleDir() { |
187 |
0 |
return moduleDir; |
188 |
|
} |
189 |
|
|
190 |
|
public void appendToManifestClassPath(String cp) { |
191 |
0 |
File manifestDotMf = ensureManifestDotMfExists(); |
192 |
|
|
193 |
0 |
String encoding = null; |
194 |
0 |
List manifestLines = Collections.EMPTY_LIST; |
195 |
|
try { |
196 |
0 |
manifestLines = FileUtils.readLines(manifestDotMf, encoding); |
197 |
0 |
} catch (IOException ex) { |
198 |
0 |
throw new RuntimeException("Failed to read MANIFEST.MF from " + |
199 |
|
manifestDotMf.getAbsolutePath(), ex); |
200 |
0 |
} |
201 |
|
|
202 |
0 |
for(int i = 0; i < manifestLines.size(); i++){ |
203 |
0 |
if(((String)manclass="keyword">ifestLines.get(i)).startsWith("Class-Path: ")){ |
204 |
0 |
StringBuffer buffer = new StringBuffer((String)manifestLines.get(i)); |
205 |
0 |
buffer.append(" "); |
206 |
0 |
buffer.append(cp); |
207 |
0 |
manifestLines.set(i, buffer.toString()); |
208 |
|
} |
209 |
|
else{ |
210 |
0 |
manifestLines.add("Class-Path: " + cp); |
211 |
|
} |
212 |
|
} |
213 |
|
|
214 |
|
|
215 |
|
|
216 |
|
|
217 |
|
|
218 |
|
|
219 |
|
|
220 |
|
|
221 |
|
|
222 |
|
|
223 |
|
|
224 |
|
|
225 |
0 |
if(manclass="keyword">ifestLines.size() == 0){ |
226 |
0 |
manifestLines.add("Class-Path: " + cp); |
227 |
|
} |
228 |
|
|
229 |
|
|
230 |
|
try { |
231 |
0 |
FileUtils.writeLines(manifestDotMf, encoding, manifestLines); |
232 |
0 |
} catch (IOException ex) { |
233 |
0 |
throw new RuntimeException("Failed to edit MANIFEST.MF at " + |
234 |
|
manifestDotMf.getAbsolutePath(), ex); |
235 |
0 |
} |
236 |
0 |
getLogger().verbose("\t[MODULE:"+ getName() + "] Added " + cp + " to MANIFEST classpath"); |
237 |
0 |
} |
238 |
|
|
239 |
|
File ensureManifestDotMfExists() { |
240 |
0 |
File metaInfDir = new File(getModuleDir(), "META-INF"); |
241 |
0 |
File manifestDotMf = new File(metaInfDir, "MANIFEST.MF"); |
242 |
|
|
243 |
0 |
if (! metaInfDir.exists()) { |
244 |
|
try { |
245 |
0 |
FileUtils.forceMkdir(metaInfDir); |
246 |
0 |
} catch (IOException ex) { |
247 |
0 |
throw new RuntimeException("Failed to create " + metaInfDir.getAbsolutePath(), ex); |
248 |
0 |
} |
249 |
|
} |
250 |
|
|
251 |
0 |
if (! manclass="keyword">ifestDotMf.exists()) { |
252 |
|
try { |
253 |
0 |
FileUtils.touch(manifestDotMf); |
254 |
0 |
} catch (IOException ex) { |
255 |
0 |
throw new RuntimeException("Failed to create manifest file " + |
256 |
|
manifestDotMf.getAbsolutePath(), ex); |
257 |
0 |
} |
258 |
|
} |
259 |
0 |
return manifestDotMf; |
260 |
|
} |
261 |
|
|
262 |
|
void setupDirectoryScanner() { |
263 |
0 |
ds = new DirectoryScanner(); |
264 |
0 |
ds.setBasedir(getModuleDir()); |
265 |
0 |
ds.setIncludes(patterns.getIncludePatterns(project)); |
266 |
0 |
ds.setExcludes(patterns.getExcludePatterns(project)); |
267 |
0 |
ds.scan(); |
268 |
0 |
} |
269 |
|
|
270 |
|
void explodeIfNeeded() { |
271 |
0 |
File module = new File(getApplicationDir(), getName()); |
272 |
0 |
if (! module.exists()) { |
273 |
0 |
throw new BuildException("Cant find module " + getName() + |
274 |
|
" in application " + getApplicationDir()); |
275 |
|
} |
276 |
0 |
if (module.isDirectory()) { |
277 |
0 |
moduleDir = module; |
278 |
0 |
wasExploded = false; |
279 |
0 |
return; |
280 |
|
} |
281 |
|
try { |
282 |
0 |
moduleDir = createTempDir(getName() + "_infrared"); |
283 |
0 |
} catch (IOException ex) { |
284 |
0 |
throw new RuntimeException("Failed to create tem directory to explode module " + |
285 |
|
module.getAbsolutePath() + " of type " + type, ex); |
286 |
0 |
} |
287 |
|
try { |
288 |
0 |
new JarHelper().unjarDir(module, moduleDir); |
289 |
0 |
wasExploded = true; |
290 |
0 |
getLogger().verbose("\t[MODULE:"+ getName() + "] Exploded " + module.getAbsolutePath() + |
291 |
|
" to " + moduleDir.getAbsolutePath()); |
292 |
0 |
} catch (IOException ex) { |
293 |
0 |
throw new BuildException("Failed to explode module " + getName() + |
294 |
|
" in " + getApplicationDir()); |
295 |
0 |
} |
296 |
0 |
} |
297 |
|
|
298 |
|
void findClassesAndJarsToInstrument() { |
299 |
0 |
if (ds == null) { |
300 |
0 |
setupDirectoryScanner(); |
301 |
|
} |
302 |
0 |
String[] includes = ds.getIncludedFiles(); |
303 |
0 |
if ("war".equalsIgnoreCase(type)) { |
304 |
0 |
findClassesAndJarsToInstrumentInWar(includes); |
305 |
0 |
} else if ( ("jar".equalsIgnoreCase(type)) |
306 |
|
|| ("java".equalsIgnoreCase(type)) |
307 |
|
|| ("classes".equalsIgnoreCase(type)) |
308 |
|
|| ("ejb".equalsIgnoreCase(type)) ) { |
309 |
|
|
310 |
0 |
for (int i = 0; i < includes.length; i++) { |
311 |
0 |
classesToInstrument.add(new File(moduleDir, includes[i])); |
312 |
0 |
packagesToInstrument.add(getPackageName(includes[i])); |
313 |
|
} |
314 |
|
} |
315 |
0 |
getLogger().verbose("\t[MODULE:"+ getName() + "] Collected all jars and classes to instrument: " + |
316 |
|
"\n\t\tJars = " + jarsToInstrument + |
317 |
|
"\n\t\tClasses = " + classesToInstrument + |
318 |
|
"\n\t\tPackages = " + packagesToInstrument); |
319 |
0 |
} |
320 |
|
|
321 |
|
void findClassesAndJarsToInstrumentInWar(String[] includes) { |
322 |
0 |
for (int i = 0; i < includes.length; i++) { |
323 |
0 |
if (includes[i].startsWith( WEB_INF_CLASSES )) { |
324 |
0 |
File classFile = new File(moduleDir, includes[i]); |
325 |
0 |
String pkg = getPackageNameInWebInfClasses(includes[i]); |
326 |
0 |
if (classFile.getName().endsWith(".class")) { |
327 |
0 |
classesToInstrument.add(classFile); |
328 |
0 |
packagesToInstrument.add(pkg); |
329 |
|
} |
330 |
|
} |
331 |
0 |
if (includes[i].startsWith( WEB_INF_LIB )) { |
332 |
0 |
jarsToInstrument.add(new File(moduleDir, includes[i])); |
333 |
|
} |
334 |
|
} |
335 |
0 |
} |
336 |
|
|
337 |
|
String getPackageNameInWebInfClasses(String path) { |
338 |
0 |
String pkg = path.substring(WEB_INF_CLASSES.length() + 1); |
339 |
0 |
return getPackageName(pkg); |
340 |
|
} |
341 |
|
|
342 |
|
String getPackageName(String path) { |
343 |
0 |
int index = path.lastIndexOf(File.separatorChar); |
344 |
0 |
if (index != -1) { |
345 |
0 |
path = path.substring(0, index); |
346 |
0 |
if ("\\".equals(File.separator)) { |
347 |
0 |
path = path.replaceAll("\\\\", "."); |
348 |
|
} else { |
349 |
0 |
path = path.replaceAll(File.separator, "."); |
350 |
|
} |
351 |
|
} else { |
352 |
0 |
path = ""; |
353 |
|
} |
354 |
0 |
return path; |
355 |
|
} |
356 |
|
|
357 |
|
File createTempDir(String name) throws IOException { |
358 |
0 |
File tempDir = null; |
359 |
|
|
360 |
0 |
for (int i = 0; true; i++) { |
361 |
0 |
tempDir = new File(System.getProperty("java.io.tmpdir"), name + "-" + i); |
362 |
0 |
if (! tempDir.exists()) { |
363 |
0 |
break; |
364 |
|
} |
365 |
|
} |
366 |
0 |
FileUtils.forceMkdir(tempDir); |
367 |
0 |
FileUtils.forceDeleteOnExit(tempDir); |
368 |
0 |
return tempDir; |
369 |
|
} |
370 |
|
} |
371 |
|
|