opendap.wcs.v1_1_2.http.Attachment.java Source code

Java tutorial

Introduction

Here is the source code for opendap.wcs.v1_1_2.http.Attachment.java

Source

/*
 * /////////////////////////////////////////////////////////////////////////////
 * // This file is part of the "Hyrax Data Server" project.
 * //
 * //
 * // Copyright (c) 2013 OPeNDAP, Inc.
 * // Author: Nathan David Potter  <ndp@opendap.org>
 * //
 * // This library is free software; you can redistribute it and/or
 * // modify it under the terms of the GNU Lesser General Public
 * // License as published by the Free Software Foundation; either
 * // version 2.1 of the License, or (at your option) any later version.
 * //
 * // This library is distributed in the hope that it will be useful,
 * // but WITHOUT ANY WARRANTY; without even the implied warranty of
 * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * // Lesser General Public License for more details.
 * //
 * // You should have received a copy of the GNU Lesser General Public
 * // License along with this library; if not, write to the Free Software
 * // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * //
 * // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 * /////////////////////////////////////////////////////////////////////////////
 */
package opendap.wcs.v1_1_2.http;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.jdom.Document;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.slf4j.Logger;

import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URISyntaxException;

/**
 * Holds The type information and a referene to an input stream for the content of a Mutipart
 * MIME attachment.
 *
 * @see opendap.coreServlet.MultipartResponse
 *      User: ndp
 *      Date: Apr 28, 2006
 *      Time: 12:13:19 PM
 */
public class Attachment {

    private enum ContentModel {
        stream, url, document
    }

    private Logger log;
    private String contentTransferEncoding = "binary";
    private String contentId;
    private String contentType;
    private InputStream _istream;
    private String _sourceUrl;
    private Document _doc;
    private int defaultBufferSize = 10240; // 10k read buffer
    private ContentModel _myContentModel;

    /**
     * @param ctype String containing the value of the HTTP header Content-Type for this attachment.
     * @param cid   String containing the value if the HTTP header Content-Id for this attachment.
     * @param is    A stream containing the content for this attachment.
     */
    public Attachment(String ctype, String cid, InputStream is) {
        log = org.slf4j.LoggerFactory.getLogger(getClass());
        contentType = ctype;
        contentId = cid;
        _istream = is;
        _doc = null;
        _myContentModel = ContentModel.stream;

    }

    /**
     * @param ctype String containing the value of the HTTP header Content-Type for this attachment.
     * @param cid   String containing the value if the HTTP header Content-Id for this attachment.
     * @param url   A URL that when dereferenced will provide the content for this attachment.
     */
    public Attachment(String ctype, String cid, String url) {
        log = org.slf4j.LoggerFactory.getLogger(getClass());
        contentType = ctype;
        contentId = cid;
        _istream = null;
        _sourceUrl = url;
        _doc = null;
        _myContentModel = ContentModel.url;
    }

    /**
     * @param ctype String containing the value of the HTTP header Content-Type for this attachment.
     * @param cid String containing the value if the HTTP header Content-Id for this attachment.
     * @param doc A JDOM XML document to provide the content for this attachment.
     */
    public Attachment(String ctype, String cid, Document doc) {
        log = org.slf4j.LoggerFactory.getLogger(getClass());
        contentType = ctype;
        contentId = cid;
        _istream = null;
        _sourceUrl = null;
        _doc = doc;
        _myContentModel = ContentModel.document;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String cntTyp) {
        contentType = cntTyp;
    }

    /**
     * Write the attchment to the indicated stream
     *
     * @param mimeBoundary MIME Boundary for the attachment.
     * @param sos          Stream to which to write the attachment.
     * @throws IOException                 When things can't be read or written.
     * @throws java.net.URISyntaxException If the target URL is hosed.
     */
    public void write(String mimeBoundary, ServletOutputStream sos) throws IOException, URISyntaxException {

        sos.println("--" + mimeBoundary);
        sos.println("Content-Type: " + contentType);
        sos.println("Content-Transfer-Encoding: " + contentTransferEncoding);
        sos.println("Content-Id: <" + contentId + ">");
        sos.println();

        switch (_myContentModel) {
        case stream:
            try {
                drainInputStream(_istream, sos);
            } finally {
                if (_istream != null) {
                    try {
                        _istream.close();
                    } catch (IOException e) {
                        log.error("Failed to close content source InputStream. " + "Error Message: "
                                + e.getMessage());

                    }
                }
            }
            break;

        case url:
            forwardUrlContent(_sourceUrl, sos);
            break;

        case document:
            sendDocument(sos);
            break;

        default:
            break;

        }

        //MIME Attachments need to end with a newline!
        sos.println();

    }

    private void sendDocument(OutputStream os) throws IOException {
        XMLOutputter xmlo = new XMLOutputter(Format.getPrettyFormat());
        xmlo.output(_doc, os);
    }

    private void forwardUrlContent(String url, OutputStream os) throws URISyntaxException, IOException {

        log.debug("Retrieving URL: " + url);

        GetMethod request = new GetMethod(url);
        InputStream is = null;
        try {

            HttpClient httpClient = new HttpClient();

            // Execute the method.
            int statusCode = httpClient.executeMethod(request);

            if (statusCode != HttpStatus.SC_OK) {
                String msg = "HttpClient failed to executeMethod(). Status: " + request.getStatusLine();
                log.error(msg);
                throw new IOException(msg);
            } else {
                is = request.getResponseBodyAsStream();
                drainInputStream(is, os);

            }

        } finally {
            if (is != null)
                is.close();
            log.debug("Releasing Http connection.");
            request.releaseConnection();
        }

    }

    private int drainInputStream(InputStream is, OutputStream os) throws IOException {

        byte[] buf = new byte[defaultBufferSize];

        boolean done = false;
        int totalBytesRead = 0;
        int totalBytesWritten = 0;
        int bytesRead;

        while (!done) {
            bytesRead = is.read(buf);
            if (bytesRead == -1) {
                if (totalBytesRead == 0)
                    totalBytesRead = -1;
                done = true;
            } else {
                totalBytesRead += bytesRead;
                os.write(buf, 0, bytesRead);
                totalBytesWritten += bytesRead;
            }
        }

        if (totalBytesRead != totalBytesWritten)
            throw new IOException("Failed to write as many bytes as I read! " + "Read: " + totalBytesRead
                    + " Wrote: " + totalBytesWritten);

        return totalBytesRead;

    }

}