Package com.dropbox.core

Source Code of com.dropbox.core.DbxEntry$WithChildren

package com.dropbox.core;

import static com.dropbox.core.util.StringUtil.jq;

import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

import com.dropbox.core.json.*;
import com.dropbox.core.json.JsonArrayReader;
import com.dropbox.core.json.JsonReader;
import com.dropbox.core.util.Collector;
import com.dropbox.core.util.DumpWriter;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

/**
* Holds the metadata for a Dropbox file system entry.  Can either be a regular file or a folder.
*/
public abstract class DbxEntry extends DbxDataObject implements Serializable
{
    public static final long serialVersionUID = 0;

    /**
     * Just the last part of {@link #path}.  Derived automatically from {@link #path}.
     *
     * @see DbxPath#getName
     */
    public final String name;

    /**
     * The path to the file or folder, relative to your application's root.
     * The path always starts with a {@code "/"}.
     *
     * <p>
     * For full-Dropbox apps, the path is relative to the root
     * of the user's Dropbox.  For App Folder apps, the path
     * is relative to your application's App Folder within the user's Dropbox.
     * </p>
     */
    public final String path;

    /**
     * The name of the icon to use for this file.  The set of names returned by this call match up
     * with icons in a set of icons provided by Dropbox.  Read more about the <em>icon</em>
     * field in <a href="https://www.dropbox.com/developers/reference/api#metadata">
     * Dropbox's documentation for the {@code /metadata} HTTP endpoint</a>.
     */
    public final String iconName;

    /**
     * Whether this file or folder might have a thumbnail image you can retrieve via
     * the [TODO: thumbnail call].
     * If this is {@code true}, there might be a thumbnail available.  If this is
     * {@code false}, there is definitely no thumbnail available.
     */
    public final boolean mightHaveThumbnail;

    /**
     * @param path {@link #path}
     * @param iconName {@link #iconName}
     * @param mightHaveThumbnail {@link #mightHaveThumbnail}
     */
    private DbxEntry(String path, String iconName, boolean mightHaveThumbnail)
    {
        this.name = DbxPath.getName(path);
        this.path = path;
        this.iconName = iconName;
        this.mightHaveThumbnail = mightHaveThumbnail;
    }

    protected void dumpFields(DumpWriter w)
    {
        w.field("path");
        dump(w, path);

        w.field("iconName");
        dump(w, iconName);

        w.field("mightHaveThumbnail");
        w.writeln(Boolean.toString(mightHaveThumbnail));
    }

    /**
     * Whether this metadata is for a folder, which can be cast to type
     * {@link Folder}.  (Every metadata object is either for a file or a folder.)
     */
    public abstract boolean isFolder();

    /**
     * Whether this metadata is for a file, which can be cast to type
     * {@link File}.  (Every metadata object is either for a file or a folder.)
     */
    public abstract boolean isFile();

    /**
     * If this metadata entry is a folder, return it as a {@code DbxEntry.Folder}
     * instance.  If it's not a folder, return {@code null}.
     */
    public abstract Folder asFolder();

    /**
     * If this metadata entry is a file, return it as a {@code DbxEntry.File}
     * instance.  If it's not a file, return {@code null}.
     */
    public abstract File asFile();

    /**
     * The subclass of {@link DbxEntry} used to represent folder metadata.  Folders
     * actually only have the same set of fields as {@link DbxEntry}.
     */
    public static final class Folder extends DbxEntry
    {
    public static final long serialVersionUID = 0;

        /**
         * @param path {@link #path}
         * @param iconName {@link #iconName}
         * @param mightHaveThumbnail {@link #mightHaveThumbnail}
         */
        public Folder(String path, String iconName, boolean mightHaveThumbnail)
        {
            super(path, iconName, mightHaveThumbnail);
        }

        protected String getTypeName() { return "Folder"; }

        /**
         * A abbreviated version of {@link #toStringMultiline}.  Only includes the path.
         */
        public String toString() { return "Folder(" + jq(path) + ")"; }

        public boolean isFolder() { return true; }
        public boolean isFile() { return false; }
        public Folder asFolder() { return this; }
        public File asFile() { return null; }
    }

    /**
     * The subclass of {@link DbxEntry} used to represent file metadata (as opposed
     * to folder metadata).
     */
    public static final class File extends DbxEntry
    {
    public static final long serialVersionUID = 0;

        /**
         * The size, in bytes, of the file content.
         */
        public final long numBytes;

        /**
         * A human-readable string version of the file size (ex: "13 kb").  This string will
         * be localized based on the {@link java.util.Locale Locale} in {@link DbxRequestConfig#userLocale}
         * (passed in to the {@link DbxClient} constructor).
         */
        public final String humanSize;

        /**
         * The time the file was added, moved, or last had it's contents changed on the Dropbox
         * server.  (This probably won't match the time on the Dropbox user's filesystem.  For that
         * the {@link #clientMtime} is a better estimate.)
         *
         */
        public final Date lastModified;

        /**
         * The modification time sent up by the Dropbox desktop client when the file was added
         * or modified.  This time is based on the system clock of the particular host that the
         * client was running on, as opposed to the system clock of the Dropbox servers.
         *
         * <p>
         * This field <em>should not</em> be used to determine if a file has changed, but only as
         * a way to sort files by date (when displaying a list of files to the user).
         * </p>
         */
        public final Date clientMtime;

        public final String mimeType;

        /**
         * The revision of the file at this path.  This can be used with {@link DbxClient#uploadFile}
         * and the {@link DbxWriteMode#update} mode to make sure you're overwriting the revision of
         * the file you think you're overwriting.
         */
        public final String revision;

        /**
         * @param path {@link #path}
         * @param iconName {@link #iconName}
         * @param mightHaveThumbnail {@link #mightHaveThumbnail}
         * @param numBytes {@link #numBytes}
         * @param humanSize {@link #humanSize}
         * @param lastModified {@link #lastModified}
         * @param clientMtime {@link #clientMtime}
         * @param mimeType {@link #mimeType}
         * @param revision {@link #revision}
         */
        public File(String path, String iconName, boolean mightHaveThumbnail, long numBytes, String humanSize, Date lastModified, Date clientMtime, String mimeType, String revision)
        {
            super(path, iconName, mightHaveThumbnail);
            this.numBytes = numBytes;
            this.humanSize = humanSize;
            this.lastModified = lastModified;
            this.clientMtime = clientMtime;
            this.mimeType = mimeType;
            this.revision = revision;
        }

        protected void dumpFields(DumpWriter w)
        {
            super.dumpFields(w);
            w.field("numBytes");
            w.writeln(Long.toString(numBytes));
            w.field("humanSize");
            dump(w, humanSize);
            w.field("lastModified");
            dump(w, lastModified);
            w.field("clientMtime");
            dump(w, clientMtime);
            w.field("mimeType");
            dump(w, mimeType);
            w.field("revision");
            dump(w, revision);
        }

        protected String getTypeName() { return "File"; }

        /**
         * A abbreviated version of {@link #toStringMultiline}.  Only includes the path.
         */
        public String toString()
        {
            return "File(" + jq(path) + ", numBytes=" + numBytes + ", lastModified=" + toStringDate(lastModified) + ", revision=" + jq(revision) + ")";
        }

        public boolean isFolder() { return false; }
        public boolean isFile() { return true; }
        public Folder asFolder() { return null; }
        public File asFile() { return this; }
    }

    // ------------------------------------------------------
    // JSON parsing

    public static final JsonReader<DbxEntry> Reader = new JsonReader<DbxEntry>()
    {
        public final DbxEntry read(JsonParser parser)
            throws IOException, JsonReadException
        {
            return DbxEntry.extract(parser, null).entry;
        }
    };

    /**
     * Holds the metadata for a file or folder; if it's a folder, we also store the folder's
     * hash and the metadata of its immediate children.
     *
     * @see DbxClient#getMetadataWithChildren
     * @see DbxClient#getMetadataWithChildrenIfChanged
     */
    public static final class WithChildren implements Serializable
    {
        public static final long serialVersionUID = 0;

        public final DbxEntry entry;

        /**
         * If {@link #entry} is a folder, this will contain a hash that identifies the folder's
         * contents.  This value can be used with {@link DbxClient#getMetadataWithChildrenIfChanged}
         * to void downloading the folder contents if they havne't changed.
         */
        public final String hash;

        /**
         * If {@link #entry} is a folder, this will contain the metadata of the folder's
         * immediate children.  If it's not a folder, this will be {@code null}.
         */
        public final List<DbxEntry> children;

        /**
         * @param entry {@link #entry}
         * @param hash {@link #hash}
         * @param children {@link #children}
         */
        public WithChildren(DbxEntry entry, String hash, List<DbxEntry> children)
        {
            this.entry = entry;
            this.hash = hash;
            this.children = children;
        }

        public static final JsonReader<WithChildren> Reader = new JsonReader<WithChildren>()
        {
            public final WithChildren read(JsonParser parser)
                throws IOException, JsonReadException
            {
                WithChildrenC<List<DbxEntry>> c = DbxEntry.<List<DbxEntry>>extract(parser, new Collector.ArrayListCollector<DbxEntry>());
                return new WithChildren(c.entry, c.hash, c.children);
            }
        };
    }

    /**
     * The more general case of {@link WithChildren}.  It's used in the {@code C}-suffixed
     * variants ({@link DbxClient#getMetadataWithChildrenC} and {@link DbxClient#getMetadataWithChildrenIfChanged}
     * to allow you to process the {@link DbxEntry} values as the come in and aggregate them into
     * your own object (instead of the default {@link List}) using a custom {@link Collector}.
     */
    public static final class WithChildrenC<C> implements Serializable
    {
        public static final long serialVersionUID = 0;

        public final DbxEntry entry;

        /**
         * If {@link #entry} is a folder, this will contain a hash that identifies the folder's
         * contents.  This value can be used with {@link DbxClient#getMetadataWithChildrenIfChanged}
         * to void downloading the folder contents if they havne't changed.
         */
        public final String hash;

        /**
         * If {@link #entry} is a folder, this will contain the metadata of the folder's
         * immediate children.  If it's not a folder, this will be {@code null}.
         */
        public final C children;

        /**
         * @param entry {@link #entry}
         * @param hash {@link #hash}
         * @param children {@link #children}
         */
        public WithChildrenC(DbxEntry entry, String hash, C children)
        {
            this.entry = entry;
            this.hash = hash;
            this.children = children;
        }

        public static class Reader<C> extends JsonReader<WithChildrenC<C>>
        {
            private final Collector<DbxEntry,? extends C> collector;
            public Reader(Collector<DbxEntry, ? extends C> collector) { this.collector = collector; }

            public final WithChildrenC<C> read(JsonParser parser)
                throws IOException, JsonReadException
            {
                return DbxEntry.extract(parser, collector);
            }
        }
    }

    /**
     * @return
     *     {@code null} if the entry is an 'is_deleted' entry.
     */
    public static <C> WithChildrenC<C> extract(JsonParser parser, Collector<DbxEntry,? extends C> collector)
        throws IOException, JsonReadException
    {
        JsonLocation top = JsonReader.expectObjectStart(parser);

        String size = null;
        long bytes = -1;
        String path = null;
        Boolean is_dir = null;
        Boolean is_deleted = null;
        String rev = null;
        Boolean thumb_exists = null;
        String icon = null;
        Date modified = null;
        Date client_mtime = null;
        String mime_type = null;
        String hash = null;
        C contents = null;

        while (parser.getCurrentToken() == JsonToken.FIELD_NAME) {
            String fieldName = parser.getCurrentName();
            JsonReader.nextToken(parser);

            int fi = FM.get(fieldName);
            try {
                switch (fi) {
                    case -1: JsonReader.skipValue(parser); break;
                    case FM_size: size = JsonReader.StringReader.readField(parser, fieldName, size); break;
                    case FM_bytes: bytes = JsonReader.extractUnsignedLongField(parser, fieldName, bytes); break;
                    case FM_path: path = JsonReader.StringReader.readField(parser, fieldName, path); break;
                    case FM_is_dir: is_dir = JsonReader.BooleanReader.readField(parser, fieldName, is_dir); break;
                    case FM_is_deleted: is_deleted = JsonReader.BooleanReader.readField(parser, fieldName, is_deleted); break;
                    case FM_rev: rev = JsonReader.StringReader.readField(parser, fieldName, rev); break;
                    case FM_thumb_exists: thumb_exists = JsonReader.BooleanReader.readField(parser, fieldName, thumb_exists); break;
                    case FM_icon: icon = JsonReader.StringReader.readField(parser, fieldName, icon); break;
                    case FM_modified: modified = JsonDateReader.Dropbox.readField(parser, fieldName, modified); break;
                    case FM_client_mtime: client_mtime = JsonDateReader.Dropbox.readField(parser, fieldName, client_mtime); break;
                    case FM_mime_type: mime_type = JsonReader.StringReader.readField(parser, fieldName, mime_type); break;
                    case FM_hash:
                        if (collector == null) throw new JsonReadException("not expecting \"hash\" field, since we didn't ask for children", parser.getCurrentLocation());
                        hash = JsonReader.StringReader.readField(parser, fieldName, hash); break;
                    case FM_contents:
                        if (collector == null) throw new JsonReadException("not expecting \"contents\" field, since we didn't ask for children", parser.getCurrentLocation());
                        contents = JsonArrayReader.mk(Reader, collector).readField(parser, fieldName, contents); break;
                    default:
                        throw new AssertionError("bad index: " + fi + ", field = \"" + fieldName + "\"");
                }
            }
            catch (JsonReadException ex) {
                throw ex.addFieldContext(fieldName);
            }
        }

        JsonReader.expectObjectEnd(parser);

        if (path == null) throw new JsonReadException("missing field \"path\"", top);
        if (icon == null) throw new JsonReadException("missing field \"icon\"", top);
        if (is_deleted == null) is_deleted = Boolean.FALSE;
        if (is_dir == null) is_dir = Boolean.FALSE;
        if (thumb_exists == null) thumb_exists = Boolean.FALSE;

        if (is_dir && (contents != null || hash != null)) {
            if (hash == null) throw new JsonReadException("missing \"hash\", when we asked for children", top);
            if (contents == null) throw new JsonReadException("missing \"contents\", when we asked for children", top);
        }

        DbxEntry e;
        if (is_dir) {
            e = new Folder(path, icon, thumb_exists);
        }
        else {
            // Normal File
            if (size == null) throw new JsonReadException("missing \"size\" for a file entry", top);
            if (bytes == -1) throw new JsonReadException("missing \"bytes\" for a file entry", top);
            if (modified == null) throw new JsonReadException("missing \"modified\" for a file entry", top);
            if (client_mtime == null) throw new JsonReadException("missing \"client_mtime\" for a file entry", top);
            if (mime_type == null) throw new JsonReadException("missing \"mime_type\" for a file entry", top);
            if (rev == null) throw new JsonReadException("missing \"rev\" for a file entry", top);
            e = new File(path, icon, thumb_exists, bytes, size, modified, client_mtime, mime_type, rev);
        }

        if (is_deleted) return null;
        return new WithChildrenC<C>(e, hash, contents);
    }

    private static final int FM_size = 0;
    private static final int FM_bytes = 1;
    private static final int FM_path = 2;
    private static final int FM_is_dir = 3;
    private static final int FM_is_deleted = 4;
    private static final int FM_rev = 5;
    private static final int FM_thumb_exists = 6;
    private static final int FM_icon = 7;
    private static final int FM_modified = 8;
    private static final int FM_client_mtime = 9;
    private static final int FM_mime_type = 10;
    private static final int FM_hash = 11;
    private static final int FM_contents = 12;
    private static final JsonReader.FieldMapping FM;

    static {
        JsonReader.FieldMapping.Builder b = new JsonReader.FieldMapping.Builder();
        b.add("size", FM_size);
        b.add("bytes", FM_bytes);
        b.add("path", FM_path);
        b.add("is_dir", FM_is_dir);
        b.add("is_deleted", FM_is_deleted);
        b.add("rev", FM_rev);
        b.add("thumb_exists", FM_thumb_exists);
        b.add("icon", FM_icon);
        b.add("modified", FM_modified);
        b.add("client_mtime", FM_client_mtime);
        b.add("mime_type", FM_mime_type);
        b.add("hash", FM_hash);
        b.add("contents", FM_contents);
        FM = b.build();
    }
}
TOP

Related Classes of com.dropbox.core.DbxEntry$WithChildren

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
li>
  • org.apache.hadoop.fs.Path
  • TOP
    Copyright © 2018 www.massapi.com. All rights reserved.
    All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.