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