package com.xiaomi.infra.galaxy.fds.client.model; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.http.Header; import com.xiaomi.infra.galaxy.fds.client.auth.Common; import com.xiaomi.infra.galaxy.fds.client.auth.Utils; /** * Represents the object metadata that is stored with Galaxy FDS. This includes * custom user-supplied metadata, as well as the standard HTTP headers that * Galaxy FDS sends and receives (Content-Length, ETag, Content-MD5, etc.). */ public class FDSObjectMetadata { private final Map<String, String> metadata = new HashMap<String, String>(); public static final String USER_DEFINED_META_PREFIX = Common.XIAOMI_META_HEADER_PREFIX; public enum PredefinedMetadata { CacheControl(Common.CACHE_CONTROL), ContentEncoding(Common.CONTENT_ENCODING), ContentLength(Common.CONTENT_LENGTH), LastModified(Common.LAST_MODIFIED), ContentMD5(Common.CONTENT_MD5), ContentType(Common.CONTENT_TYPE), LastChecked(Common.LAST_CHECKED), UploadTime(Common.UPLOAD_TIME); private final String header; private PredefinedMetadata(String header) { this.header = header; } public String getHeader() { return header; } } public void addHeader(String key, String value) { checkMetadata(key); metadata.put(key, value); } public void addUserMetadata(String key, String value) { checkMetadata(key); metadata.put(key, value); } public void setUserMetadata(Map<String, String> userMetadata) { for (Map.Entry<String, String> entry : userMetadata.entrySet()) { checkMetadata(entry.getKey()); metadata.put(entry.getKey(), entry.getValue()); } } public String getCacheControl() { return metadata.get(Common.CACHE_CONTROL); } public void setCacheControl(String cacheControl) { metadata.put(Common.CACHE_CONTROL, cacheControl); } public String getContentEncoding() { return metadata.get(Common.CONTENT_ENCODING); } public void setContentEncoding(String contentEncoding) { metadata.put(Common.CONTENT_ENCODING, contentEncoding); } public long getContentLength() { String contentLength = metadata.get(Common.CONTENT_LENGTH); if (contentLength != null) { return Long.parseLong(contentLength); } return -1; } public void setContentLength(long contentLength) { metadata.put(Common.CONTENT_LENGTH, Long.toString(contentLength)); } public Date getLastModified() { String lastModified = metadata.get(Common.LAST_MODIFIED); if (lastModified != null) { return Utils.parseDateTimeFromString(lastModified); } return null; } public void setLastModified(Date lastModified) { metadata.put(Common.LAST_MODIFIED, Utils.getGMTDatetime(lastModified)); } public String getLastChecked() { return metadata.get(Common.LAST_CHECKED); } public void setLastChecked(String timeString) { metadata.put(Common.LAST_CHECKED, timeString); } public String getContentMD5() { return metadata.get(Common.CONTENT_MD5); } public void setContentMD5(String contentMD5) { metadata.put(Common.CONTENT_MD5, contentMD5); } public String getContentType() { return metadata.get(Common.CONTENT_TYPE); } public void setContentType(String contentType) { metadata.put(Common.CONTENT_TYPE, contentType); } public Map<String, String> getRawMetadata() { return Collections.unmodifiableMap(metadata); } public static FDSObjectMetadata parseObjectMetadata(Header[] headers) { FDSObjectMetadata metadata = new FDSObjectMetadata(); Map<String, String> headerMap = new HashMap<String, String>(); for (Header h: headers) { // NOTE use lower case here String key = h.getName().toLowerCase(); String value = h.getValue(); if (headerMap.containsKey(key)) continue; headerMap.put(key, value); if (key.startsWith(FDSObjectMetadata.USER_DEFINED_META_PREFIX)) { metadata.addHeader(key, value); } } for (PredefinedMetadata m : PredefinedMetadata.values()) { String value = headerMap.get(m.getHeader()); if (value != null && !value.isEmpty()) { metadata.addHeader(m.getHeader(), value); } } return metadata; } private static void checkMetadata(String key) { boolean isValid = key.startsWith(FDSObjectMetadata.USER_DEFINED_META_PREFIX); if (!isValid) { for (PredefinedMetadata m : PredefinedMetadata.values()) { if (key.equals(m.getHeader())) { isValid = true; break; } } } if (!isValid) { throw new RuntimeException("Invalid metadata: " + key, null); } } }