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