001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 1999 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
027: * Foundation" must not be used to endorse or promote products derived
028: * from this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of the Apache Software Foundation. For more
051: * information on the Apache Software Foundation, please see
052: * <http://www.apache.org/>.
053: *
054: */
055: package com.rimfaxe.webserver.compiler.jsp;
056:
057: import java.util.Hashtable;
058: import java.util.Enumeration;
059: import javax.servlet.jsp.tagext.PageData;
060: import javax.servlet.jsp.tagext.TagData;
061: import javax.servlet.jsp.tagext.TagInfo;
062: import javax.servlet.jsp.tagext.TagAttributeInfo;
063: import javax.servlet.jsp.tagext.TagLibraryInfo;
064: import com.rimfaxe.webserver.webapp.TagLibraryInfoImpl;
065: import javax.servlet.jsp.tagext.ValidationMessage;
066:
067: import org.xml.sax.Attributes;
068: import com.rimfaxe.webserver.compiler.JspToJavaException;
069:
070: /**
071: * Performs validation on the page elements. Attributes are checked for
072: * mandatory presence, entry value validity, and consistency. As a
073: * side effect, some page global value (such as those from page direcitves)
074: * are stored, for later use.
075: *
076: * @author Kin-man Chung
077: * @author Jan Luehe
078: * @author Lars Andersen
079: */
080: public class Validator {
081:
082: /**
083: * A visitor to validate and extract page directive info
084: */
085: static class PageDirectiveVisitor extends Node.Visitor {
086:
087: private PageInfo pageInfo;
088: //private JspErrorHandler err;
089:
090: private static final JspUtil.ValidAttribute[] pageDirectiveAttrs = {
091: new JspUtil.ValidAttribute("language"),
092: new JspUtil.ValidAttribute("extends"),
093: new JspUtil.ValidAttribute("import"),
094: new JspUtil.ValidAttribute("session"),
095: new JspUtil.ValidAttribute("buffer"),
096: new JspUtil.ValidAttribute("autoFlush"),
097: new JspUtil.ValidAttribute("isThreadSafe"),
098: new JspUtil.ValidAttribute("info"),
099: new JspUtil.ValidAttribute("errorPage"),
100: new JspUtil.ValidAttribute("isErrorPage"),
101: new JspUtil.ValidAttribute("contentType"),
102: new JspUtil.ValidAttribute("pageEncoding") };
103:
104: private boolean languageSeen = false;
105: private boolean extendsSeen = false;
106: private boolean sessionSeen = false;
107: private boolean bufferSeen = false;
108: private boolean autoFlushSeen = false;
109: private boolean isThreadSafeSeen = false;
110: private boolean errorPageSeen = false;
111: private boolean isErrorPageSeen = false;
112: private boolean contentTypeSeen = false;
113: private boolean infoSeen = false;
114: private boolean pageEncodingSeen = false;
115:
116: /*
117: * Constructor
118: */
119: PageDirectiveVisitor(JspC compiler) {
120: this .pageInfo = compiler.getPageInfo();
121: //this.err = compiler.getErrorHandler();
122: }
123:
124: public void visit(Node.PageDirective n) throws JasperException,
125: JspToJavaException {
126:
127: JspUtil
128: .checkAttributes("Page directive", n
129: .getAttributes(), pageDirectiveAttrs, n
130: .getStart());
131:
132: // JSP.2.10.1
133: Attributes attrs = n.getAttributes();
134: for (int i = 0; i < attrs.getLength(); i++) {
135: String attr = attrs.getQName(i);
136: String value = attrs.getValue(i);
137:
138: if ("language".equals(attr)) {
139: if (languageSeen)
140: throw new JspToJavaException(n.getStart(),
141: "Multiple languages");
142:
143: languageSeen = true;
144: if (!"java".equalsIgnoreCase(value))
145: throw new JspToJavaException(n.getStart(),
146: "Nonjava language");
147: pageInfo.setLanguage(value);
148: } else if ("extends".equals(attr)) {
149: if (extendsSeen)
150: throw new JspToJavaException(n.getStart(),
151: "Multiple extends");
152: extendsSeen = true;
153: pageInfo.setExtends(value);
154: /*
155: * If page superclass is top level class (i.e. not in a
156: * pkg) explicitly import it. If this is not done, the
157: * compiler will assume the extended class is in the same
158: * pkg as the generated servlet.
159: */
160: if (value.indexOf('.') < 0)
161: n.addImport(value);
162: } else if ("contentType".equals(attr)) {
163: if (contentTypeSeen)
164: throw new JspToJavaException(n.getStart(),
165: "Multiple contenttypes");
166:
167: contentTypeSeen = true;
168: pageInfo.setContentType(value);
169: } else if ("session".equals(attr)) {
170: if (sessionSeen)
171: throw new JspToJavaException(n.getStart(),
172: "Multiple sessions");
173:
174: sessionSeen = true;
175: if ("true".equalsIgnoreCase(value))
176: pageInfo.setSession(true);
177: else if ("false".equalsIgnoreCase(value))
178: pageInfo.setSession(false);
179: else
180: throw new JspToJavaException(n.getStart(),
181: "Invalid session");
182:
183: } else if ("buffer".equals(attr)) {
184: if (bufferSeen)
185: throw new JspToJavaException(n.getStart(),
186: "Multiple buffers");
187:
188: bufferSeen = true;
189:
190: if ("none".equalsIgnoreCase(value))
191: pageInfo.setBuffer(0);
192: else {
193: if (value == null || !value.endsWith("kb"))
194: throw new JspToJavaException(n.getStart(),
195: "Invalid buffer");
196:
197: try {
198: Integer k = new Integer(value.substring(0,
199: value.length() - 2));
200: pageInfo.setBuffer(k.intValue() * 1024);
201: } catch (NumberFormatException e) {
202: System.out
203: .println("NumberFormatException in Validator");
204: throw new JspToJavaException(n.getStart(),
205: "Invalid buffer");
206:
207: }
208: }
209: } else if ("autoFlush".equals(attr)) {
210: if (autoFlushSeen)
211: throw new JspToJavaException(n.getStart(),
212: "Multiple autoflush");
213:
214: autoFlushSeen = true;
215: if ("true".equalsIgnoreCase(value))
216: pageInfo.setAutoFlush(true);
217: else if ("false".equalsIgnoreCase(value))
218: pageInfo.setAutoFlush(false);
219: else
220: throw new JspToJavaException(n.getStart(),
221: "Autoflush invalid");
222:
223: } else if ("isthreadSafe".equals(attr)) {
224: if (isThreadSafeSeen)
225: throw new JspToJavaException(n.getStart(),
226: "Multiple isThreadsafe");
227:
228: isThreadSafeSeen = true;
229: if ("true".equalsIgnoreCase(value))
230: pageInfo.setThreadSafe(true);
231: else if ("false".equalsIgnoreCase(value))
232: pageInfo.setThreadSafe(false);
233: else
234: throw new JspToJavaException(n.getStart(),
235: "isThreadSafe invalid");
236:
237: } else if ("isErrorPage".equals(attr)) {
238: if (isErrorPageSeen)
239: throw new JspToJavaException(n.getStart(),
240: "Multiple isErrorPage");
241:
242: isErrorPageSeen = true;
243: if ("true".equalsIgnoreCase(value))
244: pageInfo.setIsErrorPage(true);
245: else if ("false".equalsIgnoreCase(value))
246: pageInfo.setIsErrorPage(false);
247: else
248: throw new JspToJavaException(n.getStart(),
249: "isErrorPage invalid");
250:
251: } else if ("errorPage".equals(attr)) {
252: if (errorPageSeen)
253: throw new JspToJavaException(n.getStart(),
254: "Multiple errorpage");
255:
256: errorPageSeen = true;
257: pageInfo.setErrorPage(value);
258: } else if ("info".equals(attr)) {
259: if (infoSeen)
260: throw new JspToJavaException(n.getStart(),
261: "Multiple info");
262:
263: infoSeen = true;
264: } else if ("pageEncoding".equals(attr)) {
265: if (pageEncodingSeen)
266: throw new JspToJavaException(n.getStart(),
267: "Multiple page encodings");
268:
269: pageEncodingSeen = true;
270: pageInfo.setPageEncoding(value);
271: }
272: }
273:
274: // Check for bad combinations
275: if (pageInfo.getBuffer() == 0 && !pageInfo.isAutoFlush())
276: throw new JspToJavaException(n.getStart(), "Bad combo");
277:
278: // Attributes for imports for this node have been processed by
279: // the parsers, just add them to pageInfo.
280: pageInfo.addImports(n.getImports());
281: }
282: }
283:
284: /**
285: * A visitor for validating nodes other than page directives
286: */
287: static class ValidateVisitor extends Node.Visitor {
288:
289: private PageInfo pageInfo;
290:
291: private static final JspUtil.ValidAttribute[] jspRootAttrs = { new JspUtil.ValidAttribute(
292: "version", true) };
293:
294: private static final JspUtil.ValidAttribute[] includeDirectiveAttrs = { new JspUtil.ValidAttribute(
295: "file", true) };
296:
297: private static final JspUtil.ValidAttribute[] taglibDirectiveAttrs = {
298: new JspUtil.ValidAttribute("uri", true),
299: new JspUtil.ValidAttribute("prefix", true) };
300:
301: private static final JspUtil.ValidAttribute[] includeActionAttrs = {
302: new JspUtil.ValidAttribute("page", true),
303: new JspUtil.ValidAttribute("flush") };
304:
305: private static final JspUtil.ValidAttribute[] paramActionAttrs = {
306: new JspUtil.ValidAttribute("name", true),
307: new JspUtil.ValidAttribute("value", true) };
308:
309: private static final JspUtil.ValidAttribute[] forwardActionAttrs = { new JspUtil.ValidAttribute(
310: "page", true) };
311:
312: private static final JspUtil.ValidAttribute[] getPropertyAttrs = {
313: new JspUtil.ValidAttribute("name", true),
314: new JspUtil.ValidAttribute("property", true) };
315:
316: private static final JspUtil.ValidAttribute[] setPropertyAttrs = {
317: new JspUtil.ValidAttribute("name", true),
318: new JspUtil.ValidAttribute("property", true),
319: new JspUtil.ValidAttribute("value"),
320: new JspUtil.ValidAttribute("param") };
321:
322: private static final JspUtil.ValidAttribute[] useBeanAttrs = {
323: new JspUtil.ValidAttribute("id", true),
324: new JspUtil.ValidAttribute("scope"),
325: new JspUtil.ValidAttribute("class"),
326: new JspUtil.ValidAttribute("type"),
327: new JspUtil.ValidAttribute("beanName") };
328:
329: private static final JspUtil.ValidAttribute[] plugInAttrs = {
330: new JspUtil.ValidAttribute("type", true),
331: new JspUtil.ValidAttribute("code", true),
332: new JspUtil.ValidAttribute("codebase"),
333: new JspUtil.ValidAttribute("align"),
334: new JspUtil.ValidAttribute("archive"),
335: new JspUtil.ValidAttribute("height"),
336: new JspUtil.ValidAttribute("hspace"),
337: new JspUtil.ValidAttribute("jreversion"),
338: new JspUtil.ValidAttribute("name"),
339: new JspUtil.ValidAttribute("vspace"),
340: new JspUtil.ValidAttribute("width"),
341: new JspUtil.ValidAttribute("nspluginurl"),
342: new JspUtil.ValidAttribute("iepluginurl") };
343:
344: /*
345: * Constructor
346: */
347: ValidateVisitor(JspC compiler) {
348: this .pageInfo = compiler.getPageInfo();
349: //this.err = compiler.getErrorHandler();
350: }
351:
352: public void visit(Node.JspRoot n) throws JasperException,
353: JspToJavaException {
354: JspUtil.checkAttributes("Jsp:root", n.getAttributes(),
355: jspRootAttrs, n.getStart());
356: visitBody(n);
357: }
358:
359: public void visit(Node.IncludeDirective n)
360: throws JasperException, JspToJavaException {
361: JspUtil.checkAttributes("Include directive", n
362: .getAttributes(), includeDirectiveAttrs, n
363: .getStart());
364: visitBody(n);
365: }
366:
367: public void visit(Node.TaglibDirective n)
368: throws JasperException, JspToJavaException {
369: JspUtil.checkAttributes("Taglib directive", n
370: .getAttributes(), taglibDirectiveAttrs, n
371: .getStart());
372: }
373:
374: public void visit(Node.ParamAction n) throws JasperException,
375: JspToJavaException {
376: JspUtil.checkAttributes("Param action", n.getAttributes(),
377: paramActionAttrs, n.getStart());
378: n.setValue(getJspAttribute("value", n
379: .getAttributeValue("value"), n.isXmlSyntax()));
380: }
381:
382: public void visit(Node.IncludeAction n) throws JasperException,
383: JspToJavaException {
384: JspUtil
385: .checkAttributes("Include action", n
386: .getAttributes(), includeActionAttrs, n
387: .getStart());
388: n.setPage(getJspAttribute("page", n
389: .getAttributeValue("page"), n.isXmlSyntax()));
390: visitBody(n);
391: };
392:
393: public void visit(Node.ForwardAction n) throws JasperException,
394: JspToJavaException {
395: JspUtil.checkAttributes("Forward", n.getAttributes(),
396: forwardActionAttrs, n.getStart());
397: n.setPage(getJspAttribute("page", n
398: .getAttributeValue("page"), n.isXmlSyntax()));
399: visitBody(n);
400: }
401:
402: public void visit(Node.GetProperty n) throws JasperException,
403: JspToJavaException {
404: JspUtil.checkAttributes("GetProperty", n.getAttributes(),
405: getPropertyAttrs, n.getStart());
406: }
407:
408: public void visit(Node.SetProperty n) throws JasperException,
409: JspToJavaException {
410: JspUtil.checkAttributes("SetProperty", n.getAttributes(),
411: setPropertyAttrs, n.getStart());
412: String name = n.getAttributeValue("name");
413: String property = n.getAttributeValue("property");
414: String param = n.getAttributeValue("param");
415: String value = n.getAttributeValue("value");
416:
417: if ("*".equals(property)) {
418: if (param != null || value != null)
419: throw new JspToJavaException(n.getStart(),
420: "Invalid SetProperty");
421:
422: } else if (param != null && value != null) {
423: throw new JspToJavaException(n.getStart(),
424: "Invalid SetProperty");
425:
426: }
427: n
428: .setValue(getJspAttribute("value", value, n
429: .isXmlSyntax()));
430: }
431:
432: public void visit(Node.UseBean n) throws JasperException,
433: JspToJavaException {
434: //System.out.println("vist useBean");
435: JspUtil.checkAttributes("UseBean", n.getAttributes(),
436: useBeanAttrs, n.getStart());
437:
438: String name = n.getAttributeValue("id");
439: String scope = n.getAttributeValue("scope");
440: String className = n.getAttributeValue("class");
441: String type = n.getAttributeValue("type");
442: BeanRepository beanInfo = pageInfo.getBeanRepository();
443:
444: if (className == null && type == null)
445: throw new JspToJavaException(n.getStart(),
446: "Missing type in UseBean");
447:
448: if (beanInfo.checkVariable(name))
449: throw new JspToJavaException(n.getStart(),
450: "Duplicate UseBean");
451:
452: if ("session".equals(scope) && !pageInfo.isSession())
453: throw new JspToJavaException(n.getStart(),
454: "UseBean : no session");
455:
456: Node.JspAttribute jattr = getJspAttribute("beanName", n
457: .getAttributeValue("beanName"), n.isXmlSyntax());
458: n.setBeanName(jattr);
459: if (className != null && jattr != null)
460: throw new JspToJavaException(n.getStart(),
461: "UseBean error, not both");
462:
463: if (className == null)
464: className = type;
465:
466: //System.out.println("Bean : "+name+" Class="+className);
467: if (scope == null || scope.equals("page")) {
468: beanInfo.addPageBean(name, className);
469: } else if (scope.equals("request")) {
470: beanInfo.addRequestBean(name, className);
471: } else if (scope.equals("session")) {
472: beanInfo.addSessionBean(name, className);
473: } else if (scope.equals("application")) {
474: beanInfo.addApplicationBean(name, className);
475: } else {
476: throw new JspToJavaException(n.getStart(),
477: "UseBean error, bad scope");
478:
479: }
480: visitBody(n);
481: }
482:
483: public void visit(Node.PlugIn n) throws JasperException,
484: JspToJavaException {
485: JspUtil.checkAttributes("Plugin", n.getAttributes(),
486: plugInAttrs, n.getStart());
487:
488: String type = n.getAttributeValue("type");
489: if (type == null)
490: throw new JspToJavaException(n.getStart(),
491: "Plugin error, no type");
492:
493: if (!type.equals("bean") && !type.equals("applet"))
494: throw new JspToJavaException(n.getStart(),
495: "Plugin error, bad type");
496:
497: if (n.getAttributeValue("code") == null)
498: throw new JspToJavaException(n.getStart(),
499: "Plugin error, no code");
500:
501: n.setHeight(getJspAttribute("height", n
502: .getAttributeValue("height"), n.isXmlSyntax()));
503: n.setWidth(getJspAttribute("width", n
504: .getAttributeValue("width"), n.isXmlSyntax()));
505: visitBody(n);
506: }
507:
508: public void visit(Node.CustomTag n) throws JasperException,
509: JspToJavaException {
510: //System.out.println("Validator.ValidateVisitor visit(CustomTag)");
511:
512: TagLibraryInfo tagLibInfo = (TagLibraryInfo) pageInfo
513: .getTagLibraries().get(n.getPrefix());
514:
515: if (tagLibInfo == null) {
516: //System.out.println("Validator.ValidateVisitor TagLibInfo is null!");
517: } else {
518: //System.out.println("Validator.ValidateVisitor TagLibInfo is "+tagLibInfo.getPrefixString());
519: }
520:
521: TagInfo tagInfo = tagLibInfo.getTag(n.getShortName());
522: if (tagInfo == null) {
523: throw new JspToJavaException(n.getStart(),
524: "TagInfo error, missing tag info");
525: }
526:
527: /*
528: * Make sure all required attributes are present
529: */
530: TagAttributeInfo[] tldAttrs = tagInfo.getAttributes();
531: Attributes attrs = n.getAttributes();
532: for (int i = 0; i < tldAttrs.length; i++) {
533: if (tldAttrs[i].isRequired()
534: && attrs.getValue(tldAttrs[i].getName()) == null) {
535: throw new JspToJavaException(n.getStart(),
536: "TagInfo error, missing attribute name="
537: + tldAttrs[i].getName()
538: + " shortname=" + n.getShortName());
539:
540: }
541: }
542:
543: /*
544: * Make sure there are no invalid attributes
545: */
546: Hashtable tagDataAttrs = new Hashtable(attrs.getLength());
547: Node.JspAttribute[] jspAttrs = new Node.JspAttribute[attrs
548: .getLength()];
549: for (int i = 0; i < attrs.getLength(); i++) {
550: boolean found = false;
551: for (int j = 0; j < tldAttrs.length; j++) {
552: if (attrs.getQName(i).equals(tldAttrs[j].getName())) {
553: if (tldAttrs[j].canBeRequestTime()) {
554: jspAttrs[i] = getJspAttribute(attrs
555: .getQName(i), attrs.getValue(i), n
556: .isXmlSyntax());
557: } else {
558: jspAttrs[i] = new Node.JspAttribute(attrs
559: .getQName(i), attrs.getValue(i),
560: false);
561: }
562: if (jspAttrs[i].isExpression()) {
563: tagDataAttrs.put(attrs.getQName(i),
564: TagData.REQUEST_TIME_VALUE);
565: } else {
566: tagDataAttrs.put(attrs.getQName(i), attrs
567: .getValue(i));
568: }
569: found = true;
570: break;
571: }
572: }
573: if (!found) {
574: throw new JspToJavaException(n.getStart(),
575: "TagInfo error, bad attribute, name="
576: + attrs.getQName(i));
577: }
578: }
579:
580: TagData tagData = new TagData(tagDataAttrs);
581: n.setTagData(tagData);
582: n.setJspAttributes(jspAttrs);
583:
584: visitBody(n);
585: }
586:
587: /**
588: * Preprocess attributes that can be expressions. Expression
589: * delimiters are stripped.
590: */
591: private Node.JspAttribute getJspAttribute(String name,
592: String value, boolean isXml) {
593: // XXX Is it an error to see "%=foo%" in non-Xml page?
594: // (We won't see "<%=foo%> in xml page because '<' is not a
595: // valid attribute value in xml).
596:
597: if (value == null)
598: return null;
599:
600: if (isXml && value.startsWith("%=")) {
601: return new Node.JspAttribute(name, value.substring(2,
602: value.length() - 1), true);
603: }
604:
605: if (!isXml && value.startsWith("<%=")) {
606: return new Node.JspAttribute(name, value.substring(3,
607: value.length() - 2), true);
608: }
609:
610: return new Node.JspAttribute(name, value, false);
611: }
612: }
613:
614: /**
615: * A visitor for validating TagExtraInfo classes of all tags
616: */
617: static class TagExtraInfoVisitor extends Node.Visitor {
618:
619: private PageInfo pageInfo;
620:
621: //private JspErrorHandler err;
622:
623: /*
624: * Constructor
625: */
626: TagExtraInfoVisitor(JspC compiler) {
627: this .pageInfo = compiler.getPageInfo();
628: //this.err = compiler.getErrorHandler();
629: }
630:
631: public void visit(Node.CustomTag n) throws JasperException,
632: JspToJavaException {
633: TagLibraryInfo tagLibInfo = (TagLibraryInfo) pageInfo
634: .getTagLibraries().get(n.getPrefix());
635: TagInfo tagInfo = tagLibInfo.getTag(n.getShortName());
636: if (tagInfo == null) {
637: throw new JspToJavaException(n.getStart(),
638: "Missing TagInfo, name=" + n.getName());
639: }
640:
641: if (!tagInfo.isValid(n.getTagData())) {
642: throw new JspToJavaException(n.getStart(),
643: "TagInfo, missing attributes");
644: }
645:
646: visitBody(n);
647: }
648: }
649:
650: public static void validate(JspC compiler, Node.Nodes page)
651: throws JasperException, JspToJavaException {
652:
653: /*
654: * Visit the page directives first, as they are global to the page
655: * and are position independent.
656: */
657: page.visit(new PageDirectiveVisitor(compiler));
658:
659: // Determine the default output content type, per errata_a
660: // http://jcp.org/aboutJava/communityprocess/maintenance/jsr053/errata_1_2_a_20020321.html
661:
662: PageInfo pageInfo = compiler.getPageInfo();
663: String contentType = pageInfo.getContentType();
664: if (contentType == null || contentType.indexOf("charset=") < 0) {
665: boolean isXml = page.getRoot().isXmlSyntax();
666: String defaultType;
667: if (contentType == null) {
668: defaultType = isXml ? "text/xml" : "text/html";
669: } else {
670: defaultType = contentType;
671: }
672: String charset = pageInfo.getPageEncoding();
673: if (charset == null)
674: charset = isXml ? "UTF-8" : "ISO-8859-1";
675: pageInfo
676: .setContentType(defaultType + ";charset=" + charset);
677: }
678:
679: /*
680: * Validate all other nodes.
681: * This validation step includes checking a custom tag's mandatory and
682: * optional attributes against information in the TLD (first validation
683: * step for custom tags according to JSP.10.5).
684: */
685: page.visit(new ValidateVisitor(compiler));
686:
687: /*
688: * Invoke TagLibraryValidator classes of all imported tags
689: * (second validation step for custom tags according to JSP.10.5).
690: */
691: validateXmlView(new PageDataImpl(page), compiler);
692:
693: /*
694: * Invoke TagExtraInfo method isValid() for all imported tags
695: * (third validation step for custom tags according to JSP.10.5).
696: */
697: page.visit(new TagExtraInfoVisitor(compiler));
698:
699: }
700:
701: //*********************************************************************
702: // Private (utility) methods
703:
704: /**
705: * Validate XML view against the TagLibraryValidator classes of all
706: * imported tag libraries.
707: */
708: private static void validateXmlView(PageData xmlView, JspC compiler)
709: throws JasperException, JspToJavaException
710: {
711:
712: StringBuffer errMsg = null;
713: //JspErrorHandler errDisp = compiler.getErrorHandler();
714:
715: //TODO TODO OBS Taglibrary
716: Enumeration enum = compiler.getPageInfo().getTagLibraries().elements();
717: while (enum.hasMoreElements())
718: {
719: TagLibraryInfo tli = (TagLibraryInfo) enum.nextElement();
720:
721: //ValidationMessage[] errors = ((TagLibraryInfoImpl) tli).validate(xmlView);
722: ValidationMessage[] errors = null;
723: if ((errors != null) && (errors.length != 0))
724: {
725: if (errMsg == null) {
726: errMsg = new StringBuffer();
727: }
728: errMsg.append("<h3>");
729: errMsg.append("jsp.error.tlv.invalid.page"+tli.getShortName());
730: errMsg.append("</h3>");
731: for (int i=0; i<errors.length; i++) {
732: errMsg.append("<p>");
733: errMsg.append(errors[i].getId());
734: errMsg.append(": ");
735: errMsg.append(errors[i].getMessage());
736: errMsg.append("</p>");
737: }
738: }
739: }
740:
741: if (errMsg != null)
742: {
743: throw new JspToJavaException(errMsg.toString());
744: //errDisp.jspError(errMsg.toString());
745: }
746: }
747: }
|