All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jclouds.io.ContentMetadataCodec Maven / Gradle / Ivy

package org.jclouds.io;

import static com.google.common.collect.Iterables.any;
import static com.google.common.io.BaseEncoding.base64;
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
import static com.google.common.net.HttpHeaders.CONTENT_LANGUAGE;
import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
import static com.google.common.net.HttpHeaders.CONTENT_MD5;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static com.google.common.net.HttpHeaders.EXPIRES;

import java.util.Date;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
import org.jclouds.logging.Logger;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.Multimap;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;

@ImplementedBy(DefaultContentMetadataCodec.class)
public interface ContentMetadataCodec {

   /**
    * Generates standard HTTP headers for the give metadata.
    */
   public Multimap toHeaders(ContentMetadata md);

   /**
    * Sets properties related to the http headers listed in {@link ContentMetadata#HTTP_HEADERS}
    */
   public void fromHeaders(MutableContentMetadata contentMetadata, Multimap headers);

   /**
    * Parses the 'Expires' header.
    * If invalid, returns a date in the past (in accordance with HTTP 1.1 client spec).
    */
   public Date parseExpires(String expires);

   /**
    * Default implementation, in accordance with HTTP 1.1 spec.
    * 
    * @author aled
    */
   public static class DefaultContentMetadataCodec implements ContentMetadataCodec {
      
      @Resource
      protected Logger logger = Logger.NULL;

      private final DateCodec httpExpiresDateCodec;

      @Inject
      public DefaultContentMetadataCodec(DateCodecFactory dateCodecs) {
         httpExpiresDateCodec = dateCodecs.rfc1123();
      }
      
      protected DateCodec getExpiresDateCodec() {
         return httpExpiresDateCodec;
      }
      
      @Override
      public Multimap toHeaders(ContentMetadata md) {
         Builder builder = ImmutableMultimap.builder();
         if (md.getContentType() != null)
            builder.put(CONTENT_TYPE, md.getContentType());
         if (md.getContentDisposition() != null)
            builder.put(CONTENT_DISPOSITION, md.getContentDisposition());
         if (md.getContentEncoding() != null)
            builder.put(CONTENT_ENCODING, md.getContentEncoding());
         if (md.getContentLanguage() != null)
            builder.put(CONTENT_LANGUAGE, md.getContentLanguage());
         if (md.getContentLength() != null)
            builder.put(CONTENT_LENGTH, md.getContentLength() + "");
         if (md.getContentMD5() != null)
            builder.put(CONTENT_MD5, base64().encode(md.getContentMD5()));
         if (md.getExpires() != null)
            builder.put(EXPIRES, getExpiresDateCodec().toString(md.getExpires()));
         return builder.build();
      }
      
      @Override
      public void fromHeaders(MutableContentMetadata contentMetadata, Multimap headers) {
         boolean chunked = any(headers.entries(), new Predicate>() {
            @Override
            public boolean apply(Entry input) {
               return "Transfer-Encoding".equalsIgnoreCase(input.getKey()) && "chunked".equalsIgnoreCase(input.getValue());
            }
         });
         for (Entry header : headers.entries()) {
            if (!chunked && CONTENT_LENGTH.equalsIgnoreCase(header.getKey())) {
               contentMetadata.setContentLength(Long.valueOf(header.getValue()));
            } else if (CONTENT_MD5.equalsIgnoreCase(header.getKey())) {
               contentMetadata.setContentMD5(base64().decode(header.getValue()));
            } else if (CONTENT_TYPE.equalsIgnoreCase(header.getKey())) {
               contentMetadata.setContentType(header.getValue());
            } else if (CONTENT_DISPOSITION.equalsIgnoreCase(header.getKey())) {
               contentMetadata.setContentDisposition(header.getValue());
            } else if (CONTENT_ENCODING.equalsIgnoreCase(header.getKey())) {
               contentMetadata.setContentEncoding(header.getValue());
            } else if (CONTENT_LANGUAGE.equalsIgnoreCase(header.getKey())) {
               contentMetadata.setContentLanguage(header.getValue());
            } else if (EXPIRES.equalsIgnoreCase(header.getKey())) {
               contentMetadata.setExpires(parseExpires(header.getValue()));
            }
         }
      }
      
      public Date parseExpires(String expires) {
         try {
            return (expires != null) ? getExpiresDateCodec().toDate(expires) : null;
         } catch (IllegalArgumentException e) {
            logger.debug("Invalid Expires header (%s); should be in RFC-1123 format; treating as already expired: %s",
                  expires, e.getMessage());
            return new Date(0);
         }
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy