com.google.api.client.googleapis.services.AbstractGoogleClient.java Source code

Java tutorial

Introduction

Here is the source code for com.google.api.client.googleapis.services.AbstractGoogleClient.java

Source

/*
 * 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.google.api.client.googleapis.services;

import com.google.api.client.googleapis.batch.BatchRequest;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.util.ObjectParser;
import com.google.api.client.util.Preconditions;
import com.google.api.client.util.Strings;
import java.io.IOException;
import java.util.logging.Logger;

/**
 * Abstract thread-safe Google client.
 *
 * @since 1.12
 * @author Yaniv Inbar
 */
public abstract class AbstractGoogleClient {

    private static final Logger logger = Logger.getLogger(AbstractGoogleClient.class.getName());

    /** The request factory for connections to the server. */
    private final HttpRequestFactory requestFactory;

    /**
     * Initializer to use when creating an {@link AbstractGoogleClientRequest} or {@code null} for
     * none.
     */
    private final GoogleClientRequestInitializer googleClientRequestInitializer;

    /**
     * Root URL of the service, for example {@code "https://www.googleapis.com/"}. Must be URL-encoded
     * and must end with a "/".
     */
    private final String rootUrl;

    /**
     * Service path, for example {@code "tasks/v1/"}. Must be URL-encoded and must end with a "/".
     */
    private final String servicePath;

    /**
     * Batch path, for example {@code "batch/tasks"}.  Must be URL-encoded.
     */
    private final String batchPath;

    /**
     * Application name to be sent in the User-Agent header of each request or {@code null} for none.
     */
    private final String applicationName;

    /** Object parser or {@code null} for none. */
    private final ObjectParser objectParser;

    /** Whether discovery pattern checks should be suppressed on required parameters. */
    private final boolean suppressPatternChecks;

    /** Whether discovery required parameter checks should be suppressed. */
    private final boolean suppressRequiredParameterChecks;

    /**
     * @param builder builder
     *
     * @since 1.14
     */
    protected AbstractGoogleClient(Builder builder) {
        googleClientRequestInitializer = builder.googleClientRequestInitializer;
        rootUrl = normalizeRootUrl(builder.rootUrl);
        servicePath = normalizeServicePath(builder.servicePath);
        batchPath = builder.batchPath;
        if (Strings.isNullOrEmpty(builder.applicationName)) {
            logger.warning("Application name is not set. Call Builder#setApplicationName.");
        }
        applicationName = builder.applicationName;
        requestFactory = builder.httpRequestInitializer == null ? builder.transport.createRequestFactory()
                : builder.transport.createRequestFactory(builder.httpRequestInitializer);
        objectParser = builder.objectParser;
        suppressPatternChecks = builder.suppressPatternChecks;
        suppressRequiredParameterChecks = builder.suppressRequiredParameterChecks;
    }

    /**
     * Returns the URL-encoded root URL of the service, for example
     * {@code "https://www.googleapis.com/"}.
     *
     * <p>
     * Must end with a "/".
     * </p>
     */
    public final String getRootUrl() {
        return rootUrl;
    }

    /**
     * Returns the URL-encoded service path of the service, for example {@code "tasks/v1/"}.
     *
     * <p>
     * Must end with a "/" and not begin with a "/". It is allowed to be an empty string {@code ""} or
     * a forward slash {@code "/"}, if it is a forward slash then it is treated as an empty string
     * </p>
     */
    public final String getServicePath() {
        return servicePath;
    }

    /**
     * Returns the URL-encoded base URL of the service, for example
     * {@code "https://www.googleapis.com/tasks/v1/"}.
     *
     * <p>
     * Must end with a "/". It is guaranteed to be equal to {@code getRootUrl() + getServicePath()}.
     * </p>
     */
    public final String getBaseUrl() {
        return rootUrl + servicePath;
    }

    /**
     * Returns the application name to be sent in the User-Agent header of each request or
     * {@code null} for none.
     */
    public final String getApplicationName() {
        return applicationName;
    }

    /** Returns the HTTP request factory. */
    public final HttpRequestFactory getRequestFactory() {
        return requestFactory;
    }

    /** Returns the Google client request initializer or {@code null} for none. */
    public final GoogleClientRequestInitializer getGoogleClientRequestInitializer() {
        return googleClientRequestInitializer;
    }

    /**
     * Returns the object parser or {@code null} for none.
     *
     * <p>
     * Overriding is only supported for the purpose of calling the super implementation and changing
     * the return type, but nothing else.
     * </p>
     */
    public ObjectParser getObjectParser() {
        return objectParser;
    }

    /**
     * Initializes a {@link AbstractGoogleClientRequest} using a
     * {@link GoogleClientRequestInitializer}.
     *
     * <p>
     * Must be called before the Google client request is executed, preferably right after the request
     * is instantiated. Sample usage:
     * </p>
     *
     * <pre>
      public class Get extends HttpClientRequest {
        ...
      }
        
      public Get get(String userId) throws IOException {
        Get result = new Get(userId);
        initialize(result);
        return result;
      }
     * </pre>
     *
     * <p>
     * Subclasses may override by calling the super implementation.
     * </p>
     *
     * @param httpClientRequest Google client request type
     */
    protected void initialize(AbstractGoogleClientRequest<?> httpClientRequest) throws IOException {
        if (getGoogleClientRequestInitializer() != null) {
            getGoogleClientRequestInitializer().initialize(httpClientRequest);
        }
    }

    /**
     * Create an {@link BatchRequest} object from this Google API client instance.
     *
     * <p>
     * Sample usage:
     * </p>
     *
     * <pre>
       client.batch()
     .queue(...)
     .queue(...)
     .execute();
     * </pre>
     *
     * @return newly created Batch request
     */
    public final BatchRequest batch() {
        return batch(null);
    }

    /**
     * Create an {@link BatchRequest} object from this Google API client instance.
     *
     * <p>
     * Sample usage:
     * </p>
     *
     * <pre>
       client.batch(httpRequestInitializer)
     .queue(...)
     .queue(...)
     .execute();
     * </pre>
     *
     * @param httpRequestInitializer The initializer to use when creating the top-level batch HTTP
     *        request or {@code null} for none
     * @return newly created Batch request
     */
    public final BatchRequest batch(HttpRequestInitializer httpRequestInitializer) {
        @SuppressWarnings("deprecated")
        BatchRequest batch = new BatchRequest(getRequestFactory().getTransport(), httpRequestInitializer);
        if (Strings.isNullOrEmpty(batchPath)) {
            batch.setBatchUrl(new GenericUrl(getRootUrl() + "batch"));
        } else {
            batch.setBatchUrl(new GenericUrl(getRootUrl() + batchPath));
        }
        return batch;
    }

    /** Returns whether discovery pattern checks should be suppressed on required parameters. */
    public final boolean getSuppressPatternChecks() {
        return suppressPatternChecks;
    }

    /**
     * Returns whether discovery required parameter checks should be suppressed.
     *
     * @since 1.14
     */
    public final boolean getSuppressRequiredParameterChecks() {
        return suppressRequiredParameterChecks;
    }

    /** If the specified root URL does not end with a "/" then a "/" is added to the end. */
    static String normalizeRootUrl(String rootUrl) {
        Preconditions.checkNotNull(rootUrl, "root URL cannot be null.");
        if (!rootUrl.endsWith("/")) {
            rootUrl += "/";
        }
        return rootUrl;
    }

    /**
     * If the specified service path does not end with a "/" then a "/" is added to the end. If the
     * specified service path begins with a "/" then the "/" is removed.
     */
    static String normalizeServicePath(String servicePath) {
        Preconditions.checkNotNull(servicePath, "service path cannot be null");
        if (servicePath.length() == 1) {
            Preconditions.checkArgument("/".equals(servicePath),
                    "service path must equal \"/\" if it is of length 1.");
            servicePath = "";
        } else if (servicePath.length() > 0) {
            if (!servicePath.endsWith("/")) {
                servicePath += "/";
            }
            if (servicePath.startsWith("/")) {
                servicePath = servicePath.substring(1);
            }
        }
        return servicePath;
    }

    /**
     * Builder for {@link AbstractGoogleClient}.
     *
     * <p>
     * Implementation is not thread-safe.
     * </p>
     */
    public abstract static class Builder {

        /** HTTP transport. */
        final HttpTransport transport;

        /**
         * Initializer to use when creating an {@link AbstractGoogleClientRequest} or {@code null} for
         * none.
         */
        GoogleClientRequestInitializer googleClientRequestInitializer;

        /** HTTP request initializer or {@code null} for none. */
        HttpRequestInitializer httpRequestInitializer;

        /** Object parser to use for parsing responses. */
        final ObjectParser objectParser;

        /** The root URL of the service, for example {@code "https://www.googleapis.com/"}. */
        String rootUrl;

        /** The service path of the service, for example {@code "tasks/v1/"}. */
        String servicePath;

        /** The batch path of the service, for example {@code "batch/tasks"}. */
        String batchPath;

        /**
         * Application name to be sent in the User-Agent header of each request or {@code null} for
         * none.
         */
        String applicationName;

        /** Whether discovery pattern checks should be suppressed on required parameters. */
        boolean suppressPatternChecks;

        /** Whether discovery required parameter checks should be suppressed. */
        boolean suppressRequiredParameterChecks;

        /**
         * Returns an instance of a new builder.
         *
         * @param transport The transport to use for requests
         * @param rootUrl root URL of the service. Must end with a "/"
         * @param servicePath service path
         * @param objectParser object parser or {@code null} for none
         * @param httpRequestInitializer HTTP request initializer or {@code null} for none
         */
        protected Builder(HttpTransport transport, String rootUrl, String servicePath, ObjectParser objectParser,
                HttpRequestInitializer httpRequestInitializer) {
            this.transport = Preconditions.checkNotNull(transport);
            this.objectParser = objectParser;
            setRootUrl(rootUrl);
            setServicePath(servicePath);
            this.httpRequestInitializer = httpRequestInitializer;
        }

        /** Builds a new instance of {@link AbstractGoogleClient}. */
        public abstract AbstractGoogleClient build();

        /** Returns the HTTP transport. */
        public final HttpTransport getTransport() {
            return transport;
        }

        /**
         * Returns the object parser or {@code null} for none.
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         */
        public ObjectParser getObjectParser() {
            return objectParser;
        }

        /**
         * Returns the URL-encoded root URL of the service, for example
         * {@code https://www.googleapis.com/}.
         *
         * <p>
         * Must be URL-encoded and must end with a "/".
         * </p>
         */
        public final String getRootUrl() {
            return rootUrl;
        }

        /**
         * Sets the URL-encoded root URL of the service, for example {@code https://www.googleapis.com/}
         * .
         * <p>
         * If the specified root URL does not end with a "/" then a "/" is added to the end.
         * </p>
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         */
        public Builder setRootUrl(String rootUrl) {
            this.rootUrl = normalizeRootUrl(rootUrl);
            return this;
        }

        /**
         * Returns the URL-encoded service path of the service, for example {@code "tasks/v1/"}.
         *
         * <p>
         * Must be URL-encoded and must end with a "/" and not begin with a "/". It is allowed to be an
         * empty string {@code ""}.
         * </p>
         */
        public final String getServicePath() {
            return servicePath;
        }

        /**
         * Sets the URL-encoded service path of the service, for example {@code "tasks/v1/"}.
         *
         * <p>
         * It is allowed to be an empty string {@code ""} or a forward slash {@code "/"}, if it is a
         * forward slash then it is treated as an empty string. This is determined when the library is
         * generated and normally should not be changed.
         * </p>
         *
         * <p>
         * If the specified service path does not end with a "/" then a "/" is added to the end. If the
         * specified service path begins with a "/" then the "/" is removed.
         * </p>
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         */
        public Builder setServicePath(String servicePath) {
            this.servicePath = normalizeServicePath(servicePath);
            return this;
        }

        /**
         * Sets the URL-encoded batch path of the service, for example {@code "batch/tasks"}.
         */
        public Builder setBatchPath(String batchPath) {
            this.batchPath = batchPath;
            return this;
        }

        /** Returns the Google client request initializer or {@code null} for none. */
        public final GoogleClientRequestInitializer getGoogleClientRequestInitializer() {
            return googleClientRequestInitializer;
        }

        /**
         * Sets the Google client request initializer or {@code null} for none.
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         */
        public Builder setGoogleClientRequestInitializer(
                GoogleClientRequestInitializer googleClientRequestInitializer) {
            this.googleClientRequestInitializer = googleClientRequestInitializer;
            return this;
        }

        /** Returns the HTTP request initializer or {@code null} for none. */
        public final HttpRequestInitializer getHttpRequestInitializer() {
            return httpRequestInitializer;
        }

        /**
         * Sets the HTTP request initializer or {@code null} for none.
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         */
        public Builder setHttpRequestInitializer(HttpRequestInitializer httpRequestInitializer) {
            this.httpRequestInitializer = httpRequestInitializer;
            return this;
        }

        /**
         * Returns the application name to be used in the UserAgent header of each request or
         * {@code null} for none.
         */
        public final String getApplicationName() {
            return applicationName;
        }

        /**
         * Sets the application name to be used in the UserAgent header of each request or {@code null}
         * for none.
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         */
        public Builder setApplicationName(String applicationName) {
            this.applicationName = applicationName;
            return this;
        }

        /** Returns whether discovery pattern checks should be suppressed on required parameters. */
        public final boolean getSuppressPatternChecks() {
            return suppressPatternChecks;
        }

        /**
         * Sets whether discovery pattern checks should be suppressed on required parameters.
         *
         * <p>
         * Default value is {@code false}.
         * </p>
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         */
        public Builder setSuppressPatternChecks(boolean suppressPatternChecks) {
            this.suppressPatternChecks = suppressPatternChecks;
            return this;
        }

        /**
         * Returns whether discovery required parameter checks should be suppressed.
         *
         * @since 1.14
         */
        public final boolean getSuppressRequiredParameterChecks() {
            return suppressRequiredParameterChecks;
        }

        /**
         * Sets whether discovery required parameter checks should be suppressed.
         *
         * <p>
         * Default value is {@code false}.
         * </p>
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         *
         * @since 1.14
         */
        public Builder setSuppressRequiredParameterChecks(boolean suppressRequiredParameterChecks) {
            this.suppressRequiredParameterChecks = suppressRequiredParameterChecks;
            return this;
        }

        /**
         * Suppresses all discovery pattern and required parameter checks.
         *
         * <p>
         * Overriding is only supported for the purpose of calling the super implementation and changing
         * the return type, but nothing else.
         * </p>
         *
         * @since 1.14
         */
        public Builder setSuppressAllChecks(boolean suppressAllChecks) {
            return setSuppressPatternChecks(true).setSuppressRequiredParameterChecks(true);
        }
    }
}