0001: /*
0002: * The Apache Software License, Version 1.1
0003: *
0004: * Copyright (c) 1999 The Apache Software Foundation. All rights
0005: * reserved.
0006: *
0007: * Redistribution and use in source and binary forms, with or without
0008: * modification, are permitted provided that the following conditions
0009: * are met:
0010: *
0011: * 1. Redistributions of source code must retain the above copyright
0012: * notice, this list of conditions and the following disclaimer.
0013: *
0014: * 2. Redistributions in binary form must reproduce the above copyright
0015: * notice, this list of conditions and the following disclaimer in
0016: * the documentation and/or other materials provided with the
0017: * distribution.
0018: *
0019: * 3. The end-user documentation included with the redistribution, if
0020: * any, must include the following acknowlegement:
0021: * "This product includes software developed by the
0022: * Apache Software Foundation (http://www.apache.org/)."
0023: * Alternately, this acknowlegement may appear in the software itself,
0024: * if and wherever such third-party acknowlegements normally appear.
0025: *
0026: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
0027: * Foundation" must not be used to endorse or promote products derived
0028: * from this software without prior written permission. For written
0029: * permission, please contact apache@apache.org.
0030: *
0031: * 5. Products derived from this software may not be called "Apache"
0032: * nor may "Apache" appear in their names without prior written
0033: * permission of the Apache Group.
0034: *
0035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0046: * SUCH DAMAGE.
0047: * ====================================================================
0048: *
0049: * This software consists of voluntary contributions made by many
0050: * individuals on behalf of the Apache Software Foundation. For more
0051: * information on the Apache Software Foundation, please see
0052: * <http://www.apache.org/>.
0053: *
0054: */
0055: package com.rimfaxe.webserver.compiler.jsp;
0056:
0057: import java.util.*;
0058: import java.io.CharArrayWriter;
0059: import javax.servlet.jsp.tagext.*;
0060: import org.xml.sax.Attributes;
0061:
0062: import com.rimfaxe.webserver.compiler.JspToJavaException;
0063:
0064: /**
0065: * An internal data representation of a JSP page or a JSP docuement (XML).
0066: * Also included here is a visitor class for tranversing nodes.
0067: *
0068: * @author Kin-man Chung
0069: * @author Jan Luehe
0070: * @author Lars Andersen
0071: */
0072:
0073: public abstract class Node {
0074:
0075: protected Attributes attrs;
0076: protected Nodes body;
0077: protected char[] text;
0078: protected Mark startMark;
0079: protected int beginJavaLine;
0080: protected int endJavaLine;
0081: protected Node parent;
0082:
0083: /**
0084: * Constructor.
0085: * @param start The location of the jsp page
0086: * @param parent The enclosing node
0087: */
0088: public Node(Mark start, Node parent) {
0089: this .startMark = start;
0090: addToParent(parent);
0091: }
0092:
0093: /**
0094: * Constructor.
0095: * @param attrs The attributes for this node
0096: * @param start The location of the jsp page
0097: * @param parent The enclosing node
0098: */
0099: public Node(Attributes attrs, Mark start, Node parent) {
0100: this .attrs = attrs;
0101: this .startMark = start;
0102: addToParent(parent);
0103: }
0104:
0105: /*
0106: * Constructor.
0107: * @param text The text associated with this node
0108: * @param start The location of the jsp page
0109: * @param parent The enclosing node
0110: */
0111: public Node(char[] text, Mark start, Node parent) {
0112: this .text = text;
0113: this .startMark = start;
0114: addToParent(parent);
0115: }
0116:
0117: public Attributes getAttributes() {
0118: return attrs;
0119: }
0120:
0121: public void setAttributes(Attributes attrs) {
0122: this .attrs = attrs;
0123: }
0124:
0125: public String getAttributeValue(String name) {
0126: return (attrs == null) ? null : attrs.getValue(name);
0127: }
0128:
0129: public Nodes getBody() {
0130: return body;
0131: }
0132:
0133: public void setBody(Nodes body) {
0134: this .body = body;
0135: }
0136:
0137: public char[] getText() {
0138: return text;
0139: }
0140:
0141: public Mark getStart() {
0142: return startMark;
0143: }
0144:
0145: public Node getParent() {
0146: return parent;
0147: }
0148:
0149: public int getBeginJavaLine() {
0150: return beginJavaLine;
0151: }
0152:
0153: public void setBeginJavaLine(int begin) {
0154: beginJavaLine = begin;
0155: }
0156:
0157: public int getEndJavaLine() {
0158: return endJavaLine;
0159: }
0160:
0161: public void setEndJavaLine(int end) {
0162: endJavaLine = end;
0163: }
0164:
0165: /**
0166: * @return true if the current page is in xml syntax, false otherwise.
0167: */
0168: public boolean isXmlSyntax() {
0169: Node r = this ;
0170: while (!(r instanceof Node.Root)) {
0171: r = r.getParent();
0172: if (r == null)
0173: return false;
0174: }
0175:
0176: return r.isXmlSyntax();
0177: }
0178:
0179: /**
0180: * Selects and invokes a method in the visitor class based on the node
0181: * type. This is abstract and should be overrode by the extending classes.
0182: * @param v The visitor class
0183: */
0184: abstract void accept(Visitor v) throws JasperException,
0185: JspToJavaException;
0186:
0187: //*********************************************************************
0188: // Private utility methods
0189:
0190: /*
0191: * Adds this Node to the body of the given parent.
0192: */
0193: private void addToParent(Node parent) {
0194: if (parent != null) {
0195: this .parent = parent;
0196: Nodes parentBody = parent.getBody();
0197: if (parentBody == null) {
0198: parentBody = new Nodes();
0199: parent.setBody(parentBody);
0200: }
0201: parentBody.add(this );
0202: }
0203: }
0204:
0205: /*********************************************************************
0206: * Child classes
0207: */
0208:
0209: /**
0210: * Represents the root of a Jsp page or Jsp document
0211: */
0212: public static class Root extends Node {
0213:
0214: private Root parentRoot;
0215:
0216: Root(Attributes attrs, Mark start, Node parent) {
0217: super (attrs, start, parent);
0218:
0219: // Figure out and set the parent root
0220: Node r = parent;
0221: while ((r != null) && !(r instanceof Node.Root))
0222: r = r.getParent();
0223: parentRoot = (Node.Root) r;
0224: }
0225:
0226: void accept(Visitor v) throws JasperException,
0227: JspToJavaException {
0228: v.visit(this );
0229: }
0230:
0231: public boolean isXmlSyntax() {
0232: return false;
0233: }
0234:
0235: /**
0236: * @ return The enclosing root to this root. Usually represents the
0237: * page that includes this one.
0238: */
0239: public Root getParentRoot() {
0240: return parentRoot;
0241: }
0242: }
0243:
0244: /**
0245: * Represents the root of a Jsp document (XML syntax)
0246: */
0247: public static class JspRoot extends Root {
0248:
0249: public JspRoot(Attributes attrs, Mark start, Node parent) {
0250: super (attrs, start, parent);
0251: }
0252:
0253: void accept(Visitor v) throws JasperException,
0254: JspToJavaException {
0255: v.visit(this );
0256: }
0257:
0258: public boolean isXmlSyntax() {
0259: return true;
0260: }
0261:
0262: }
0263:
0264: /**
0265: * Represents a page directive
0266: */
0267: public static class PageDirective extends Node {
0268:
0269: private Vector imports;
0270:
0271: public PageDirective(Attributes attrs, Mark start, Node parent) {
0272: super (attrs, start, parent);
0273: imports = new Vector();
0274: }
0275:
0276: void accept(Visitor v) throws JasperException,
0277: JspToJavaException {
0278: v.visit(this );
0279: }
0280:
0281: /**
0282: * Parses the comma-separated list of class or package names in the
0283: * given attribute value and adds each component to this
0284: * PageDirective's vector of imported classes and packages.
0285: * @param value A comma-separated string of imports.
0286: */
0287: public void addImport(String value) {
0288: int start = 0;
0289: int index;
0290: while ((index = value.indexOf(',', start)) != -1) {
0291: imports.add(value.substring(start, index).trim());
0292: start = index + 1;
0293: }
0294: if (start == 0) {
0295: // No comma found
0296: imports.add(value.trim());
0297: } else {
0298: imports.add(value.substring(start).trim());
0299: }
0300: }
0301:
0302: public List getImports() {
0303: return imports;
0304: }
0305: }
0306:
0307: /**
0308: * Represents an include directive
0309: */
0310: public static class IncludeDirective extends Node {
0311:
0312: public IncludeDirective(Attributes attrs, Mark start,
0313: Node parent) {
0314: super (attrs, start, parent);
0315: }
0316:
0317: void accept(Visitor v) throws JasperException,
0318: JspToJavaException {
0319: v.visit(this );
0320: }
0321: }
0322:
0323: /**
0324: * Represents a custom taglib directive
0325: */
0326: public static class TaglibDirective extends Node {
0327:
0328: public TaglibDirective(Attributes attrs, Mark start, Node parent) {
0329: super (attrs, start, parent);
0330: }
0331:
0332: void accept(Visitor v) throws JasperException,
0333: JspToJavaException {
0334: v.visit(this );
0335: }
0336: }
0337:
0338: /**
0339: * Represents a Jsp comment
0340: * Comments are kept for completeness.
0341: */
0342: public static class Comment extends Node {
0343:
0344: public Comment(char[] text, Mark start, Node parent) {
0345: super (text, start, parent);
0346: }
0347:
0348: void accept(Visitor v) throws JasperException,
0349: JspToJavaException {
0350: v.visit(this );
0351: }
0352: }
0353:
0354: /**
0355: * Represents an expression, declaration, or scriptlet
0356: */
0357: public static abstract class ScriptingElement extends Node {
0358:
0359: public ScriptingElement(char[] text, Mark start, Node parent) {
0360: super (text, start, parent);
0361: }
0362:
0363: public ScriptingElement(Mark start, Node parent) {
0364: super (start, parent);
0365: }
0366:
0367: /**
0368: * When this node was created from a JSP page in JSP syntax, its text
0369: * was stored as a String in the "text" field, whereas when this node
0370: * was created from a JSP document, its text was stored as one or more
0371: * TemplateText nodes in its body. This method handles either case.
0372: * @return The text string
0373: */
0374: public char[] getText() {
0375: char[] ret = text;
0376: if ((ret == null) && (body != null)) {
0377: CharArrayWriter chars = new CharArrayWriter();
0378: int size = body.size();
0379: for (int i = 0; i < size; i++) {
0380: chars.write(body.getNode(i).getText(), 0, body
0381: .getNode(i).getText().length);
0382: }
0383: ret = chars.toCharArray();
0384: }
0385: return ret;
0386: }
0387:
0388: /** Selects and invokes a method in the visitor class based on the node
0389: * type. This is abstract and should be overrode by the extending classes.
0390: * @param v The visitor class
0391: *
0392: */
0393: void accept(Visitor v) throws JasperException,
0394: JspToJavaException {
0395: }
0396:
0397: }
0398:
0399: /**
0400: * Represents a declaration
0401: */
0402: public static class Declaration extends ScriptingElement {
0403:
0404: public Declaration(char[] text, Mark start, Node parent) {
0405: super (text, start, parent);
0406: }
0407:
0408: public Declaration(Mark start, Node parent) {
0409: super (start, parent);
0410: }
0411:
0412: void accept(Visitor v) throws JasperException,
0413: JspToJavaException {
0414: v.visit(this );
0415: }
0416: }
0417:
0418: /**
0419: * Represents an expression. Expressions in attributes are embedded
0420: * in the attribute string and not here.
0421: */
0422: public static class Expression extends ScriptingElement {
0423:
0424: public Expression(char[] text, Mark start, Node parent) {
0425: super (text, start, parent);
0426: }
0427:
0428: public Expression(Mark start, Node parent) {
0429: super (start, parent);
0430: }
0431:
0432: void accept(Visitor v) throws JasperException,
0433: JspToJavaException {
0434: v.visit(this );
0435: }
0436: }
0437:
0438: /**
0439: * Represents a scriptlet
0440: */
0441: public static class Scriptlet extends ScriptingElement {
0442:
0443: public Scriptlet(char[] text, Mark start, Node parent) {
0444: super (text, start, parent);
0445: }
0446:
0447: public Scriptlet(Mark start, Node parent) {
0448: super (start, parent);
0449: }
0450:
0451: void accept(Visitor v) throws JasperException,
0452: JspToJavaException {
0453: v.visit(this );
0454: }
0455: }
0456:
0457: /**
0458: * Represents a param action
0459: */
0460: public static class ParamAction extends Node {
0461:
0462: JspAttribute value;
0463:
0464: public ParamAction(Attributes attrs, Mark start, Node parent) {
0465: super (attrs, start, parent);
0466: }
0467:
0468: void accept(Visitor v) throws JasperException,
0469: JspToJavaException {
0470: v.visit(this );
0471: }
0472:
0473: public void setValue(JspAttribute value) {
0474: this .value = value;
0475: }
0476:
0477: public JspAttribute getValue() {
0478: return value;
0479: }
0480: }
0481:
0482: /**
0483: * Represents a params action
0484: */
0485: public static class ParamsAction extends Node {
0486:
0487: public ParamsAction(Mark start, Node parent) {
0488: super (start, parent);
0489: }
0490:
0491: void accept(Visitor v) throws JasperException,
0492: JspToJavaException {
0493: v.visit(this );
0494: }
0495: }
0496:
0497: /**
0498: * Represents a fallback action
0499: */
0500: public static class FallBackAction extends Node {
0501:
0502: public FallBackAction(Mark start, char[] text, Node parent) {
0503: super (text, start, parent);
0504: }
0505:
0506: void accept(Visitor v) throws JasperException,
0507: JspToJavaException {
0508: v.visit(this );
0509: }
0510: }
0511:
0512: /**
0513: * Represents an include action
0514: */
0515: public static class IncludeAction extends Node {
0516:
0517: private JspAttribute page;
0518:
0519: public IncludeAction(Attributes attrs, Mark start, Node parent) {
0520: super (attrs, start, parent);
0521: }
0522:
0523: void accept(Visitor v) throws JasperException,
0524: JspToJavaException {
0525: v.visit(this );
0526: }
0527:
0528: public void setPage(JspAttribute page) {
0529: this .page = page;
0530: }
0531:
0532: public JspAttribute getPage() {
0533: return page;
0534: }
0535: }
0536:
0537: /**
0538: * Represents a forward action
0539: */
0540: public static class ForwardAction extends Node {
0541:
0542: private JspAttribute page;
0543:
0544: public ForwardAction(Attributes attrs, Mark start, Node parent) {
0545: super (attrs, start, parent);
0546: }
0547:
0548: void accept(Visitor v) throws JasperException,
0549: JspToJavaException {
0550: v.visit(this );
0551: }
0552:
0553: public void setPage(JspAttribute page) {
0554: this .page = page;
0555: }
0556:
0557: public JspAttribute getPage() {
0558: return page;
0559: }
0560: }
0561:
0562: /**
0563: * Represents a getProperty action
0564: */
0565: public static class GetProperty extends Node {
0566:
0567: public GetProperty(Attributes attrs, Mark start, Node parent) {
0568: super (attrs, start, parent);
0569: }
0570:
0571: void accept(Visitor v) throws JasperException,
0572: JspToJavaException {
0573: v.visit(this );
0574: }
0575: }
0576:
0577: /**
0578: * Represents a setProperty action
0579: */
0580: public static class SetProperty extends Node {
0581:
0582: private JspAttribute value;
0583:
0584: public SetProperty(Attributes attrs, Mark start, Node parent) {
0585: super (attrs, start, parent);
0586: }
0587:
0588: void accept(Visitor v) throws JasperException,
0589: JspToJavaException {
0590: v.visit(this );
0591: }
0592:
0593: public void setValue(JspAttribute value) {
0594: this .value = value;
0595: }
0596:
0597: public JspAttribute getValue() {
0598: return value;
0599: }
0600: }
0601:
0602: /**
0603: * Represents a useBean action
0604: */
0605: public static class UseBean extends Node {
0606:
0607: JspAttribute beanName;
0608:
0609: public UseBean(Attributes attrs, Mark start, Node parent) {
0610: super (attrs, start, parent);
0611: }
0612:
0613: void accept(Visitor v) throws JasperException,
0614: JspToJavaException {
0615: v.visit(this );
0616: }
0617:
0618: public void setBeanName(JspAttribute beanName) {
0619: this .beanName = beanName;
0620: }
0621:
0622: public JspAttribute getBeanName() {
0623: return beanName;
0624: }
0625: }
0626:
0627: /**
0628: * Represents a plugin action
0629: */
0630: public static class PlugIn extends Node {
0631:
0632: JspAttribute height;
0633: JspAttribute width;
0634:
0635: public PlugIn(Attributes attrs, Mark start, Node parent) {
0636: super (attrs, start, parent);
0637: }
0638:
0639: void accept(Visitor v) throws JasperException,
0640: JspToJavaException {
0641: v.visit(this );
0642: }
0643:
0644: public void setHeight(JspAttribute height) {
0645: this .height = height;
0646: }
0647:
0648: public void setWidth(JspAttribute width) {
0649: this .width = width;
0650: }
0651:
0652: public JspAttribute getHeight() {
0653: return height;
0654: }
0655:
0656: public JspAttribute getWidth() {
0657: return width;
0658: }
0659: }
0660:
0661: /**
0662: * Represents an uninterpreted tag, from a Jsp document
0663: */
0664: public static class UninterpretedTag extends Node {
0665: private String tagName;
0666:
0667: public UninterpretedTag(Attributes attrs, Mark start,
0668: String name, Node parent) {
0669: super (attrs, start, parent);
0670: tagName = name;
0671: }
0672:
0673: void accept(Visitor v) throws JasperException,
0674: JspToJavaException {
0675: v.visit(this );
0676: }
0677:
0678: public String getName() {
0679: return tagName;
0680: }
0681: }
0682:
0683: /**
0684: * Represents a custom tag
0685: */
0686: public static class CustomTag extends Node {
0687: private String name;
0688: private String prefix;
0689: private String shortName;
0690: private JspAttribute[] jspAttrs;
0691: private TagData tagData;
0692: private boolean scriptless; // true if the tag and its body
0693: // contians no scripting elements.
0694: private boolean hasUsebean;
0695: private boolean hasIncludeAction;
0696: private boolean hasSetProperty;
0697: private boolean hasScriptingVars;
0698: private String tagHandlerPoolName;
0699: private TagInfo tagInfo;
0700: private VariableInfo[] varInfos;
0701: private VariableInfo[] nestedVarInfos;
0702: private int customNestingLevel;
0703:
0704: public CustomTag(Attributes attrs, Mark start, String name,
0705: String prefix, String shortName, TagInfo tagInfo,
0706: Node parent) {
0707: super (attrs, start, parent);
0708: this .name = name;
0709: this .prefix = prefix;
0710: this .shortName = shortName;
0711: this .tagInfo = tagInfo;
0712: this .customNestingLevel = computeCustomNestingLevel();
0713: }
0714:
0715: void accept(Visitor v) throws JasperException,
0716: JspToJavaException {
0717:
0718: //System.out.println("Node.CustomTag "+shortName+" accept("+v.getClass().getName()+")");
0719: v.visit(this );
0720:
0721: }
0722:
0723: /**
0724: * @return The full tag name
0725: */
0726: public String getName() {
0727: return name;
0728: }
0729:
0730: /**
0731: * @return The tag prefix
0732: */
0733: public String getPrefix() {
0734: return prefix;
0735: }
0736:
0737: /**
0738: * @return The tag name without prefix
0739: */
0740: public String getShortName() {
0741: return shortName;
0742: }
0743:
0744: public void setJspAttributes(JspAttribute[] jspAttrs) {
0745: this .jspAttrs = jspAttrs;
0746: }
0747:
0748: public JspAttribute[] getJspAttributes() {
0749: return jspAttrs;
0750: }
0751:
0752: public void setTagData(TagData tagData) {
0753: this .tagData = tagData;
0754: this .varInfos = tagInfo.getVariableInfo(tagData);
0755: determineNestedVarInfos();
0756: }
0757:
0758: public TagData getTagData() {
0759: return tagData;
0760: }
0761:
0762: public void setScriptless(boolean s) {
0763: scriptless = s;
0764: }
0765:
0766: public boolean isScriptless() {
0767: return scriptless;
0768: }
0769:
0770: public void setHasUsebean(boolean u) {
0771: hasUsebean = u;
0772: }
0773:
0774: public boolean isHasUsebean() {
0775: return hasUsebean;
0776: }
0777:
0778: public void setHasIncludeAction(boolean i) {
0779: hasIncludeAction = i;
0780: }
0781:
0782: public boolean isHasIncludeAction() {
0783: return hasIncludeAction;
0784: }
0785:
0786: public void setHasSetProperty(boolean s) {
0787: hasSetProperty = s;
0788: }
0789:
0790: public boolean isHasSetProperty() {
0791: return hasSetProperty;
0792: }
0793:
0794: public void setHasScriptingVars(boolean s) {
0795: hasScriptingVars = s;
0796: }
0797:
0798: public boolean hasScriptingVars() {
0799: return hasScriptingVars;
0800: }
0801:
0802: public void setTagHandlerPoolName(String s) {
0803: tagHandlerPoolName = s;
0804: }
0805:
0806: public String getTagHandlerPoolName() {
0807: return tagHandlerPoolName;
0808: }
0809:
0810: public TagInfo getTagInfo() {
0811: return tagInfo;
0812: }
0813:
0814: public TagVariableInfo[] getTagVariableInfos() {
0815: return tagInfo.getTagVariableInfos();
0816: }
0817:
0818: public VariableInfo[] getVariableInfos() {
0819: return varInfos;
0820: }
0821:
0822: public VariableInfo[] getNestedVariableInfos() {
0823: return nestedVarInfos;
0824: }
0825:
0826: /*
0827: * Gets this custom tag's custom nesting level, which is given as
0828: * the number of times this custom tag is nested inside itself.
0829: */
0830: public int getCustomNestingLevel() {
0831: return customNestingLevel;
0832: }
0833:
0834: /*
0835: * Computes this custom tag's custom nesting level, which corresponds
0836: * to the number of times this custom tag is nested inside itself.
0837: *
0838: * Example:
0839: *
0840: * <g:h>
0841: * <a:b> -- nesting level 0
0842: * <c:d>
0843: * <e:f>
0844: * <a:b> -- nesting level 1
0845: * <a:b> -- nesting level 2
0846: * </a:b>
0847: * </a:b>
0848: * <a:b> -- nesting level 1
0849: * </a:b>
0850: * </e:f>
0851: * </c:d>
0852: * </a:b>
0853: * </g:h>
0854: *
0855: * @return Custom tag's nesting level
0856: */
0857: private int computeCustomNestingLevel() {
0858: int n = 0;
0859: Node p = parent;
0860: while (p != null) {
0861: if ((p instanceof Node.CustomTag)
0862: && name.equals(((Node.CustomTag) p).name)) {
0863: n++;
0864: }
0865: p = p.parent;
0866: }
0867: return n;
0868: }
0869:
0870: /*
0871: * Determines all the scripting variables with NESTED scope contained
0872: * in this custom action's VariableInfo[] that are not already
0873: * contained in the VariableInfo[] of a custom action of the same type
0874: * in the parent chain.
0875: */
0876: private void determineNestedVarInfos() {
0877:
0878: if (varInfos == null) {
0879: return;
0880: }
0881:
0882: Vector vec = new Vector();
0883:
0884: if (customNestingLevel == 0) {
0885: // tag not nested inside itself
0886: for (int i = 0; i < varInfos.length; i++) {
0887: if (varInfos[i].getScope() == VariableInfo.NESTED
0888: && varInfos[i].getDeclare()) {
0889: vec.add(varInfos[i]);
0890: }
0891: }
0892: } else {
0893: for (int i = 0; i < varInfos.length; i++) {
0894: if (varInfos[i].getScope() != VariableInfo.NESTED
0895: || !varInfos[i].getDeclare()) {
0896: continue;
0897: }
0898: Node p = parent;
0899: boolean found = false;
0900: while ((p != null) && !found) {
0901: if ((p instanceof Node.CustomTag)
0902: && name
0903: .equals(((Node.CustomTag) p).name)) {
0904: VariableInfo[] parentVarInfos = ((Node.CustomTag) p)
0905: .getVariableInfos();
0906: for (int j = 0; j < parentVarInfos.length; j++) {
0907: if (varInfos[i].getVarName().equals(
0908: parentVarInfos[j].getVarName())) {
0909: found = true;
0910: break;
0911: }
0912: }
0913: }
0914: p = p.parent;
0915: }
0916: if (p == null) {
0917: vec.add(varInfos[i]);
0918: }
0919: }
0920: }
0921:
0922: if (vec.size() > 0) {
0923: nestedVarInfos = (VariableInfo[]) vec
0924: .toArray(new VariableInfo[vec.size()]);
0925: }
0926: }
0927: }
0928:
0929: /**
0930: * Represents the body of a <jsp:text> element
0931: */
0932: public static class JspText extends Node {
0933:
0934: public JspText(Mark start, Node parent) {
0935: super (start, parent);
0936: }
0937:
0938: void accept(Visitor v) throws JasperException,
0939: JspToJavaException {
0940: v.visit(this );
0941: }
0942: }
0943:
0944: /**
0945: * Represents a template text string
0946: */
0947: public static class TemplateText extends Node {
0948:
0949: public TemplateText(char[] text, Mark start, Node parent) {
0950: super (text, start, parent);
0951: }
0952:
0953: void accept(Visitor v) throws JasperException,
0954: JspToJavaException {
0955: v.visit(this );
0956: }
0957: }
0958:
0959: /*********************************************************************
0960: * Auxillary classes used in Node
0961: */
0962:
0963: /**
0964: * Represents attributes that can be request time expressions.
0965: */
0966:
0967: public static class JspAttribute {
0968:
0969: private String name;
0970: private String value;
0971: private boolean expression;
0972:
0973: JspAttribute(String name, String value, boolean expr) {
0974: this .name = name;
0975: this .value = value;
0976: this .expression = expr;
0977: }
0978:
0979: /**
0980: * @return The name of the attribute
0981: */
0982: public String getName() {
0983: return name;
0984: }
0985:
0986: /**
0987: * @return the value for the attribute, or the expression string
0988: * (stripped of "<%=", "%>", "%=", or "%")
0989: */
0990: public String getValue() {
0991: return value;
0992: }
0993:
0994: /**
0995: * @return true is the value represents an expression
0996: */
0997: public boolean isExpression() {
0998: return expression;
0999: }
1000: }
1001:
1002: /**
1003: * An ordered list of Node, used to represent the body of an element, or
1004: * a jsp page of jsp document.
1005: */
1006: public static class Nodes {
1007:
1008: private List list;
1009: private Node.Root root; // null if this is not a page
1010:
1011: public Nodes() {
1012: list = new Vector();
1013: }
1014:
1015: public Nodes(Node.Root root) {
1016: this .root = root;
1017: list = new Vector();
1018: list.add(root);
1019: }
1020:
1021: /**
1022: * Appends a node to the list
1023: * @param n The node to add
1024: */
1025: public void add(Node n) {
1026: list.add(n);
1027: root = null;
1028: }
1029:
1030: /**
1031: * Visit the nodes in the list with the supplied visitor
1032: * @param v The visitor used
1033: */
1034: public void visit(Visitor v) throws JasperException,
1035: JspToJavaException {
1036: //System.out.println("Node.Nodes visit("+v+")");
1037: Iterator iter = list.iterator();
1038: while (iter.hasNext()) {
1039: Node n = (Node) iter.next();
1040: n.accept(v);
1041: }
1042: }
1043:
1044: public int size() {
1045: return list.size();
1046: }
1047:
1048: public Node getNode(int index) {
1049: Node n = null;
1050: try {
1051: n = (Node) list.get(index);
1052: } catch (ArrayIndexOutOfBoundsException e) {
1053: }
1054: return n;
1055: }
1056:
1057: public Node.Root getRoot() {
1058: return root;
1059: }
1060: }
1061:
1062: /**
1063: * A visitor class for visiting the node. This class also provides the
1064: * default action (i.e. nop) for each of the child class of the Node.
1065: * An actual visitor should extend this class and supply the visit
1066: * method for the nodes that it cares.
1067: */
1068: public static class Visitor {
1069:
1070: /**
1071: * The method provides a place to put actions that are common to
1072: * all nodes. Override this in the child visitor class if need to.
1073: */
1074: protected void doVisit(Node n) throws JasperException,
1075: JspToJavaException {
1076: }
1077:
1078: /**
1079: * Visit the body of a node, using the current visitor
1080: */
1081: protected void visitBody(Node n) throws JasperException,
1082: JspToJavaException {
1083: if (n.getBody() != null) {
1084: n.getBody().visit(this );
1085: }
1086: }
1087:
1088: public void visit(Root n) throws JasperException,
1089: JspToJavaException {
1090: doVisit(n);
1091: visitBody(n);
1092: }
1093:
1094: public void visit(JspRoot n) throws JasperException,
1095: JspToJavaException {
1096: doVisit(n);
1097: visitBody(n);
1098: }
1099:
1100: public void visit(PageDirective n) throws JasperException,
1101: JspToJavaException {
1102: doVisit(n);
1103: }
1104:
1105: public void visit(IncludeDirective n) throws JasperException,
1106: JspToJavaException {
1107: doVisit(n);
1108: visitBody(n);
1109: }
1110:
1111: public void visit(TaglibDirective n) throws JasperException,
1112: JspToJavaException {
1113: doVisit(n);
1114: }
1115:
1116: public void visit(Comment n) throws JasperException,
1117: JspToJavaException {
1118: doVisit(n);
1119: }
1120:
1121: public void visit(Declaration n) throws JasperException,
1122: JspToJavaException {
1123: doVisit(n);
1124: }
1125:
1126: public void visit(Expression n) throws JasperException,
1127: JspToJavaException {
1128: doVisit(n);
1129: }
1130:
1131: public void visit(Scriptlet n) throws JasperException,
1132: JspToJavaException {
1133: doVisit(n);
1134: }
1135:
1136: public void visit(IncludeAction n) throws JasperException,
1137: JspToJavaException {
1138: doVisit(n);
1139: visitBody(n);
1140: }
1141:
1142: public void visit(ForwardAction n) throws JasperException,
1143: JspToJavaException {
1144: doVisit(n);
1145: visitBody(n);
1146: }
1147:
1148: public void visit(GetProperty n) throws JasperException,
1149: JspToJavaException {
1150: doVisit(n);
1151: }
1152:
1153: public void visit(SetProperty n) throws JasperException,
1154: JspToJavaException {
1155: doVisit(n);
1156: }
1157:
1158: public void visit(ParamAction n) throws JasperException,
1159: JspToJavaException {
1160: doVisit(n);
1161: }
1162:
1163: public void visit(ParamsAction n) throws JasperException,
1164: JspToJavaException {
1165: doVisit(n);
1166: visitBody(n);
1167: }
1168:
1169: public void visit(FallBackAction n) throws JasperException,
1170: JspToJavaException {
1171: doVisit(n);
1172: visitBody(n);
1173: }
1174:
1175: public void visit(UseBean n) throws JasperException,
1176: JspToJavaException {
1177: doVisit(n);
1178: visitBody(n);
1179: }
1180:
1181: public void visit(PlugIn n) throws JasperException,
1182: JspToJavaException {
1183: doVisit(n);
1184: visitBody(n);
1185: }
1186:
1187: public void visit(CustomTag n) throws JasperException,
1188: JspToJavaException {
1189: //System.out.println("Node.Visitor visit(CustomTag)");
1190: doVisit(n);
1191: visitBody(n);
1192: }
1193:
1194: public void visit(UninterpretedTag n) throws JasperException,
1195: JspToJavaException {
1196: doVisit(n);
1197: visitBody(n);
1198: }
1199:
1200: public void visit(JspText n) throws JasperException,
1201: JspToJavaException {
1202: doVisit(n);
1203: visitBody(n);
1204: }
1205:
1206: public void visit(TemplateText n) throws JasperException,
1207: JspToJavaException {
1208: doVisit(n);
1209: }
1210: }
1211: }
|