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