Java tutorial
/* * Copyright 2013-2015 EMC Corporation. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.emc.ecs.sync.model; import com.emc.ecs.sync.CommonOptions; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import javax.xml.bind.annotation.XmlTransient; import java.io.File; import java.util.Date; import java.util.Map; import java.util.TreeMap; public class SyncMetadata { public static final String METADATA_DIR = ".ecsmeta"; public static final String DIR_META_FILE = ".dirmeta"; protected String instanceClass = SyncMetadata.class.getName(); protected String cacheControl; protected String contentDisposition; protected String contentEncoding; protected long contentLength; protected String contentType; protected Date httpExpires; protected Date modificationTime; protected Map<String, UserMetadata> userMetadata = new TreeMap<>(); protected SyncAcl acl; protected Checksum checksum; protected Date expirationDate; public String getCacheControl() { return cacheControl; } public void setCacheControl(String cacheControl) { this.cacheControl = cacheControl; } public String getContentDisposition() { return contentDisposition; } public void setContentDisposition(String contentDisposition) { this.contentDisposition = contentDisposition; } public String getContentEncoding() { return contentEncoding; } public void setContentEncoding(String contentEncoding) { this.contentEncoding = contentEncoding; } public long getContentLength() { return contentLength; } public void setContentLength(long contentLength) { this.contentLength = contentLength; } public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } public Date getHttpExpires() { return httpExpires; } public void setHttpExpires(Date httpExpires) { this.httpExpires = httpExpires; } public Date getModificationTime() { return modificationTime; } public void setModificationTime(Date modificationTime) { this.modificationTime = modificationTime; } public Map<String, UserMetadata> getUserMetadata() { return userMetadata; } @XmlTransient public Map<String, String> getUserMetadataValueMap() { Map<String, String> valueMap = new TreeMap<>(); for (String key : userMetadata.keySet()) { valueMap.put(key, userMetadata.get(key).getValue()); } return valueMap; } public String getUserMetadataValue(String key) { UserMetadata meta = getUserMetadata().get(key); if (meta == null) return null; return meta.getValue(); } public void setUserMetadata(Map<String, UserMetadata> userMetadata) { this.userMetadata = userMetadata; } public void setUserMetadataValue(String key, String value) { UserMetadata meta = getUserMetadata().get(key); if (meta == null) { setUserMetadataValue(key, value, false); } else { meta.setValue(value); } } public void setUserMetadataValue(String key, String value, boolean indexed) { getUserMetadata().put(key, new UserMetadata(key, value, indexed)); } public SyncAcl getAcl() { return acl; } public void setAcl(SyncAcl acl) { this.acl = acl; } public Checksum getChecksum() { return checksum; } public void setChecksum(Checksum checksum) { this.checksum = checksum; } public Date getExpirationDate() { return expirationDate; } public void setExpirationDate(Date expirationDate) { this.expirationDate = expirationDate; } /** * For a given object path, returns the appropriate path that should contain that * object's Metadata container. This is a path/file with the same name inside the * .ecsmeta subdirectory. If the object itself is a directory, it's * ./.ecsmeta/.dirmeta. * * @param relativePath the relative path of the object to compute the metadata path name from * @return the path that should contain this object's metadata. This path may not exist. */ public static String getMetaPath(String relativePath, boolean directory) { String name = new File(relativePath).getName(); String base = directory ? relativePath : new File(relativePath).getParent(); return new File(new File(base, METADATA_DIR), directory ? DIR_META_FILE : name).getPath(); } public static SyncMetadata fromJson(String json) { JsonObject root = new JsonParser().parse(json).getAsJsonObject(); JsonElement instanceClass = root.get("instanceClass"); if (instanceClass == null) { // might be data from an older version; make sure user is aware throw new RuntimeException( "could not parse meta-file. this could mean you used an older version of EcsSync to move data to the source location. either use that same version again or use --" + CommonOptions.IGNORE_METADATA_OPTION + " to continue using this version"); } else { try { return ((SyncMetadata) Class.forName(instanceClass.getAsString()).newInstance()) .createFromJson(json); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } } /** * Override in subclasses to add fidelity */ protected SyncMetadata createFromJson(String json) { return new GsonBuilder().serializeNulls().create().fromJson(json, SyncMetadata.class); } public final String toJson() { return new GsonBuilder().serializeNulls().create().toJson(this); } public static class UserMetadata { private String key; private String value; private boolean indexed; public UserMetadata(String key, String value) { this(key, value, false); } public UserMetadata(String key, String value, boolean indexed) { this.key = key; this.value = value; this.indexed = indexed; } public String getKey() { return key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public boolean isIndexed() { return indexed; } public void setIndexed(boolean indexed) { this.indexed = indexed; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof UserMetadata)) return false; UserMetadata that = (UserMetadata) o; if (indexed != that.indexed) return false; if (!key.equals(that.key)) return false; if (value != null ? !value.equals(that.value) : that.value != null) return false; return true; } @Override public int hashCode() { int result = key.hashCode(); result = 31 * result + (value != null ? value.hashCode() : 0); result = 31 * result + (indexed ? 1 : 0); return result; } } }