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 File generatedClassesDir = new File(generatedClasses);
337
338 if(generatedClassesDir.exists() && generatedClassesDir.isDirectory())
339 {
340 delete(generatedClassesDir, new FileFilter()
341 {
342 public boolean accept(File f)
343 {
344 return f.isDirectory() || f.getName().endsWith(".java");
345 }
346 });
347 }
348 }
349 }
350
351 static void delete(File dir, FileFilter filter)
352 {
353 File[] files = dir.listFiles(filter);
354 for(int i=0; i<files.length; i++)
355 {
356 File f = files[i];
357 if(f.isDirectory())
358 delete(f, filter);
359 else
360 f.delete();
361 }
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375
376 public void mergeWebXml() throws Exception
377 {
378 if (mergeFragment)
379 {
380
381 File webXml = new File(webAppSourceDirectory + "/WEB-INF/web.xml");
382 if (!webXml.exists())
383 {
384 getLog()
385 .info(
386 webAppSourceDirectory
387 + "/WEB-INF/web.xml does not exist, cannot merge with generated fragment");
388 return;
389 }
390
391 File fragmentWebXml = new File(webXmlFragment);
392 if (!fragmentWebXml.exists())
393 {
394 getLog().info("No fragment web.xml file generated");
395 }
396 File mergedWebXml = new File(fragmentWebXml.getParentFile(),
397 "web.xml");
398 BufferedReader webXmlReader = new BufferedReader(new FileReader(
399 webXml));
400 PrintWriter mergedWebXmlWriter = new PrintWriter(new FileWriter(
401 mergedWebXml));
402
403
404
405 boolean atInsertPoint = false;
406 boolean atEOF = false;
407 String marker = (insertionMarker == null
408 || insertionMarker.equals("") ? END_OF_WEBAPP : insertionMarker);
409 while (!atInsertPoint && !atEOF)
410 {
411 String line = webXmlReader.readLine();
412 if (line == null)
413 atEOF = true;
414 else if (line.indexOf(marker) >= 0)
415 {
416 atInsertPoint = true;
417 }
418 else
419 {
420 mergedWebXmlWriter.println(line);
421 }
422 }
423
424
425 BufferedReader fragmentWebXmlReader = new BufferedReader(
426 new FileReader(fragmentWebXml));
427 IO.copy(fragmentWebXmlReader, mergedWebXmlWriter);
428
429
430 if (marker.equals(END_OF_WEBAPP))
431 mergedWebXmlWriter.println(END_OF_WEBAPP);
432
433
434 IO.copy(webXmlReader, mergedWebXmlWriter);
435
436 webXmlReader.close();
437 mergedWebXmlWriter.close();
438 fragmentWebXmlReader.close();
439 }
440 }
441
442 private void prepare() throws Exception
443 {
444
445
446 File generatedSourceDirectoryFile = new File(generatedClasses);
447 if (!generatedSourceDirectoryFile.exists())
448 generatedSourceDirectoryFile.mkdirs();
449 }
450
451
452
453
454
455
456
457
458
459
460 private void setUpClassPath(List urls) throws Exception
461 {
462 String classesDir = classesDirectory.getCanonicalPath();
463 classesDir = classesDir
464 + (classesDir.endsWith(File.pathSeparator) ? "" : File.separator);
465 urls.add(new File(classesDir).toURL());
466
467 if (getLog().isDebugEnabled())
468 getLog().debug("Adding to classpath classes dir: " + classesDir);
469
470 for (Iterator iter = project.getArtifacts().iterator(); iter.hasNext();)
471 {
472 Artifact artifact = (Artifact) iter.next();
473
474
475 if (!Artifact.SCOPE_TEST.equals(artifact.getScope()))
476 {
477 String filePath = artifact.getFile().getCanonicalPath();
478 if (getLog().isDebugEnabled())
479 getLog().debug(
480 "Adding to classpath dependency file: " + filePath);
481
482 urls.add(artifact.getFile().toURL());
483 }
484 }
485 }
486 }