Package org.exist.xquery.value

Source Code of org.exist.xquery.value.BinaryValueFromBinaryString

package org.exist.xquery.value;

import org.apache.commons.io.output.ByteArrayOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.output.CloseShieldOutputStream;
import org.apache.log4j.Logger;
import org.exist.xquery.XPathException;

/**
* Representation of an XSD binary value e.g. (xs:base64Binary or xs:hexBinary)
* whose source is backed by a pre-encoded String.
*
* Note - BinaryValueFromBinaryString is a special case of BinaryValue
* where the value is already encoded.
*
* @author Adam Retter <adam@existsolutions.com>
*/
public class BinaryValueFromBinaryString extends BinaryValue {

    private final static Logger LOG = Logger.getLogger(BinaryValueFromBinaryString.class);
   
    private final String value;

    public BinaryValueFromBinaryString(BinaryValueType binaryValueType, String value) throws XPathException {
        super(null, binaryValueType);
        this.value = binaryValueType.verifyAndFormatString(value);
    }

    @Override
    public BinaryValue convertTo(BinaryValueType binaryValueType) throws XPathException {
        //TODO temporary approach, consider implementing a TranscodingBinaryValueFromBinaryString(BinaryValueFromBinaryString) class
        //that only does the transncoding lazily

        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        FilterOutputStream fos = null;
        try {

            //transcode
            fos = binaryValueType.getEncoder(baos);
            streamBinaryTo(fos);

        } catch(final IOException ioe) {
            throw new XPathException(ioe);
        } finally {
            if(fos != null) {
                try {
                    fos.close();
                } catch(final IOException ioe) {
                    LOG.error("Unable to close stream: " + ioe.getMessage(), ioe);
                }
            }

            try {
                baos.close();
            } catch(final IOException ioe) {
                LOG.error("Unable to close stream: " + ioe.getMessage(), ioe);
            }
        }

        return new BinaryValueFromBinaryString(binaryValueType, new String(baos.toByteArray()));
    }

    @Override
    public void streamBinaryTo(OutputStream os) throws IOException {
       
        //we need to create a safe output stream that cannot be closed
        final OutputStream safeOutputStream = new CloseShieldOutputStream(os);
       
        //get the decoder
        final FilterOutputStream fos = getBinaryValueType().getDecoder(safeOutputStream);
       
        //write with the decoder
        final byte data[] = value.getBytes();
        fos.write(data);
       
        //we do have to close the decoders output stream though
        //to ensure that all bytes have been written, this is
        //particularly nessecary for Apache Commons Codec stream encoders
        try {
            fos.close();
        } catch(final IOException ioe) {
            LOG.error("Unable to close stream: " + ioe.getMessage(), ioe);
        }
    }

    @Override
    public void streamTo(OutputStream os) throws IOException {
        //write
        final byte data[] = value.getBytes(); //TODO consider a more efficient approach for writting large strings
        os.write(data);
    }

    @Override
    public InputStream getInputStream() {

        //TODO consider a more efficient approach for writting large strings
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            streamBinaryTo(baos);
        } catch(final IOException ioe) {
            LOG.error("Unable to get read only buffer: " + ioe.getMessage(), ioe);
        }

        return new InputStream() {
            int offset = 0;
            final byte data[] = baos.toByteArray();

            @Override
            public int read() throws IOException {

                if(offset >= data.length) {
                    return -1;
                }
                return data[offset++];
            }
        };
    }

    @Override
    public void close() throws IOException {
    }
}
TOP

Related Classes of org.exist.xquery.value.BinaryValueFromBinaryString

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.