/*
* Copyright (c) 2002-2008 Gargoyle Software Inc.
*
* 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 com.gargoylesoftware.htmlunit.xml;
import java.io.IOException;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.DomAttr;
import com.gargoylesoftware.htmlunit.html.DomNode;
/**
* A page that will be returned for response with content type "text/xml".
* It doesn't implement itself {@link org.w3c.dom.Document} to allow to see the source of badly formed
* XML responses.
*
* @version $Revision$
* @author Marc Guillemot
* @author David K. Taylor
* @author Ahmed Ashour
*/
public class XmlPage extends SgmlPage implements Document {
private static final long serialVersionUID = -1430136241030261308L;
private Node node_;
private Element documentElement_;
private final transient Log mainLog_ = LogFactory.getLog(getClass());
/**
* Create an instance.
* A warning is logged if an exception is thrown while parsing the XML content
* (for instance when the content is not a valid XML and can't be parsed).
*
* @param webResponse the response from the server
* @param enclosingWindow the window that holds the page
* @throws IOException if the page could not be created
*/
public XmlPage(final WebResponse webResponse, final WebWindow enclosingWindow) throws IOException {
this(webResponse, enclosingWindow, true);
}
/**
* Create an instance.
* A warning is logged if an exception is thrown while parsing the XML content
* (for instance when the content is not a valid XML and can't be parsed).
*
* @param node the node to initialize this page with
* @param enclosingWindow the window that holds the page
*/
public XmlPage(final Node node, final WebWindow enclosingWindow) {
super(null, enclosingWindow);
node_ = node;
if (node_ != null) {
XmlUtil.appendChild(this, this, node_);
}
}
/**
* Create an instance.
* A warning is logged if an exception is thrown while parsing the XML content
* (for instance when the content is not a valid XML and can't be parsed).
*
* @param webResponse the response from the server
* @param enclosingWindow the window that holds the page
* @param ignoreSAXException Whether to ignore {@link SAXException} or throw it as {@link IOException}
* @throws IOException if the page could not be created
*/
public XmlPage(final WebResponse webResponse, final WebWindow enclosingWindow, final boolean ignoreSAXException)
throws IOException {
super(webResponse, enclosingWindow);
try {
if (webResponse == null || webResponse.getContentAsString().trim().length() == 0) {
node_ =
DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().getDocumentElement();
}
else {
node_ = XmlUtil.buildDocument(webResponse).getDocumentElement();
}
if (node_ != null) {
XmlUtil.appendChild(this, this, node_);
}
}
catch (final SAXException e) {
if (mainLog_.isWarnEnabled()) {
mainLog_.warn("Failed parsing XML document " + webResponse.getUrl() + ": " + e.getMessage());
}
if (!ignoreSAXException) {
throw new IOException(e.getMessage());
}
}
catch (final ParserConfigurationException e) {
if (mainLog_.isWarnEnabled()) {
mainLog_.warn("Failed parsing XML document " + webResponse.getUrl() + ": " + e.getMessage());
}
}
}
/**
* Returns the content of the page.
* @return the content of the page
*/
public String getContent() {
return getWebResponse().getContentAsString();
}
/**
* Returns the DOM representation of the XML content.
* @return null if the content couldn't be parsed
*/
public Document getXmlDocument() {
if (node_ != null) {
return node_.getOwnerDocument();
}
return null;
}
/**
* Gets the root XmlElement of this document.
* @return the root element
*/
//TODO: should be removed later to SgmlPage
public XmlElement getDocumentXmlElement() {
DomNode childNode = getFirstChild();
while (childNode != null && !(childNode instanceof XmlElement)) {
childNode = childNode.getNextSibling();
}
return (XmlElement) childNode;
}
/**
* Create a new XML element with the given tag name.
*
* @param tagName the tag name
* @return the new XML element
*/
public XmlElement createXmlElement(final String tagName) {
return createXmlElementNS(null, tagName);
}
/**
* Create a new HtmlElement with the given namespace and qualified name.
*
* @param namespaceURI the URI that identifies an XML namespace
* @param qualifiedName the qualified name of the element type to instantiate
* @return the new HTML element
*/
public XmlElement createXmlElementNS(final String namespaceURI, final String qualifiedName) {
return new XmlElement(namespaceURI, qualifiedName, this, new HashMap());
}
/**
* {@inheritDoc}.
* Exactly behaves as {@link #asXml()}.
*/
@Override
public String asText() {
return asXml();
}
/**
* {@inheritDoc}
*/
@Override
public String asXml() {
return getDocumentXmlElement().asXml();
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Node adoptNode(final Node source) throws DOMException {
throw new UnsupportedOperationException("XmlPage.adoptNode is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Attr createAttribute(final String name) throws DOMException {
throw new UnsupportedOperationException("XmlPage.createAttribute is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Attr createAttributeNS(final String namespaceURI, final String qualifiedName) throws DOMException {
throw new UnsupportedOperationException("XmlPage.createAttributeNS is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public CDATASection createCDATASection(final String data) throws DOMException {
throw new UnsupportedOperationException("XmlPage.createCDATASection is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Comment createComment(final String data) {
throw new UnsupportedOperationException("XmlPage.createComment is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public DocumentFragment createDocumentFragment() {
throw new UnsupportedOperationException("XmlPage.createDocumentFragment is not yet implemented.");
}
/**
* {@inheritDoc}
*/
@Override
public Element createElement(final String tagName) throws DOMException {
return createXmlElement(tagName);
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Element createElementNS(final String namespaceURI, final String qualifiedName) throws DOMException {
throw new UnsupportedOperationException("XmlPage.createElementNS is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public EntityReference createEntityReference(final String name) throws DOMException {
throw new UnsupportedOperationException("XmlPage.createEntityReference is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public ProcessingInstruction createProcessingInstruction(final String target, final String data)
throws DOMException {
throw new UnsupportedOperationException("XmlPage.createProcessingInstruction is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Text createTextNode(final String data) {
throw new UnsupportedOperationException("XmlPage.createTextNode is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public DocumentType getDoctype() {
throw new UnsupportedOperationException("XmlPage.getDoctype is not yet implemented.");
}
/**
* {@inheritDoc}
*/
@Override
public Element getDocumentElement() {
if (documentElement_ == null) {
DomNode childNode = getFirstChild();
while (childNode != null && !(childNode instanceof Element)) {
childNode = childNode.getNextSibling();
}
documentElement_ = (Element) childNode;
}
return documentElement_;
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public String getDocumentURI() {
throw new UnsupportedOperationException("XmlPage.getDocumentURI is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public DOMConfiguration getDomConfig() {
throw new UnsupportedOperationException("XmlPage.getDomConfig is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Element getElementById(final String elementId) {
throw new UnsupportedOperationException("XmlPage.getElementById is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public NodeList getElementsByTagName(final String tagname) {
throw new UnsupportedOperationException("XmlPage.getElementsByTagName is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public NodeList getElementsByTagNameNS(final String namespace, final String name) {
throw new UnsupportedOperationException("XmlPage.getElementsByTagNameNS is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public DOMImplementation getImplementation() {
throw new UnsupportedOperationException("XmlPage.getImplementation is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public String getInputEncoding() {
throw new UnsupportedOperationException("XmlPage.getInputEncoding is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public boolean getStrictErrorChecking() {
throw new UnsupportedOperationException("XmlPage.getStrictErrorChecking is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public String getXmlEncoding() {
throw new UnsupportedOperationException("XmlPage.getXmlEncoding is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public boolean getXmlStandalone() {
throw new UnsupportedOperationException("XmlPage.getXmlStandalone is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public String getXmlVersion() {
throw new UnsupportedOperationException("XmlPage.getXmlVersion is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Node importNode(final Node importedNode, final boolean deep) throws DOMException {
throw new UnsupportedOperationException("XmlPage.importNode is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public void normalizeDocument() {
throw new UnsupportedOperationException("XmlPage.normalizeDocument is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public Node renameNode(final Node n, final String namespaceURI, final String qualifiedName) throws DOMException {
throw new UnsupportedOperationException("XmlPage.renameNode is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public void setDocumentURI(final String documentURI) {
throw new UnsupportedOperationException("XmlPage.setDocumentURI is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public void setStrictErrorChecking(final boolean strictErrorChecking) {
throw new UnsupportedOperationException("XmlPage.setStrictErrorChecking is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public void setXmlStandalone(final boolean xmlStandalone) throws DOMException {
throw new UnsupportedOperationException("XmlPage.setXmlStandalone is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
public void setXmlVersion(final String xmlVersion) throws DOMException {
throw new UnsupportedOperationException("XmlPage.setXmlVersion is not yet implemented.");
}
/**
* {@inheritDoc}
* Not yet implemented.
*/
@Override
public String getPageEncoding() {
throw new UnsupportedOperationException("XmlPage.getPageEncoding is not yet implemented.");
}
}