1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.jasper;
19
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.net.MalformedURLException;
23 import java.net.URL;
24 import java.net.URLClassLoader;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.Set;
28
29 import javax.servlet.ServletContext;
30 import javax.servlet.jsp.tagext.TagInfo;
31
32 import org.apache.jasper.compiler.Compiler;
33 import org.apache.jasper.compiler.JspRuntimeContext;
34 import org.apache.jasper.compiler.JspUtil;
35 import org.apache.jasper.compiler.Localizer;
36 import org.apache.jasper.compiler.ServletWriter;
37 import org.apache.jasper.servlet.JasperLoader;
38 import org.apache.jasper.servlet.JspServletWrapper;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class JspCompilationContext {
55
56 protected org.apache.juli.logging.Log log =
57 org.apache.juli.logging.LogFactory.getLog(JspCompilationContext.class);
58
59 protected Map<String, URL> tagFileJarUrls;
60 protected boolean isPackagedTagFile;
61
62 protected String className;
63 protected String jspUri;
64 protected boolean isErrPage;
65 protected String basePackageName;
66 protected String derivedPackageName;
67 protected String servletJavaFileName;
68 protected String javaPath;
69 protected String classFileName;
70 protected String contentType;
71 protected ServletWriter writer;
72 protected Options options;
73 protected JspServletWrapper jsw;
74 protected Compiler jspCompiler;
75 protected String classPath;
76
77 protected String baseURI;
78 protected String outputDir;
79 protected ServletContext context;
80 protected URLClassLoader loader;
81
82 protected JspRuntimeContext rctxt;
83
84 protected int removed = 0;
85
86 protected URLClassLoader jspLoader;
87 protected URL baseUrl;
88 protected Class servletClass;
89
90 protected boolean isTagFile;
91 protected boolean protoTypeMode;
92 protected TagInfo tagInfo;
93 protected URL tagFileJarUrl;
94
95
96 public JspCompilationContext(String jspUri,
97 boolean isErrPage,
98 Options options,
99 ServletContext context,
100 JspServletWrapper jsw,
101 JspRuntimeContext rctxt) {
102
103 this.jspUri = canonicalURI(jspUri);
104 this.isErrPage = isErrPage;
105 this.options = options;
106 this.jsw = jsw;
107 this.context = context;
108
109 this.baseURI = jspUri.substring(0, jspUri.lastIndexOf('/') + 1);
110
111 if (baseURI == null) {
112 baseURI = "/";
113 } else if (baseURI.charAt(0) != '/') {
114
115
116 baseURI = "/" + baseURI;
117 }
118 if (baseURI.charAt(baseURI.length() - 1) != '/') {
119 baseURI += '/';
120 }
121
122 this.rctxt = rctxt;
123 this.tagFileJarUrls = new HashMap<String, URL>();
124 this.basePackageName = Constants.JSP_PACKAGE_NAME;
125 }
126
127 public JspCompilationContext(String tagfile,
128 TagInfo tagInfo,
129 Options options,
130 ServletContext context,
131 JspServletWrapper jsw,
132 JspRuntimeContext rctxt,
133 URL tagFileJarUrl) {
134 this(tagfile, false, options, context, jsw, rctxt);
135 this.isTagFile = true;
136 this.tagInfo = tagInfo;
137 this.tagFileJarUrl = tagFileJarUrl;
138 if (tagFileJarUrl != null) {
139 isPackagedTagFile = true;
140 }
141 }
142
143
144
145
146
147
148
149
150 public String getClassPath() {
151 if( classPath != null )
152 return classPath;
153 return rctxt.getClassPath();
154 }
155
156
157
158
159 public void setClassPath(String classPath) {
160 this.classPath = classPath;
161 }
162
163
164
165
166
167 public ClassLoader getClassLoader() {
168 if( loader != null )
169 return loader;
170 return rctxt.getParentClassLoader();
171 }
172
173 public void setClassLoader(URLClassLoader loader) {
174 this.loader = loader;
175 }
176
177 public ClassLoader getJspLoader() {
178 if( jspLoader == null ) {
179 jspLoader = new JasperLoader
180 (new URL[] {baseUrl},
181 getClassLoader(),
182 rctxt.getPermissionCollection(),
183 rctxt.getCodeSource());
184 }
185 return jspLoader;
186 }
187
188
189
190
191
192
193
194
195 public String getOutputDir() {
196 if (outputDir == null) {
197 createOutputDir();
198 }
199
200 return outputDir;
201 }
202
203
204
205
206
207
208 public Compiler createCompiler() throws JasperException {
209 if (jspCompiler != null ) {
210 return jspCompiler;
211 }
212 jspCompiler = null;
213 if (options.getCompilerClassName() != null) {
214 jspCompiler = createCompiler(options.getCompilerClassName());
215 } else {
216 if (options.getCompiler() == null) {
217 jspCompiler = createCompiler("org.apache.jasper.compiler.JDTCompiler");
218 if (jspCompiler == null) {
219 jspCompiler = createCompiler("org.apache.jasper.compiler.AntCompiler");
220 }
221 } else {
222 jspCompiler = createCompiler("org.apache.jasper.compiler.AntCompiler");
223 if (jspCompiler == null) {
224 jspCompiler = createCompiler("org.apache.jasper.compiler.JDTCompiler");
225 }
226 }
227 }
228 if (jspCompiler == null) {
229 throw new IllegalStateException(Localizer.getMessage("jsp.error.compiler"));
230 }
231 jspCompiler.init(this, jsw);
232 return jspCompiler;
233 }
234
235 protected Compiler createCompiler(String className) {
236 Compiler compiler = null;
237 try {
238 compiler = (Compiler) Class.forName(className).newInstance();
239 } catch (InstantiationException e) {
240 log.warn(Localizer.getMessage("jsp.error.compiler"), e);
241 } catch (IllegalAccessException e) {
242 log.warn(Localizer.getMessage("jsp.error.compiler"), e);
243 } catch (NoClassDefFoundError e) {
244 if (log.isDebugEnabled()) {
245 log.debug(Localizer.getMessage("jsp.error.compiler"), e);
246 }
247 } catch (ClassNotFoundException e) {
248 if (log.isDebugEnabled()) {
249 log.debug(Localizer.getMessage("jsp.error.compiler"), e);
250 }
251 }
252 return compiler;
253 }
254
255 public Compiler getCompiler() {
256 return jspCompiler;
257 }
258
259
260
261
262
263
264
265 public String resolveRelativeUri(String uri) {
266
267
268 if (uri.startsWith("/") || uri.startsWith(File.separator)) {
269 return uri;
270 } else {
271 return baseURI + uri;
272 }
273 }
274
275
276
277
278
279
280
281 public java.io.InputStream getResourceAsStream(String res) {
282 return context.getResourceAsStream(canonicalURI(res));
283 }
284
285
286 public URL getResource(String res) throws MalformedURLException {
287 URL result = null;
288
289 if (res.startsWith("/META-INF/")) {
290
291 URL jarUrl = tagFileJarUrls.get(res);
292 if (jarUrl == null) {
293 jarUrl = tagFileJarUrl;
294 }
295 if (jarUrl != null) {
296 result = new URL(jarUrl.toExternalForm() + res.substring(1));
297 }
298 } else if (res.startsWith("jar:file:")) {
299
300
301 result = new URL(res);
302
303 } else {
304 result = context.getResource(canonicalURI(res));
305 }
306 return result;
307 }
308
309
310 public Set getResourcePaths(String path) {
311 return context.getResourcePaths(canonicalURI(path));
312 }
313
314
315
316
317
318 public String getRealPath(String path) {
319 if (context != null) {
320 return context.getRealPath(path);
321 }
322 return path;
323 }
324
325
326
327
328
329
330
331
332
333 public URL getTagFileJarUrl(String tagFile) {
334 return this.tagFileJarUrls.get(tagFile);
335 }
336
337 public void setTagFileJarUrl(String tagFile, URL tagFileURL) {
338 this.tagFileJarUrls.put(tagFile, tagFileURL);
339 }
340
341
342
343
344
345
346
347 public URL getTagFileJarUrl() {
348 return this.tagFileJarUrl;
349 }
350
351
352
353
354
355
356
357 public String getServletClassName() {
358
359 if (className != null) {
360 return className;
361 }
362
363 if (isTagFile) {
364 className = tagInfo.getTagClassName();
365 int lastIndex = className.lastIndexOf('.');
366 if (lastIndex != -1) {
367 className = className.substring(lastIndex + 1);
368 }
369 } else {
370 int iSep = jspUri.lastIndexOf('/') + 1;
371 className = JspUtil.makeJavaIdentifier(jspUri.substring(iSep));
372 }
373 return className;
374 }
375
376 public void setServletClassName(String className) {
377 this.className = className;
378 }
379
380
381
382
383
384 public String getJspFile() {
385 return jspUri;
386 }
387
388
389
390
391
392 public boolean isErrorPage() {
393 return isErrPage;
394 }
395
396 public void setErrorPage(boolean isErrPage) {
397 this.isErrPage = isErrPage;
398 }
399
400 public boolean isTagFile() {
401 return isTagFile;
402 }
403
404 public TagInfo getTagInfo() {
405 return tagInfo;
406 }
407
408 public void setTagInfo(TagInfo tagi) {
409 tagInfo = tagi;
410 }
411
412
413
414
415
416
417 public boolean isPrototypeMode() {
418 return protoTypeMode;
419 }
420
421 public void setPrototypeMode(boolean pm) {
422 protoTypeMode = pm;
423 }
424
425
426
427
428
429
430 public String getServletPackageName() {
431 if (isTagFile()) {
432 String className = tagInfo.getTagClassName();
433 int lastIndex = className.lastIndexOf('.');
434 String pkgName = "";
435 if (lastIndex != -1) {
436 pkgName = className.substring(0, lastIndex);
437 }
438 return pkgName;
439 } else {
440 String dPackageName = getDerivedPackageName();
441 if (dPackageName.length() == 0) {
442 return basePackageName;
443 }
444 return basePackageName + '.' + getDerivedPackageName();
445 }
446 }
447
448 protected String getDerivedPackageName() {
449 if (derivedPackageName == null) {
450 int iSep = jspUri.lastIndexOf('/');
451 derivedPackageName = (iSep > 0) ?
452 JspUtil.makeJavaPackage(jspUri.substring(1,iSep)) : "";
453 }
454 return derivedPackageName;
455 }
456
457
458
459
460 public void setServletPackageName(String servletPackageName) {
461 this.basePackageName = servletPackageName;
462 }
463
464
465
466
467
468 public String getServletJavaFileName() {
469 if (servletJavaFileName == null) {
470 servletJavaFileName = getOutputDir() + getServletClassName() + ".java";
471 }
472 return servletJavaFileName;
473 }
474
475
476
477
478 public Options getOptions() {
479 return options;
480 }
481
482 public ServletContext getServletContext() {
483 return context;
484 }
485
486 public JspRuntimeContext getRuntimeContext() {
487 return rctxt;
488 }
489
490
491
492
493 public String getJavaPath() {
494
495 if (javaPath != null) {
496 return javaPath;
497 }
498
499 if (isTagFile()) {
500 String tagName = tagInfo.getTagClassName();
501 javaPath = tagName.replace('.', '/') + ".java";
502 } else {
503 javaPath = getServletPackageName().replace('.', '/') + '/' +
504 getServletClassName() + ".java";
505 }
506 return javaPath;
507 }
508
509 public String getClassFileName() {
510 if (classFileName == null) {
511 classFileName = getOutputDir() + getServletClassName() + ".class";
512 }
513 return classFileName;
514 }
515
516
517
518
519
520
521 public String getContentType() {
522 return contentType;
523 }
524
525 public void setContentType(String contentType) {
526 this.contentType = contentType;
527 }
528
529
530
531
532 public ServletWriter getWriter() {
533 return writer;
534 }
535
536 public void setWriter(ServletWriter writer) {
537 this.writer = writer;
538 }
539
540
541
542
543
544
545
546
547
548
549 public String[] getTldLocation(String uri) throws JasperException {
550 String[] location =
551 getOptions().getTldLocationsCache().getLocation(uri);
552 return location;
553 }
554
555
556
557
558 public boolean keepGenerated() {
559 return getOptions().getKeepGenerated();
560 }
561
562
563
564 public void incrementRemoved() {
565 if (removed == 0 && rctxt != null) {
566 rctxt.removeWrapper(jspUri);
567 }
568 removed++;
569 }
570
571 public boolean isRemoved() {
572 if (removed > 1 ) {
573 return true;
574 }
575 return false;
576 }
577
578
579
580 public void compile() throws JasperException, FileNotFoundException {
581 createCompiler();
582 if (jspCompiler.isOutDated()) {
583 try {
584 jspCompiler.removeGeneratedFiles();
585 jspLoader = null;
586 jspCompiler.compile();
587 jsw.setReload(true);
588 jsw.setCompilationException(null);
589 } catch (JasperException ex) {
590
591 jsw.setCompilationException(ex);
592 throw ex;
593 } catch (Exception ex) {
594 JasperException je = new JasperException(
595 Localizer.getMessage("jsp.error.unable.compile"),
596 ex);
597
598 jsw.setCompilationException(je);
599 throw je;
600 }
601 }
602 }
603
604
605
606 public Class load()
607 throws JasperException, FileNotFoundException
608 {
609 try {
610 getJspLoader();
611
612 String name = getFQCN();
613 servletClass = jspLoader.loadClass(name);
614 } catch (ClassNotFoundException cex) {
615 throw new JasperException(Localizer.getMessage("jsp.error.unable.load"),
616 cex);
617 } catch (Exception ex) {
618 throw new JasperException(Localizer.getMessage("jsp.error.unable.compile"),
619 ex);
620 }
621 removed = 0;
622 return servletClass;
623 }
624
625 public String getFQCN() {
626 String name;
627 if (isTagFile()) {
628 name = tagInfo.getTagClassName();
629 } else {
630 name = getServletPackageName() + "." + getServletClassName();
631 }
632 return name;
633 }
634
635
636
637 static Object outputDirLock = new Object();
638
639 public void checkOutputDir() {
640 if (outputDir != null) {
641 if (!(new File(outputDir)).exists()) {
642 makeOutputDir();
643 }
644 } else {
645 createOutputDir();
646 }
647 }
648
649 protected boolean makeOutputDir() {
650 synchronized(outputDirLock) {
651 File outDirFile = new File(outputDir);
652 return (outDirFile.exists() || outDirFile.mkdirs());
653 }
654 }
655
656 protected void createOutputDir() {
657 String path = null;
658 if (isTagFile()) {
659 String tagName = tagInfo.getTagClassName();
660 path = tagName.replace('.', File.separatorChar);
661 path = path.substring(0, path.lastIndexOf(File.separatorChar));
662 } else {
663 path = getServletPackageName().replace('.',File.separatorChar);
664 }
665
666
667 try {
668 File base = options.getScratchDir();
669 baseUrl = base.toURI().toURL();
670 outputDir = base.getAbsolutePath() + File.separator + path +
671 File.separator;
672 if (!makeOutputDir()) {
673 throw new IllegalStateException(Localizer.getMessage("jsp.error.outputfolder"));
674 }
675 } catch (MalformedURLException e) {
676 throw new IllegalStateException(Localizer.getMessage("jsp.error.outputfolder"), e);
677 }
678 }
679
680 protected static final boolean isPathSeparator(char c) {
681 return (c == '/' || c == '\\');
682 }
683
684 protected static final String canonicalURI(String s) {
685 if (s == null) return null;
686 StringBuffer result = new StringBuffer();
687 final int len = s.length();
688 int pos = 0;
689 while (pos < len) {
690 char c = s.charAt(pos);
691 if ( isPathSeparator(c) ) {
692
693
694
695
696 while (pos+1 < len && isPathSeparator(s.charAt(pos+1))) {
697 ++pos;
698 }
699
700 if (pos+1 < len && s.charAt(pos+1) == '.') {
701
702
703
704 if (pos+2 >= len) break;
705
706 switch (s.charAt(pos+2)) {
707
708
709
710
711 case '/':
712 case '\\':
713 pos += 2;
714 continue;
715
716
717
718
719
720 case '.':
721
722 if (pos+3 < len && isPathSeparator(s.charAt(pos+3))) {
723 pos += 3;
724 int separatorPos = result.length()-1;
725 while (separatorPos >= 0 &&
726 ! isPathSeparator(result
727 .charAt(separatorPos))) {
728 --separatorPos;
729 }
730 if (separatorPos >= 0)
731 result.setLength(separatorPos);
732 continue;
733 }
734 }
735 }
736 }
737 result.append(c);
738 ++pos;
739 }
740 return result.toString();
741 }
742 }
743