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

com.mockrunner.mock.jdbc.MockSQLXML Maven / Gradle / Ivy

package com.mockrunner.mock.jdbc;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.sql.SQLException;
import java.sql.SQLXML;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.jdom.Document;
import org.jdom.input.DOMBuilder;
import org.jdom.input.SAXBuilder;
import org.jdom.input.SAXHandler;
import org.jdom.output.DOMOutputter;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import com.mockrunner.base.NestedApplicationException;
import com.mockrunner.util.common.StreamUtil;

/**
 * Mock implementation of MockSQLXML.
 * Uses JDOM for XML handling.
 */
public class MockSQLXML implements SQLXML, Cloneable
{
    private DocumentBuilder domParser;
    private SAXParser saxParser;
    private XMLOutputFactory outputFactory;
    private XMLInputFactory inputFactory;
    private SAXBuilder jdomParser;
    private DOMBuilder jdomDOMBuilder;
    private XMLOutputter xmlPrintOutputter;
    private DOMOutputter domOutputter;
    private XMLOutputter xmlCompareOutputter;
    private Object content;
    private boolean wasFreeCalled;
    private boolean wasWriteMethodCalled;
    private boolean wasReadMethodCalled;

    public MockSQLXML()
    {
        createXMLObjects();
        content = null;
        wasFreeCalled = false;
        wasWriteMethodCalled = false;
        wasReadMethodCalled = false;
    }
    
    public MockSQLXML(String stringContent)
    {
        createXMLObjects();
        content = stringContent;
        wasFreeCalled = false;
        wasWriteMethodCalled = false;
        wasReadMethodCalled = false;
    }
    
    public MockSQLXML(Reader readerContent)
    {
        createXMLObjects();
        content = StreamUtil.getReaderAsString(readerContent);
        wasFreeCalled = false;
        wasWriteMethodCalled = false;
        wasReadMethodCalled = false;
    }
    
    public MockSQLXML(InputStream inputStreamContent)
    {
        createXMLObjects();
        content = StreamUtil.getStreamAsByteArray(inputStreamContent);
        wasFreeCalled = false;
        wasWriteMethodCalled = false;
        wasReadMethodCalled = false;
    }
    
    public MockSQLXML(org.w3c.dom.Document documentContent)
    {
        createXMLObjects();
        content = documentContent;
        wasFreeCalled = false;
        wasWriteMethodCalled = false;
        wasReadMethodCalled = false;
    }
    
    protected DocumentBuilder createDocumentBuilder()
    {
        try
        {
            return DocumentBuilderFactory.newInstance().newDocumentBuilder();
        } 
        catch(ParserConfigurationException exc)
        {
            throw new NestedApplicationException(exc);
        }
    }
    
    protected SAXParser createSAXParser()
    {
        try
        {
            return SAXParserFactory.newInstance().newSAXParser();
        } 
        catch(Exception exc)
        {
            throw new NestedApplicationException(exc);
        }
    }
    
    protected XMLOutputFactory createXMLOutputFactory()
    {
        return XMLOutputFactory.newInstance();
    }
    
    protected XMLInputFactory createXMLInputFactory()
    {
        return XMLInputFactory.newInstance();
    }
    
    protected SAXBuilder createJDOMSAXBuilder()
    {
        SAXBuilder builder = new SAXBuilder();
        builder.setValidation(false);
        return builder;
    }
    
    protected DOMBuilder createJDOMDOMBuilder()
    {
        return new DOMBuilder();
    }
    
    protected XMLOutputter createJDOMXMLPrintOutputter()
    {
        return new XMLOutputter(Format.getPrettyFormat());
    }
    
    protected XMLOutputter createJDOMXMLCompareOutputter()
    {
        Format format = Format.getCompactFormat();
        format.setOmitDeclaration(true);
        format.setOmitEncoding(true);
        return new XMLOutputter(format);
    }
    
    protected DOMOutputter createJDOMDOMOutputter()
    {
        return new DOMOutputter();
    }
    
    /**
     * Returns the XML content as a string without affecting the state of
     * the object. This method can be called multiple times unlike
     * the get methods of java.sql.SQLXML.
     * @return the XML content as a string
     */
    public String getContentAsString()
    {
        try
        {
            return contentToString();
        } 
        catch(Exception exc)
        {
            throw new NestedApplicationException(exc);
        }
    }
    
    /**
     * Returns the XML content as an InputStream without affecting the 
     * state of the object. This method can be called multiple times unlike
     * the get methods of java.sql.SQLXML.
     * @return the XML content as an InputStream
     */
    public InputStream getContentAsInputStream() throws SQLException
    {
        try
        {
            return contentToInputStream();
        } 
        catch(Exception exc)
        {
            throw new NestedApplicationException(exc);
        }
    }
    
    /**
     * Returns the XML content as a Reader without affecting the 
     * state of the object. This method can be called multiple times unlike
     * the get methods of java.sql.SQLXML.
     * @return the XML content as a Reader
     */
    public Reader getContentAsReader() throws SQLException
    {
        try
        {
            return contentToReader();
        } 
        catch(Exception exc)
        {
            throw new NestedApplicationException(exc);
        }
    }
    
    /**
     * Returns the XML content as a W3C Document without affecting 
     * the state of the object. This method can be called multiple times unlike
     * the get methods of java.sql.SQLXML.
     * @return the XML content as a W3C Document
     */
    public org.w3c.dom.Document getContentAsW3CDocument()
    {
        try
        {
            return contentToW3CDocument();
        } 
        catch(Exception exc)
        {
            throw new NestedApplicationException(exc);
        }
    }

    public InputStream getBinaryStream() throws SQLException
    {
        verifyRead();
        wasReadMethodCalled = true;
        try
        {
            return contentToInputStream();
        } 
        catch(Exception exc)
        {
            throw new SQLException(exc);
        }
    }

    public Reader getCharacterStream() throws SQLException
    {
        verifyRead();
        wasReadMethodCalled = true;
        try
        {
            return contentToReader();
        } 
        catch(Exception exc)
        {
            throw new SQLException(exc);
        }
    }

    public Source getSource(Class sourceClass) throws SQLException
    {
        verifyRead();
        wasReadMethodCalled = true;
        try
        {
            if(null == sourceClass || StreamSource.class.equals(sourceClass))
            {
                return new StreamSource(contentToInputStream());
            }
            if(DOMSource.class.equals(sourceClass))
            {
                return new DOMSource(contentToW3CDocument());
            }
            if(SAXSource.class.equals(sourceClass))
            {
                return new SAXSource(saxParser.getXMLReader(), new InputSource(contentToInputStream()));
            }
            if(StAXSource.class.equals(sourceClass))
            {
                return new StAXSource(contentToXMLStreamReader());
            }
        } 
        catch(Exception exc)
        {
            throw new SQLException(exc);
        }
        throw new SQLException(sourceClass.getName() + " not supported as Source");
    }

    public String getString() throws SQLException
    {
        verifyRead();
        wasReadMethodCalled = true;
        try
        {
            return contentToString();
        } 
        catch(Exception exc)
        {
            throw new SQLException(exc);
        }
    }

    public OutputStream setBinaryStream() throws SQLException
    {
        verifyWrite();
        wasWriteMethodCalled = true;
        content = new ByteArrayOutputStream();
        return (OutputStream)content;
    }

    public Writer setCharacterStream() throws SQLException
    {
        verifyWrite();
        wasWriteMethodCalled = true;
        content = new StringWriter();
        return (Writer)content;
    }

    public Result setResult(Class resultClass) throws SQLException
    {
        verifyWrite();
        wasWriteMethodCalled = true;
        if(null == resultClass || StreamResult.class.equals(resultClass))
        {
            content = new ByteArrayOutputStream();
            return new StreamResult((OutputStream)content);
        }
        if(DOMResult.class.equals(resultClass))
        {
            org.w3c.dom.Document document = domParser.newDocument();
            content = new DOMResult(document);
            return (DOMResult)content;
        }
        if(SAXResult.class.equals(resultClass))
        {
            content = new SAXHandler();
            return new SAXResult((SAXHandler)content);
        }
        if(StAXResult.class.equals(resultClass))
        {
            XMLStreamWriter xmlWriter;
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            try
            {
                xmlWriter = outputFactory.createXMLStreamWriter(outStream);
            } 
            catch(XMLStreamException exc)
            {
                throw new SQLException(exc);
            }
            content = new StreamWriterOutputStreamMapping(xmlWriter, outStream);
            return new StAXResult(xmlWriter);
        }
        throw new SQLException(resultClass.getName() + " not supported as Result");
    }

    public void setString(String value) throws SQLException
    {
        verifyWrite();
        wasWriteMethodCalled = true;
        content = value;
    }
    
    public void free() throws SQLException
    {
        wasFreeCalled = true;
    }

    /**
     * Returns if {@link #free} has been called.
     * @return true if {@link #free} has been called,
     *         false otherwise
     */
    public boolean wasFreeCalled()
    {
        return wasFreeCalled;
    }
    
    /**
     * Returns if this object is readable.
     * @return true this object is readable,
     *         false otherwise
     */
    public boolean isReadable()
    {
        return !(wasFreeCalled || wasReadMethodCalled);
    }
    
    /**
     * Returns if this object is writeable.
     * @return true this object is writeable,
     *         false otherwise
     */
    public boolean isWriteable()
    {
        return !(wasFreeCalled || wasWriteMethodCalled);
    }
    
    public boolean equals(Object otherObject)
    {
        if(null == otherObject) return false;
        if(this == otherObject) return true;
        if(!otherObject.getClass().equals(this.getClass())) return false;
        MockSQLXML otherSQLXML = (MockSQLXML)otherObject;
        if(wasFreeCalled != otherSQLXML.wasFreeCalled()) return false;
        if(null == content && null == otherSQLXML.content) return true;
        if(null == content || null == otherSQLXML.content) return false;
        try
        {
            Document thisContent = contentToJDOMDocument();
            Document otherContent = otherSQLXML.contentToJDOMDocument();
            if(null == thisContent || null == otherContent) return false;
            String thisContentAsString = xmlCompareOutputter.outputString(thisContent);
            String otherContentAsString = xmlCompareOutputter.outputString(otherContent);
            return thisContentAsString.equals(otherContentAsString);
        } 
        catch(Exception exc)
        {
            return false;
        }   
    }

    public int hashCode()
    {
        int hashCode = 17;
        if(null != content)
        {
            try
            {
                Document document = contentToJDOMDocument();
                if(null == document) return hashCode;
                String documentAsString = xmlCompareOutputter.outputString(document);
                if(null != documentAsString) hashCode = (31 * hashCode) + documentAsString.hashCode();
            } 
            catch(Exception exc)
            {
                
            }
        }
        hashCode = (31 * hashCode) + (wasFreeCalled ? 31 : 62);
        return hashCode;
    }
    
    public Object clone()
    {
        try
        {
            MockSQLXML other = (MockSQLXML)super.clone();
            other.domParser = createDocumentBuilder();
            other.saxParser = createSAXParser();
            other.outputFactory = createXMLOutputFactory();
            other.inputFactory = createXMLInputFactory();
            other.jdomParser = createJDOMSAXBuilder();
            other.jdomDOMBuilder = createJDOMDOMBuilder();
            other.xmlPrintOutputter = createJDOMXMLPrintOutputter();
            other.domOutputter = createJDOMDOMOutputter();
            other.xmlCompareOutputter = createJDOMXMLCompareOutputter();
            if(null != content)
            {
                try
                {
                    Document document = contentToJDOMDocument();
                    other.content = document.clone();
                } 
                catch(Exception exc)
                {
                    other.content = null;
                }
            }
            return other;
        }
        catch(CloneNotSupportedException exc)
        {
            throw new NestedApplicationException(exc);
        }
    }

    public String toString()
    {
        StringBuffer buffer = new StringBuffer("XML data:\n");
        if(null == content)
        {
            buffer.append("null");
        }
        else
        {
            try
            {
                Document document = contentToJDOMDocument();
                if(null != document) buffer.append(document.toString());
            } 
            catch(Exception exc)
            {
                buffer.append(exc.getMessage());
            }
        }
        return buffer.toString();
    }
    
    private void createXMLObjects()
    {
        domParser = createDocumentBuilder();
        saxParser = createSAXParser();
        outputFactory = createXMLOutputFactory();
        inputFactory = createXMLInputFactory();
        jdomParser = createJDOMSAXBuilder();
        jdomDOMBuilder = createJDOMDOMBuilder();
        xmlPrintOutputter = createJDOMXMLPrintOutputter();
        domOutputter = createJDOMDOMOutputter();
        xmlCompareOutputter = createJDOMXMLCompareOutputter();
    }

    private void verifyWrite() throws SQLException
    {
        if(!isWriteable())
        {
            throw new SQLException("not writeable");
        }
    }
    
    private void verifyRead() throws SQLException
    {
        if(!isReadable())
        {
            throw new SQLException("not readable");
        }
        if(null == content)
        {
            throw new SQLException("no content");
        }
    }
    
    private Document contentToJDOMDocument() throws Exception
    {
        Document jdomDocument = null;
        if(content instanceof Document)
        {
            jdomDocument = (Document)content;
        }
        else if(content instanceof String)
        {
            jdomDocument = jdomParser.build(new StringReader((String)content));
        }
        else if(content instanceof StringWriter)
        {
            jdomDocument = jdomParser.build(new StringReader(((StringWriter)content).toString()));
        }
        else if(content instanceof ByteArrayOutputStream)
        {
            jdomDocument = jdomParser.build(new ByteArrayInputStream(((ByteArrayOutputStream)content).toByteArray()));
        }
        else if(content instanceof byte[])
        {
            jdomDocument = jdomParser.build(new ByteArrayInputStream((byte[])content));
        }
        else if(content instanceof org.w3c.dom.Document)
        {
            jdomDocument = jdomDOMBuilder.build((org.w3c.dom.Document)content);
        }
        else if(content instanceof DOMResult)
        {
            Node node = ((DOMResult)content).getNode();
            org.w3c.dom.Document document = null;
            if(node instanceof org.w3c.dom.Document)
            {
                document = (org.w3c.dom.Document)node; 
            }
            else
            {
                document = domParser.newDocument(); 
                document.appendChild(document.importNode(node, true));
            }
            jdomDocument = jdomDOMBuilder.build(document);
        }
        else if(content instanceof SAXHandler)
        {
            jdomDocument = ((SAXHandler)content).getDocument();
        }
        else if(content instanceof StreamWriterOutputStreamMapping)
        {
            XMLStreamWriter xmlWriter = ((StreamWriterOutputStreamMapping)content).getStreamWriter();
            xmlWriter.flush();
            xmlWriter.close();
            ByteArrayOutputStream outStream = ((StreamWriterOutputStreamMapping)content).getOutputStream();
            jdomDocument = jdomParser.build(new ByteArrayInputStream(outStream.toByteArray()));
        }
        return jdomDocument;
    }
    
    private String contentToString() throws Exception
    {
        Document jdomDocument = contentToJDOMDocument();
        if(null != jdomDocument)
        {
            return xmlPrintOutputter.outputString(jdomDocument);
        }
        return null;
    }
    
    private Reader contentToReader() throws Exception
    {
        Document jdomDocument = contentToJDOMDocument();
        if(null != jdomDocument)
        {
            return new StringReader(xmlPrintOutputter.outputString(jdomDocument));
        }
        return null;
    }
    
    private InputStream contentToInputStream() throws Exception
    {
        Document jdomDocument = contentToJDOMDocument();
        if(null != jdomDocument)
        {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            xmlPrintOutputter.output(jdomDocument, outStream);
            outStream.flush();
            return new ByteArrayInputStream(outStream.toByteArray());
        }
        return null;
    }
    
    private org.w3c.dom.Document contentToW3CDocument() throws Exception
    {
        Document jdomDocument = contentToJDOMDocument();
        if(null != jdomDocument)
        {
            return domOutputter.output(jdomDocument);
        }
        return null;
    }
    
    private XMLStreamReader contentToXMLStreamReader() throws Exception
    {
        Document jdomDocument = contentToJDOMDocument();
        if(null != jdomDocument)
        {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            xmlPrintOutputter.output(jdomDocument, outStream);
            outStream.flush();
            InputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
            return inputFactory.createXMLStreamReader(inStream);
        }
        return null;
    }
    
    private class StreamWriterOutputStreamMapping
    {
        private XMLStreamWriter streamWriter;
        private ByteArrayOutputStream outputStream;
        
        public StreamWriterOutputStreamMapping(XMLStreamWriter streamWriter, ByteArrayOutputStream outputStream)
        {
            this.streamWriter = streamWriter;
            this.outputStream = outputStream;
        }
        
        public XMLStreamWriter getStreamWriter()
        {
            return streamWriter;
        }

        public ByteArrayOutputStream getOutputStream()
        {
            return outputStream;
        } 
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy