Source Code Cross Referenced for Validator.java in  » Sevlet-Container » tomcat-jasper2 » org » apache » jasper » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Sevlet Container » tomcat jasper2 » org.apache.jasper.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999,2004 The Apache Software Foundation.
0003:         * 
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         * 
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         * 
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:
0017:        package org.apache.jasper.compiler;
0018:
0019:        import java.lang.reflect.Method;
0020:        import java.util.ArrayList;
0021:        import java.util.HashMap;
0022:        import java.util.Hashtable;
0023:        import java.util.Iterator;
0024:
0025:        import javax.servlet.jsp.el.FunctionMapper;
0026:        import javax.servlet.jsp.tagext.FunctionInfo;
0027:        import javax.servlet.jsp.tagext.JspFragment;
0028:        import javax.servlet.jsp.tagext.PageData;
0029:        import javax.servlet.jsp.tagext.TagAttributeInfo;
0030:        import javax.servlet.jsp.tagext.TagData;
0031:        import javax.servlet.jsp.tagext.TagExtraInfo;
0032:        import javax.servlet.jsp.tagext.TagInfo;
0033:        import javax.servlet.jsp.tagext.TagLibraryInfo;
0034:        import javax.servlet.jsp.tagext.ValidationMessage;
0035:
0036:        import org.apache.jasper.Constants;
0037:        import org.apache.jasper.JasperException;
0038:        import org.apache.jasper.JspCompilationContext;
0039:        import org.xml.sax.Attributes;
0040:
0041:        /**
0042:         * Performs validation on the page elements.  Attributes are checked for
0043:         * mandatory presence, entry value validity, and consistency.  As a
0044:         * side effect, some page global value (such as those from page direcitves)
0045:         * are stored, for later use.
0046:         *
0047:         * @author Kin-man Chung
0048:         * @author Jan Luehe
0049:         * @author Shawn Bayern
0050:         * @author Mark Roth
0051:         */
0052:        class Validator {
0053:
0054:            /**
0055:             * A visitor to validate and extract page directive info
0056:             */
0057:            static class DirectiveVisitor extends Node.Visitor {
0058:
0059:                private PageInfo pageInfo;
0060:                private ErrorDispatcher err;
0061:
0062:                private static final JspUtil.ValidAttribute[] pageDirectiveAttrs = {
0063:                        new JspUtil.ValidAttribute("language"),
0064:                        new JspUtil.ValidAttribute("extends"),
0065:                        new JspUtil.ValidAttribute("import"),
0066:                        new JspUtil.ValidAttribute("session"),
0067:                        new JspUtil.ValidAttribute("buffer"),
0068:                        new JspUtil.ValidAttribute("autoFlush"),
0069:                        new JspUtil.ValidAttribute("isThreadSafe"),
0070:                        new JspUtil.ValidAttribute("info"),
0071:                        new JspUtil.ValidAttribute("errorPage"),
0072:                        new JspUtil.ValidAttribute("isErrorPage"),
0073:                        new JspUtil.ValidAttribute("contentType"),
0074:                        new JspUtil.ValidAttribute("pageEncoding"),
0075:                        new JspUtil.ValidAttribute("isELIgnored") };
0076:
0077:                private boolean pageEncodingSeen = false;
0078:
0079:                /*
0080:                 * Constructor
0081:                 */
0082:                DirectiveVisitor(Compiler compiler) throws JasperException {
0083:                    this .pageInfo = compiler.getPageInfo();
0084:                    this .err = compiler.getErrorDispatcher();
0085:                    JspCompilationContext ctxt = compiler
0086:                            .getCompilationContext();
0087:                }
0088:
0089:                public void visit(Node.IncludeDirective n)
0090:                        throws JasperException {
0091:                    // Since pageDirectiveSeen flag only applies to the Current page
0092:                    // save it here and restore it after the file is included.
0093:                    boolean pageEncodingSeenSave = pageEncodingSeen;
0094:                    pageEncodingSeen = false;
0095:                    visitBody(n);
0096:                    pageEncodingSeen = pageEncodingSeenSave;
0097:                }
0098:
0099:                public void visit(Node.PageDirective n) throws JasperException {
0100:
0101:                    JspUtil.checkAttributes("Page directive", n,
0102:                            pageDirectiveAttrs, err);
0103:
0104:                    // JSP.2.10.1
0105:                    Attributes attrs = n.getAttributes();
0106:                    for (int i = 0; attrs != null && i < attrs.getLength(); i++) {
0107:                        String attr = attrs.getQName(i);
0108:                        String value = attrs.getValue(i);
0109:
0110:                        if ("language".equals(attr)) {
0111:                            if (pageInfo.getLanguage(false) == null) {
0112:                                pageInfo.setLanguage(value, n, err, true);
0113:                            } else if (!pageInfo.getLanguage(false).equals(
0114:                                    value)) {
0115:                                err.jspError(n,
0116:                                        "jsp.error.page.conflict.language",
0117:                                        pageInfo.getLanguage(false), value);
0118:                            }
0119:                        } else if ("extends".equals(attr)) {
0120:                            if (pageInfo.getExtends(false) == null) {
0121:                                pageInfo.setExtends(value, n);
0122:                            } else if (!pageInfo.getExtends(false)
0123:                                    .equals(value)) {
0124:                                err.jspError(n,
0125:                                        "jsp.error.page.conflict.extends",
0126:                                        pageInfo.getExtends(false), value);
0127:                            }
0128:                        } else if ("contentType".equals(attr)) {
0129:                            if (pageInfo.getContentType() == null) {
0130:                                pageInfo.setContentType(value);
0131:                            } else if (!pageInfo.getContentType().equals(value)) {
0132:                                err.jspError(n,
0133:                                        "jsp.error.page.conflict.contenttype",
0134:                                        pageInfo.getContentType(), value);
0135:                            }
0136:                        } else if ("session".equals(attr)) {
0137:                            if (pageInfo.getSession() == null) {
0138:                                pageInfo.setSession(value, n, err);
0139:                            } else if (!pageInfo.getSession().equals(value)) {
0140:                                err.jspError(n,
0141:                                        "jsp.error.page.conflict.session",
0142:                                        pageInfo.getSession(), value);
0143:                            }
0144:                        } else if ("buffer".equals(attr)) {
0145:                            if (pageInfo.getBufferValue() == null) {
0146:                                pageInfo.setBufferValue(value, n, err);
0147:                            } else if (!pageInfo.getBufferValue().equals(value)) {
0148:                                err.jspError(n,
0149:                                        "jsp.error.page.conflict.buffer",
0150:                                        pageInfo.getBufferValue(), value);
0151:                            }
0152:                        } else if ("autoFlush".equals(attr)) {
0153:                            if (pageInfo.getAutoFlush() == null) {
0154:                                pageInfo.setAutoFlush(value, n, err);
0155:                            } else if (!pageInfo.getAutoFlush().equals(value)) {
0156:                                err.jspError(n,
0157:                                        "jsp.error.page.conflict.autoflush",
0158:                                        pageInfo.getAutoFlush(), value);
0159:                            }
0160:                        } else if ("isThreadSafe".equals(attr)) {
0161:                            if (pageInfo.getIsThreadSafe() == null) {
0162:                                pageInfo.setIsThreadSafe(value, n, err);
0163:                            } else if (!pageInfo.getIsThreadSafe()
0164:                                    .equals(value)) {
0165:                                err.jspError(n,
0166:                                        "jsp.error.page.conflict.isthreadsafe",
0167:                                        pageInfo.getIsThreadSafe(), value);
0168:                            }
0169:                        } else if ("isELIgnored".equals(attr)) {
0170:                            if (pageInfo.getIsELIgnored() == null) {
0171:                                pageInfo.setIsELIgnored(value, n, err, true);
0172:                            } else if (!pageInfo.getIsELIgnored().equals(value)) {
0173:                                err.jspError(n,
0174:                                        "jsp.error.page.conflict.iselignored",
0175:                                        pageInfo.getIsELIgnored(), value);
0176:                            }
0177:                        } else if ("isErrorPage".equals(attr)) {
0178:                            if (pageInfo.getIsErrorPage() == null) {
0179:                                pageInfo.setIsErrorPage(value, n, err);
0180:                            } else if (!pageInfo.getIsErrorPage().equals(value)) {
0181:                                err.jspError(n,
0182:                                        "jsp.error.page.conflict.iserrorpage",
0183:                                        pageInfo.getIsErrorPage(), value);
0184:                            }
0185:                        } else if ("errorPage".equals(attr)) {
0186:                            if (pageInfo.getErrorPage() == null) {
0187:                                pageInfo.setErrorPage(value);
0188:                            } else if (!pageInfo.getErrorPage().equals(value)) {
0189:                                err.jspError(n,
0190:                                        "jsp.error.page.conflict.errorpage",
0191:                                        pageInfo.getErrorPage(), value);
0192:                            }
0193:                        } else if ("info".equals(attr)) {
0194:                            if (pageInfo.getInfo() == null) {
0195:                                pageInfo.setInfo(value);
0196:                            } else if (!pageInfo.getInfo().equals(value)) {
0197:                                err.jspError(n, "jsp.error.page.conflict.info",
0198:                                        pageInfo.getInfo(), value);
0199:                            }
0200:                        } else if ("pageEncoding".equals(attr)) {
0201:                            if (pageEncodingSeen)
0202:                                err.jspError(n,
0203:                                        "jsp.error.page.multi.pageencoding");
0204:                            // 'pageEncoding' can occur at most once per file
0205:                            pageEncodingSeen = true;
0206:                            /*
0207:                             * Report any encoding conflict, treating "UTF-16",
0208:                             * "UTF-16BE", and "UTF-16LE" as identical.
0209:                             */
0210:                            comparePageEncodings(value, n);
0211:                        }
0212:                    }
0213:
0214:                    // Check for bad combinations
0215:                    if (pageInfo.getBuffer() == 0 && !pageInfo.isAutoFlush())
0216:                        err.jspError(n, "jsp.error.page.badCombo");
0217:
0218:                    // Attributes for imports for this node have been processed by
0219:                    // the parsers, just add them to pageInfo.
0220:                    pageInfo.addImports(n.getImports());
0221:                }
0222:
0223:                public void visit(Node.TagDirective n) throws JasperException {
0224:                    // Note: Most of the validation is done in TagFileProcessor
0225:                    // when it created a TagInfo object from the
0226:                    // tag file in which the directive appeared.
0227:
0228:                    // This method does additional processing to collect page info
0229:
0230:                    Attributes attrs = n.getAttributes();
0231:                    for (int i = 0; attrs != null && i < attrs.getLength(); i++) {
0232:                        String attr = attrs.getQName(i);
0233:                        String value = attrs.getValue(i);
0234:
0235:                        if ("language".equals(attr)) {
0236:                            if (pageInfo.getLanguage(false) == null) {
0237:                                pageInfo.setLanguage(value, n, err, false);
0238:                            } else if (!pageInfo.getLanguage(false).equals(
0239:                                    value)) {
0240:                                err.jspError(n,
0241:                                        "jsp.error.tag.conflict.language",
0242:                                        pageInfo.getLanguage(false), value);
0243:                            }
0244:                        } else if ("isELIgnored".equals(attr)) {
0245:                            if (pageInfo.getIsELIgnored() == null) {
0246:                                pageInfo.setIsELIgnored(value, n, err, false);
0247:                            } else if (!pageInfo.getIsELIgnored().equals(value)) {
0248:                                err.jspError(n,
0249:                                        "jsp.error.tag.conflict.iselignored",
0250:                                        pageInfo.getIsELIgnored(), value);
0251:                            }
0252:                        } else if ("pageEncoding".equals(attr)) {
0253:                            if (pageEncodingSeen)
0254:                                err.jspError(n,
0255:                                        "jsp.error.tag.multi.pageencoding");
0256:                            pageEncodingSeen = true;
0257:                            n.getRoot().setPageEncoding(value);
0258:                        }
0259:                    }
0260:
0261:                    // Attributes for imports for this node have been processed by
0262:                    // the parsers, just add them to pageInfo.
0263:                    pageInfo.addImports(n.getImports());
0264:                }
0265:
0266:                public void visit(Node.AttributeDirective n)
0267:                        throws JasperException {
0268:                    // Do nothing, since this attribute directive has already been
0269:                    // validated by TagFileProcessor when it created a TagInfo object
0270:                    // from the tag file in which the directive appeared
0271:                }
0272:
0273:                public void visit(Node.VariableDirective n)
0274:                        throws JasperException {
0275:                    // Do nothing, since this variable directive has already been
0276:                    // validated by TagFileProcessor when it created a TagInfo object
0277:                    // from the tag file in which the directive appeared
0278:                }
0279:
0280:                /*
0281:                 * Compares the page encoding specified in the 'pageEncoding'
0282:                 * attribute of the page directive with the encoding explicitly
0283:                 * specified in the XML prolog (only for XML syntax) and the encoding
0284:                 * specified in the JSP config element whose URL pattern matches the
0285:                 * page, and throws an error in case of a mismatch.
0286:                 */
0287:                private void comparePageEncodings(String pageDirEnc,
0288:                        Node.PageDirective n) throws JasperException {
0289:
0290:                    String configEnc = n.getRoot().getJspConfigPageEncoding();
0291:
0292:                    if (configEnc != null
0293:                            && !pageDirEnc.equals(configEnc)
0294:                            && (!pageDirEnc.startsWith("UTF-16") || !configEnc
0295:                                    .startsWith("UTF-16"))) {
0296:                        err.jspError(n,
0297:                                "jsp.error.config_pagedir_encoding_mismatch",
0298:                                configEnc, pageDirEnc);
0299:                    }
0300:
0301:                    if (n.getRoot().isXmlSyntax()
0302:                            && n.getRoot().isEncodingSpecifiedInProlog()) {
0303:                        String pageEnc = n.getRoot().getPageEncoding();
0304:                        if (!pageDirEnc.equals(pageEnc)
0305:                                && (!pageDirEnc.startsWith("UTF-16") || !pageEnc
0306:                                        .startsWith("UTF-16"))) {
0307:                            err
0308:                                    .jspError(
0309:                                            n,
0310:                                            "jsp.error.prolog_pagedir_encoding_mismatch",
0311:                                            pageEnc, pageDirEnc);
0312:                        }
0313:                    }
0314:                }
0315:            }
0316:
0317:            /**
0318:             * A visitor for validating nodes other than page directives
0319:             */
0320:            static class ValidateVisitor extends Node.Visitor {
0321:
0322:                private PageInfo pageInfo;
0323:                private ErrorDispatcher err;
0324:                private TagInfo tagInfo;
0325:                private ClassLoader loader;
0326:
0327:                private static final JspUtil.ValidAttribute[] jspRootAttrs = {
0328:                        new JspUtil.ValidAttribute("xsi:schemaLocation"),
0329:                        new JspUtil.ValidAttribute("version", true) };
0330:
0331:                private static final JspUtil.ValidAttribute[] includeDirectiveAttrs = { new JspUtil.ValidAttribute(
0332:                        "file", true) };
0333:
0334:                private static final JspUtil.ValidAttribute[] taglibDirectiveAttrs = {
0335:                        new JspUtil.ValidAttribute("uri"),
0336:                        new JspUtil.ValidAttribute("tagdir"),
0337:                        new JspUtil.ValidAttribute("prefix", true) };
0338:
0339:                private static final JspUtil.ValidAttribute[] includeActionAttrs = {
0340:                        new JspUtil.ValidAttribute("page", true, true),
0341:                        new JspUtil.ValidAttribute("flush") };
0342:
0343:                private static final JspUtil.ValidAttribute[] paramActionAttrs = {
0344:                        new JspUtil.ValidAttribute("name", true),
0345:                        new JspUtil.ValidAttribute("value", true, true) };
0346:
0347:                private static final JspUtil.ValidAttribute[] forwardActionAttrs = { new JspUtil.ValidAttribute(
0348:                        "page", true, true) };
0349:
0350:                private static final JspUtil.ValidAttribute[] getPropertyAttrs = {
0351:                        new JspUtil.ValidAttribute("name", true),
0352:                        new JspUtil.ValidAttribute("property", true) };
0353:
0354:                private static final JspUtil.ValidAttribute[] setPropertyAttrs = {
0355:                        new JspUtil.ValidAttribute("name", true),
0356:                        new JspUtil.ValidAttribute("property", true),
0357:                        new JspUtil.ValidAttribute("value", false, true),
0358:                        new JspUtil.ValidAttribute("param") };
0359:
0360:                private static final JspUtil.ValidAttribute[] useBeanAttrs = {
0361:                        new JspUtil.ValidAttribute("id", true),
0362:                        new JspUtil.ValidAttribute("scope"),
0363:                        new JspUtil.ValidAttribute("class"),
0364:                        new JspUtil.ValidAttribute("type"),
0365:                        new JspUtil.ValidAttribute("beanName", false, true) };
0366:
0367:                private static final JspUtil.ValidAttribute[] plugInAttrs = {
0368:                        new JspUtil.ValidAttribute("type", true),
0369:                        new JspUtil.ValidAttribute("code", true),
0370:                        new JspUtil.ValidAttribute("codebase"),
0371:                        new JspUtil.ValidAttribute("align"),
0372:                        new JspUtil.ValidAttribute("archive"),
0373:                        new JspUtil.ValidAttribute("height", false, true),
0374:                        new JspUtil.ValidAttribute("hspace"),
0375:                        new JspUtil.ValidAttribute("jreversion"),
0376:                        new JspUtil.ValidAttribute("name"),
0377:                        new JspUtil.ValidAttribute("vspace"),
0378:                        new JspUtil.ValidAttribute("width", false, true),
0379:                        new JspUtil.ValidAttribute("nspluginurl"),
0380:                        new JspUtil.ValidAttribute("iepluginurl") };
0381:
0382:                private static final JspUtil.ValidAttribute[] attributeAttrs = {
0383:                        new JspUtil.ValidAttribute("name", true),
0384:                        new JspUtil.ValidAttribute("trim") };
0385:
0386:                private static final JspUtil.ValidAttribute[] invokeAttrs = {
0387:                        new JspUtil.ValidAttribute("fragment", true),
0388:                        new JspUtil.ValidAttribute("var"),
0389:                        new JspUtil.ValidAttribute("varReader"),
0390:                        new JspUtil.ValidAttribute("scope") };
0391:
0392:                private static final JspUtil.ValidAttribute[] doBodyAttrs = {
0393:                        new JspUtil.ValidAttribute("var"),
0394:                        new JspUtil.ValidAttribute("varReader"),
0395:                        new JspUtil.ValidAttribute("scope") };
0396:
0397:                private static final JspUtil.ValidAttribute[] jspOutputAttrs = {
0398:                        new JspUtil.ValidAttribute("omit-xml-declaration"),
0399:                        new JspUtil.ValidAttribute("doctype-root-element"),
0400:                        new JspUtil.ValidAttribute("doctype-public"),
0401:                        new JspUtil.ValidAttribute("doctype-system") };
0402:
0403:                /*
0404:                 * Constructor
0405:                 */
0406:                ValidateVisitor(Compiler compiler) {
0407:                    this .pageInfo = compiler.getPageInfo();
0408:                    this .err = compiler.getErrorDispatcher();
0409:                    this .tagInfo = compiler.getCompilationContext()
0410:                            .getTagInfo();
0411:                    this .loader = compiler.getCompilationContext()
0412:                            .getClassLoader();
0413:                }
0414:
0415:                public void visit(Node.JspRoot n) throws JasperException {
0416:                    JspUtil.checkAttributes("Jsp:root", n, jspRootAttrs, err);
0417:                    String version = n.getTextAttribute("version");
0418:                    if (!version.equals("1.2") && !version.equals("2.0")) {
0419:                        err.jspError(n, "jsp.error.jsproot.version.invalid",
0420:                                version);
0421:                    }
0422:                    visitBody(n);
0423:                }
0424:
0425:                public void visit(Node.IncludeDirective n)
0426:                        throws JasperException {
0427:                    JspUtil.checkAttributes("Include directive", n,
0428:                            includeDirectiveAttrs, err);
0429:                    visitBody(n);
0430:                }
0431:
0432:                public void visit(Node.TaglibDirective n)
0433:                        throws JasperException {
0434:                    JspUtil.checkAttributes("Taglib directive", n,
0435:                            taglibDirectiveAttrs, err);
0436:                    // Either 'uri' or 'tagdir' attribute must be specified
0437:                    String uri = n.getAttributeValue("uri");
0438:                    String tagdir = n.getAttributeValue("tagdir");
0439:                    if (uri == null && tagdir == null) {
0440:                        err.jspError(n,
0441:                                "jsp.error.taglibDirective.missing.location");
0442:                    }
0443:                    if (uri != null && tagdir != null) {
0444:                        err
0445:                                .jspError(n,
0446:                                        "jsp.error.taglibDirective.both_uri_and_tagdir");
0447:                    }
0448:                }
0449:
0450:                public void visit(Node.ParamAction n) throws JasperException {
0451:                    JspUtil.checkAttributes("Param action", n,
0452:                            paramActionAttrs, err);
0453:                    // make sure the value of the 'name' attribute is not a
0454:                    // request-time expression
0455:                    throwErrorIfExpression(n, "name", "jsp:param");
0456:                    n.setValue(getJspAttribute("value", null, null, n
0457:                            .getAttributeValue("value"),
0458:                            java.lang.String.class, n, false));
0459:                    visitBody(n);
0460:                }
0461:
0462:                public void visit(Node.ParamsAction n) throws JasperException {
0463:                    // Make sure we've got at least one nested jsp:param
0464:                    Node.Nodes subElems = n.getBody();
0465:                    if (subElems == null) {
0466:                        err.jspError(n, "jsp.error.params.emptyBody");
0467:                    }
0468:                    visitBody(n);
0469:                }
0470:
0471:                public void visit(Node.IncludeAction n) throws JasperException {
0472:                    JspUtil.checkAttributes("Include action", n,
0473:                            includeActionAttrs, err);
0474:                    n.setPage(getJspAttribute("page", null, null, n
0475:                            .getAttributeValue("page"), java.lang.String.class,
0476:                            n, false));
0477:                    visitBody(n);
0478:                };
0479:
0480:                public void visit(Node.ForwardAction n) throws JasperException {
0481:                    JspUtil.checkAttributes("Forward", n, forwardActionAttrs,
0482:                            err);
0483:                    n.setPage(getJspAttribute("page", null, null, n
0484:                            .getAttributeValue("page"), java.lang.String.class,
0485:                            n, false));
0486:                    visitBody(n);
0487:                }
0488:
0489:                public void visit(Node.GetProperty n) throws JasperException {
0490:                    JspUtil.checkAttributes("GetProperty", n, getPropertyAttrs,
0491:                            err);
0492:                }
0493:
0494:                public void visit(Node.SetProperty n) throws JasperException {
0495:                    JspUtil.checkAttributes("SetProperty", n, setPropertyAttrs,
0496:                            err);
0497:                    String name = n.getTextAttribute("name");
0498:                    String property = n.getTextAttribute("property");
0499:                    String param = n.getTextAttribute("param");
0500:                    String value = n.getAttributeValue("value");
0501:
0502:                    n.setValue(getJspAttribute("value", null, null, value,
0503:                            java.lang.Object.class, n, false));
0504:
0505:                    boolean valueSpecified = n.getValue() != null;
0506:
0507:                    if ("*".equals(property)) {
0508:                        if (param != null || valueSpecified)
0509:                            err.jspError(n, "jsp.error.setProperty.invalid");
0510:
0511:                    } else if (param != null && valueSpecified) {
0512:                        err.jspError(n, "jsp.error.setProperty.invalid");
0513:                    }
0514:
0515:                    visitBody(n);
0516:                }
0517:
0518:                public void visit(Node.UseBean n) throws JasperException {
0519:                    JspUtil.checkAttributes("UseBean", n, useBeanAttrs, err);
0520:
0521:                    String name = n.getTextAttribute("id");
0522:                    String scope = n.getTextAttribute("scope");
0523:                    JspUtil.checkScope(scope, n, err);
0524:                    String className = n.getTextAttribute("class");
0525:                    String type = n.getTextAttribute("type");
0526:                    BeanRepository beanInfo = pageInfo.getBeanRepository();
0527:
0528:                    if (className == null && type == null)
0529:                        err.jspError(n, "jsp.error.useBean.missingType");
0530:
0531:                    if (beanInfo.checkVariable(name))
0532:                        err.jspError(n, "jsp.error.useBean.duplicate");
0533:
0534:                    if ("session".equals(scope) && !pageInfo.isSession())
0535:                        err.jspError(n, "jsp.error.useBean.noSession");
0536:
0537:                    Node.JspAttribute jattr = getJspAttribute("beanName", null,
0538:                            null, n.getAttributeValue("beanName"),
0539:                            java.lang.String.class, n, false);
0540:                    n.setBeanName(jattr);
0541:                    if (className != null && jattr != null)
0542:                        err.jspError(n, "jsp.error.useBean.notBoth");
0543:
0544:                    if (className == null)
0545:                        className = type;
0546:
0547:                    beanInfo.addBean(n, name, className, scope);
0548:
0549:                    visitBody(n);
0550:                }
0551:
0552:                public void visit(Node.PlugIn n) throws JasperException {
0553:                    JspUtil.checkAttributes("Plugin", n, plugInAttrs, err);
0554:
0555:                    throwErrorIfExpression(n, "type", "jsp:plugin");
0556:                    throwErrorIfExpression(n, "code", "jsp:plugin");
0557:                    throwErrorIfExpression(n, "codebase", "jsp:plugin");
0558:                    throwErrorIfExpression(n, "align", "jsp:plugin");
0559:                    throwErrorIfExpression(n, "archive", "jsp:plugin");
0560:                    throwErrorIfExpression(n, "hspace", "jsp:plugin");
0561:                    throwErrorIfExpression(n, "jreversion", "jsp:plugin");
0562:                    throwErrorIfExpression(n, "name", "jsp:plugin");
0563:                    throwErrorIfExpression(n, "vspace", "jsp:plugin");
0564:                    throwErrorIfExpression(n, "nspluginurl", "jsp:plugin");
0565:                    throwErrorIfExpression(n, "iepluginurl", "jsp:plugin");
0566:
0567:                    String type = n.getTextAttribute("type");
0568:                    if (type == null)
0569:                        err.jspError(n, "jsp.error.plugin.notype");
0570:                    if (!type.equals("bean") && !type.equals("applet"))
0571:                        err.jspError(n, "jsp.error.plugin.badtype");
0572:                    if (n.getTextAttribute("code") == null)
0573:                        err.jspError(n, "jsp.error.plugin.nocode");
0574:
0575:                    Node.JspAttribute width = getJspAttribute("width", null,
0576:                            null, n.getAttributeValue("width"),
0577:                            java.lang.String.class, n, false);
0578:                    n.setWidth(width);
0579:
0580:                    Node.JspAttribute height = getJspAttribute("height", null,
0581:                            null, n.getAttributeValue("height"),
0582:                            java.lang.String.class, n, false);
0583:                    n.setHeight(height);
0584:
0585:                    visitBody(n);
0586:                }
0587:
0588:                public void visit(Node.NamedAttribute n) throws JasperException {
0589:                    JspUtil
0590:                            .checkAttributes("Attribute", n, attributeAttrs,
0591:                                    err);
0592:                    visitBody(n);
0593:                }
0594:
0595:                public void visit(Node.JspBody n) throws JasperException {
0596:                    visitBody(n);
0597:                }
0598:
0599:                public void visit(Node.Declaration n) throws JasperException {
0600:                    if (pageInfo.isScriptingInvalid()) {
0601:                        err.jspError(n.getStart(), "jsp.error.no.scriptlets");
0602:                    }
0603:                }
0604:
0605:                public void visit(Node.Expression n) throws JasperException {
0606:                    if (pageInfo.isScriptingInvalid()) {
0607:                        err.jspError(n.getStart(), "jsp.error.no.scriptlets");
0608:                    }
0609:                }
0610:
0611:                public void visit(Node.Scriptlet n) throws JasperException {
0612:                    if (pageInfo.isScriptingInvalid()) {
0613:                        err.jspError(n.getStart(), "jsp.error.no.scriptlets");
0614:                    }
0615:                }
0616:
0617:                public void visit(Node.ELExpression n) throws JasperException {
0618:                    if (!pageInfo.isELIgnored()) {
0619:                        String expressions = "${" + new String(n.getText())
0620:                                + "}";
0621:                        ELNode.Nodes el = ELParser.parse(expressions);
0622:                        validateFunctions(el, n);
0623:                        JspUtil.validateExpressions(n.getStart(), expressions,
0624:                                java.lang.String.class, // XXX - Should template text 
0625:                                // always evaluate to String?
0626:                                getFunctionMapper(el), err);
0627:                        n.setEL(el);
0628:                    }
0629:                }
0630:
0631:                public void visit(Node.UninterpretedTag n)
0632:                        throws JasperException {
0633:                    if (n.getNamedAttributeNodes().size() != 0) {
0634:                        err.jspError(n, "jsp.error.namedAttribute.invalidUse");
0635:                    }
0636:
0637:                    Attributes attrs = n.getAttributes();
0638:                    if (attrs != null) {
0639:                        int attrSize = attrs.getLength();
0640:                        Node.JspAttribute[] jspAttrs = new Node.JspAttribute[attrSize];
0641:                        for (int i = 0; i < attrSize; i++) {
0642:                            jspAttrs[i] = getJspAttribute(attrs.getQName(i),
0643:                                    attrs.getURI(i), attrs.getLocalName(i),
0644:                                    attrs.getValue(i), java.lang.Object.class,
0645:                                    n, false);
0646:                        }
0647:                        n.setJspAttributes(jspAttrs);
0648:                    }
0649:
0650:                    visitBody(n);
0651:                }
0652:
0653:                public void visit(Node.CustomTag n) throws JasperException {
0654:
0655:                    TagInfo tagInfo = n.getTagInfo();
0656:                    if (tagInfo == null) {
0657:                        err.jspError(n, "jsp.error.missing.tagInfo", n
0658:                                .getQName());
0659:                    }
0660:
0661:                    /*
0662:                     * The bodyconet of a SimpleTag cannot be JSP.
0663:                     */
0664:                    if (n.implements SimpleTag()
0665:                            && tagInfo.getBodyContent().equalsIgnoreCase(
0666:                                    TagInfo.BODY_CONTENT_JSP)) {
0667:                        err.jspError(n, "jsp.error.simpletag.badbodycontent",
0668:                                tagInfo.getTagClassName());
0669:                    }
0670:
0671:                    /*
0672:                     * If the tag handler declares in the TLD that it supports dynamic
0673:                     * attributes, it also must implement the DynamicAttributes
0674:                     * interface.
0675:                     */
0676:                    if (tagInfo.hasDynamicAttributes()
0677:                            && !n.implements DynamicAttributes()) {
0678:                        err.jspError(n,
0679:                                "jsp.error.dynamic.attributes.not.implemented",
0680:                                n.getQName());
0681:                    }
0682:
0683:                    /*
0684:                     * Make sure all required attributes are present, either as
0685:                     * attributes or named attributes (<jsp:attribute>).
0686:                     * Also make sure that the same attribute is not specified in
0687:                     * both attributes or named attributes.
0688:                     */
0689:                    TagAttributeInfo[] tldAttrs = tagInfo.getAttributes();
0690:                    String customActionUri = n.getURI();
0691:                    Attributes attrs = n.getAttributes();
0692:                    int attrsSize = (attrs == null) ? 0 : attrs.getLength();
0693:                    for (int i = 0; i < tldAttrs.length; i++) {
0694:                        String attr = null;
0695:                        if (attrs != null) {
0696:                            attr = attrs.getValue(tldAttrs[i].getName());
0697:                            if (attr == null) {
0698:                                attr = attrs.getValue(customActionUri,
0699:                                        tldAttrs[i].getName());
0700:                            }
0701:                        }
0702:                        Node.NamedAttribute na = n
0703:                                .getNamedAttributeNode(tldAttrs[i].getName());
0704:
0705:                        if (tldAttrs[i].isRequired() && attr == null
0706:                                && na == null) {
0707:                            err.jspError(n, "jsp.error.missing_attribute",
0708:                                    tldAttrs[i].getName(), n.getLocalName());
0709:                        }
0710:                        if (attr != null && na != null) {
0711:                            err.jspError(n,
0712:                                    "jsp.error.duplicate.name.jspattribute",
0713:                                    tldAttrs[i].getName());
0714:                        }
0715:                    }
0716:
0717:                    Node.Nodes naNodes = n.getNamedAttributeNodes();
0718:                    int jspAttrsSize = naNodes.size() + attrsSize;
0719:                    Node.JspAttribute[] jspAttrs = null;
0720:                    if (jspAttrsSize > 0) {
0721:                        jspAttrs = new Node.JspAttribute[jspAttrsSize];
0722:                    }
0723:                    Hashtable tagDataAttrs = new Hashtable(attrsSize);
0724:
0725:                    checkXmlAttributes(n, jspAttrs, tagDataAttrs);
0726:                    checkNamedAttributes(n, jspAttrs, attrsSize, tagDataAttrs);
0727:
0728:                    TagData tagData = new TagData(tagDataAttrs);
0729:
0730:                    // JSP.C1: It is a (translation time) error for an action that
0731:                    // has one or more variable subelements to have a TagExtraInfo
0732:                    // class that returns a non-null object.
0733:                    TagExtraInfo tei = tagInfo.getTagExtraInfo();
0734:                    if (tei != null && tei.getVariableInfo(tagData) != null
0735:                            && tei.getVariableInfo(tagData).length > 0
0736:                            && tagInfo.getTagVariableInfos().length > 0) {
0737:                        err.jspError("jsp.error.non_null_tei_and_var_subelems",
0738:                                n.getQName());
0739:                    }
0740:
0741:                    n.setTagData(tagData);
0742:                    n.setJspAttributes(jspAttrs);
0743:
0744:                    visitBody(n);
0745:                }
0746:
0747:                public void visit(Node.JspElement n) throws JasperException {
0748:
0749:                    Attributes attrs = n.getAttributes();
0750:                    if (attrs == null) {
0751:                        err.jspError(n, "jsp.error.jspelement.missing.name");
0752:                    }
0753:                    int xmlAttrLen = attrs.getLength();
0754:
0755:                    Node.Nodes namedAttrs = n.getNamedAttributeNodes();
0756:
0757:                    // XML-style 'name' attribute, which is mandatory, must not be
0758:                    // included in JspAttribute array
0759:                    int jspAttrSize = xmlAttrLen - 1 + namedAttrs.size();
0760:
0761:                    Node.JspAttribute[] jspAttrs = new Node.JspAttribute[jspAttrSize];
0762:                    int jspAttrIndex = 0;
0763:
0764:                    // Process XML-style attributes
0765:                    for (int i = 0; i < xmlAttrLen; i++) {
0766:                        if ("name".equals(attrs.getLocalName(i))) {
0767:                            n.setNameAttribute(getJspAttribute(attrs
0768:                                    .getQName(i), attrs.getURI(i), attrs
0769:                                    .getLocalName(i), attrs.getValue(i),
0770:                                    java.lang.String.class, n, false));
0771:                        } else {
0772:                            if (jspAttrIndex < jspAttrSize) {
0773:                                jspAttrs[jspAttrIndex++] = getJspAttribute(
0774:                                        attrs.getQName(i), attrs.getURI(i),
0775:                                        attrs.getLocalName(i), attrs
0776:                                                .getValue(i),
0777:                                        java.lang.Object.class, n, false);
0778:                            }
0779:                        }
0780:                    }
0781:                    if (n.getNameAttribute() == null) {
0782:                        err.jspError(n, "jsp.error.jspelement.missing.name");
0783:                    }
0784:
0785:                    // Process named attributes
0786:                    for (int i = 0; i < namedAttrs.size(); i++) {
0787:                        Node.NamedAttribute na = (Node.NamedAttribute) namedAttrs
0788:                                .getNode(i);
0789:                        jspAttrs[jspAttrIndex++] = new Node.JspAttribute(na,
0790:                                false);
0791:                    }
0792:
0793:                    n.setJspAttributes(jspAttrs);
0794:
0795:                    visitBody(n);
0796:                }
0797:
0798:                public void visit(Node.JspOutput n) throws JasperException {
0799:                    JspUtil.checkAttributes("jsp:output", n, jspOutputAttrs,
0800:                            err);
0801:
0802:                    if (n.getBody() != null) {
0803:                        err.jspError(n, "jsp.error.jspoutput.nonemptybody");
0804:                    }
0805:
0806:                    String omitXmlDecl = n
0807:                            .getAttributeValue("omit-xml-declaration");
0808:                    String doctypeName = n
0809:                            .getAttributeValue("doctype-root-element");
0810:                    String doctypePublic = n
0811:                            .getAttributeValue("doctype-public");
0812:                    String doctypeSystem = n
0813:                            .getAttributeValue("doctype-system");
0814:
0815:                    String omitXmlDeclOld = pageInfo.getOmitXmlDecl();
0816:                    String doctypeNameOld = pageInfo.getDoctypeName();
0817:                    String doctypePublicOld = pageInfo.getDoctypePublic();
0818:                    String doctypeSystemOld = pageInfo.getDoctypeSystem();
0819:
0820:                    if (omitXmlDecl != null && omitXmlDeclOld != null
0821:                            && !omitXmlDecl.equals(omitXmlDeclOld)) {
0822:                        err.jspError(n, "jsp.error.jspoutput.conflict",
0823:                                "omit-xml-declaration", omitXmlDeclOld,
0824:                                omitXmlDecl);
0825:                    }
0826:
0827:                    if (doctypeName != null && doctypeNameOld != null
0828:                            && !doctypeName.equals(doctypeNameOld)) {
0829:                        err.jspError(n, "jsp.error.jspoutput.conflict",
0830:                                "doctype-root-element", doctypeNameOld,
0831:                                doctypeName);
0832:                    }
0833:
0834:                    if (doctypePublic != null && doctypePublicOld != null
0835:                            && !doctypePublic.equals(doctypePublicOld)) {
0836:                        err.jspError(n, "jsp.error.jspoutput.conflict",
0837:                                "doctype-public", doctypePublicOld,
0838:                                doctypePublic);
0839:                    }
0840:
0841:                    if (doctypeSystem != null && doctypeSystemOld != null
0842:                            && !doctypeSystem.equals(doctypeSystemOld)) {
0843:                        err.jspError(n, "jsp.error.jspoutput.conflict",
0844:                                "doctype-system", doctypeSystemOld,
0845:                                doctypeSystem);
0846:                    }
0847:
0848:                    if (doctypeName == null && doctypeSystem != null
0849:                            || doctypeName != null && doctypeSystem == null) {
0850:                        err
0851:                                .jspError(n,
0852:                                        "jsp.error.jspoutput.doctypenamesystem");
0853:                    }
0854:
0855:                    if (doctypePublic != null && doctypeSystem == null) {
0856:                        err.jspError(n,
0857:                                "jsp.error.jspoutput.doctypepulicsystem");
0858:                    }
0859:
0860:                    if (omitXmlDecl != null) {
0861:                        pageInfo.setOmitXmlDecl(omitXmlDecl);
0862:                    }
0863:                    if (doctypeName != null) {
0864:                        pageInfo.setDoctypeName(doctypeName);
0865:                    }
0866:                    if (doctypeSystem != null) {
0867:                        pageInfo.setDoctypeSystem(doctypeSystem);
0868:                    }
0869:                    if (doctypePublic != null) {
0870:                        pageInfo.setDoctypePublic(doctypePublic);
0871:                    }
0872:                }
0873:
0874:                public void visit(Node.InvokeAction n) throws JasperException {
0875:
0876:                    JspUtil.checkAttributes("Invoke", n, invokeAttrs, err);
0877:
0878:                    String scope = n.getTextAttribute("scope");
0879:                    JspUtil.checkScope(scope, n, err);
0880:
0881:                    String var = n.getTextAttribute("var");
0882:                    String varReader = n.getTextAttribute("varReader");
0883:                    if (scope != null && var == null && varReader == null) {
0884:                        err.jspError(n, "jsp.error.missing_var_or_varReader");
0885:                    }
0886:                    if (var != null && varReader != null) {
0887:                        err.jspError(n, "jsp.error.var_and_varReader");
0888:                    }
0889:                }
0890:
0891:                public void visit(Node.DoBodyAction n) throws JasperException {
0892:
0893:                    JspUtil.checkAttributes("DoBody", n, doBodyAttrs, err);
0894:
0895:                    String scope = n.getTextAttribute("scope");
0896:                    JspUtil.checkScope(scope, n, err);
0897:
0898:                    String var = n.getTextAttribute("var");
0899:                    String varReader = n.getTextAttribute("varReader");
0900:                    if (scope != null && var == null && varReader == null) {
0901:                        err.jspError(n, "jsp.error.missing_var_or_varReader");
0902:                    }
0903:                    if (var != null && varReader != null) {
0904:                        err.jspError(n, "jsp.error.var_and_varReader");
0905:                    }
0906:                }
0907:
0908:                /*
0909:                 * Make sure the given custom action does not have any invalid
0910:                 * attributes.
0911:                 *
0912:                 * A custom action and its declared attributes always belong to the
0913:                 * same namespace, which is identified by the prefix name of the
0914:                 * custom tag invocation. For example, in this invocation:
0915:                 *
0916:                 *     <my:test a="1" b="2" c="3"/>, the action
0917:                 *
0918:                 * "test" and its attributes "a", "b", and "c" all belong to the
0919:                 * namespace identified by the prefix "my". The above invocation would
0920:                 * be equivalent to:
0921:                 *
0922:                 *     <my:test my:a="1" my:b="2" my:c="3"/>
0923:                 *
0924:                 * An action attribute may have a prefix different from that of the
0925:                 * action invocation only if the underlying tag handler supports
0926:                 * dynamic attributes, in which case the attribute with the different
0927:                 * prefix is considered a dynamic attribute.
0928:                 */
0929:                private void checkXmlAttributes(Node.CustomTag n,
0930:                        Node.JspAttribute[] jspAttrs, Hashtable tagDataAttrs)
0931:                        throws JasperException {
0932:
0933:                    TagInfo tagInfo = n.getTagInfo();
0934:                    if (tagInfo == null) {
0935:                        err.jspError(n, "jsp.error.missing.tagInfo", n
0936:                                .getQName());
0937:                    }
0938:                    TagAttributeInfo[] tldAttrs = tagInfo.getAttributes();
0939:                    Attributes attrs = n.getAttributes();
0940:
0941:                    for (int i = 0; attrs != null && i < attrs.getLength(); i++) {
0942:                        boolean found = false;
0943:                        for (int j = 0; tldAttrs != null && j < tldAttrs.length; j++) {
0944:                            if (attrs.getLocalName(i).equals(
0945:                                    tldAttrs[j].getName())
0946:                                    && (attrs.getURI(i) == null
0947:                                            || attrs.getURI(i).length() == 0 || attrs
0948:                                            .getURI(i).equals(n.getURI()))) {
0949:                                if (tldAttrs[j].canBeRequestTime()) {
0950:                                    Class expectedType = String.class;
0951:                                    try {
0952:                                        String typeStr = tldAttrs[j]
0953:                                                .getTypeName();
0954:                                        if (tldAttrs[j].isFragment()) {
0955:                                            expectedType = JspFragment.class;
0956:                                        } else if (typeStr != null) {
0957:                                            expectedType = JspUtil.toClass(
0958:                                                    typeStr, loader);
0959:                                        }
0960:                                        jspAttrs[i] = getJspAttribute(attrs
0961:                                                .getQName(i), attrs.getURI(i),
0962:                                                attrs.getLocalName(i), attrs
0963:                                                        .getValue(i),
0964:                                                expectedType, n, false);
0965:                                    } catch (ClassNotFoundException e) {
0966:                                        err
0967:                                                .jspError(
0968:                                                        n,
0969:                                                        "jsp.error.unknown_attribute_type",
0970:                                                        tldAttrs[j].getName(),
0971:                                                        tldAttrs[j]
0972:                                                                .getTypeName());
0973:                                    }
0974:                                } else {
0975:                                    // Attribute does not accept any expressions.
0976:                                    // Make sure its value does not contain any.
0977:                                    if (isExpression(n, attrs.getValue(i))) {
0978:                                        err
0979:                                                .jspError(
0980:                                                        n,
0981:                                                        "jsp.error.attribute.custom.non_rt_with_expr",
0982:                                                        tldAttrs[j].getName());
0983:                                    }
0984:                                    jspAttrs[i] = new Node.JspAttribute(attrs
0985:                                            .getQName(i), attrs.getURI(i),
0986:                                            attrs.getLocalName(i), attrs
0987:                                                    .getValue(i), false, null,
0988:                                            false);
0989:                                }
0990:                                if (jspAttrs[i].isExpression()) {
0991:                                    tagDataAttrs.put(attrs.getQName(i),
0992:                                            TagData.REQUEST_TIME_VALUE);
0993:                                } else {
0994:                                    tagDataAttrs.put(attrs.getQName(i), attrs
0995:                                            .getValue(i));
0996:                                }
0997:                                found = true;
0998:                                break;
0999:                            }
1000:                        }
1001:                        if (!found) {
1002:                            if (tagInfo.hasDynamicAttributes()) {
1003:                                jspAttrs[i] = getJspAttribute(
1004:                                        attrs.getQName(i), attrs.getURI(i),
1005:                                        attrs.getLocalName(i), attrs
1006:                                                .getValue(i),
1007:                                        java.lang.Object.class, n, true);
1008:                            } else {
1009:                                err.jspError(n, "jsp.error.bad_attribute",
1010:                                        attrs.getQName(i), n.getLocalName());
1011:                            }
1012:                        }
1013:                    }
1014:                }
1015:
1016:                /*
1017:                 * Make sure the given custom action does not have any invalid named
1018:                 * attributes
1019:                 */
1020:                private void checkNamedAttributes(Node.CustomTag n,
1021:                        Node.JspAttribute[] jspAttrs, int start,
1022:                        Hashtable tagDataAttrs) throws JasperException {
1023:
1024:                    TagInfo tagInfo = n.getTagInfo();
1025:                    if (tagInfo == null) {
1026:                        err.jspError(n, "jsp.error.missing.tagInfo", n
1027:                                .getQName());
1028:                    }
1029:                    TagAttributeInfo[] tldAttrs = tagInfo.getAttributes();
1030:                    Node.Nodes naNodes = n.getNamedAttributeNodes();
1031:
1032:                    for (int i = 0; i < naNodes.size(); i++) {
1033:                        Node.NamedAttribute na = (Node.NamedAttribute) naNodes
1034:                                .getNode(i);
1035:                        boolean found = false;
1036:                        for (int j = 0; j < tldAttrs.length; j++) {
1037:                            /*
1038:                             * See above comment about namespace matches. For named
1039:                             * attributes, we use the prefix instead of URI as the
1040:                             * match criterion, because in the case of a JSP document,
1041:                             * we'd have to keep track of which namespaces are in scope
1042:                             * when parsing a named attribute, in order to determine
1043:                             * the URI that the prefix of the named attribute's name
1044:                             * matches to.
1045:                             */
1046:                            String attrPrefix = na.getPrefix();
1047:                            if (na.getLocalName().equals(tldAttrs[j].getName())
1048:                                    && (attrPrefix == null
1049:                                            || attrPrefix.length() == 0 || attrPrefix
1050:                                            .equals(n.getPrefix()))) {
1051:                                jspAttrs[start + i] = new Node.JspAttribute(na,
1052:                                        false);
1053:                                NamedAttributeVisitor nav = null;
1054:                                if (na.getBody() != null) {
1055:                                    nav = new NamedAttributeVisitor();
1056:                                    na.getBody().visit(nav);
1057:                                }
1058:                                if (nav != null && nav.hasDynamicContent()) {
1059:                                    tagDataAttrs.put(na.getName(),
1060:                                            TagData.REQUEST_TIME_VALUE);
1061:                                } else {
1062:                                    tagDataAttrs
1063:                                            .put(na.getName(), na.getText());
1064:                                }
1065:                                found = true;
1066:                                break;
1067:                            }
1068:                        }
1069:                        if (!found) {
1070:                            if (tagInfo.hasDynamicAttributes()) {
1071:                                jspAttrs[start + i] = new Node.JspAttribute(na,
1072:                                        true);
1073:                            } else {
1074:                                err.jspError(n, "jsp.error.bad_attribute", na
1075:                                        .getName(), n.getLocalName());
1076:                            }
1077:                        }
1078:                    }
1079:                }
1080:
1081:                /**
1082:                 * Preprocess attributes that can be expressions.  Expression
1083:                 * delimiters are stripped.
1084:                 * <p>
1085:                 * If value is null, checks if there are any
1086:                 * NamedAttribute subelements in the tree node, and if so,
1087:                 * constructs a JspAttribute out of a child NamedAttribute node.
1088:                 */
1089:                private Node.JspAttribute getJspAttribute(String qName,
1090:                        String uri, String localName, String value,
1091:                        Class expectedType, Node n, boolean dynamic)
1092:                        throws JasperException {
1093:
1094:                    Node.JspAttribute result = null;
1095:
1096:                    // XXX Is it an error to see "%=foo%" in non-Xml page?
1097:                    // (We won't see "<%=foo%> in xml page because '<' is not a
1098:                    // valid attribute value in xml).
1099:
1100:                    if (value != null) {
1101:                        if (n.getRoot().isXmlSyntax() && value.startsWith("%=")) {
1102:                            result = new Node.JspAttribute(qName, uri,
1103:                                    localName, value.substring(2, value
1104:                                            .length() - 1), true, null, dynamic);
1105:                        } else if (!n.getRoot().isXmlSyntax()
1106:                                && value.startsWith("<%=")) {
1107:                            result = new Node.JspAttribute(qName, uri,
1108:                                    localName, value.substring(3, value
1109:                                            .length() - 2), true, null, dynamic);
1110:                        } else {
1111:                            // The attribute can contain expressions but is not a
1112:                            // scriptlet expression; thus, we want to run it through 
1113:                            // the expression interpreter
1114:
1115:                            // validate expression syntax if string contains
1116:                            // expression(s)
1117:                            ELNode.Nodes el = ELParser.parse(value);
1118:                            if (el.containsEL() && !pageInfo.isELIgnored()) {
1119:                                validateFunctions(el, n);
1120:                                JspUtil.validateExpressions(n.getStart(),
1121:                                        value, expectedType,
1122:                                        getFunctionMapper(el), this .err);
1123:
1124:                                result = new Node.JspAttribute(qName, uri,
1125:                                        localName, value, false, el, dynamic);
1126:                            } else {
1127:                                value = value.replace(Constants.ESC, '$');
1128:                                result = new Node.JspAttribute(qName, uri,
1129:                                        localName, value, false, null, dynamic);
1130:                            }
1131:                        }
1132:                    } else {
1133:                        // Value is null.  Check for any NamedAttribute subnodes
1134:                        // that might contain the value for this attribute.
1135:                        // Otherwise, the attribute wasn't found so we return null.
1136:
1137:                        Node.NamedAttribute namedAttributeNode = n
1138:                                .getNamedAttributeNode(qName);
1139:                        if (namedAttributeNode != null) {
1140:                            result = new Node.JspAttribute(namedAttributeNode,
1141:                                    dynamic);
1142:                        }
1143:                    }
1144:
1145:                    return result;
1146:                }
1147:
1148:                /*
1149:                 * Checks to see if the given attribute value represents a runtime or
1150:                 * EL expression.
1151:                 */
1152:                private boolean isExpression(Node n, String value) {
1153:                    if ((n.getRoot().isXmlSyntax() && value.startsWith("%="))
1154:                            || (!n.getRoot().isXmlSyntax() && value
1155:                                    .startsWith("<%="))
1156:                            || (value.indexOf("${") != -1 && !pageInfo
1157:                                    .isELIgnored()))
1158:                        return true;
1159:                    else
1160:                        return false;
1161:                }
1162:
1163:                /*
1164:                 * Throws exception if the value of the attribute with the given
1165:                 * name in the given node is given as an RT or EL expression, but the
1166:                 * spec requires a static value.
1167:                 */
1168:                private void throwErrorIfExpression(Node n, String attrName,
1169:                        String actionName) throws JasperException {
1170:                    if (n.getAttributes() != null
1171:                            && n.getAttributes().getValue(attrName) != null
1172:                            && isExpression(n, n.getAttributes().getValue(
1173:                                    attrName))) {
1174:                        err
1175:                                .jspError(
1176:                                        n,
1177:                                        "jsp.error.attribute.standard.non_rt_with_expr",
1178:                                        attrName, actionName);
1179:                    }
1180:                }
1181:
1182:                private static class NamedAttributeVisitor extends Node.Visitor {
1183:                    private boolean hasDynamicContent;
1184:
1185:                    public void doVisit(Node n) throws JasperException {
1186:                        if (!(n instanceof  Node.JspText)
1187:                                && !(n instanceof  Node.TemplateText)) {
1188:                            hasDynamicContent = true;
1189:                        }
1190:                        visitBody(n);
1191:                    }
1192:
1193:                    public boolean hasDynamicContent() {
1194:                        return hasDynamicContent;
1195:                    }
1196:                }
1197:
1198:                private String findUri(String prefix, Node n) {
1199:
1200:                    for (Node p = n; p != null; p = p.getParent()) {
1201:                        Attributes attrs = p.getTaglibAttributes();
1202:                        if (attrs == null) {
1203:                            continue;
1204:                        }
1205:                        for (int i = 0; i < attrs.getLength(); i++) {
1206:                            String name = attrs.getQName(i);
1207:                            int k = name.indexOf(':');
1208:                            if (prefix == null && k < 0) {
1209:                                // prefix not specified and a default ns found
1210:                                return attrs.getValue(i);
1211:                            }
1212:                            if (prefix != null && k >= 0
1213:                                    && prefix.equals(name.substring(k + 1))) {
1214:                                return attrs.getValue(i);
1215:                            }
1216:                        }
1217:                    }
1218:                    return null;
1219:                }
1220:
1221:                /**
1222:                 * Validate functions in EL expressions
1223:                 */
1224:                private void validateFunctions(ELNode.Nodes el, Node n)
1225:                        throws JasperException {
1226:
1227:                    class FVVisitor extends ELNode.Visitor {
1228:
1229:                        Node n;
1230:
1231:                        FVVisitor(Node n) {
1232:                            this .n = n;
1233:                        }
1234:
1235:                        public void visit(ELNode.Function func)
1236:                                throws JasperException {
1237:                            String prefix = func.getPrefix();
1238:                            String function = func.getName();
1239:                            String uri = null;
1240:
1241:                            if (n.getRoot().isXmlSyntax()) {
1242:                                uri = findUri(prefix, n);
1243:                            } else if (prefix != null) {
1244:                                uri = pageInfo.getURI(prefix);
1245:                            }
1246:
1247:                            if (uri == null) {
1248:                                if (prefix == null) {
1249:                                    err.jspError(n,
1250:                                            "jsp.error.noFunctionPrefix",
1251:                                            function);
1252:                                } else {
1253:                                    err
1254:                                            .jspError(
1255:                                                    n,
1256:                                                    "jsp.error.attribute.invalidPrefix",
1257:                                                    prefix);
1258:                                }
1259:                            }
1260:                            TagLibraryInfo taglib = pageInfo.getTaglib(uri);
1261:                            FunctionInfo funcInfo = null;
1262:                            if (taglib != null) {
1263:                                funcInfo = taglib.getFunction(function);
1264:                            }
1265:                            if (funcInfo == null) {
1266:                                err.jspError(n, "jsp.error.noFunction",
1267:                                        function);
1268:                            }
1269:                            // Skip TLD function uniqueness check.  Done by Schema ?
1270:                            func.setUri(uri);
1271:                            func.setFunctionInfo(funcInfo);
1272:                            processSignature(func);
1273:                        }
1274:                    }
1275:
1276:                    el.visit(new FVVisitor(n));
1277:                }
1278:
1279:                private void processSignature(ELNode.Function func)
1280:                        throws JasperException {
1281:                    func.setMethodName(getMethod(func));
1282:                    func.setParameters(getParameters(func));
1283:                }
1284:
1285:                /**
1286:                 * Get the method name from the signature.
1287:                 */
1288:                private String getMethod(ELNode.Function func)
1289:                        throws JasperException {
1290:                    FunctionInfo funcInfo = func.getFunctionInfo();
1291:                    String signature = funcInfo.getFunctionSignature();
1292:
1293:                    int start = signature.indexOf(' ');
1294:                    if (start < 0) {
1295:                        err.jspError("jsp.error.tld.fn.invalid.signature", func
1296:                                .getPrefix(), func.getName());
1297:                    }
1298:                    int end = signature.indexOf('(');
1299:                    if (end < 0) {
1300:                        err
1301:                                .jspError(
1302:                                        "jsp.error.tld.fn.invalid.signature.parenexpected",
1303:                                        func.getPrefix(), func.getName());
1304:                    }
1305:                    return signature.substring(start + 1, end).trim();
1306:                }
1307:
1308:                /**
1309:                 * Get the parameters types from the function signature.
1310:                 * @return An array of parameter class names
1311:                 */
1312:                private String[] getParameters(ELNode.Function func)
1313:                        throws JasperException {
1314:                    FunctionInfo funcInfo = func.getFunctionInfo();
1315:                    String signature = funcInfo.getFunctionSignature();
1316:                    ArrayList params = new ArrayList();
1317:                    // Signature is of the form
1318:                    // <return-type> S <method-name S? '('
1319:                    // < <arg-type> ( ',' <arg-type> )* )? ')'
1320:                    int start = signature.indexOf('(') + 1;
1321:                    boolean lastArg = false;
1322:                    while (true) {
1323:                        int p = signature.indexOf(',', start);
1324:                        if (p < 0) {
1325:                            p = signature.indexOf(')', start);
1326:                            if (p < 0) {
1327:                                err.jspError(
1328:                                        "jsp.error.tld.fn.invalid.signature",
1329:                                        func.getPrefix(), func.getName());
1330:                            }
1331:                            lastArg = true;
1332:                        }
1333:                        String arg = signature.substring(start, p).trim();
1334:                        if (!"".equals(arg)) {
1335:                            params.add(arg);
1336:                        }
1337:                        if (lastArg) {
1338:                            break;
1339:                        }
1340:                        start = p + 1;
1341:                    }
1342:                    return (String[]) params.toArray(new String[params.size()]);
1343:                }
1344:
1345:                private FunctionMapper getFunctionMapper(ELNode.Nodes el)
1346:                        throws JasperException {
1347:
1348:                    class ValidateFunctionMapper implements  FunctionMapper {
1349:
1350:                        private HashMap fnmap = new java.util.HashMap();
1351:
1352:                        public void mapFunction(String fnQName, Method method) {
1353:                            fnmap.put(fnQName, method);
1354:                        }
1355:
1356:                        public Method resolveFunction(String prefix,
1357:                                String localName) {
1358:                            return (Method) this .fnmap.get(prefix + ":"
1359:                                    + localName);
1360:                        }
1361:                    }
1362:
1363:                    class MapperELVisitor extends ELNode.Visitor {
1364:                        ValidateFunctionMapper fmapper;
1365:
1366:                        MapperELVisitor(ValidateFunctionMapper fmapper) {
1367:                            this .fmapper = fmapper;
1368:                        }
1369:
1370:                        public void visit(ELNode.Function n)
1371:                                throws JasperException {
1372:
1373:                            Class c = null;
1374:                            Method method = null;
1375:                            try {
1376:                                c = loader.loadClass(n.getFunctionInfo()
1377:                                        .getFunctionClass());
1378:                            } catch (ClassNotFoundException e) {
1379:                                err.jspError(
1380:                                        "jsp.error.function.classnotfound", n
1381:                                                .getFunctionInfo()
1382:                                                .getFunctionClass(), n
1383:                                                .getPrefix()
1384:                                                + ':' + n.getName(), e
1385:                                                .getMessage());
1386:                            }
1387:                            String paramTypes[] = n.getParameters();
1388:                            int size = paramTypes.length;
1389:                            Class params[] = new Class[size];
1390:                            int i = 0;
1391:                            try {
1392:                                for (i = 0; i < size; i++) {
1393:                                    params[i] = JspUtil.toClass(paramTypes[i],
1394:                                            loader);
1395:                                }
1396:                                method = c.getDeclaredMethod(n.getMethodName(),
1397:                                        params);
1398:                            } catch (ClassNotFoundException e) {
1399:                                err.jspError(
1400:                                        "jsp.error.signature.classnotfound",
1401:                                        paramTypes[i], n.getPrefix() + ':'
1402:                                                + n.getName(), e.getMessage());
1403:                            } catch (NoSuchMethodException e) {
1404:                                err.jspError("jsp.error.noFunctionMethod", n
1405:                                        .getMethodName(), n.getName(), c
1406:                                        .getName());
1407:                            }
1408:                            fmapper.mapFunction(n.getPrefix() + ':'
1409:                                    + n.getName(), method);
1410:                        }
1411:                    }
1412:
1413:                    ValidateFunctionMapper fmapper = new ValidateFunctionMapper();
1414:                    el.visit(new MapperELVisitor(fmapper));
1415:                    return fmapper;
1416:                }
1417:            } // End of ValidateVisitor
1418:
1419:            /**
1420:             * A visitor for validating TagExtraInfo classes of all tags
1421:             */
1422:            static class TagExtraInfoVisitor extends Node.Visitor {
1423:
1424:                private PageInfo pageInfo;
1425:                private ErrorDispatcher err;
1426:
1427:                /*
1428:                 * Constructor
1429:                 */
1430:                TagExtraInfoVisitor(Compiler compiler) {
1431:                    this .pageInfo = compiler.getPageInfo();
1432:                    this .err = compiler.getErrorDispatcher();
1433:                }
1434:
1435:                public void visit(Node.CustomTag n) throws JasperException {
1436:                    TagInfo tagInfo = n.getTagInfo();
1437:                    if (tagInfo == null) {
1438:                        err.jspError(n, "jsp.error.missing.tagInfo", n
1439:                                .getQName());
1440:                    }
1441:
1442:                    ValidationMessage[] errors = tagInfo.validate(n
1443:                            .getTagData());
1444:                    if (errors != null && errors.length != 0) {
1445:                        StringBuffer errMsg = new StringBuffer();
1446:                        errMsg.append("<h3>");
1447:                        errMsg.append(Localizer.getMessage(
1448:                                "jsp.error.tei.invalid.attributes", n
1449:                                        .getQName()));
1450:                        errMsg.append("</h3>");
1451:                        for (int i = 0; i < errors.length; i++) {
1452:                            errMsg.append("<p>");
1453:                            if (errors[i].getId() != null) {
1454:                                errMsg.append(errors[i].getId());
1455:                                errMsg.append(": ");
1456:                            }
1457:                            errMsg.append(errors[i].getMessage());
1458:                            errMsg.append("</p>");
1459:                        }
1460:
1461:                        err.jspError(n, errMsg.toString());
1462:                    }
1463:
1464:                    visitBody(n);
1465:                }
1466:            }
1467:
1468:            public static void validate(Compiler compiler, Node.Nodes page)
1469:                    throws JasperException {
1470:
1471:                /*
1472:                 * Visit the page/tag directives first, as they are global to the page
1473:                 * and are position independent.
1474:                 */
1475:                page.visit(new DirectiveVisitor(compiler));
1476:
1477:                // Determine the default output content type
1478:                PageInfo pageInfo = compiler.getPageInfo();
1479:                String contentType = pageInfo.getContentType();
1480:
1481:                if (contentType == null || contentType.indexOf("charset=") < 0) {
1482:                    boolean isXml = page.getRoot().isXmlSyntax();
1483:                    String defaultType;
1484:                    if (contentType == null) {
1485:                        defaultType = isXml ? "text/xml" : "text/html";
1486:                    } else {
1487:                        defaultType = contentType;
1488:                    }
1489:
1490:                    String charset = null;
1491:                    if (isXml) {
1492:                        charset = "UTF-8";
1493:                    } else {
1494:                        if (!page.getRoot().isDefaultPageEncoding()) {
1495:                            charset = page.getRoot().getPageEncoding();
1496:                        }
1497:                    }
1498:
1499:                    if (charset != null) {
1500:                        pageInfo.setContentType(defaultType + ";charset="
1501:                                + charset);
1502:                    } else {
1503:                        pageInfo.setContentType(defaultType);
1504:                    }
1505:                }
1506:
1507:                /*
1508:                 * Validate all other nodes.
1509:                 * This validation step includes checking a custom tag's mandatory and
1510:                 * optional attributes against information in the TLD (first validation
1511:                 * step for custom tags according to JSP.10.5).
1512:                 */
1513:                page.visit(new ValidateVisitor(compiler));
1514:
1515:                /*
1516:                 * Invoke TagLibraryValidator classes of all imported tags
1517:                 * (second validation step for custom tags according to JSP.10.5).
1518:                 */
1519:                validateXmlView(new PageDataImpl(page, compiler), compiler);
1520:
1521:                /*
1522:                 * Invoke TagExtraInfo method isValid() for all imported tags 
1523:                 * (third validation step for custom tags according to JSP.10.5).
1524:                 */
1525:                page.visit(new TagExtraInfoVisitor(compiler));
1526:
1527:            }
1528:
1529:            //*********************************************************************
1530:            // Private (utility) methods
1531:
1532:            /**
1533:             * Validate XML view against the TagLibraryValidator classes of all
1534:             * imported tag libraries.
1535:             */
1536:            private static void validateXmlView(PageData xmlView,
1537:                    Compiler compiler) throws JasperException {
1538:
1539:                StringBuffer errMsg = null;
1540:                ErrorDispatcher errDisp = compiler.getErrorDispatcher();
1541:
1542:                for (Iterator iter = compiler.getPageInfo().getTaglibs()
1543:                        .iterator(); iter.hasNext();) {
1544:
1545:                    Object o = iter.next();
1546:                    if (!(o instanceof  TagLibraryInfoImpl))
1547:                        continue;
1548:                    TagLibraryInfoImpl tli = (TagLibraryInfoImpl) o;
1549:
1550:                    ValidationMessage[] errors = tli.validate(xmlView);
1551:                    if ((errors != null) && (errors.length != 0)) {
1552:                        if (errMsg == null) {
1553:                            errMsg = new StringBuffer();
1554:                        }
1555:                        errMsg.append("<h3>");
1556:                        errMsg.append(Localizer.getMessage(
1557:                                "jsp.error.tlv.invalid.page", tli
1558:                                        .getShortName()));
1559:                        errMsg.append("</h3>");
1560:                        for (int i = 0; i < errors.length; i++) {
1561:                            if (errors[i] != null) {
1562:                                errMsg.append("<p>");
1563:                                errMsg.append(errors[i].getId());
1564:                                errMsg.append(": ");
1565:                                errMsg.append(errors[i].getMessage());
1566:                                errMsg.append("</p>");
1567:                            }
1568:                        }
1569:                    }
1570:                }
1571:
1572:                if (errMsg != null) {
1573:                    errDisp.jspError(errMsg.toString());
1574:                }
1575:            }
1576:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.