001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.fcrepo.client;
018
019import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE;
020import static org.fcrepo.client.FedoraHeaderConstants.DIGEST;
021import static org.fcrepo.client.FedoraHeaderConstants.IF_MATCH;
022import static org.fcrepo.client.FedoraHeaderConstants.IF_UNMODIFIED_SINCE;
023
024import java.io.File;
025import java.io.FileInputStream;
026import java.io.IOException;
027import java.io.InputStream;
028import java.net.URI;
029
030import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
031import org.apache.http.entity.InputStreamEntity;
032
033/**
034 * Request builder which includes a body component
035 * 
036 * @author bbpennel
037 */
038public abstract class BodyRequestBuilder extends
039        RequestBuilder {
040
041    /**
042     * Instantiate builder
043     * 
044     * @param uri uri request will be issued to
045     * @param client the client
046     */
047    protected BodyRequestBuilder(final URI uri, final FcrepoClient client) {
048        super(uri, client);
049    }
050
051    /**
052     * Add a body to this request from a stream, with application/octet-stream as its content type
053     * 
054     * @param stream InputStream of the content to be sent to the server
055     * @return this builder
056     */
057    protected BodyRequestBuilder body(final InputStream stream) {
058        return body(stream, null);
059    }
060
061    /**
062     * Add a body to this request as a stream with the given content type
063     * 
064     * @param stream InputStream of the content to be sent to the server
065     * @param contentType the Content-Type of the body
066     * @return this builder
067     */
068    protected BodyRequestBuilder body(final InputStream stream, final String contentType) {
069        if (stream != null) {
070            String type = contentType;
071            if (type == null) {
072                type = "application/octet-stream";
073            }
074
075            ((HttpEntityEnclosingRequestBase) request).setEntity(new InputStreamEntity(stream));
076            request.addHeader(CONTENT_TYPE, type);
077        }
078
079        return this;
080    }
081
082    /**
083     * Add the given file as the body for this request with the provided content type
084     * 
085     * @param file File containing the content to be sent to the server
086     * @param contentType the Content-Type of the body
087     * @return this builder
088     * @throws IOException when unable to stream the body file
089     */
090    protected BodyRequestBuilder body(final File file, final String contentType) throws IOException {
091        return body(new FileInputStream(file), contentType);
092    }
093
094    /**
095     * Provide a SHA-1 checksum for the body of this request
096     * 
097     * @param digest sha-1 checksum to provide as the digest for the request body
098     * @return this builder
099     */
100    protected BodyRequestBuilder digest(final String digest) {
101        if (digest != null) {
102            request.addHeader(DIGEST, "sha1=" + digest);
103        }
104        return this;
105    }
106
107    /**
108     * Provide a if-unmodified-since header for this request
109     * 
110     * @param modified date to provide as the if-unmodified-since header
111     * @return this builder
112     */
113    public BodyRequestBuilder ifUnmodifiedSince(final String modified) {
114        if (modified != null) {
115            request.setHeader(IF_UNMODIFIED_SINCE, modified);
116        }
117        return this;
118    }
119
120    /**
121     * Provide an etag for the if-match header for this request
122     * 
123     * @param etag etag to provide as the if-match header
124     * @return this builder
125     */
126    protected BodyRequestBuilder ifMatch(final String etag) {
127        if (etag != null) {
128            request.setHeader(IF_MATCH, etag);
129        }
130        return this;
131    }
132}