⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pagedataimpl.java

📁 业界著名的tomcat服务器的最新6.0的源代码。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.CharArrayWriter;
import java.io.UnsupportedEncodingException;
import java.util.ListIterator;
import javax.servlet.jsp.tagext.PageData;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.jasper.JasperException;

/**
 * An implementation of <tt>javax.servlet.jsp.tagext.PageData</tt> which
 * builds the XML view of a given page.
 *
 * The XML view is built in two passes:
 *
 * During the first pass, the FirstPassVisitor collects the attributes of the
 * top-level jsp:root and those of the jsp:root elements of any included
 * pages, and adds them to the jsp:root element of the XML view.
 * In addition, any taglib directives are converted into xmlns: attributes and
 * added to the jsp:root element of the XML view.
 * This pass ignores any nodes other than JspRoot and TaglibDirective.
 *
 * During the second pass, the SecondPassVisitor produces the XML view, using
 * the combined jsp:root attributes determined in the first pass and any
 * remaining pages nodes (this pass ignores any JspRoot and TaglibDirective
 * nodes).
 *
 * @author Jan Luehe
 */
class PageDataImpl extends PageData implements TagConstants {

    private static final String JSP_VERSION = "2.0";
    private static final String CDATA_START_SECTION = "<![CDATA[\n";
    private static final String CDATA_END_SECTION = "]]>\n";

    // string buffer used to build XML view
    private StringBuffer buf;

    /**
     * Constructor.
     *
     * @param page the page nodes from which to generate the XML view
     */
    public PageDataImpl(Node.Nodes page, Compiler compiler)
	        throws JasperException {

	// First pass
	FirstPassVisitor firstPass = new FirstPassVisitor(page.getRoot(),
							  compiler.getPageInfo());
	page.visit(firstPass);

	// Second pass
	buf = new StringBuffer();
	SecondPassVisitor secondPass
	    = new SecondPassVisitor(page.getRoot(), buf, compiler,
				    firstPass.getJspIdPrefix());
	page.visit(secondPass);
    }

    /**
     * Returns the input stream of the XML view.
     *
     * @return the input stream of the XML view
     */
    public InputStream getInputStream() {
	// Turn StringBuffer into InputStream
        try {
            return new ByteArrayInputStream(buf.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException uee) {
	    // should never happen
            throw new RuntimeException(uee.toString());
        }
    }

    /*
     * First-pass Visitor for JspRoot nodes (representing jsp:root elements)
     * and TablibDirective nodes, ignoring any other nodes.
     *
     * The purpose of this Visitor is to collect the attributes of the
     * top-level jsp:root and those of the jsp:root elements of any included
     * pages, and add them to the jsp:root element of the XML view.
     * In addition, this Visitor converts any taglib directives into xmlns:
     * attributes and adds them to the jsp:root element of the XML view.
     */
    static class FirstPassVisitor
	        extends Node.Visitor implements TagConstants {

	private Node.Root root;
	private AttributesImpl rootAttrs;
	private PageInfo pageInfo;

	// Prefix for the 'id' attribute
	private String jspIdPrefix;

	/*
	 * Constructor
	 */
	public FirstPassVisitor(Node.Root root, PageInfo pageInfo) {
	    this.root = root;
	    this.pageInfo = pageInfo;
	    this.rootAttrs = new AttributesImpl();
	    this.rootAttrs.addAttribute("", "", "version", "CDATA",
					JSP_VERSION);
	    this.jspIdPrefix = "jsp";
	}

	public void visit(Node.Root n) throws JasperException {
	    visitBody(n);
	    if (n == root) {
		/*
		 * Top-level page.
		 *
		 * Add
		 *   xmlns:jsp="http://java.sun.com/JSP/Page"
		 * attribute only if not already present.
		 */
		if (!JSP_URI.equals(rootAttrs.getValue("xmlns:jsp"))) {
		    rootAttrs.addAttribute("", "", "xmlns:jsp", "CDATA",
					   JSP_URI);
		}

		if (pageInfo.isJspPrefixHijacked()) {
		    /*
		     * 'jsp' prefix has been hijacked, that is, bound to a
		     * namespace other than the JSP namespace. This means that
		     * when adding an 'id' attribute to each element, we can't
		     * use the 'jsp' prefix. Therefore, create a new prefix 
		     * (one that is unique across the translation unit) for use
		     * by the 'id' attribute, and bind it to the JSP namespace
		     */
		    jspIdPrefix += "jsp";
		    while (pageInfo.containsPrefix(jspIdPrefix)) {
			jspIdPrefix += "jsp";
		    }
		    rootAttrs.addAttribute("", "", "xmlns:" + jspIdPrefix,
					   "CDATA", JSP_URI);
		}

		root.setAttributes(rootAttrs);
	    }
	}

	public void visit(Node.JspRoot n) throws JasperException {
	    addAttributes(n.getTaglibAttributes());
            addAttributes(n.getNonTaglibXmlnsAttributes());
	    addAttributes(n.getAttributes());

	    visitBody(n);
	}

	/*
	 * Converts taglib directive into "xmlns:..." attribute of jsp:root
	 * element.
	 */
	public void visit(Node.TaglibDirective n) throws JasperException {
	    Attributes attrs = n.getAttributes();
	    if (attrs != null) {
		String qName = "xmlns:" + attrs.getValue("prefix");
		/*
		 * According to javadocs of org.xml.sax.helpers.AttributesImpl,
		 * the addAttribute method does not check to see if the
		 * specified attribute is already contained in the list: This
		 * is the application's responsibility!
		 */
		if (rootAttrs.getIndex(qName) == -1) {
		    String location = attrs.getValue("uri");
		    if (location != null) {
                        if (location.startsWith("/")) {
                            location = URN_JSPTLD + location;
                        }
			rootAttrs.addAttribute("", "", qName, "CDATA",
					       location);
		    } else {
			location = attrs.getValue("tagdir");
			rootAttrs.addAttribute("", "", qName, "CDATA",
					       URN_JSPTAGDIR + location);
		    }
		}
	    }
	}

	public String getJspIdPrefix() {
	    return jspIdPrefix;
	}

	private void addAttributes(Attributes attrs) {
	    if (attrs != null) {
		int len = attrs.getLength();

		for (int i=0; i<len; i++) {
                    String qName = attrs.getQName(i);
		    if ("version".equals(qName)) {
			continue;
		    }

                    // Bugzilla 35252: http://issues.apache.org/bugzilla/show_bug.cgi?id=35252
                    if(rootAttrs.getIndex(qName) == -1) {
                        rootAttrs.addAttribute(attrs.getURI(i),
                                               attrs.getLocalName(i),
                                               qName,
                                               attrs.getType(i),
                                               attrs.getValue(i));
                    }
		}
	    }
	}
    }


    /*
     * Second-pass Visitor responsible for producing XML view and assigning
     * each element a unique jsp:id attribute.
     */
    static class SecondPassVisitor extends Node.Visitor
        	implements TagConstants {

	private Node.Root root;
	private StringBuffer buf;
	private Compiler compiler;
	private String jspIdPrefix;
	private boolean resetDefaultNS = false;

	// Current value of jsp:id attribute
	private int jspId;

	/*
	 * Constructor
	 */
	public SecondPassVisitor(Node.Root root, StringBuffer buf,
				 Compiler compiler, String jspIdPrefix) {
	    this.root = root;
	    this.buf = buf;
	    this.compiler = compiler;
	    this.jspIdPrefix = jspIdPrefix;
	}

	/*
	 * Visits root node.
	 */
	public void visit(Node.Root n) throws JasperException {
	    if (n == this.root) {
		// top-level page
		appendXmlProlog();
		appendTag(n);
	    } else {
		boolean resetDefaultNSSave = resetDefaultNS;
		if (n.isXmlSyntax()) {
		    resetDefaultNS = true;
		}
		visitBody(n);
		resetDefaultNS = resetDefaultNSSave;
	    }
	}

	/*
	 * Visits jsp:root element of JSP page in XML syntax.
	 *
	 * Any nested jsp:root elements (from pages included via an
	 * include directive) are ignored.
	 */
	public void visit(Node.JspRoot n) throws JasperException {
	    visitBody(n);
	}

	public void visit(Node.PageDirective n) throws JasperException {
	    appendPageDirective(n);
	}

	public void visit(Node.IncludeDirective n) throws JasperException {
	    // expand in place
	    visitBody(n);
	}

	public void visit(Node.Comment n) throws JasperException {
	    // Comments are ignored in XML view
	}

	public void visit(Node.Declaration n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.Expression n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.Scriptlet n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.JspElement n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.ELExpression n) throws JasperException {
	    if (!n.getRoot().isXmlSyntax()) {
		buf.append("<").append(JSP_TEXT_ACTION);
		buf.append(" ");
	        buf.append(jspIdPrefix);
		buf.append(":id=\"");
		buf.append(jspId++).append("\">");
	    }
	    buf.append("${");
            buf.append(JspUtil.escapeXml(n.getText()));
	    buf.append("}");
	    if (!n.getRoot().isXmlSyntax()) {
		buf.append(JSP_TEXT_ACTION_END);
	    }
	    buf.append("\n");
	}

	public void visit(Node.IncludeAction n) throws JasperException {
	    appendTag(n);
	}
    
	public void visit(Node.ForwardAction n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.GetProperty n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.SetProperty n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.ParamAction n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.ParamsAction n) throws JasperException {
	    appendTag(n);
	}

	public void visit(Node.FallBackAction n) throws JasperException {
	    appendTag(n);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -