com.google.api.client.googleapis.services.AbstractGoogleClient Maven / Gradle / Ivy
/*
* 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/"}.
*
* Must end with a "/".
*/
public final String getRootUrl() {
return rootUrl;
}
/**
* Returns the URL-encoded service path of the service, for example {@code "tasks/v1/"}.
*
*
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
*/
public final String getServicePath() {
return servicePath;
}
/**
* Returns the URL-encoded base URL of the service, for example {@code
* "https://www.googleapis.com/tasks/v1/"}.
*
*
Must end with a "/". It is guaranteed to be equal to {@code getRootUrl() +
* getServicePath()}.
*/
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.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
public ObjectParser getObjectParser() {
return objectParser;
}
/**
* Initializes a {@link AbstractGoogleClientRequest} using a {@link
* GoogleClientRequestInitializer}.
*
*
Must be called before the Google client request is executed, preferably right after the
* request is instantiated. Sample usage:
*
*
* public class Get extends HttpClientRequest {
* ...
* }
*
* public Get get(String userId) throws IOException {
* Get result = new Get(userId);
* initialize(result);
* return result;
* }
*
*
* Subclasses may override by calling the super implementation.
*
* @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.
*
*
Sample usage:
*
*
* client.batch()
* .queue(...)
* .queue(...)
* .execute();
*
*
* @return newly created Batch request
*/
public final BatchRequest batch() {
return batch(null);
}
/**
* Create an {@link BatchRequest} object from this Google API client instance.
*
* Sample usage:
*
*
* client.batch(httpRequestInitializer)
* .queue(...)
* .queue(...)
* .execute();
*
*
* @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}.
*
* Implementation is not thread-safe.
*/
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.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
public ObjectParser getObjectParser() {
return objectParser;
}
/**
* Returns the URL-encoded root URL of the service, for example {@code
* https://www.googleapis.com/}.
*
*
Must be URL-encoded and must end with a "/".
*/
public final String getRootUrl() {
return rootUrl;
}
/**
* Sets the URL-encoded root URL of the service, for example {@code https://www.googleapis.com/}
* .
*
*
If the specified root URL does not end with a "/" then a "/" is added to the end.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
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/"}.
*
*
Must be URL-encoded and must end with a "/" and not begin with a "/". It is allowed to be
* an empty string {@code ""}.
*/
public final String getServicePath() {
return servicePath;
}
/**
* Sets the URL-encoded service path of the service, for example {@code "tasks/v1/"}.
*
*
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.
*
*
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.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
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.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
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.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
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.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
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.
*
*
Default value is {@code false}.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*/
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.
*
*
Default value is {@code false}.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*
* @since 1.14
*/
public Builder setSuppressRequiredParameterChecks(boolean suppressRequiredParameterChecks) {
this.suppressRequiredParameterChecks = suppressRequiredParameterChecks;
return this;
}
/**
* Suppresses all discovery pattern and required parameter checks.
*
*
Overriding is only supported for the purpose of calling the super implementation and
* changing the return type, but nothing else.
*
* @since 1.14
*/
public Builder setSuppressAllChecks(boolean suppressAllChecks) {
return setSuppressPatternChecks(true).setSuppressRequiredParameterChecks(true);
}
}
}