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

main.java.com.cloudant.client.internal.views.PaginationToken Maven / Gradle / Ivy

There is a newer version: 2.20.1
Show newest version
/*
 * Copyright (c) 2015 IBM Corp. 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. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License 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.cloudant.client.internal.views;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;

import org.apache.commons.codec.binary.Base64;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

/**
 * This class is purely for serializing the fields necessary to generate an opaque pagination token.
 */
class PaginationToken {

    @SerializedName("d")
    public Boolean descending = null;

    @SerializedName("e")
    public JsonElement endkey = null;

    @SerializedName("ei")
    public String endkey_docid = null;

    @SerializedName("i")
    public Boolean inclusive_end = null;

    @SerializedName("s")
    public JsonElement startkey = null;

    @SerializedName("si")
    public String startkey_docid = null;

    @SerializedName("n")
    long pageNumber;

    @SerializedName("dr")
    PageMetadata.PagingDirection direction;

    // Construct a pagination token using the appropriate metadata
    private PaginationToken(PageMetadata pageMetadata) {
        this.pageNumber = pageMetadata.pageNumber;
        this.direction = pageMetadata.direction;
        this.descending = pageMetadata.pageRequestParameters.descending;
        this.endkey = pageMetadata.pageRequestParameters.endkey;
        this.endkey_docid = pageMetadata.pageRequestParameters.endkey_docid;
        this.inclusive_end = pageMetadata.pageRequestParameters.inclusive_end;
        this.startkey = pageMetadata.pageRequestParameters.startkey;
        this.startkey_docid = pageMetadata.pageRequestParameters.startkey_docid;
    }

    /**
     * Generate a PageMetadata object for the page represented by the specified pagination token.
     *
     * @param paginationToken   opaque pagination token
     * @param initialParameters the initial view query parameters (i.e. for the page 1 request).
     * @param                the view key type
     * @param                the view value type
     * @return PageMetadata object for the given page
     */
    static  PageMetadata mergeTokenAndQueryParameters(String paginationToken, final
    ViewQueryParameters initialParameters) {

        // Decode the base64 token into JSON
        String json = new String(Base64.decodeBase64(paginationToken), Charset.forName("UTF-8"));

        // Get a suitable Gson, we need any adapter registered for the K key type
        Gson paginationTokenGson = getGsonWithKeyAdapter(initialParameters);

        // Deserialize the pagination token JSON, using the appropriate K, V types
        PaginationToken token = paginationTokenGson.fromJson(json, PaginationToken.class);

        // Create new query parameters using the initial ViewQueryParameters as a starting point.
        ViewQueryParameters tokenPageParameters = initialParameters.copy();

        // Merge the values from the token into the new query parameters
        tokenPageParameters.descending = token.descending;
        tokenPageParameters.endkey = token.endkey;
        tokenPageParameters.endkey_docid = token.endkey_docid;
        tokenPageParameters.inclusive_end = token.inclusive_end;
        tokenPageParameters.startkey = token.startkey;
        tokenPageParameters.startkey_docid = token.startkey_docid;

        return new PageMetadata(token.direction, token
                .pageNumber, tokenPageParameters);
    }

    /**
     * Generate an opaque pagination token from the supplied PageMetadata.
     *
     * @param pageMetadata page metadata of the page for which the token should be generated
     * @return opaque pagination token
     */
    static String tokenize(PageMetadata pageMetadata) {
        try {
            Gson g = getGsonWithKeyAdapter(pageMetadata.pageRequestParameters);
            return new String(Base64.encodeBase64URLSafe(g.toJson(new PaginationToken
                    (pageMetadata)).getBytes("UTF-8")),
                    Charset.forName("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            //all JVMs should support UTF-8
            throw new RuntimeException(e);
        }
    }

    private static  Gson getGsonWithKeyAdapter(ViewQueryParameters vqp) {
        return new GsonBuilder().registerTypeAdapter(vqp.getKeyType(), vqp.getClient().getGson()
                .getAdapter(vqp.getKeyType())).create();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy