001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jasper.compiler;
018:
019: import java.util.Collection;
020: import java.util.HashMap;
021: import java.util.HashSet;
022: import java.util.LinkedList;
023: import java.util.List;
024: import java.util.Vector;
025:
026: import org.apache.el.ExpressionFactoryImpl;
027: import org.apache.jasper.Constants;
028: import org.apache.jasper.JasperException;
029:
030: import javax.el.ExpressionFactory;
031: import javax.servlet.jsp.tagext.TagLibraryInfo;
032:
033: /**
034: * A repository for various info about the translation unit under compilation.
035: *
036: * @author Kin-man Chung
037: */
038:
039: class PageInfo {
040:
041: private Vector imports;
042: private Vector dependants;
043:
044: private BeanRepository beanRepository;
045: private HashMap taglibsMap;
046: private HashMap jspPrefixMapper;
047: private HashMap xmlPrefixMapper;
048: private HashMap nonCustomTagPrefixMap;
049: private String jspFile;
050: private String defaultLanguage = "java";
051: private String language;
052: private String defaultExtends = Constants.JSP_SERVLET_BASE;
053: private String xtends;
054: private String contentType = null;
055: private String session;
056: private boolean isSession = true;
057: private String bufferValue;
058: private int buffer = 8 * 1024; // XXX confirm
059: private String autoFlush;
060: private boolean isAutoFlush = true;
061: private String isThreadSafeValue;
062: private boolean isThreadSafe = true;
063: private String isErrorPageValue;
064: private boolean isErrorPage = false;
065: private String errorPage = null;
066: private String info;
067:
068: private boolean scriptless = false;
069: private boolean scriptingInvalid = false;
070:
071: private String isELIgnoredValue;
072: private boolean isELIgnored = false;
073:
074: // JSP 2.1
075: private String deferredSyntaxAllowedAsLiteralValue;
076: private boolean deferredSyntaxAllowedAsLiteral = false;
077: private ExpressionFactory expressionFactory = new ExpressionFactoryImpl();
078: private String trimDirectiveWhitespacesValue;
079: private boolean trimDirectiveWhitespaces = false;
080:
081: private String omitXmlDecl = null;
082: private String doctypeName = null;
083: private String doctypePublic = null;
084: private String doctypeSystem = null;
085:
086: private boolean isJspPrefixHijacked;
087:
088: // Set of all element and attribute prefixes used in this translation unit
089: private HashSet prefixes;
090:
091: private boolean hasJspRoot = false;
092: private Vector includePrelude;
093: private Vector includeCoda;
094: private Vector pluginDcls; // Id's for tagplugin declarations
095:
096: PageInfo(BeanRepository beanRepository, String jspFile) {
097:
098: this .jspFile = jspFile;
099: this .beanRepository = beanRepository;
100: this .taglibsMap = new HashMap();
101: this .jspPrefixMapper = new HashMap();
102: this .xmlPrefixMapper = new HashMap();
103: this .nonCustomTagPrefixMap = new HashMap();
104: this .imports = new Vector();
105: this .dependants = new Vector();
106: this .includePrelude = new Vector();
107: this .includeCoda = new Vector();
108: this .pluginDcls = new Vector();
109: this .prefixes = new HashSet();
110:
111: // Enter standard imports
112: for (int i = 0; i < Constants.STANDARD_IMPORTS.length; i++)
113: imports.add(Constants.STANDARD_IMPORTS[i]);
114: }
115:
116: /**
117: * Check if the plugin ID has been previously declared. Make a not
118: * that this Id is now declared.
119: * @return true if Id has been declared.
120: */
121: public boolean isPluginDeclared(String id) {
122: if (pluginDcls.contains(id))
123: return true;
124: pluginDcls.add(id);
125: return false;
126: }
127:
128: public void addImports(List imports) {
129: this .imports.addAll(imports);
130: }
131:
132: public void addImport(String imp) {
133: this .imports.add(imp);
134: }
135:
136: public List getImports() {
137: return imports;
138: }
139:
140: public String getJspFile() {
141: return jspFile;
142: }
143:
144: public void addDependant(String d) {
145: if (!dependants.contains(d) && !jspFile.equals(d))
146: dependants.add(d);
147: }
148:
149: public List getDependants() {
150: return dependants;
151: }
152:
153: public BeanRepository getBeanRepository() {
154: return beanRepository;
155: }
156:
157: public void setScriptless(boolean s) {
158: scriptless = s;
159: }
160:
161: public boolean isScriptless() {
162: return scriptless;
163: }
164:
165: public void setScriptingInvalid(boolean s) {
166: scriptingInvalid = s;
167: }
168:
169: public boolean isScriptingInvalid() {
170: return scriptingInvalid;
171: }
172:
173: public List getIncludePrelude() {
174: return includePrelude;
175: }
176:
177: public void setIncludePrelude(Vector prelude) {
178: includePrelude = prelude;
179: }
180:
181: public List getIncludeCoda() {
182: return includeCoda;
183: }
184:
185: public void setIncludeCoda(Vector coda) {
186: includeCoda = coda;
187: }
188:
189: public void setHasJspRoot(boolean s) {
190: hasJspRoot = s;
191: }
192:
193: public boolean hasJspRoot() {
194: return hasJspRoot;
195: }
196:
197: public String getOmitXmlDecl() {
198: return omitXmlDecl;
199: }
200:
201: public void setOmitXmlDecl(String omit) {
202: omitXmlDecl = omit;
203: }
204:
205: public String getDoctypeName() {
206: return doctypeName;
207: }
208:
209: public void setDoctypeName(String doctypeName) {
210: this .doctypeName = doctypeName;
211: }
212:
213: public String getDoctypeSystem() {
214: return doctypeSystem;
215: }
216:
217: public void setDoctypeSystem(String doctypeSystem) {
218: this .doctypeSystem = doctypeSystem;
219: }
220:
221: public String getDoctypePublic() {
222: return doctypePublic;
223: }
224:
225: public void setDoctypePublic(String doctypePublic) {
226: this .doctypePublic = doctypePublic;
227: }
228:
229: /* Tag library and XML namespace management methods */
230:
231: public void setIsJspPrefixHijacked(boolean isHijacked) {
232: isJspPrefixHijacked = isHijacked;
233: }
234:
235: public boolean isJspPrefixHijacked() {
236: return isJspPrefixHijacked;
237: }
238:
239: /*
240: * Adds the given prefix to the set of prefixes of this translation unit.
241: *
242: * @param prefix The prefix to add
243: */
244: public void addPrefix(String prefix) {
245: prefixes.add(prefix);
246: }
247:
248: /*
249: * Checks to see if this translation unit contains the given prefix.
250: *
251: * @param prefix The prefix to check
252: *
253: * @return true if this translation unit contains the given prefix, false
254: * otherwise
255: */
256: public boolean containsPrefix(String prefix) {
257: return prefixes.contains(prefix);
258: }
259:
260: /*
261: * Maps the given URI to the given tag library.
262: *
263: * @param uri The URI to map
264: * @param info The tag library to be associated with the given URI
265: */
266: public void addTaglib(String uri, TagLibraryInfo info) {
267: taglibsMap.put(uri, info);
268: }
269:
270: /*
271: * Gets the tag library corresponding to the given URI.
272: *
273: * @return Tag library corresponding to the given URI
274: */
275: public TagLibraryInfo getTaglib(String uri) {
276: return (TagLibraryInfo) taglibsMap.get(uri);
277: }
278:
279: /*
280: * Gets the collection of tag libraries that are associated with a URI
281: *
282: * @return Collection of tag libraries that are associated with a URI
283: */
284: public Collection getTaglibs() {
285: return taglibsMap.values();
286: }
287:
288: /*
289: * Checks to see if the given URI is mapped to a tag library.
290: *
291: * @param uri The URI to map
292: *
293: * @return true if the given URI is mapped to a tag library, false
294: * otherwise
295: */
296: public boolean hasTaglib(String uri) {
297: return taglibsMap.containsKey(uri);
298: }
299:
300: /*
301: * Maps the given prefix to the given URI.
302: *
303: * @param prefix The prefix to map
304: * @param uri The URI to be associated with the given prefix
305: */
306: public void addPrefixMapping(String prefix, String uri) {
307: jspPrefixMapper.put(prefix, uri);
308: }
309:
310: /*
311: * Pushes the given URI onto the stack of URIs to which the given prefix
312: * is mapped.
313: *
314: * @param prefix The prefix whose stack of URIs is to be pushed
315: * @param uri The URI to be pushed onto the stack
316: */
317: public void pushPrefixMapping(String prefix, String uri) {
318: LinkedList stack = (LinkedList) xmlPrefixMapper.get(prefix);
319: if (stack == null) {
320: stack = new LinkedList();
321: xmlPrefixMapper.put(prefix, stack);
322: }
323: stack.addFirst(uri);
324: }
325:
326: /*
327: * Removes the URI at the top of the stack of URIs to which the given
328: * prefix is mapped.
329: *
330: * @param prefix The prefix whose stack of URIs is to be popped
331: */
332: public void popPrefixMapping(String prefix) {
333: LinkedList stack = (LinkedList) xmlPrefixMapper.get(prefix);
334: if (stack == null || stack.size() == 0) {
335: // XXX throw new Exception("XXX");
336: }
337: stack.removeFirst();
338: }
339:
340: /*
341: * Returns the URI to which the given prefix maps.
342: *
343: * @param prefix The prefix whose URI is sought
344: *
345: * @return The URI to which the given prefix maps
346: */
347: public String getURI(String prefix) {
348:
349: String uri = null;
350:
351: LinkedList stack = (LinkedList) xmlPrefixMapper.get(prefix);
352: if (stack == null || stack.size() == 0) {
353: uri = (String) jspPrefixMapper.get(prefix);
354: } else {
355: uri = (String) stack.getFirst();
356: }
357:
358: return uri;
359: }
360:
361: /* Page/Tag directive attributes */
362:
363: /*
364: * language
365: */
366: public void setLanguage(String value, Node n, ErrorDispatcher err,
367: boolean pagedir) throws JasperException {
368:
369: if (!"java".equalsIgnoreCase(value)) {
370: if (pagedir)
371: err.jspError(n, "jsp.error.page.language.nonjava");
372: else
373: err.jspError(n, "jsp.error.tag.language.nonjava");
374: }
375:
376: language = value;
377: }
378:
379: public String getLanguage(boolean useDefault) {
380: return (language == null && useDefault ? defaultLanguage
381: : language);
382: }
383:
384: public String getLanguage() {
385: return getLanguage(true);
386: }
387:
388: /*
389: * extends
390: */
391: public void setExtends(String value, Node.PageDirective n) {
392:
393: xtends = value;
394:
395: /*
396: * If page superclass is top level class (i.e. not in a package)
397: * explicitly import it. If this is not done, the compiler will assume
398: * the extended class is in the same pkg as the generated servlet.
399: */
400: if (value.indexOf('.') < 0)
401: n.addImport(value);
402: }
403:
404: /**
405: * Gets the value of the 'extends' page directive attribute.
406: *
407: * @param useDefault TRUE if the default
408: * (org.apache.jasper.runtime.HttpJspBase) should be returned if this
409: * attribute has not been set, FALSE otherwise
410: *
411: * @return The value of the 'extends' page directive attribute, or the
412: * default (org.apache.jasper.runtime.HttpJspBase) if this attribute has
413: * not been set and useDefault is TRUE
414: */
415: public String getExtends(boolean useDefault) {
416: return (xtends == null && useDefault ? defaultExtends : xtends);
417: }
418:
419: /**
420: * Gets the value of the 'extends' page directive attribute.
421: *
422: * @return The value of the 'extends' page directive attribute, or the
423: * default (org.apache.jasper.runtime.HttpJspBase) if this attribute has
424: * not been set
425: */
426: public String getExtends() {
427: return getExtends(true);
428: }
429:
430: /*
431: * contentType
432: */
433: public void setContentType(String value) {
434: contentType = value;
435: }
436:
437: public String getContentType() {
438: return contentType;
439: }
440:
441: /*
442: * buffer
443: */
444: public void setBufferValue(String value, Node n, ErrorDispatcher err)
445: throws JasperException {
446:
447: if ("none".equalsIgnoreCase(value))
448: buffer = 0;
449: else {
450: if (value == null || !value.endsWith("kb"))
451: err.jspError(n, "jsp.error.page.invalid.buffer");
452: try {
453: Integer k = new Integer(value.substring(0, value
454: .length() - 2));
455: buffer = k.intValue() * 1024;
456: } catch (NumberFormatException e) {
457: err.jspError(n, "jsp.error.page.invalid.buffer");
458: }
459: }
460:
461: bufferValue = value;
462: }
463:
464: public String getBufferValue() {
465: return bufferValue;
466: }
467:
468: public int getBuffer() {
469: return buffer;
470: }
471:
472: /*
473: * session
474: */
475: public void setSession(String value, Node n, ErrorDispatcher err)
476: throws JasperException {
477:
478: if ("true".equalsIgnoreCase(value))
479: isSession = true;
480: else if ("false".equalsIgnoreCase(value))
481: isSession = false;
482: else
483: err.jspError(n, "jsp.error.page.invalid.session");
484:
485: session = value;
486: }
487:
488: public String getSession() {
489: return session;
490: }
491:
492: public boolean isSession() {
493: return isSession;
494: }
495:
496: /*
497: * autoFlush
498: */
499: public void setAutoFlush(String value, Node n, ErrorDispatcher err)
500: throws JasperException {
501:
502: if ("true".equalsIgnoreCase(value))
503: isAutoFlush = true;
504: else if ("false".equalsIgnoreCase(value))
505: isAutoFlush = false;
506: else
507: err.jspError(n, "jsp.error.autoFlush.invalid");
508:
509: autoFlush = value;
510: }
511:
512: public String getAutoFlush() {
513: return autoFlush;
514: }
515:
516: public boolean isAutoFlush() {
517: return isAutoFlush;
518: }
519:
520: /*
521: * isThreadSafe
522: */
523: public void setIsThreadSafe(String value, Node n,
524: ErrorDispatcher err) throws JasperException {
525:
526: if ("true".equalsIgnoreCase(value))
527: isThreadSafe = true;
528: else if ("false".equalsIgnoreCase(value))
529: isThreadSafe = false;
530: else
531: err.jspError(n, "jsp.error.page.invalid.isthreadsafe");
532:
533: isThreadSafeValue = value;
534: }
535:
536: public String getIsThreadSafe() {
537: return isThreadSafeValue;
538: }
539:
540: public boolean isThreadSafe() {
541: return isThreadSafe;
542: }
543:
544: /*
545: * info
546: */
547: public void setInfo(String value) {
548: info = value;
549: }
550:
551: public String getInfo() {
552: return info;
553: }
554:
555: /*
556: * errorPage
557: */
558: public void setErrorPage(String value) {
559: errorPage = value;
560: }
561:
562: public String getErrorPage() {
563: return errorPage;
564: }
565:
566: /*
567: * isErrorPage
568: */
569: public void setIsErrorPage(String value, Node n, ErrorDispatcher err)
570: throws JasperException {
571:
572: if ("true".equalsIgnoreCase(value))
573: isErrorPage = true;
574: else if ("false".equalsIgnoreCase(value))
575: isErrorPage = false;
576: else
577: err.jspError(n, "jsp.error.page.invalid.iserrorpage");
578:
579: isErrorPageValue = value;
580: }
581:
582: public String getIsErrorPage() {
583: return isErrorPageValue;
584: }
585:
586: public boolean isErrorPage() {
587: return isErrorPage;
588: }
589:
590: /*
591: * isELIgnored
592: */
593: public void setIsELIgnored(String value, Node n,
594: ErrorDispatcher err, boolean pagedir)
595: throws JasperException {
596:
597: if ("true".equalsIgnoreCase(value))
598: isELIgnored = true;
599: else if ("false".equalsIgnoreCase(value))
600: isELIgnored = false;
601: else {
602: if (pagedir)
603: err.jspError(n, "jsp.error.page.invalid.iselignored");
604: else
605: err.jspError(n, "jsp.error.tag.invalid.iselignored");
606: }
607:
608: isELIgnoredValue = value;
609: }
610:
611: /*
612: * deferredSyntaxAllowedAsLiteral
613: */
614: public void setDeferredSyntaxAllowedAsLiteral(String value, Node n,
615: ErrorDispatcher err, boolean pagedir)
616: throws JasperException {
617:
618: if ("true".equalsIgnoreCase(value))
619: deferredSyntaxAllowedAsLiteral = true;
620: else if ("false".equalsIgnoreCase(value))
621: deferredSyntaxAllowedAsLiteral = false;
622: else {
623: if (pagedir)
624: err
625: .jspError(n,
626: "jsp.error.page.invalid.deferredsyntaxallowedasliteral");
627: else
628: err
629: .jspError(n,
630: "jsp.error.tag.invalid.deferredsyntaxallowedasliteral");
631: }
632:
633: deferredSyntaxAllowedAsLiteralValue = value;
634: }
635:
636: /*
637: * trimDirectiveWhitespaces
638: */
639: public void setTrimDirectiveWhitespaces(String value, Node n,
640: ErrorDispatcher err, boolean pagedir)
641: throws JasperException {
642:
643: if ("true".equalsIgnoreCase(value))
644: trimDirectiveWhitespaces = true;
645: else if ("false".equalsIgnoreCase(value))
646: trimDirectiveWhitespaces = false;
647: else {
648: if (pagedir)
649: err
650: .jspError(n,
651: "jsp.error.page.invalid.trimdirectivewhitespaces");
652: else
653: err
654: .jspError(n,
655: "jsp.error.tag.invalid.trimdirectivewhitespaces");
656: }
657:
658: trimDirectiveWhitespacesValue = value;
659: }
660:
661: public void setELIgnored(boolean s) {
662: isELIgnored = s;
663: }
664:
665: public String getIsELIgnored() {
666: return isELIgnoredValue;
667: }
668:
669: public boolean isELIgnored() {
670: return isELIgnored;
671: }
672:
673: public void putNonCustomTagPrefix(String prefix, Mark where) {
674: nonCustomTagPrefixMap.put(prefix, where);
675: }
676:
677: public Mark getNonCustomTagPrefix(String prefix) {
678: return (Mark) nonCustomTagPrefixMap.get(prefix);
679: }
680:
681: public String getDeferredSyntaxAllowedAsLiteral() {
682: return deferredSyntaxAllowedAsLiteralValue;
683: }
684:
685: public boolean isDeferredSyntaxAllowedAsLiteral() {
686: return deferredSyntaxAllowedAsLiteral;
687: }
688:
689: public void setDeferredSyntaxAllowedAsLiteral(boolean isELDeferred) {
690: this .deferredSyntaxAllowedAsLiteral = isELDeferred;
691: }
692:
693: public ExpressionFactory getExpressionFactory() {
694: return expressionFactory;
695: }
696:
697: public String getTrimDirectiveWhitespaces() {
698: return trimDirectiveWhitespacesValue;
699: }
700:
701: public boolean isTrimDirectiveWhitespaces() {
702: return trimDirectiveWhitespaces;
703: }
704:
705: public void setTrimDirectiveWhitespaces(
706: boolean trimDirectiveWhitespaces) {
707: this.trimDirectiveWhitespaces = trimDirectiveWhitespaces;
708: }
709: }
|