1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mortbay.jetty.jspc.plugin;
17
18 import org.apache.jasper.JspC;
19 import org.apache.maven.artifact.Artifact;
20 import org.apache.maven.plugin.AbstractMojo;
21 import org.apache.maven.plugin.MojoExecutionException;
22 import org.apache.maven.plugin.MojoFailureException;
23 import org.apache.maven.project.MavenProject;
24 import org.codehaus.plexus.util.FileUtils;
25 import org.codehaus.plexus.util.StringUtils;
26 import org.mortbay.util.IO;
27
28 import java.io.BufferedReader;
29 import java.io.File;
30 import java.io.FileFilter;
31 import java.io.FileReader;
32 import java.io.FileWriter;
33 import java.io.FilenameFilter;
34 import java.io.PrintWriter;
35 import java.net.URL;
36 import java.net.URLClassLoader;
37 import java.util.ArrayList;
38 import java.util.Iterator;
39 import java.util.List;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class JspcMojo extends AbstractMojo
72 {
73 public static final String END_OF_WEBAPP = "</web-app>";
74
75
76
77
78
79
80
81
82
83 private MavenProject project;
84
85
86
87
88
89
90
91 private String webXmlFragment;
92
93
94
95
96
97
98
99
100
101
102 private String insertionMarker;
103
104
105
106
107
108
109
110
111 private boolean mergeFragment;
112
113
114
115
116
117
118 private String generatedClasses;
119
120
121
122
123
124
125
126 private boolean keepSources;
127
128
129
130
131
132
133 private String packageRoot;
134
135
136
137
138
139
140
141 private String webAppSourceDirectory;
142
143
144
145
146
147
148
149
150 private String includes;
151
152
153
154
155
156
157 private String excludes;
158
159
160
161
162
163
164 private File classesDirectory;
165
166
167
168
169
170
171 private boolean verbose;
172
173
174
175
176
177
178 private boolean validateXml;
179
180
181
182
183
184
185 private String javaEncoding;
186
187
188
189
190
191
192 private boolean suppressSmap;
193
194
195
196
197
198
199 private boolean ignoreJspFragmentErrors;
200
201
202
203
204
205
206
207 private String schemaResourcePrefix;
208
209
210 public void execute() throws MojoExecutionException, MojoFailureException
211 {
212 if (getLog().isDebugEnabled())
213 {
214 getLog().info("verbose=" + verbose);
215 getLog().info("webAppSourceDirectory=" + webAppSourceDirectory);
216 getLog().info("generatedClasses=" + generatedClasses);
217 getLog().info("webXmlFragment=" + webXmlFragment);
218 getLog().info("validateXml=" + validateXml);
219 getLog().info("packageRoot=" + packageRoot);
220 getLog().info("javaEncoding=" + javaEncoding);
221 getLog().info("insertionMarker="+ (insertionMarker == null || insertionMarker.equals("") ? END_OF_WEBAPP : insertionMarker));
222 getLog().info("keepSources=" + keepSources);
223 getLog().info("mergeFragment=" + mergeFragment);
224 getLog().info("suppressSmap=" + suppressSmap);
225 getLog().info("ignoreJspFragmentErrors=" + ignoreJspFragmentErrors);
226 getLog().info("schemaResourcePrefix=" + schemaResourcePrefix);
227 }
228 try
229 {
230 prepare();
231 compile();
232 cleanupSrcs();
233 mergeWebXml();
234 }
235 catch (Exception e)
236 {
237 throw new MojoFailureException(e, "Failure processing jsps","Failure processing jsps");
238 }
239 }
240
241 public void compile() throws Exception
242 {
243 ClassLoader currentClassLoader = Thread.currentThread()
244 .getContextClassLoader();
245
246 ArrayList urls = new ArrayList();
247 setUpClassPath(urls);
248 URLClassLoader ucl = new URLClassLoader((URL[]) urls.toArray(new URL[0]), currentClassLoader);
249 StringBuffer classpathStr = new StringBuffer();
250
251 for (int i = 0; i < urls.size(); i++)
252 {
253 if (getLog().isDebugEnabled())
254 getLog().debug("webappclassloader contains: " + urls.get(i));
255 classpathStr.append(((URL) urls.get(i)).getFile());
256 if (getLog().isDebugEnabled())
257 getLog().debug(
258 "added to classpath: " + ((URL) urls.get(i)).getFile());
259 classpathStr.append(System.getProperty("path.separator"));
260 }
261
262 Thread.currentThread().setContextClassLoader(ucl);
263
264 JspC jspc = new JspC();
265 jspc.setWebXmlFragment(webXmlFragment);
266 jspc.setUriroot(webAppSourceDirectory);
267 jspc.setPackage(packageRoot);
268 jspc.setOutputDir(generatedClasses);
269 jspc.setValidateXml(validateXml);
270 jspc.setClassPath(classpathStr.toString());
271 jspc.setCompile(true);
272 jspc.setSmapSuppressed(suppressSmap);
273 jspc.setSmapDumped(!suppressSmap);
274 jspc.setJavaEncoding(javaEncoding);
275
276
277
278 String jspFiles = getJspFiles(webAppSourceDirectory);
279 System.err.println("Compiling "+jspFiles);
280 System.err.println("Includes="+includes);
281 System.err.println("Excludes="+excludes);
282 jspc.setJspFiles(jspFiles);
283 if (verbose)
284 {
285 getLog().info("Files selected to precompile: " + jspFiles);
286 }
287
288
289 try
290 {
291 jspc.setIgnoreJspFragmentErrors(ignoreJspFragmentErrors);
292 }
293 catch (NoSuchMethodError e)
294 {
295 getLog().debug("Tomcat Jasper does not support configuration option 'ignoreJspFragmentErrors': ignored");
296 }
297
298 try
299 {
300 if (schemaResourcePrefix != null)
301 jspc.setSchemaResourcePrefix(schemaResourcePrefix);
302 }
303 catch (NoSuchMethodError e)
304 {
305 getLog().debug("Tomcat Jasper does not support configuration option 'schemaResourcePrefix': ignored");
306 }
307 if (verbose)
308 jspc.setVerbose(99);
309 else
310 jspc.setVerbose(0);
311
312 jspc.execute();
313
314 Thread.currentThread().setContextClassLoader(currentClassLoader);
315 }
316
317 private String getJspFiles(String webAppSourceDirectory)
318 throws Exception
319 {
320 List fileNames = FileUtils.getFileNames(new File(webAppSourceDirectory),includes, excludes, false);
321 return StringUtils.join(fileNames.toArray(new String[0]), ",");
322
323 }
324
325
326
327
328
329
330
331 public void cleanupSrcs() throws Exception
332 {
333
334 if (!keepSources)
335 {
336 String packageRootDirectory = packageRoot.replace('.',
337 File.separatorChar);
338
339 File generatedClassesDir = new File(generatedClasses
340 + File.separatorChar + packageRootDirectory);
341
342 if(generatedClassesDir.exists() && generatedClassesDir.isDirectory())
343 {
344 delete(generatedClassesDir, new FileFilter()
345 {
346 public boolean accept(File f)
347 {
348 return f.isDirectory() || f.getName().endsWith(".java");
349 }
350 });
351 }
352 }
353 }
354
355 static void delete(File dir, FileFilter filter)
356 {
357 File[] files = dir.listFiles(filter);
358 for(int i=0; i<files.length; i++)
359 {
360 File f = files[i];
361 if(f.isDirectory())
362 delete(f, filter);
363 else
364 f.delete();
365 }
366 }
367
368
369
370
371
372
373
374
375
376
377
378
379
380 public void mergeWebXml() throws Exception
381 {
382 if (mergeFragment)
383 {
384
385 File webXml = new File(webAppSourceDirectory + "/WEB-INF/web.xml");
386 if (!webXml.exists())
387 {
388 getLog()
389 .info(
390 webAppSourceDirectory
391 + "/WEB-INF/web.xml does not exist, cannot merge with generated fragment");
392 return;
393 }
394
395 File fragmentWebXml = new File(webXmlFragment);
396 if (!fragmentWebXml.exists())
397 {
398 getLog().info("No fragment web.xml file generated");
399 }
400 File mergedWebXml = new File(fragmentWebXml.getParentFile(),
401 "web.xml");
402 BufferedReader webXmlReader = new BufferedReader(new FileReader(
403 webXml));
404 PrintWriter mergedWebXmlWriter = new PrintWriter(new FileWriter(
405 mergedWebXml));
406
407
408
409 boolean atInsertPoint = false;
410 boolean atEOF = false;
411 String marker = (insertionMarker == null
412 || insertionMarker.equals("") ? END_OF_WEBAPP : insertionMarker);
413 while (!atInsertPoint && !atEOF)
414 {
415 String line = webXmlReader.readLine();
416 if (line == null)
417 atEOF = true;
418 else if (line.indexOf(marker) >= 0)
419 {
420 atInsertPoint = true;
421 }
422 else
423 {
424 mergedWebXmlWriter.println(line);
425 }
426 }
427
428
429 BufferedReader fragmentWebXmlReader = new BufferedReader(
430 new FileReader(fragmentWebXml));
431 IO.copy(fragmentWebXmlReader, mergedWebXmlWriter);
432
433
434 if (marker.equals(END_OF_WEBAPP))
435 mergedWebXmlWriter.println(END_OF_WEBAPP);
436
437
438 IO.copy(webXmlReader, mergedWebXmlWriter);
439
440 webXmlReader.close();
441 mergedWebXmlWriter.close();
442 fragmentWebXmlReader.close();
443 }
444 }
445
446 private void prepare() throws Exception
447 {
448
449
450 File generatedSourceDirectoryFile = new File(generatedClasses);
451 if (!generatedSourceDirectoryFile.exists())
452 generatedSourceDirectoryFile.mkdirs();
453 }
454
455
456
457
458
459
460
461
462
463
464 private void setUpClassPath(List urls) throws Exception
465 {
466 String classesDir = classesDirectory.getCanonicalPath();
467 classesDir = classesDir
468 + (classesDir.endsWith(File.pathSeparator) ? "" : File.separator);
469 urls.add(new File(classesDir).toURL());
470
471 if (getLog().isDebugEnabled())
472 getLog().debug("Adding to classpath classes dir: " + classesDir);
473
474 for (Iterator iter = project.getArtifacts().iterator(); iter.hasNext();)
475 {
476 Artifact artifact = (Artifact) iter.next();
477
478
479 if (!Artifact.SCOPE_TEST.equals(artifact.getScope()))
480 {
481 String filePath = artifact.getFile().getCanonicalPath();
482 if (getLog().isDebugEnabled())
483 getLog().debug(
484 "Adding to classpath dependency file: " + filePath);
485
486 urls.add(artifact.getFile().toURL());
487 }
488 }
489 }
490 }