All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jasper.compiler.Node Maven / Gradle / Ivy

There is a newer version: 5.5.23
Show newest version
/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 
package org.apache.jasper.compiler;

import java.util.*;
import java.io.CharArrayWriter;
import javax.servlet.jsp.tagext.*;
import org.xml.sax.Attributes;
import org.apache.jasper.JasperException;

/**
 * An internal data representation of a JSP page or a JSP docuement (XML).
 * Also included here is a visitor class for tranversing nodes.
 *
 * @author Kin-man Chung
 * @author Jan Luehe
 */

public abstract class Node {
    
    protected Attributes attrs;
    protected Nodes body;
    protected char[] text;
    protected Mark startMark;
    protected int beginJavaLine;
    protected int endJavaLine;
    protected Node parent;

    /**
     * Constructor.
     * @param start The location of the jsp page
     * @param parent The enclosing node
     */
    public Node(Mark start, Node parent) {
        this.startMark = start;
        addToParent(parent);
    }

    /**
     * Constructor.
     * @param attrs The attributes for this node
     * @param start The location of the jsp page
     * @param parent The enclosing node
     */
    public Node(Attributes attrs, Mark start, Node parent) {
        this.attrs = attrs;
        this.startMark = start;
        addToParent(parent);
    }

    /*
     * Constructor.
     * @param text The text associated with this node
     * @param start The location of the jsp page
     * @param parent The enclosing node
     */
    public Node(char[] text, Mark start, Node parent) {
        this.text = text;
        this.startMark = start;
        addToParent(parent);
    }

    public Attributes getAttributes() {
        return attrs;
    }

    public void setAttributes(Attributes attrs) {
        this.attrs = attrs;
    }

    public String getAttributeValue(String name) {
        return (attrs == null) ? null : attrs.getValue(name);
    }

    public Nodes getBody() {
        return body;
    }

    public void setBody(Nodes body) {
        this.body = body;
    }

    public char[] getText() {
        return text;
    }

    public Mark getStart() {
        return startMark;
    }

    public Node getParent() {
        return parent;
    }

    public int getBeginJavaLine() {
        return beginJavaLine;
    }

    public void setBeginJavaLine(int begin) {
        beginJavaLine = begin;
    }

    public int getEndJavaLine() {
        return endJavaLine;
    }

    public void setEndJavaLine(int end) {
        endJavaLine = end;
    }

    /**
     * @return true if the current page is in xml syntax, false otherwise.
     */
    public boolean isXmlSyntax() {
        Node r = this;
        while (!(r instanceof Node.Root)) {
            r = r.getParent();
            if (r == null)
                return false;
        }

        return r.isXmlSyntax();
    }

    /**
     * Selects and invokes a method in the visitor class based on the node
     * type.  This is abstract and should be overrode by the extending classes.
     * @param v The visitor class
     */
    abstract void accept(Visitor v) throws JasperException;


    //*********************************************************************
    // Private utility methods

    /*
     * Adds this Node to the body of the given parent.
     */
    private void addToParent(Node parent) {
        if (parent != null) {
            this.parent = parent;
            Nodes parentBody = parent.getBody();
            if (parentBody == null) {
                parentBody = new Nodes();
                parent.setBody(parentBody);
            }
            parentBody.add(this);
        }
    }


    /*********************************************************************
     * Child classes
     */
    
    /**
     * Represents the root of a Jsp page or Jsp document
     */
    public static class Root extends Node {

        private Root parentRoot;

        Root(Attributes attrs, Mark start, Node parent) {
            super(attrs, start, parent);

            // Figure out and set the parent root
            Node r = parent;
            while ((r != null) && !(r instanceof Node.Root))
                r = r.getParent();
            parentRoot = (Node.Root) r;
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }

        public boolean isXmlSyntax() {
            return false;
        }

        /**
         * @return The enclosing root to this root.  Usually represents the
         * page that includes this one.
         */
        public Root getParentRoot() {
            return parentRoot;
        }
    }
    
    /**
     * Represents the root of a Jsp document (XML syntax)
     */
    public static class JspRoot extends Root {

        public JspRoot(Attributes attrs, Mark start, Node parent) {
            super(attrs, start, parent);
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }

        public boolean isXmlSyntax() {
            return true;
        }

    }

    /**
     * Represents a page directive
     */
    public static class PageDirective extends Node {

        private Vector imports;

        public PageDirective(Attributes attrs, Mark start, Node parent) {
            super(attrs, start, parent);
            imports = new Vector();
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }

        /**
         * Parses the comma-separated list of class or package names in the
         * given attribute value and adds each component to this
         * PageDirective's vector of imported classes and packages.
         * @param value A comma-separated string of imports.
         */
        public void addImport(String value) {
            int start = 0;
            int index;
            while ((index = value.indexOf(',', start)) != -1) {
                imports.add(value.substring(start, index).trim());
                start = index + 1;
            }
            if (start == 0) {
                // No comma found
                imports.add(value.trim());
            } else {
                imports.add(value.substring(start).trim());
            }
        }

        public List getImports() {
            return imports;
        }
    }

    /**
     * Represents an include directive
     */
    public static class IncludeDirective extends Node {

        public IncludeDirective(Attributes attrs, Mark start, Node parent) {
            super(attrs, start, parent);
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }
    }

    /**
     * Represents a custom taglib directive
     */
    public static class TaglibDirective extends Node {

        public TaglibDirective(Attributes attrs, Mark start, Node parent) {
            super(attrs, start, parent);
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }
    }

    /**
     * Represents a Jsp comment
     * Comments are kept for completeness.
     */
    public static class Comment extends Node {

        public Comment(char[] text, Mark start, Node parent) {
            super(text, start, parent);
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }
    }

    /**
     * Represents an expression, declaration, or scriptlet
     */
    public static abstract class ScriptingElement extends Node {

        public ScriptingElement(char[] text, Mark start, Node parent) {
            super(text, start, parent);
        }

        public ScriptingElement(Mark start, Node parent) {
            super(start, parent);
        }

        /**
         * When this node was created from a JSP page in JSP syntax, its text
         * was stored as a String in the "text" field, whereas when this node
         * was created from a JSP document, its text was stored as one or more
         * TemplateText nodes in its body. This method handles either case.
         * @return The text string
         */
        public char[] getText() {
            char[] ret = text;
            if ((ret == null) && (body != null)) {
                CharArrayWriter chars = new CharArrayWriter();
                int size = body.size();
                for (int i=0; i
         *     -- nesting level 0
         *      
         *        
         *           -- nesting level 1
         *             -- nesting level 2
         *            
         *          
         *           -- nesting level 1
         *          
         *        
         *      
         *    
         *  
         * 
         * @return Custom tag's nesting level
         */
        private int makeCustomNestingLevel() {
            int n = 0;
            Node p = parent;
            while (p != null) {
                if ((p instanceof Node.CustomTag)
                        && name.equals(((Node.CustomTag) p).name)) {
                    n++;
                }
                p = p.parent;
            }
            return n;
        }
    }

    /**
     * Represents the body of a  element
     */
    public static class JspText extends Node {

        public JspText(Mark start, Node parent) {
            super(start, parent);
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }
    }

    /**
     * Represents a template text string
     */
    public static class TemplateText extends Node {

        public TemplateText(char[] text, Mark start, Node parent) {
            super(text, start, parent);
        }

        public void accept(Visitor v) throws JasperException {
            v.visit(this);
        }
    }

    /*********************************************************************
     * Auxillary classes used in Node
     */

    /**
     * Represents attributes that can be request time expressions.
     */

    public static class JspAttribute {

        private String name;
        private String value;
        private boolean expression;

        JspAttribute(String name, String value, boolean expr) {
            this.name = name;
            this.value = value;
            this.expression = expr;
        }

        /**
          * @return The name of the attribute
         */
        public String getName() {
            return name;
        }

        /**
         * @return the value for the attribute, or the expression string
         *           (stripped of "<%=", "%>", "%=", or "%")
         */
        public String getValue() {
            return value;
        }

        /**
         * @return true is the value represents an expression
         */
        public boolean isExpression() {
            return expression;
        }
    }

    /**
     * An ordered list of Node, used to represent the body of an element, or
     * a jsp page of jsp document.
     */
    public static class Nodes {

        private List list;
        private Node.Root root;                // null if this is not a page

        public Nodes() {
            list = new Vector();
        }

        public Nodes(Node.Root root) {
            this.root = root;
            list = new Vector();
            list.add(root);
        }

        /**
         * Appends a node to the list
         * @param n The node to add
         */
        public void add(Node n) {
            list.add(n);
            root = null;
        }

        /**
         * Visit the nodes in the list with the supplied visitor
         * @param v The visitor used
         */
        public void visit(Visitor v) throws JasperException {
            Iterator iter = list.iterator();
            while (iter.hasNext()) {
                Node n = (Node) iter.next();
                n.accept(v);
            }
        }

        public int size() {
            return list.size();
        }

        public Node getNode(int index) {
            Node n = null;
            try {
                n = (Node) list.get(index);
            } catch (ArrayIndexOutOfBoundsException e) {
            }
            return n;
        }
        
        public Node.Root getRoot() {
            return root;
        }
    }

    /**
     * A visitor class for visiting the node.  This class also provides the
     * default action (i.e. nop) for each of the child class of the Node.
     * An actual visitor should extend this class and supply the visit
     * method for the nodes that it cares.
     */
    public static class Visitor {

        /**
         * The method provides a place to put actions that are common to
         * all nodes.  Override this in the child visitor class if need to.
         */
        protected void doVisit(Node n) throws JasperException {
        }

        /**
         * Visit the body of a node, using the current visitor
         */
        protected void visitBody(Node n) throws JasperException {
            if (n.getBody() != null) {
                n.getBody().visit(this);
            }
        }

        public void visit(Root n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(JspRoot n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(PageDirective n) throws JasperException {
            doVisit(n);
        }

        public void visit(IncludeDirective n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(TaglibDirective n) throws JasperException {
            doVisit(n);
        }

        public void visit(Comment n) throws JasperException {
            doVisit(n);
        }

        public void visit(Declaration n) throws JasperException {
            doVisit(n);
        }

        public void visit(Expression n) throws JasperException {
            doVisit(n);
        }

        public void visit(Scriptlet n) throws JasperException {
            doVisit(n);
        }

        public void visit(IncludeAction n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(ForwardAction n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(GetProperty n) throws JasperException {
            doVisit(n);
        }

        public void visit(SetProperty n) throws JasperException {
            doVisit(n);
        }

        public void visit(ParamAction n) throws JasperException {
            doVisit(n);
        }

        public void visit(ParamsAction n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(FallBackAction n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(UseBean n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(PlugIn n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(CustomTag n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(UninterpretedTag n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(JspText n) throws JasperException {
            doVisit(n);
            visitBody(n);
        }

        public void visit(TemplateText n) throws JasperException {
            doVisit(n);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy