SaxRepresentation.java :  » Web-Services » restlet-1.0.8 » org » restlet » resource » Java Open Source

Java Open Source » Web Services » restlet 1.0.8 
restlet 1.0.8 » org » restlet » resource » SaxRepresentation.java
/*
 * Copyright 2005-2007 Noelios Consulting.
 * 
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License (the "License"). You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at
 * http://www.opensource.org/licenses/cddl1.txt See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL HEADER in each file and
 * include the License file at http://www.opensource.org/licenses/cddl1.txt If
 * applicable, add the following below this CDDL HEADER, with the fields
 * enclosed by brackets "[]" replaced with your own identifying information:
 * Portions Copyright [yyyy] [name of copyright owner]
 */

package org.restlet.resource;

import java.io.IOException;
import java.io.OutputStream;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.restlet.data.MediaType;
import org.restlet.util.XmlWriter;
import org.w3c.dom.Document;
import org.xml.sax.ContentHandler;

/**
 * XML representation for SAX events processing. The purpose is to create a
 * streamable content based on a custom Java object model instead of a neutral
 * DOM tree. This domain object can then be directly modified and efficiently
 * serialized at a later time.<br/> Subclasses only need to override the
 * ContentHandler methods required for the reading and also the write(XmlWriter
 * writer) method when serialization is requested.<br/>
 * 
 * @author Jerome Louvel (contact@noelios.com)
 */
public class SaxRepresentation extends XmlRepresentation {
    /** The wrapped DOM document to parse. */
    private Document xmlDocument;

    /** The wrapped XML representation. */
    private Representation xmlRepresentation;

    /**
     * Constructor.
     * 
     * @param mediaType
     *            The representation media type.
     */
    public SaxRepresentation(MediaType mediaType) {
        super(mediaType);
    }

    /**
     * Constructor.
     * 
     * @param mediaType
     *            The representation's media type.
     * @param xmlDocument
     *            A source DOM representation to parse.
     */
    public SaxRepresentation(MediaType mediaType, Document xmlDocument) {
        super(mediaType);
        this.xmlDocument = xmlDocument;
    }

    /**
     * Constructor.
     * 
     * @param xmlRepresentation
     *            A source XML representation to parse.
     */
    public SaxRepresentation(Representation xmlRepresentation)
            throws IOException {
        super(xmlRepresentation.getMediaType());
        this.xmlRepresentation = xmlRepresentation;
    }

    /**
     * Parses the source and sends SAX events to a content handler.
     * 
     * @param contentHandler
     *            The SAX content handler to use for parsing.
     */
    public void parse(ContentHandler contentHandler) throws IOException {
        if (contentHandler != null) {
            try {
                Source source = null;

                if (this.xmlDocument != null) {
                    source = new DOMSource(xmlDocument);
                } else {
                    source = new StreamSource(xmlRepresentation.getStream());
                }

                if (xmlRepresentation.getIdentifier() != null) {
                    source.setSystemId(xmlRepresentation.getIdentifier()
                            .getTargetRef().toString());
                }

                Result result = new SAXResult(contentHandler);
                TransformerFactory.newInstance().newTransformer().transform(
                        source, result);
            } catch (TransformerConfigurationException tce) {
                throw new IOException(
                        "Couldn't parse the source representation: "
                                + tce.getMessage());
            } catch (TransformerException te) {
                te.printStackTrace();
                throw new IOException(
                        "Couldn't parse the source representation: "
                                + te.getMessage());
            } catch (TransformerFactoryConfigurationError tfce) {
                throw new IOException(
                        "Couldn't parse the source representation: "
                                + tfce.getMessage());
            }
        } else {
            throw new IOException(
                    "Couldn't parse the source representation: no content restlet defined.");
        }
    }

    /**
     * Writes the representation to a byte stream.
     * 
     * @param outputStream
     *            The output stream.
     */
    public void write(OutputStream outputStream) throws IOException {
        write(new XmlWriter(outputStream, "UTF-8"));
    }

    /**
     * Writes the representation to a XML writer. The default implementation
     * does nothing and is intended to be overriden.
     * 
     * @param writer
     *            The XML writer to write to.
     * @throws IOException
     */
    public void write(XmlWriter writer) throws IOException {
        // Do nothing by default.
    }

    /**
     * Returns a document builder properly configured.
     * 
     * @return A document builder properly configured.
     */
    private DocumentBuilder getDocumentBuilder() throws IOException {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(isNamespaceAware());
            dbf.setValidating(false);
            return dbf.newDocumentBuilder();
        } catch (ParserConfigurationException pce) {
            throw new IOException("Couldn't create the empty document: "
                    + pce.getMessage());
        }
    }

    @Override
    public Object evaluate(String expression, QName returnType)
            throws Exception {
        Object result = null;
        XPath xpath = XPathFactory.newInstance().newXPath();
        xpath.setNamespaceContext(this);

        if (this.xmlDocument == null) {
            this.xmlDocument = getDocumentBuilder().parse(
                    this.xmlRepresentation.getStream());
        }

        if (this.xmlDocument != null) {
            result = xpath.evaluate(expression, this.xmlDocument, returnType);
        } else {
            throw new Exception(
                    "Unable to obtain a DOM document for the SAX representation. "
                            + "XPath evaluation cancelled.");
        }

        return result;
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.