EMMA Coverage Report (generated Fri Aug 26 14:14:05 EDT 2011)
[all classes][org.jclouds.blobstore.functions]

COVERAGE SUMMARY FOR SOURCE FILE [ParseSystemAndUserMetadataFromHeaders.java]

nameclass, %method, %block, %line, %
ParseSystemAndUserMetadataFromHeaders.java100% (1/1)86%  (6/7)86%  (175/204)90%  (35/39)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ParseSystemAndUserMetadataFromHeaders100% (1/1)86%  (6/7)86%  (175/204)90%  (35/39)
setContext (HttpRequest): ParseSystemAndUserMetadataFromHeaders 0%   (0/1)0%   (0/16)0%   (0/3)
parseLastModifiedOrThrowException (HttpResponse, MutableBlobMetadata): void 100% (1/1)80%  (48/60)90%  (9/10)
apply (HttpResponse): MutableBlobMetadata 100% (1/1)98%  (47/48)100% (11/11)
ParseSystemAndUserMetadataFromHeaders (Provider, DateService, String): void 100% (1/1)100% (21/21)100% (5/5)
addETagTo (HttpResponse, MutableBlobMetadata): void 100% (1/1)100% (13/13)100% (4/4)
addUserMetadataTo (HttpResponse, MutableBlobMetadata): void 100% (1/1)100% (38/38)100% (4/4)
setName (String): ParseSystemAndUserMetadataFromHeaders 100% (1/1)100% (8/8)100% (2/2)

1/**
2 *
3 * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4 *
5 * ====================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ====================================================================
18 */
19package org.jclouds.blobstore.functions;
20 
21import static com.google.common.base.Preconditions.checkArgument;
22import static com.google.common.base.Preconditions.checkNotNull;
23import static com.google.common.base.Preconditions.checkState;
24import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
25import static org.jclouds.blobstore.util.BlobStoreUtils.getNameFor;
26 
27import java.net.URI;
28import java.util.Map.Entry;
29 
30import javax.inject.Inject;
31import javax.inject.Named;
32import javax.inject.Provider;
33import javax.ws.rs.core.HttpHeaders;
34 
35import org.jclouds.blobstore.domain.MutableBlobMetadata;
36import org.jclouds.date.DateService;
37import org.jclouds.http.HttpException;
38import org.jclouds.http.HttpRequest;
39import org.jclouds.http.HttpResponse;
40import org.jclouds.http.HttpUtils;
41import org.jclouds.rest.InvocationContext;
42import org.jclouds.rest.internal.GeneratedHttpRequest;
43 
44import com.google.common.annotations.VisibleForTesting;
45import com.google.common.base.Function;
46 
47/**
48 * @author Adrian Cole
49 */
50public 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         // scaleup-storage uses the wrong case for the last modified header
96         if ((lastModified = from.getFirstHeaderOrNull("Last-modified")) == null)
97            throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: " + from);
98      }
99 
100      // Walrus
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}

[all classes][org.jclouds.blobstore.functions]
EMMA 2.0.5312 (C) Vladimir Roubtsov