/*
 * 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);
        }

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

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

        public void visit(Node.CustomTag n) throws JasperException {
            boolean resetDefaultNSSave = resetDefaultNS;
            appendTag(n, resetDefaultNS);
            resetDefaultNS = resetDefaultNSSave;
        }

        public void visit(Node.UninterpretedTag n) throws JasperException {
            boolean resetDefaultNSSave = resetDefaultNS;
            appendTag(n, resetDefaultNS);
            resetDefaultNS = resetDefaultNSSave;
        }

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

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

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

        public void visit(Node.TagDirective n) throws JasperException {
            appendTagDirective(n);
        }

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

        public void visit(Node.VariableDirective n) throws JasperException {
            appendTag(n);
        }
        
        public void visit(Node.TemplateText n) throws JasperException {
            /*
             * If the template text came from a JSP page written in JSP syntax,
             * create a jsp:text element for it (JSP 5.3.2).
             */
            appendText(n.getText(), !n.getRoot().isXmlSyntax());
        }

        /*
         * Appends the given tag, including its body, to the XML view.
         */
        private void appendTag(Node n) throws JasperException {
            appendTag(n, false);
        }

        /*
         * Appends the given tag, including its body, to the XML view,
         * and optionally reset default namespace to "", if none specified.
         */
        private void appendTag(Node n, boolean addDefaultNS)
                throws JasperException {

            Node.Nodes body = n.getBody();
            String text = n.getText();

            buf.append("<").append(n.getQName());
            buf.append("\n");

            printAttributes(n, addDefaultNS);
            buf.append("  ").append(jspIdPrefix).append(":id").append("=\"");
            buf.append(jspId++).append("\"\n");

            if (ROOT_ACTION.equals(n.getLocalName()) || body != null
                        || text != null) {
                buf.append(">\n");
                if (ROOT_ACTION.equals(n.getLocalName())) {
                    if (compiler.getCompilationContext().isTagFile()) {
                        appendTagDirective();
                    } else {
                        appendPageDirective();
                    }
                }
                if (body != null) {
                    body.visit(this);
                } else {
                    appendText(text, false);
                }
                buf.append("</" + n.getQName() + ">\n");
            } else {
                buf.append("/>\n");
            }
        }

        /*
         * Appends the page directive with the given attributes to the XML
         * view.
         *
         * Since the import attribute of the page directive is the only page
         * attribute that is allowed to appear multiple times within the same
         * document, and since XML allows only single-value attributes,
         * the values of multiple import attributes must be combined into one,
         * separated by comma.
         *
         * If the given page directive contains just 'contentType' and/or
         * 'pageEncoding' attributes, we ignore it, as we've already appended
         * a page directive containing just these two attributes.
         */
        private void appendPageDirective(Node.PageDirective n) {
            boolean append = false;
            Attributes attrs = n.getAttributes();
            int len = (attrs == null) ? 0 : attrs.getLength();
            for (int i=0; i<len; i++) {
                String attrName = attrs.getQName(i);
                if (!"pageEncoding".equals(attrName)
                        && !"contentType".equals(attrName)) {
                    append = true;
                    break;
                }
            }
            if (!append) {
                return;
            }

            buf.append("<").append(n.getQName());
            buf.append("\n");

            // append jsp:id
            buf.append("  ").append(jspIdPrefix).append(":id").append("=\"");
            buf.append(jspId++).append("\"\n");

            // append remaining attributes
            for (int i=0; i<len; i++) {
                String attrName = attrs.getQName(i);
                if ("import".equals(attrName) || "contentType".equals(attrName)
                        || "pageEncoding".equals(attrName)) {
                    /*
                     * Page directive's 'import' attribute is considered
                     * further down, and its 'pageEncoding' and 'contentType'
                     * attributes are ignored, since we've already appended
                     * a new page directive containing just these two
                     * attributes
                     */
                    continue;
                }
                String value = attrs.getValue(i);
                buf.append("  ").append(attrName).append("=\"");
                buf.append(JspUtil.getExprInXml(value)).append("\"\n");
            }
            if (n.getImports().size() > 0) {
                // Concatenate names of imported classes/packages
                boolean first = true;
                ListIterator iter = n.getImports().listIterator();
                while (iter.hasNext()) {
                    if (first) {
                        first = false;
                        buf.append("  import=\"");
                    } else {
                        buf.append(",");
                    }
                    buf.append(JspUtil.getExprInXml((String) iter.next()));
                }
                buf.append("\"\n");
            }
            buf.append("/>\n");
        }

        /*
         * Appends a page directive with 'pageEncoding' and 'contentType'
         * attributes.
         *
         * The value of the 'pageEncoding' attribute is hard-coded
         * to UTF-8, whereas the value of the 'contentType' attribute, which
         * is identical to what the container will pass to
         * ServletResponse.setContentType(), is derived from the pageInfo.
         */
        private void appendPageDirective() {
            buf.append("<").append(JSP_PAGE_DIRECTIVE_ACTION);
            buf.append("\n");

            // append jsp:id
            buf.append("  ").append(jspIdPrefix).append(":id").append("=\"");
            buf.append(jspId++).append("\"\n");
            buf.append("  ").append("pageEncoding").append("=\"UTF-8\"\n");
            buf.append("  ").append("contentType").append("=\"");
            buf.append(compiler.getPageInfo().getContentType()).append("\"\n");
            buf.append("/>\n");            
        }

        /*
         * Appends the tag directive with the given attributes to the XML
         * view.
         *
         * If the given tag directive contains just a 'pageEncoding'
         * attributes, we ignore it, as we've already appended
         * a tag directive containing just this attributes.
         */
        private void appendTagDirective(Node.TagDirective n)
                throws JasperException {

            boolean append = false;
            Attributes attrs = n.getAttributes();
            int len = (attrs == null) ? 0 : attrs.getLength();
            for (int i=0; i<len; i++) {
                String attrName = attrs.getQName(i);
                if (!"pageEncoding".equals(attrName)) {
                    append = true;
                    break;
                }
            }
            if (!append) {
                return;
            }

            appendTag(n);
        }

        /*
         * Appends a tag directive containing a single 'pageEncoding'
         * attribute whose value is hard-coded to UTF-8.
         */
        private void appendTagDirective() {
            buf.append("<").append(JSP_TAG_DIRECTIVE_ACTION);
            buf.append("\n");

            // append jsp:id
            buf.append("  ").append(jspIdPrefix).append(":id").append("=\"");
            buf.append(jspId++).append("\"\n");
            buf.append("  ").append("pageEncoding").append("=\"UTF-8\"\n");
            buf.append("/>\n");            
        }

        private void appendText(String text, boolean createJspTextElement) {
            if (createJspTextElement) {
                buf.append("<").append(JSP_TEXT_ACTION);
                buf.append("\n");

                // append jsp:id
                buf.append("  ").append(jspIdPrefix).append(":id").append("=\"");
                buf.append(jspId++).append("\"\n");
                buf.append(">\n");

                appendCDATA(text);
                buf.append(JSP_TEXT_ACTION_END);
                buf.append("\n");
            } else {
                appendCDATA(text);
            }
        }
        
        /*
         * Appends the given text as a CDATA section to the XML view, unless
         * the text has already been marked as CDATA.
         */
        private void appendCDATA(String text) {
            buf.append(CDATA_START_SECTION);
            buf.append(escapeCDATA(text));
            buf.append(CDATA_END_SECTION);
        }

        /*
         * Escapes any occurrences of "]]>" (by replacing them with "]]&gt;")
         * within the given text, so it can be included in a CDATA section.
         */
        private String escapeCDATA(String text) {
            if( text==null ) return "";
            int len = text.length();
            CharArrayWriter result = new CharArrayWriter(len);
            for (int i=0; i<len; i++) {
                if (((i+2) < len)
                        && (text.charAt(i) == ']')
                        && (text.charAt(i+1) == ']')
                        && (text.charAt(i+2) == '>')) {
                    // match found
                    result.write(']');
                    result.write(']');
                    result.write('&');
                    result.write('g');
                    result.write('t');
                    result.write(';');
                    i += 2;
                } else {
                    result.write(text.charAt(i));
                }
            }
            return result.toString();
        }

        /*
         * Appends the attributes of the given Node to the XML view.
         */
        private void printAttributes(Node n, boolean addDefaultNS) {

            /*
             * Append "xmlns" attributes that represent tag libraries
             */
            Attributes attrs = n.getTaglibAttributes();
            int len = (attrs == null) ? 0 : attrs.getLength();
            for (int i=0; i<len; i++) {
                String name = attrs.getQName(i);
                String value = attrs.getValue(i);
                buf.append("  ").append(name).append("=\"").append(value).append("\"\n");
            }

            /*
             * Append "xmlns" attributes that do not represent tag libraries
             */
            attrs = n.getNonTaglibXmlnsAttributes();
            len = (attrs == null) ? 0 : attrs.getLength();
            boolean defaultNSSeen = false;
            for (int i=0; i<len; i++) {
                String name = attrs.getQName(i);
                String value = attrs.getValue(i);
                buf.append("  ").append(name).append("=\"").append(value).append("\"\n");
                defaultNSSeen |= "xmlns".equals(name);
            }
            if (addDefaultNS && !defaultNSSeen) {
                buf.append("  xmlns=\"\"\n");
            }
            resetDefaultNS = false;

            /*
             * Append all other attributes
             */
            attrs = n.getAttributes();
            len = (attrs == null) ? 0 : attrs.getLength();
            for (int i=0; i<len; i++) {
                String name = attrs.getQName(i);
                String value = attrs.getValue(i);
                buf.append("  ").append(name).append("=\"");
                buf.append(JspUtil.getExprInXml(value)).append("\"\n");
            }
        }

        /*
         * Appends XML prolog with encoding declaration.
         */
        private void appendXmlProlog() {
            buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
        }
    }
}

