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

com.dropbox.core.DbxDelta Maven / Gradle / Ivy

The newest version!
package com.dropbox.core;

import com.dropbox.core.json.JsonArrayExtractor;
import com.dropbox.core.json.JsonExtractionException;
import com.dropbox.core.json.JsonExtractor;
import com.dropbox.core.util.DumpWriter;
import static com.dropbox.core.util.StringUtil.jq;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Represents a single "page" of results from a delta-style API call.
 *
 * @param 
 *     The type of metadata being returned in the delta results.  For example, in the
 *     {@link DbxClient#getDelta}, this has type {@link DbxEntry}.
 */
public final class DbxDelta extends DbxDataObject
{
    /**
     * If {@code true}, then you should reset your local state to be an empty
     * folder before processing the list of delta entries.
     *
     * 

* This is always {@code true} for the first delta result, but for subsequent results * it is true only in {@code true} rare situations. For example, if Dropbox * changes their cursor format, or if a user asks Dropbox to completely reset his/her * account, then the next time you call a delta API it may send down a reset and * start you from scratch. *

*/ public final boolean reset; /** * Apply these entries to your local state to catch up with the Dropbox server's state. */ public final List> entries; /** * A string that is used by the server to keep track of which entries have already been * returned to you. This is what you pass in to the next API call to continue where you * left off. * *

* This cursor is valid for a long time. You'd typically store this somewhere persistent * (such as a database) so you can resume continue you left off. *

*/ public final String cursor; /** * If {@code true}, then there are more entries available. You can retrieve * them immediately by making the call again (passing in {@link #cursor}). * If {@code false}, then wait at least 5 minutes before checking again. */ public final boolean hasMore; /** * @param reset {@link #reset} * @param entries {@link #entries} * @param cursor {@link #cursor} * @param hasMore {@link #hasMore} */ public DbxDelta(boolean reset, List> entries, String cursor, boolean hasMore) { this.reset = reset; this.entries = entries; this.cursor = cursor; this.hasMore = hasMore; } protected void dumpFields(DumpWriter out) { out.field("reset"); out.writeln(Boolean.toString(reset)); out.field("entries"); dump(out, entries); } public String toString() { return "{reset=" + reset + ", entries.size=" + entries.size() + ", cursor=" + jq(cursor) + ", hasMore=" + hasMore + "}"; } /** * For JSON parsing. */ public static final class Extractor extends JsonExtractor> { public final JsonExtractor metadataExtractor; public Extractor(JsonExtractor metadataExtractor) { this.metadataExtractor = metadataExtractor; } public DbxDelta extract(JsonParser parser) throws IOException, JsonExtractionException { return extract(parser, metadataExtractor); } public static DbxDelta extract(JsonParser parser, JsonExtractor metadataExtractor) throws IOException, JsonExtractionException { JsonLocation top = JsonExtractor.expectObjectStart(parser); Boolean reset = null; ArrayList> entries = null; String cursor = null; Boolean has_more = null; while (parser.getCurrentToken() == JsonToken.FIELD_NAME) { String fieldName = parser.getCurrentName(); JsonExtractor.nextToken(parser); int fi = FM.get(fieldName); try { if (fi == -1) { // Unknown field. Skip over it. JsonExtractor.skipValue(parser); continue; } switch (fi) { case FM_reset: reset = JsonExtractor.BooleanExtractor.extractField(parser, fieldName, reset); break; case FM_entries: JsonExtractor> entryExtractor = new Entry.Extractor(metadataExtractor); entries = JsonArrayExtractor.mk(entryExtractor).extractField(parser, fieldName, entries); break; case FM_cursor: cursor = JsonExtractor.StringExtractor.extractField(parser, fieldName, cursor); break; case FM_has_more: has_more = JsonExtractor.BooleanExtractor.extractField(parser, fieldName, has_more); break; default: throw new AssertionError("bad index: " + fi + ", field = \"" + fieldName + "\""); } } catch (JsonExtractionException ex) { throw ex.addFieldContext(fieldName); } } JsonExtractor.expectObjectEnd(parser); if (reset == null) throw new JsonExtractionException("missing field \"path\"", top); if (entries == null) throw new JsonExtractionException("missing field \"entries\"", top); if (cursor == null) throw new JsonExtractionException("missing field \"cursor\"", top); if (has_more == null) throw new JsonExtractionException("missing field \"has_more\"", top); return new DbxDelta(reset, entries, cursor, has_more); } private static final int FM_reset = 0; private static final int FM_entries = 1; private static final int FM_cursor = 2; private static final int FM_has_more = 3; private static final JsonExtractor.FieldMapping FM; static { JsonExtractor.FieldMapping.Builder b = new JsonExtractor.FieldMapping.Builder(); b.add("reset", FM_reset); b.add("entries", FM_entries); b.add("cursor", FM_cursor); b.add("has_more", FM_has_more); FM = b.build(); } } /** * A single "delta entry" in a {@link DbxDelta} page. * * @param * The type of metadata being returned in the delta results. */ public static final class Entry extends DbxDataObject { /** * The lower-cased path of the entry. Dropbox compares file paths in a * case-insensitive manner. For example, an entry for {@code "/readme.txt"} * should overwrite the entry for {@code "/ReadMe.TXT"}. * *

* To get the original case-preserved path, look in the {@link #metadata} field. *

*/ public final String lcPath; /** * If this is {@code null}, it means that this path doesn't exist on * on Dropbox's copy of the file system. To update your local state to * match, delete whatever is at that path, including any children. * If your local state doesn't have anything at this path, ignore this entry. * *

* If this is not {@code null}, it means that Dropbox has a file/folder * at this path with the given metadata. To update your local state to match, * add the entry to your local state as well. *

*
    *
  • * If the path refers to parent folders that don't exist yet in your local * state, create those parent folders in your local state. *
  • *
  • * If the metadata is for a file, replace whatever your local state has at * that path with the new entry. *
  • *
  • * If the metadata is for a folder, check what your local state has at the * path. If it's a file, replace it with the new entry. If it's a folder, * apply the new metadata to the folder, but do not modify the folder's * children. *
  • *
*/ public final MD metadata; /** * @param lcPath {@link #lcPath} * @param metadata {@link #metadata} */ public Entry(String lcPath, MD metadata) { this.lcPath = lcPath; this.metadata = metadata; } protected void dumpFields(DumpWriter out) { out.field(lcPath); dump(out, metadata); } public String toString() { if (metadata == null) { return "-" + jq(lcPath); } else { return "+" + metadata.toString(); } } /** * For JSON parsing. */ public static final class Extractor extends JsonExtractor> { public final JsonExtractor metadataExtractor; public Extractor(JsonExtractor metadataExtractor) { this.metadataExtractor = metadataExtractor; } public Entry extract(JsonParser parser) throws IOException, JsonExtractionException { return extract(parser, metadataExtractor); } public static Entry extract(JsonParser parser, JsonExtractor metadataExtractor) throws IOException, JsonExtractionException { JsonLocation arrayStart = JsonExtractor.expectArrayStart(parser); if (JsonExtractor.isArrayEnd(parser)) { throw new JsonExtractionException("expecting a two-element array of [path, metadata], found a zero-element array", arrayStart); } String lcPath; try { lcPath = JsonExtractor.StringExtractor.extract(parser); } catch (JsonExtractionException ex) { throw ex.addArrayContext(0); } if (JsonExtractor.isArrayEnd(parser)) { throw new JsonExtractionException("expecting a two-element array of [path, metadata], found a one-element array: " + jq(lcPath), arrayStart); } MD metadata; try { metadata = metadataExtractor.extractOptional(parser); } catch (JsonExtractionException ex) { throw ex.addArrayContext(1); } if (!JsonExtractor.isArrayEnd(parser)) { throw new JsonExtractionException("expecting a two-element array of [path, metadata], found non \"]\" token after the two elements: " + parser.getCurrentToken(), arrayStart); } parser.nextToken(); return new Entry(lcPath, metadata); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy