001: /*
002: * Copyright (c) 2002-2008 Gargoyle Software Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: * 2. Redistributions in binary form must reproduce the above copyright notice,
010: * this list of conditions and the following disclaimer in the documentation
011: * and/or other materials provided with the distribution.
012: * 3. The end-user documentation included with the redistribution, if any, must
013: * include the following acknowledgment:
014: *
015: * "This product includes software developed by Gargoyle Software Inc.
016: * (http://www.GargoyleSoftware.com/)."
017: *
018: * Alternately, this acknowledgment may appear in the software itself, if
019: * and wherever such third-party acknowledgments normally appear.
020: * 4. The name "Gargoyle Software" must not be used to endorse or promote
021: * products derived from this software without prior written permission.
022: * For written permission, please contact info@GargoyleSoftware.com.
023: * 5. Products derived from this software may not be called "HtmlUnit", nor may
024: * "HtmlUnit" appear in their name, without prior written permission of
025: * Gargoyle Software Inc.
026: *
027: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
028: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
029: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
030: * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
031: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
032: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
033: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
034: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
035: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
036: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: */
038: package com.gargoylesoftware.htmlunit.xml;
039:
040: import java.io.IOException;
041: import java.util.HashMap;
042:
043: import javax.xml.parsers.DocumentBuilderFactory;
044: import javax.xml.parsers.ParserConfigurationException;
045:
046: import org.mozilla.javascript.ScriptableObject;
047: import org.w3c.dom.Document;
048: import org.w3c.dom.Node;
049: import org.xml.sax.SAXException;
050:
051: import com.gargoylesoftware.htmlunit.SgmlPage;
052: import com.gargoylesoftware.htmlunit.WebResponse;
053: import com.gargoylesoftware.htmlunit.WebWindow;
054: import com.gargoylesoftware.htmlunit.html.DomNode;
055:
056: /**
057: * A page that will be returned for response with content type "text/xml".
058: * It doesn't implement itself {@link org.w3c.dom.Document} to allow to see the source of badly formed
059: * xml responses.
060: *
061: * @version $Revision: 2132 $
062: * @author Marc Guillemot
063: * @author David K. Taylor
064: * @author Ahmed Ashour
065: */
066: public class XmlPage extends SgmlPage {
067: private static final long serialVersionUID = -1430136241030261308L;
068: private Node node_;
069:
070: /**
071: * Create an instance.
072: * A warning is logged if an exception is thrown while parsing the xml content
073: * (for instance when the content is not a valid xml and can't be parsed).
074: *
075: * @param webResponse The response from the server
076: * @param enclosingWindow The window that holds the page.
077: * @throws IOException If the page could not be created
078: */
079: public XmlPage(final WebResponse webResponse,
080: final WebWindow enclosingWindow) throws IOException {
081: this (webResponse, enclosingWindow, true);
082: }
083:
084: /**
085: * Create an instance.
086: * A warning is logged if an exception is thrown while parsing the xml content
087: * (for instance when the content is not a valid xml and can't be parsed).
088: *
089: * @param node The node to initialize this page with.
090: * @param enclosingWindow The window that holds the page.
091: */
092: public XmlPage(final Node node, final WebWindow enclosingWindow) {
093: super (null, enclosingWindow);
094: node_ = node;
095: }
096:
097: /**
098: * Create an instance.
099: * A warning is logged if an exception is thrown while parsing the xml content
100: * (for instance when the content is not a valid xml and can't be parsed).
101: *
102: * @param webResponse The response from the server
103: * @param enclosingWindow The window that holds the page.
104: * @param ignoreSAXException Whether to ignore {@link SAXException} or throw it as {@link IOException}.
105: * @throws IOException If the page could not be created
106: */
107: public XmlPage(final WebResponse webResponse,
108: final WebWindow enclosingWindow,
109: final boolean ignoreSAXException) throws IOException {
110: super (webResponse, enclosingWindow);
111:
112: try {
113: if (webResponse == null
114: || webResponse.getContentAsString().trim().length() == 0) {
115: node_ = DocumentBuilderFactory.newInstance()
116: .newDocumentBuilder().newDocument()
117: .getDocumentElement();
118: } else {
119: node_ = XmlUtil.buildDocument(webResponse)
120: .getDocumentElement();
121: }
122: } catch (final SAXException e) {
123: getLog().warn(
124: "Failed parsing xml document "
125: + webResponse.getUrl() + ": "
126: + e.getMessage());
127: if (!ignoreSAXException) {
128: throw new IOException(e.getMessage());
129: }
130: } catch (final ParserConfigurationException e) {
131: getLog().warn(
132: "Failed parsing xml document "
133: + webResponse.getUrl() + ": "
134: + e.getMessage());
135: }
136: }
137:
138: /**
139: * {@inheritDoc}
140: */
141: public void setScriptObject(final ScriptableObject scriptObject) {
142: super .setScriptObject(scriptObject);
143: if (node_ != null) {
144: XmlUtil.appendChild(this , this , node_);
145: }
146: }
147:
148: /**
149: * Clean up this page.
150: */
151: public void cleanUp() {
152: }
153:
154: /**
155: * Return the content of the page
156: *
157: * @return See above
158: */
159: public String getContent() {
160: return getWebResponse().getContentAsString();
161: }
162:
163: /**
164: * Gets the DOM representation of the xml content
165: * @return <code>null</code> if the content couldn't be parsed.
166: */
167: public Document getXmlDocument() {
168: if (node_ != null) {
169: return node_.getOwnerDocument();
170: } else {
171: return null;
172: }
173: }
174:
175: /**
176: * Get the root XmlElement of this document.
177: * @return The root element
178: */
179: //TODO: should be removed later to SgmlPage
180: public XmlElement getDocumentXmlElement() {
181: DomNode childNode = getFirstDomChild();
182: while (childNode != null && !(childNode instanceof XmlElement)) {
183: childNode = childNode.getNextDomSibling();
184: }
185: return (XmlElement) childNode;
186: }
187:
188: /**
189: * Create a new XML element with the given tag name.
190: *
191: * @param tagName The tag name.
192: * @return the new XML element.
193: */
194: public XmlElement createXmlElement(final String tagName) {
195: return createXmlElementNS(null, tagName);
196: }
197:
198: /**
199: * Create a new HtmlElement with the given namespace and qualified name.
200: *
201: * @param namespaceURI the URI that identifies an XML namespace.
202: * @param qualifiedName The qualified name of the element type to instantiate
203: * @return the new HTML element.
204: */
205: public XmlElement createXmlElementNS(final String namespaceURI,
206: final String qualifiedName) {
207: return new XmlElement(namespaceURI, qualifiedName, this ,
208: new HashMap());
209: }
210:
211: }
|