001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.client; 007 008import static org.fcrepo.client.FedoraHeaderConstants.ACCEPT; 009import static org.fcrepo.client.FedoraHeaderConstants.IF_MODIFIED_SINCE; 010import static org.fcrepo.client.FedoraHeaderConstants.IF_NONE_MATCH; 011import static org.fcrepo.client.FedoraHeaderConstants.PREFER; 012import static org.fcrepo.client.FedoraHeaderConstants.RANGE; 013import java.net.URI; 014import java.time.Instant; 015import java.util.List; 016import java.util.StringJoiner; 017import java.util.stream.Collectors; 018 019import org.apache.http.client.methods.HttpRequestBase; 020 021/** 022 * Builds a GET request to retrieve the content of a resource from the Fedora HTTP API 023 * 024 * @author bbpennel 025 */ 026public class GetBuilder extends RetrieveRequestBuilder { 027 028 /** 029 * Construct a GetBuilder 030 * 031 * @param uri the target 032 * @param client the client for this request 033 */ 034 public GetBuilder(final URI uri, final FcrepoClient client) { 035 super(uri, client); 036 } 037 038 @Override 039 protected HttpRequestBase createRequest() { 040 return HttpMethods.GET.createRequest(targetUri); 041 } 042 043 /** 044 * Add the accept header to this request to negotiate the response format. 045 * 046 * @param mediaType media type to set as the accept header. It should be a value from one of the allowed RDF 047 * source formats supported by Fedora. 048 * @return this builder 049 */ 050 public GetBuilder accept(final String mediaType) { 051 if (mediaType != null) { 052 request.setHeader(ACCEPT, mediaType); 053 } 054 return this; 055 } 056 057 /** 058 * Set the byte range of content to retrieve 059 * 060 * @param rangeStart beginning byte index 061 * @param rangeEnd ending byte index 062 * @return this builder 063 */ 064 public GetBuilder range(final Long rangeStart, final Long rangeEnd) { 065 if (rangeStart != null || rangeEnd != null) { 066 String range = "bytes="; 067 if (rangeStart != null && rangeStart.longValue() > -1L) { 068 range += rangeStart.toString(); 069 } 070 range += "-"; 071 if (rangeEnd != null && rangeEnd.longValue() > -1L) { 072 range += rangeEnd.toString(); 073 } 074 request.setHeader(RANGE, range); 075 } 076 return this; 077 } 078 079 /** 080 * Set the prefer header for this request to representation, to indicate that links to other resources and their 081 * properties should also be included. 082 * 083 * @return this builder 084 */ 085 public GetBuilder preferRepresentation() { 086 request.setHeader(PREFER, buildPrefer("representation", null, null)); 087 return this; 088 } 089 090 /** 091 * Set the prefer header for this request to representation, to indicate that links to other resources and their 092 * properties should also be included. The set of properties returned can be further specified by providing lists 093 * of LDP defined preferences to omit or include. 094 * 095 * @param includeUris URIs of LDP defined preferences to include 096 * @param omitUris URIs of LDP defined preferences to omit 097 * @return this builder 098 */ 099 public GetBuilder preferRepresentation(final List<URI> includeUris, final List<URI> omitUris) { 100 request.setHeader(PREFER, buildPrefer("representation", includeUris, omitUris)); 101 return this; 102 } 103 104 private String buildPrefer(final String prefer, final List<URI> includeUris, final List<URI> omitUris) { 105 final StringJoiner preferJoin = new StringJoiner("; "); 106 preferJoin.add("return=" + prefer); 107 108 if (includeUris != null) { 109 final String include = includeUris.stream().map(URI::toString).collect(Collectors.joining(" ")); 110 if (include.length() > 0) { 111 preferJoin.add("include=\"" + include + "\""); 112 } 113 } 114 115 if (omitUris != null) { 116 final String omit = omitUris.stream().map(URI::toString).collect(Collectors.joining(" ")); 117 if (omit.length() > 0) { 118 preferJoin.add("omit=\"" + omit + "\""); 119 } 120 } 121 122 return preferJoin.toString(); 123 } 124 125 /** 126 * Provide an etag for the if-none-match header for this request 127 * 128 * @param etag etag to provide as the if-none-match header 129 * @return this builder 130 */ 131 public GetBuilder ifNoneMatch(final String etag) { 132 if (etag != null) { 133 request.setHeader(IF_NONE_MATCH, etag); 134 } 135 return this; 136 } 137 138 /** 139 * Provide a if-last-modified header for this request 140 * 141 * @param lastModified date to provided as the if-modified-since header 142 * @return this builder 143 */ 144 public GetBuilder ifModifiedSince(final String lastModified) { 145 if (lastModified != null) { 146 request.setHeader(IF_MODIFIED_SINCE, lastModified); 147 } 148 return this; 149 } 150 151 @Override 152 public GetBuilder disableRedirects() { 153 return (GetBuilder) super.disableRedirects(); 154 } 155 156 @Override 157 public GetBuilder wantDigest(final String value) { 158 return (GetBuilder) super.wantDigest(value); 159 } 160 161 @Override 162 public GetBuilder noCache() { 163 return (GetBuilder) super.noCache(); 164 } 165 166 @Override 167 public GetBuilder acceptDatetime(final Instant acceptInstant) { 168 return (GetBuilder) super.acceptDatetime(acceptInstant); 169 } 170 171 @Override 172 public GetBuilder acceptDatetime(final String acceptDatetime) { 173 return (GetBuilder) super.acceptDatetime(acceptDatetime); 174 } 175 176 @Override 177 public GetBuilder addHeader(final String name, final String value) { 178 return (GetBuilder) super.addHeader(name, value); 179 } 180 181 @Override 182 public GetBuilder addLinkHeader(final FcrepoLink linkHeader) { 183 return (GetBuilder) super.addLinkHeader(linkHeader); 184 } 185 186 @Override 187 public GetBuilder addTransaction(final URI transaction) { 188 return (GetBuilder) super.addTransaction(transaction); 189 } 190}