001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.client; 019 020import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE; 021import static org.fcrepo.client.FedoraHeaderConstants.DIGEST; 022import static org.fcrepo.client.FedoraHeaderConstants.IF_MATCH; 023import static org.fcrepo.client.FedoraHeaderConstants.IF_UNMODIFIED_SINCE; 024 025import java.io.File; 026import java.io.FileInputStream; 027import java.io.IOException; 028import java.io.InputStream; 029import java.net.URI; 030import java.util.StringJoiner; 031 032import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; 033import org.apache.http.entity.InputStreamEntity; 034 035/** 036 * Request builder which includes a body component 037 * 038 * @author bbpennel 039 */ 040public abstract class BodyRequestBuilder extends 041 RequestBuilder { 042 043 private StringJoiner digestJoiner; 044 045 /** 046 * Instantiate builder 047 * 048 * @param uri uri request will be issued to 049 * @param client the client 050 */ 051 protected BodyRequestBuilder(final URI uri, final FcrepoClient client) { 052 super(uri, client); 053 } 054 055 /** 056 * Add a body to this request from a stream, with application/octet-stream as its content type 057 * 058 * @param stream InputStream of the content to be sent to the server 059 * @return this builder 060 */ 061 protected BodyRequestBuilder body(final InputStream stream) { 062 return body(stream, null); 063 } 064 065 /** 066 * Add a body to this request as a stream with the given content type 067 * 068 * @param stream InputStream of the content to be sent to the server 069 * @param contentType the Content-Type of the body 070 * @return this builder 071 */ 072 protected BodyRequestBuilder body(final InputStream stream, final String contentType) { 073 if (stream != null) { 074 String type = contentType; 075 if (type == null) { 076 type = "application/octet-stream"; 077 } 078 079 ((HttpEntityEnclosingRequestBase) request).setEntity(new InputStreamEntity(stream)); 080 request.addHeader(CONTENT_TYPE, type); 081 } 082 083 return this; 084 } 085 086 /** 087 * Add the given file as the body for this request with the provided content type 088 * 089 * @param file File containing the content to be sent to the server 090 * @param contentType the Content-Type of the body 091 * @return this builder 092 * @throws IOException when unable to stream the body file 093 */ 094 protected BodyRequestBuilder body(final File file, final String contentType) throws IOException { 095 return body(new FileInputStream(file), contentType); 096 } 097 098 /** 099 * Provide a SHA-1 checksum for the body of this request. 100 * 101 * @deprecated Use {@link #digestSha1(java.lang.String)}. 102 * @param digest sha-1 checksum to provide as the digest for the request body 103 * @return this builder 104 */ 105 @Deprecated 106 protected BodyRequestBuilder digest(final String digest) { 107 return digestSha1(digest); 108 } 109 110 /** 111 * Provide a checksum for the body of this request 112 * 113 * @param digest checksum to provide as the digest for the request body 114 * @param alg abbreviated algorithm identifier for the type of checksum being 115 * added (for example, sha1, md5, etc) 116 * @return this builder 117 */ 118 protected BodyRequestBuilder digest(final String digest, final String alg) { 119 if (digest != null) { 120 if (digestJoiner == null) { 121 digestJoiner = new StringJoiner(", "); 122 } 123 digestJoiner.add(alg + "=" + digest); 124 request.setHeader(DIGEST, digestJoiner.toString()); 125 } 126 return this; 127 } 128 129 /** 130 * Provide a SHA-1 checksum for the body of this request. 131 * 132 * @param digest sha-1 checksum to provide as the digest for the request body 133 * @return this builder 134 */ 135 protected BodyRequestBuilder digestSha1(final String digest) { 136 return digest(digest, "sha1"); 137 } 138 139 /** 140 * Provide a MD5 checksum for the body of this request 141 * 142 * @param digest MD5 checksum to provide as the digest for the request body 143 * @return this builder 144 */ 145 protected BodyRequestBuilder digestMd5(final String digest) { 146 return digest(digest, "md5"); 147 } 148 149 /** 150 * Provide a SHA-256 checksum for the body of this request 151 * 152 * @param digest sha-256 checksum to provide as the digest for the request body 153 * @return this builder 154 */ 155 protected BodyRequestBuilder digestSha256(final String digest) { 156 return digest(digest, "sha256"); 157 } 158 159 /** 160 * Provide a if-unmodified-since header for this request 161 * 162 * @param modified date to provide as the if-unmodified-since header 163 * @return this builder 164 */ 165 public BodyRequestBuilder ifUnmodifiedSince(final String modified) { 166 if (modified != null) { 167 request.setHeader(IF_UNMODIFIED_SINCE, modified); 168 } 169 return this; 170 } 171 172 /** 173 * Provide an etag for the if-match header for this request 174 * 175 * @param etag etag to provide as the if-match header 176 * @return this builder 177 */ 178 protected BodyRequestBuilder ifMatch(final String etag) { 179 if (etag != null) { 180 request.setHeader(IF_MATCH, etag); 181 } 182 return this; 183 } 184}