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

org.apache.tapestry5.dom.Document Maven / Gradle / Ivy

Go to download

Central module for Tapestry, containing interfaces to the Java Servlet API and all core services and components.

There is a newer version: 5.8.6
Show newest version
// Copyright 2006, 2007, 2008, 2009, 2010 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.tapestry5.dom;

import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;

/**
 * The root node of a DOM.
 */
public final class Document extends Node
{
    /**
     * XML Namespace URI. May be bound to the "xml" but must not be bound to any other prefix.
     */
    public static final String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";

    /**
     * Namespace used exclusively for defining namespaces.
     */
    public static final String XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";

    private Element rootElement;

    private DTD dtd;

    private final MarkupModel model;

    private final String encoding;

    /**
     * Non-element content that comes between the DOCTYPE and the root element.
     */
    private List preamble;

    public Document(MarkupModel model)
    {
        this(model, null);
    }

    public Document(MarkupModel model, String encoding)
    {
        super(null);

        assert model != null;

        this.model = model;
        this.encoding = encoding;
    }

    @Override
    public Document getDocument()
    {
        return this;
    }

    /**
     * Finds an element based on a path of element names.
     * 
     * @param path
     *            slash separated series of element names
     * @return the matching element, or null if not found
     * @see Element#find(String)
     */
    public Element find(String path)
    {
        assert InternalUtils.isNonBlank(path);

        if (rootElement == null)
            return null;

        int slashx = path.indexOf("/");

        String rootElementName = slashx < 0 ? path : path.substring(0, slashx);

        if (!rootElement.getName().equals(rootElementName))
            return null;

        return slashx < 0 ? rootElement : rootElement.find(path.substring(slashx + 1));
    }

    /**
     * Builds with an instance of {@link DefaultMarkupModel}.
     */
    public Document()
    {
        this(new DefaultMarkupModel());
    }

    public MarkupModel getMarkupModel()
    {
        return model;
    }

    /**
     * Creates the root element for this document, replacing any previous root element.
     */
    public Element newRootElement(String name)
    {
        rootElement = new Element(this, null, name);

        return rootElement;
    }

    /**
     * Creates a new root element within a namespace.
     * 
     * @param namespace
     *            URI of namespace containing the element
     * @param name
     *            name of element with namespace
     * @return the root element
     */
    public Element newRootElement(String namespace, String name)
    {
        rootElement = new Element(this, namespace, name);

        return rootElement;
    }

    @Override
    public void toMarkup(Document document, PrintWriter writer, Map namespaceURIToPrefix)
    {
        if (model.isXML())
        {
            writer.print("\n");
        }
        if (dtd != null)
        {
            dtd.toMarkup(writer);
        }

        if (preamble != null)
        {
            for (Node n : preamble)
                n.toMarkup(this, writer, namespaceURIToPrefix);
        }

        if (rootElement == null)
            return;

        Map initialNamespaceMap = CollectionFactory.newMap();

        initialNamespaceMap.put("xml", "http://www.w3.org/XML/1998/namespace");
        initialNamespaceMap.put("xmlns", "http://www.w3.org/2000/xmlns/");

        rootElement.toMarkup(document, writer, initialNamespaceMap);
    }

    public Element getRootElement()
    {
        return rootElement;
    }

    /**
     * Tries to find an element in this document whose id is specified.
     * 
     * @param id
     *            the value of the id attribute of the element being looked for
     * @return the element if found. null if not found.
     */
    public Element getElementById(String id)
    {
        return rootElement.getElementById(id);
    }

    public void dtd(String name, String publicId, String systemId)
    {
        dtd = new DTD(name, publicId, systemId);
    }

    @Override
    protected Map getNamespaceURIToPrefix()
    {
        if (rootElement == null) { return Collections.emptyMap(); }

        return rootElement.getNamespaceURIToPrefix();
    }

    /**
     * Visits the root element of the document.
     * 
     * @param visitor
     *            callback
     * @since 5.1.0.0
     */
    void visit(Visitor visitor)
    {
        rootElement.visit(visitor);
    }

    private  T newChild(T child)
    {
        if (preamble == null)
            preamble = CollectionFactory.newList();

        preamble.add(child);

        return child;
    }

    /**
     * Adds the comment and returns this document for further construction.
     * 
     * @since 5.1.0.0
     */
    public Document comment(String text)
    {
        newChild(new Comment(null, text));

        return this;
    }

    /**
     * Adds the raw text and returns this document for further construction.
     * 
     * @since 5.1.0.0
     */
    public Document raw(String text)
    {
        newChild(new Raw(null, text));

        return this;
    }

    /**
     * Adds and returns a new text node (the text node is returned so that {@link Text#write(String)} or [@link
     * {@link Text#writef(String, Object[])} may be invoked.
     * 
     * @param text
     *            initial text for the node
     * @return the new Text node
     */
    public Text text(String text)
    {
        return newChild(new Text(null, text));
    }

    /**
     * Adds and returns a new CDATA node.
     * 
     * @param content
     *            the content to be rendered by the node
     * @return the newly created node
     */
    public CData cdata(String content)
    {
        return newChild(new CData(null, content));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy