com.emc.ecs.sync.model.ObjectMetadata.java Source code

Java tutorial

Introduction

Here is the source code for com.emc.ecs.sync.model.ObjectMetadata.java

Source

/*
 * 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.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.*;

public class ObjectMetadata implements Cloneable {
    public static final String METADATA_DIR = ".ecsmeta";
    public static final String DIR_META_FILE = ".dirmeta";

    protected String instanceClass = ObjectMetadata.class.getName();
    protected boolean directory;
    private String cacheControl;
    private String contentDisposition;
    private String contentEncoding;
    private long contentLength;
    private String contentType;
    private Date httpExpires;
    private Date modificationTime;
    private Date metaChangeTime;
    private Map<String, UserMetadata> userMetadata = new TreeMap<>();
    protected Checksum checksum;
    private Date expirationDate;
    private String retentionPolicy;
    private Date retentionEndDate;

    /**
     * Returns whether this object represents a directory or prefix. If false, assume this is a data object (even if
     * size is zero). Note that if you override this method, it *CANNOT* throw an exception. This would silently break
     * several logic flows.
     */
    public boolean isDirectory() {
        return directory;
    }

    public void setDirectory(boolean directory) {
        this.directory = directory;
    }

    public ObjectMetadata withDirectory(boolean directory) {
        setDirectory(directory);
        return this;
    }

    public String getCacheControl() {
        return cacheControl;
    }

    public void setCacheControl(String cacheControl) {
        this.cacheControl = cacheControl;
    }

    public ObjectMetadata withCacheControl(String cacheControl) {
        setCacheControl(cacheControl);
        return this;
    }

    public String getContentDisposition() {
        return contentDisposition;
    }

    public void setContentDisposition(String contentDisposition) {
        this.contentDisposition = contentDisposition;
    }

    public ObjectMetadata withContentDisposition(String contentDisposition) {
        setContentDisposition(contentDisposition);
        return this;
    }

    public String getContentEncoding() {
        return contentEncoding;
    }

    public void setContentEncoding(String contentEncoding) {
        this.contentEncoding = contentEncoding;
    }

    public ObjectMetadata withContentEncoding(String contentEncoding) {
        setContentEncoding(contentEncoding);
        return this;
    }

    public long getContentLength() {
        return contentLength;
    }

    public void setContentLength(long contentLength) {
        this.contentLength = contentLength;
    }

    public ObjectMetadata withContentLength(long contentLength) {
        setContentLength(contentLength);
        return this;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public ObjectMetadata withContentType(String contentType) {
        setContentType(contentType);
        return this;
    }

    public Date getHttpExpires() {
        return httpExpires;
    }

    public void setHttpExpires(Date httpExpires) {
        this.httpExpires = httpExpires;
    }

    public ObjectMetadata withHttpExpires(Date httpExpires) {
        setHttpExpires(httpExpires);
        return this;
    }

    public Date getModificationTime() {
        return modificationTime;
    }

    public void setModificationTime(Date modificationTime) {
        this.modificationTime = modificationTime;
    }

    public ObjectMetadata withModificationTime(Date modificationTime) {
        setModificationTime(modificationTime);
        return this;
    }

    public Date getMetaChangeTime() {
        return metaChangeTime;
    }

    public void setMetaChangeTime(Date metaChangeTime) {
        this.metaChangeTime = metaChangeTime;
    }

    public ObjectMetadata withMetaChangeTime(Date metaChangeTime) {
        setMetaChangeTime(metaChangeTime);
        return this;
    }

    public Map<String, UserMetadata> getUserMetadata() {
        return userMetadata;
    }

    @XmlTransient
    public Map<String, String> getUserMetadataValueMap() {
        return new StringView();
    }

    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 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;
    }

    public String getRetentionPolicy() {
        return retentionPolicy;
    }

    public void setRetentionPolicy(String retentionPolicy) {
        this.retentionPolicy = retentionPolicy;
    }

    public Date getRetentionEndDate() {
        return retentionEndDate;
    }

    public void setRetentionEndDate(Date retentionEndDate) {
        this.retentionEndDate = retentionEndDate;
    }

    /**
     * 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 ObjectMetadata 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 --no-sync-user-metadata to continue using this version");
        } else {
            try {
                return ((ObjectMetadata) Class.forName(instanceClass.getAsString()).newInstance())
                        .createFromJson(json);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
    }

    /**
     * Override in subclasses to add fidelity
     */
    protected ObjectMetadata createFromJson(String json) {
        return new GsonBuilder().serializeNulls().create().fromJson(json, ObjectMetadata.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;
        }
    }

    private class StringView implements Map<String, String> {
        @Override
        public int size() {
            return userMetadata.size();
        }

        @Override
        public boolean isEmpty() {
            return userMetadata.isEmpty();
        }

        @Override
        public boolean containsKey(Object key) {
            return userMetadata.containsKey(key);
        }

        @Override
        public boolean containsValue(Object value) {
            return userMetadata.containsValue(value);
        }

        @Override
        public String get(Object key) {
            return getUserMetadataValue((String) key);
        }

        @Override
        public String put(String key, String value) {
            String oldValue = get(key);
            setUserMetadataValue(key, value);
            return oldValue;
        }

        @Override
        public String remove(Object key) {
            String oldValue = get(key);
            userMetadata.remove(key);
            return oldValue;
        }

        @Override
        public void putAll(Map<? extends String, ? extends String> m) {
            for (String key : m.keySet()) {
                put(key, m.get(key));
            }
        }

        @Override
        public void clear() {
            userMetadata.clear();
        }

        @Override
        public Set<String> keySet() {
            return userMetadata.keySet();
        }

        @Override
        public Collection<String> values() {
            throw new UnsupportedOperationException("cannot get values collection");
        }

        @Override
        public Set<Entry<String, String>> entrySet() {
            throw new UnsupportedOperationException("cannot get entry set");
        }
    }
}