1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jclouds.blobstore.functions;
20
21 import static com.google.common.base.Preconditions.checkArgument;
22 import static com.google.common.base.Preconditions.checkNotNull;
23 import static com.google.common.base.Preconditions.checkState;
24 import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
25 import static org.jclouds.blobstore.util.BlobStoreUtils.getNameFor;
26
27 import java.net.URI;
28 import java.util.Map.Entry;
29
30 import javax.inject.Inject;
31 import javax.inject.Named;
32 import javax.inject.Provider;
33 import javax.ws.rs.core.HttpHeaders;
34
35 import org.jclouds.blobstore.domain.MutableBlobMetadata;
36 import org.jclouds.date.DateService;
37 import org.jclouds.http.HttpException;
38 import org.jclouds.http.HttpRequest;
39 import org.jclouds.http.HttpResponse;
40 import org.jclouds.http.HttpUtils;
41 import org.jclouds.rest.InvocationContext;
42 import org.jclouds.rest.internal.GeneratedHttpRequest;
43
44 import com.google.common.annotations.VisibleForTesting;
45 import com.google.common.base.Function;
46
47
48
49
50 public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpResponse, MutableBlobMetadata>,
51 InvocationContext<ParseSystemAndUserMetadataFromHeaders> {
52 private final String metadataPrefix;
53 private final DateService dateParser;
54 private final Provider<MutableBlobMetadata> metadataFactory;
55
56 private String name;
57 private URI endpoint;
58
59 @Inject
60 public ParseSystemAndUserMetadataFromHeaders(Provider<MutableBlobMetadata> metadataFactory, DateService dateParser,
61 @Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
62 this.metadataFactory = checkNotNull(metadataFactory, "metadataFactory");
63 this.dateParser = checkNotNull(dateParser, "dateParser");
64 this.metadataPrefix = checkNotNull(metadataPrefix, "metadataPrefix");
65 }
66
67 public MutableBlobMetadata apply(HttpResponse from) {
68 checkNotNull(from, "request");
69 checkState(name != null, "name must be initialized by now");
70
71 MutableBlobMetadata to = metadataFactory.get();
72 to.setName(name);
73 to.setUri(endpoint);
74 if (from.getPayload() != null)
75 HttpUtils.copy(from.getPayload().getContentMetadata(), to.getContentMetadata());
76 addETagTo(from, to);
77 parseLastModifiedOrThrowException(from, to);
78 addUserMetadataTo(from, to);
79 return to;
80 }
81
82 @VisibleForTesting
83 void addUserMetadataTo(HttpResponse from, MutableBlobMetadata metadata) {
84 for (Entry<String, String> header : from.getHeaders().entries()) {
85 if (header.getKey() != null && header.getKey().startsWith(metadataPrefix))
86 metadata.getUserMetadata().put((header.getKey().substring(metadataPrefix.length())).toLowerCase(),
87 header.getValue());
88 }
89 }
90
91 @VisibleForTesting
92 void parseLastModifiedOrThrowException(HttpResponse from, MutableBlobMetadata metadata) throws HttpException {
93 String lastModified = from.getFirstHeaderOrNull(HttpHeaders.LAST_MODIFIED);
94 if (lastModified == null) {
95
96 if ((lastModified = from.getFirstHeaderOrNull("Last-modified")) == null)
97 throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: " + from);
98 }
99
100
101 if (lastModified.startsWith("20")) {
102 metadata.setLastModified(dateParser.iso8601DateParse(lastModified.replace("+0000", "Z")));
103 } else {
104 metadata.setLastModified(dateParser.rfc822DateParse(lastModified));
105 }
106
107 if (metadata.getLastModified() == null)
108 throw new HttpException("could not parse: " + HttpHeaders.LAST_MODIFIED + ": " + lastModified);
109 }
110
111 protected void addETagTo(HttpResponse from, MutableBlobMetadata metadata) {
112 String eTag = from.getFirstHeaderOrNull(HttpHeaders.ETAG);
113 if (metadata.getETag() == null && eTag != null) {
114 metadata.setETag(eTag);
115 }
116 }
117
118 public ParseSystemAndUserMetadataFromHeaders setContext(HttpRequest request) {
119 this.endpoint = request.getEndpoint();
120 checkArgument(request instanceof GeneratedHttpRequest<?>, "note this handler requires a GeneratedHttpRequest");
121 return setName(getNameFor(GeneratedHttpRequest.class.cast(request)));
122 }
123
124 public ParseSystemAndUserMetadataFromHeaders setName(String name) {
125 this.name = checkNotNull(name, "name");
126 return this;
127 }
128 }