/* Copyright (c) 2008 Google Inc. * * 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.gdata.client.docs; import com.google.gdata.client.AuthTokenFactory; import com.google.gdata.client.Service; import com.google.gdata.client.media.MediaService; import com.google.gdata.data.acl.AclEntry; import com.google.gdata.data.acl.AclFeed; import com.google.gdata.data.acl.AclRole; import com.google.gdata.data.acl.AclScope; import com.google.gdata.data.batch.BatchUtils; import com.google.gdata.data.docs.AudioEntry; import com.google.gdata.data.docs.DocumentEntry; import com.google.gdata.data.docs.DocumentExportEntry; import com.google.gdata.data.docs.DocumentExportFeed; import com.google.gdata.data.docs.DocumentListFeed; import com.google.gdata.data.docs.FolderEntry; import com.google.gdata.data.docs.MetadataFeed; import com.google.gdata.data.docs.PdfEntry; import com.google.gdata.data.docs.PresentationEntry; import com.google.gdata.data.docs.QueryParameter; import com.google.gdata.data.docs.RevisionFeed; import com.google.gdata.data.docs.SpreadsheetEntry; import com.google.gdata.util.ServiceException; import com.google.gdata.util.Version; import com.google.gdata.util.VersionRegistry; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.List; /** * Extends the basic {@link MediaService} abstraction to define a service that * is preconfigured for access to the Google Documents List Data API. * * */ public class DocsService extends MediaService { /** * The abbreviated name of Google Documents List Data API recognized by * Google. The service name is used when requesting an authentication token. */ public static final String DOCS_SERVICE = "writely"; /** * The version ID of the service. */ public static final String DOCS_SERVICE_VERSION = "GDocs-Java/" + DocsService.class.getPackage().getImplementationVersion(); /** GData versions supported by the Google Documents List Data API. */ public static final class Versions { /** Version 1. This is the initial version of the API and is based on * Version 1 of the GData protocol. */ public static final Version V1 = new Version(DocsService.class, "1.0", Service.Versions.V1); /** Version 2. This version of the API adds full compliance with the Atom * Publishing Protocol and is based on Version 2 of the GData protocol. */ public static final Version V2 = new Version(DocsService.class, "2.0", Service.Versions.V2); /** Version 3. This version of the API adds a revision feed, PDF support, * folder and group sharing, * and introduces backwards in compatible changes from Version 2. */ public static final Version V3 = new Version(DocsService.class, "3.0", Service.Versions.V2); private Versions() {} } /** * Default GData version used by the Google Documents List Data API. */ public static final Version DEFAULT_VERSION = Service.initServiceVersion(DocsService.class, Versions.V3); /** * Constructs an instance connecting to the Google Documents List Data API for * an application with the name {@code applicationName}. * * @param applicationName the name of the client application accessing the * service. Application names should preferably have the format * [company-id]-[app-name]-[app-version]. The name will be used by the * Google servers to monitor the source of authentication. */ public DocsService(String applicationName) { super(DOCS_SERVICE, applicationName); declareExtensions(); } /** * Constructs an instance connecting to the Google Documents List Data API for * an application with the name {@code applicationName} and the given {@code * GDataRequestFactory} and {@code AuthTokenFactory}. Use this constructor to * override the default factories. * * @param applicationName the name of the client application accessing the * service. Application names should preferably have the format * [company-id]-[app-name]-[app-version]. The name will be used by the * Google servers to monitor the source of authentication. * @param requestFactory the request factory that generates gdata request * objects * @param authTokenFactory the factory that creates auth tokens */ public DocsService(String applicationName, Service.GDataRequestFactory requestFactory, AuthTokenFactory authTokenFactory) { super(applicationName, requestFactory, authTokenFactory); declareExtensions(); } /** * Constructs an instance connecting to the Google Documents List Data API * with name {@code serviceName} for an application with the name {@code * applicationName}. The service will authenticate at the provided {@code * domainName}. * * @param applicationName the name of the client application accessing the * service. Application names should preferably have the format * [company-id]-[app-name]-[app-version]. The name will be used by the * Google servers to monitor the source of authentication. * @param protocol name of protocol to use for authentication * ("http"/"https") * @param domainName the name of the domain hosting the login handler */ public DocsService(String applicationName, String protocol, String domainName) { super(DOCS_SERVICE, applicationName, protocol, domainName); declareExtensions(); } @Override public String getServiceVersion() { return DOCS_SERVICE_VERSION + " " + super.getServiceVersion(); } /** * Returns the current GData version used by the Google Documents List Data * API. */ public static Version getVersion() { return VersionRegistry.get().getVersion(DocsService.class); } /** * Declare the extensions of the feeds for the Google Documents List Data API. */ private void declareExtensions() { new AclFeed().declareExtensions(extProfile); new DocumentExportFeed().declareExtensions(extProfile); new MetadataFeed().declareExtensions(extProfile); new RevisionFeed().declareExtensions(extProfile); /* Declarations for extensions that need to be handled as specific type * should be done before call to {@see ExtensionProfile#setAutoExtending}. * Order of declaration is important. */ extProfile.setAutoExtending(true); new AudioEntry().declareExtensions(extProfile); new DocumentEntry().declareExtensions(extProfile); new DocumentListFeed().declareExtensions(extProfile); new FolderEntry().declareExtensions(extProfile); new PdfEntry().declareExtensions(extProfile); new PresentationEntry().declareExtensions(extProfile); new SpreadsheetEntry().declareExtensions(extProfile); BatchUtils.declareExtensions(extProfile); } /** * Adds the Google Docs extensions. */ public void addExtensions() { declareExtensions(); } /** * Inserts a new {@link com.google.gdata.data.acl.AclEntry} into a feed * associated with the target service. It will return the inserted AclEntry, * including any additional attributes or extensions set by the GData server. * <p> * This is a convenience method. It constructs the AclEntry from the * specified AclScope and AclRole. * * @param aclFeedUrl the POST URL associated with the target acl feed * @param scope the scope of the new acl * @param role the desired role for scope * * @return the newly inserted AclEntry returned by the service * * @throws IOException an ill-formed URI, internal error. See * makeEntryUrl * @throws ServiceException insert request failed due to lack of * permissions, scope already defined on this feed, unsupported role or scope, * system error, etc */ public AclEntry insert(URL aclFeedUrl, AclScope scope, AclRole role) throws IOException, ServiceException { AclEntry entry = new AclEntry(); entry.setScope(scope); entry.setRole(role); return insert(aclFeedUrl, entry); } /** * Updates an existing {@link com.google.gdata.data.acl.AclEntry} by writing * it to the specified feed URL. The resulting AclEntry (after update) * will be returned. * <p> * This is a convenience method. It constructs the entry edit URL from * the feed URL and scope, and also constructs the AclEntry. * * @param aclFeedUrl the POST URL associated with the target acl feed * @param scope the scope of the to-be-updated acl * @param role the desired role for scope * * @return the updated entry returned by the service * * @throws IOException an ill-formed URI, internal error. See * makeEntryUrl * @throws ServiceException update request failed due to lack of * permissions, unsupported role or scope, system error, etc */ public AclEntry update(URL aclFeedUrl, AclScope scope, AclRole role) throws IOException, ServiceException { URL entryUrl = makeEntryUrl(aclFeedUrl, scope); AclEntry entry = new AclEntry(); entry.setScope(scope); entry.setRole(role); entry.setId(entryUrl.toExternalForm()); return update(entryUrl, entry); } /** * Deletes an existing AclEntry from the specified feed URL. * specified edit URL. * <p> * This is a convenience method. It constructs the entry edit URL from * the feed URL and scope. * * @param aclFeedUrl the POST URI associated with the target acl feed * @param scope the scope of the to-be-deleted acl * * @throws IOException an ill-formed URI, internal error. See * makeEntryUrl * @throws ServiceException delete request failed due to lack of * permissions, unsupported role or scope, system error, etc */ public void delete(URL aclFeedUrl, AclScope scope) throws IOException, ServiceException { delete(makeEntryUrl(aclFeedUrl, scope)); } private URL makeEntryUrl(URL aclFeedUrl, AclScope scope) throws IOException { try { URI uri = new URI(aclFeedUrl.getProtocol(), null, aclFeedUrl.getHost(), aclFeedUrl.getPort(), aclFeedUrl.getPath() + "/" + scope.toExternalForm(), null, null); return uri.toURL(); } catch (URISyntaxException e) { throw new IOException(); } } /** * * Start a new request to download the documents that match all search * criteria as a zip file. * @param exportFeedUrl the POST URL associated with the target export feed. * @param params the search criteria. * @return the newly inserted DocumentExportEntry returned by the service. * @throws IOException an ill-formed URI, internal error. * @throws ServiceException insert request failed due to lack of permissions, * scope already defined on this feed, unsupported role or scope, system * error, etc. */ public DocumentExportEntry insert(URL exportFeedUrl, List<QueryParameter> params) throws IOException, ServiceException { DocumentExportEntry entry = new DocumentExportEntry(); for (QueryParameter param : params) { entry.addQuery(param); } return insert(exportFeedUrl, entry); } }