com.caucho.xml2.QElement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resin Show documentation
Show all versions of resin Show documentation
Resin Java Application Server
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
* Free SoftwareFoundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.xml2;
import com.caucho.util.CharBuffer;
import org.w3c.dom.*;
import java.io.IOException;
import java.util.HashMap;
import javax.xml.namespace.QName;
/**
* Resin's implementation of the DOM element.
*/
public class QElement extends QAttributedNode implements CauchoElement {
private QName _name;
/**
* Create a new element.
*/
public QElement()
{
}
/**
* Create a new named element.
*
* @param name the element's name.
*/
public QElement(String name)
{
_name = new QName(name);
}
/**
* Create a new named element.
*
* @param name the element's name.
*/
public QElement(String name, String namespace)
{
_name = new QName(name, namespace);
}
/**
* Create a new named element.
*
* @param name the element's name.
*/
public QElement(QName name)
{
_name = name;
}
protected QElement(QDocument owner, QName name)
{
_owner = owner;
_name = name;
}
/**
* Create a new named element with initial parameters.
*
* @param name the element's name.
* @param attributes the element's attributes.
*/
QElement(QName name, HashMap attributes)
{
_name = name;
}
/**
* Assign a name to the element. Not normally called by external
* API.
*
* @param name the element's name.
*/
public void setName(QName name)
{
_name = name;
}
/**
* Returns the qname
*/
public QName getQName()
{
return _name;
}
/**
* Returns the element's qualified-name as the node name.
*/
public String getNodeName()
{
return _name.getLocalPart();
}
/**
* Returns the element's qualified-name as the node name.
*/
public String getTagName()
{
return _name.getLocalPart();
}
/**
* Returns the local part of the element's name.
*/
public String getLocalName()
{
return _name.getLocalPart();
}
/**
* Returns the namespace prefix for the element.
*/
public String getPrefix()
{
return _name.getPrefix();
}
/**
* Returns the canonical name of the element.
*/
public String getCanonicalName()
{
return _name.toString();
}
/**
* Returns the namespace of the element.
*/
public String getNamespaceURI()
{
return _name.getNamespaceURI();
}
/**
* Given a prefix, returns the namespace in effect at this element.
*
* @param prefix the prefix to test.
* @return the namespace URL matching the prefix or null.
*/
public String getNamespace(String prefix)
{
if (prefix == null)
return getNamespace("", "xmlns");
else
return getNamespace(prefix, "xmlns:" + prefix);
}
private String getNamespace(String prefix, String xmlns)
{
Attr namespace = getAttributeNode(xmlns);
if (namespace != null)
return namespace.getNodeValue();
if (_parent instanceof QElement)
return ((QElement) _parent).getNamespace(prefix, xmlns);
return _owner.getNamespace(prefix);
}
/**
* Returns the DOM NodeType, ELEMENT_NODE.
*/
public short getNodeType()
{
return ELEMENT_NODE;
}
/**
* Returns the schema type.
*/
public TypeInfo getSchemaTypeInfo()
{
return null;
}
/**
* Returns a list of elements, given a tag name.
*/
public NodeList getElementsByTagName(String tagName)
{
QAbstractNode child = (QAbstractNode) getFirstChild();
if (child != null)
return new QDeepNodeList(this, child, new TagPredicate(tagName));
else
return new QDeepNodeList(this, null, new TagPredicate(tagName));
}
/**
* Returns a list of elements, given a namespace and a local name.
*/
public NodeList getElementsByTagNameNS(String uri, String name)
{
QAbstractNode child = (QAbstractNode) getFirstChild();
if (child != null)
return new QDeepNodeList(this, child, new NSTagPredicate(uri, name));
else
return new QDeepNodeList(this, null, new NSTagPredicate(uri, name));
}
/**
* Appends a new node as the last child of the element.
*
* @param child the new child.
* @return the child.
*/
public Node appendChild(Node child)
throws DOMException
{
Node result = super.appendChild(child);
if (child instanceof QElement) {
QElement elt = (QElement) child;
QName name = elt._name;
if (name.getNamespaceURI() != "") {
addNamespace(name);
}
for (QAttr attr = (QAttr) elt.getFirstAttribute();
attr != null;
attr = (QAttr) attr.getNextSibling()) {
name = attr._name;
if (name.getNamespaceURI() != "") {
addNamespace(name);
}
}
}
return result;
}
/**
* Adds the name to the global namespace, if possible.
*/
void addNamespace(QName name)
{
_owner.addNamespace(name.getPrefix(), name.getNamespaceURI());
}
/**
* Normalize the element, i.e. smash all neighboring text nodes together.
*/
public void normalize()
{
Node node = _firstChild;
while (node != null) {
if (node.getNodeType() == TEXT_NODE &&
node.getNextSibling() != null &&
node.getNextSibling().getNodeType() == TEXT_NODE) {
Text text = (Text) node;
Text next = (Text) node.getNextSibling();
text.appendData(next.getData());
removeChild(next);
} else if (node.getNodeType() == ELEMENT_NODE) {
Element elt = (Element) node;
elt.normalize();
node = node.getNextSibling();
} else
node = node.getNextSibling();
}
}
public boolean hasContent()
{
return true;
}
public boolean equals(Object arg)
{
return this == arg;
}
public boolean equals(Node arg, boolean deep)
{
return this == arg;
}
/**
* Returns the text value of the element. For an element, the text
* value is the smashing together of all the child text nodes.
*/
public String getTextValue()
{
CharBuffer cb = CharBuffer.allocate();
for (QAbstractNode node = _firstChild; node != null; node = node._next) {
cb.append(node.getTextValue());
}
return cb.close();
}
void print(XmlPrinter out) throws IOException
{
out.startElement(getNamespaceURI(), getLocalName(), getNodeName());
for (QAbstractNode node = (QAbstractNode) getFirstAttribute();
node != null;
node = (QAbstractNode) node.getNextSibling()) {
out.attribute(node.getNamespaceURI(),
node.getLocalName(),
node.getNodeName(),
node.getNodeValue());
}
for (Node node = getFirstChild();
node != null;
node = node.getNextSibling()) {
((QAbstractNode) node).print(out);
}
out.endElement(getNamespaceURI(), getLocalName(), getNodeName());
}
public String toString()
{
CharBuffer cb = CharBuffer.allocate();
cb.append("Element[" + _name);
for (QAttr attr = (QAttr) getFirstAttribute();
attr != null;
attr = (QAttr) attr.getNextSibling())
cb.append(" " + attr);
cb.append("]");
return cb.close();
}
private Object writeReplace()
{
return new SerializedXml(this);
}
static class TagPredicate implements QNodePredicate {
String _name;
TagPredicate(String name)
{
if (name == null)
name = "*";
_name = name;
}
public boolean isMatch(QAbstractNode node)
{
return (node.getNodeName().equals(_name) ||
_name.equals("*") && node instanceof Element);
}
}
static class NSTagPredicate implements QNodePredicate {
String _uri;
String _local;
NSTagPredicate(String uri, String local)
{
_uri = uri;
_local = local;
}
public boolean isMatch(QAbstractNode node)
{
return (_local.equals(node.getLocalName()) &&
_uri.equals(node.getNamespaceURI()));
}
}
}