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

com.google.api.client.googleapis.xml.atom.package-info Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010 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.
 */

/**
 * {@link com.google.api.client.util.Beta} 
* Utilities for Google's Atom XML implementation (see detailed package specification). * *

Package Specification

* *

User-defined Partial XML data models allow you to defined Plain Old Java Objects (POJO's) to * define how the library should parse/serialize XML. Each field that should be included must have * an @{@link com.google.api.client.util.Key} annotation. The field can be of any visibility * (private, package private, protected, or public) and must not be static. * *

The optional value parameter of this @{@link com.google.api.client.util.Key} annotation * specifies the XPath name to use to represent the field. For example, an XML attribute a * has an XPath name of @a, an XML element <a> has an XPath * name of * a * , and an XML text content has an XPath name of text(). These are named based * on their usage with the partial * response/update syntax for Google API's. If the @{@link com.google.api.client.util.Key} * annotation is missing, the default is to use the Atom XML namespace and the Java field's name as * the local XML name. By default, the field name is used as the JSON key. Any unrecognized XML is * normally simply ignored and not stored. If the ability to store unknown keys is important, use * {@link com.google.api.client.xml.GenericXml}. * *

Let's take a look at a typical partial Atom XML album feed from the Picasa Web Albums Data * API: * *

{@code
 * <?xml version='1.0' encoding='utf-8'?>
 * <feed xmlns='http://www.w3.org/2005/Atom'
 * xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'
 * xmlns:gphoto='http://schemas.google.com/photos/2007'>
 * <link rel='http://schemas.google.com/g/2005#post'
 * type='application/atom+xml'
 * href='http://picasaweb.google.com/data/feed/api/user/liz' />
 * <author>
 * <name>Liz</name>
 * </author>
 * <openSearch:totalResults>1</openSearch:totalResults>
 * <entry gd:etag='"RXY8fjVSLyp7ImA9WxVVGE8KQAE."'>
 * <category scheme='http://schemas.google.com/g/2005#kind'
 * term='http://schemas.google.com/photos/2007#album' />
 * <title>lolcats</title>
 * <summary>Hilarious Felines</summary>
 * <gphoto:access>public</gphoto:access>
 * </entry>
 * </feed>
 * }
* *

Here's one possible way to design the Java data classes for this (each class in its own Java * file): * *

{@code
 * import com.google.api.client.util.*;
 * import java.util.List;
 *
 * public class Link {
 *
 *   @Key("@href")
 *   public String href;
 *
 *   @Key("@rel")
 *   public String rel;
 *
 *   public static String find(List<Link> links, String rel) {
 *     if (links != null) {
 *       for (Link link : links) {
 *         if (rel.equals(link.rel)) {
 *           return link.href;
 *         }
 *       }
 *     }
 *     return null;
 *   }
 * }
 *
 * public class Category {
 *
 *   @Key("@scheme")
 *   public String scheme;
 *
 *   @Key("@term")
 *   public String term;
 *
 *   public static Category newKind(String kind) {
 *     Category category = new Category();
 *     category.scheme = "http://schemas.google.com/g/2005#kind";
 *     category.term = "http://schemas.google.com/photos/2007#" + kind;
 *     return category;
 *   }
 * }
 *
 * public class AlbumEntry {
 *
 *   @Key
 *   public String summary;
 *
 *   @Key
 *   public String title;
 *
 *   @Key("gphoto:access")
 *   public String access;
 *
 *   public Category category = newKind("album");
 *
 *   private String getEditLink() {
 *     return Link.find(links, "edit");
 *   }
 * }
 *
 * public class Author {
 *
 *   @Key
 *   public String name;
 * }
 *
 * public class AlbumFeed {
 *
 *   @Key
 *   public Author author;
 *
 *   @Key("openSearch:totalResults")
 *   public int totalResults;
 *
 *   @Key("entry")
 *   public List<AlbumEntry> photos;
 *
 *   @Key("link")
 *   public List<Link> links;
 *
 *   private String getPostLink() {
 *     return Link.find(links, "http://schemas.google.com/g/2005#post");
 *   }
 * }
 * }
* *

You can also use the @{@link com.google.api.client.util.Key} annotation to defined query * parameters for a URL. For example: * *

{@code
 * public class PicasaUrl extends GoogleUrl {
 *
 *   @Key("max-results")
 *   public Integer maxResults;
 *
 *   @Key
 *   public String kinds;
 *
 *   public PicasaUrl(String url) {
 *     super(url);
 *   }
 *
 *   public static PicasaUrl fromRelativePath(String relativePath) {
 *     PicasaUrl result = new PicasaUrl(PicasaWebAlbums.ROOT_URL);
 *     result.path += relativePath;
 *     return result;
 *   }
 * }
 * }
* *

To work with a Google API, you first need to set up the {@link * com.google.api.client.http.HttpTransport}. For example: * *

{@code
 * private static HttpTransport setUpTransport() throws IOException {
 *   HttpTransport result = new NetHttpTransport();
 *   GoogleUtils.useMethodOverride(result);
 *   HttpHeaders headers = new HttpHeaders();
 *   headers.setApplicationName("Google-PicasaSample/1.0");
 *   headers.gdataVersion = "2";
 *   AtomParser parser = new AtomParser();
 *   parser.namespaceDictionary = PicasaWebAlbumsAtom.NAMESPACE_DICTIONARY;
 *   transport.addParser(parser);
 *   // insert authentication code...
 *   return transport;
 * }
 * }
* *

Now that we have a transport, we can execute a partial GET request to the Picasa Web Albums * API and parse the result: * *

{@code
 * public static AlbumFeed executeGet(HttpTransport transport, PicasaUrl url) throws IOException {
 *   url.fields = GoogleAtom.getFieldsFor(AlbumFeed.class);
 *   url.kinds = "photo";
 *   url.maxResults = 5;
 *   HttpRequest request = transport.buildGetRequest();
 *   request.url = url;
 *   return request.execute().parseAs(AlbumFeed.class);
 * }
 * }
* *

If the server responds with an error the {@link * com.google.api.client.http.HttpRequest#execute} method will throw an {@link * com.google.api.client.http.HttpResponseException}, which has an {@link * com.google.api.client.http.HttpResponse} field which can be parsed the same way as a success * response inside of a catch block. For example: * *

{@code
 * try {
 *   ...
 * } catch (HttpResponseException e) {
 *   if (e.response.getParser() != null) {
 *     Error error = e.response.parseAs(Error.class);
 *     // process error response
 *   } else {
 *     String errorContentString = e.response.parseAsString();
 *     // process error response as string
 *   }
 *   throw e;
 * }
 * }
* *

To update an album, we use the transport to execute an efficient partial update request using * the PATCH method to the Picasa Web Albums API: * *

{@code
 * public AlbumEntry executePatchRelativeToOriginal
 *     (HttpTransport transport, AlbumEntry original) throws IOException {
 *   HttpRequest request = transport.buildPatchRequest();
 *   request.setUrl(getEditLink());
 *   request.headers.ifMatch = etag;
 *   AtomPatchRelativeToOriginalContent content = new AtomPatchRelativeToOriginalContent();
 *   content.namespaceDictionary = PicasaWebAlbumsAtom.NAMESPACE_DICTIONARY;
 *   content.originalEntry = original;
 *   content.patchedEntry = this;
 *   request.content = content;
 *   return request.execute().parseAs(AlbumEntry.class);
 * }
 *
 * private static AlbumEntry updateTitle
 *     (HttpTransport transport, AlbumEntry album) throws IOException {
 *   AlbumEntry patched = album.clone();
 *   patched.title = "An alternate title";
 *   return patched.executePatchRelativeToOriginal(transport, album);
 * }
 * }
* *

To insert an album, we use the transport to execute a POST request to the Picasa Web Albums * API: * *

{@code
 * public AlbumEntry insertAlbum(HttpTransport transport, AlbumEntry entry) throws IOException {
 *   HttpRequest request = transport.buildPostRequest();
 *   request.setUrl(getPostLink());
 *   AtomContent content = new AtomContent();
 *   content.namespaceDictionary = PicasaWebAlbumsAtom.NAMESPACE_DICTIONARY;
 *   content.entry = entry;
 *   request.content = content;
 *   return request.execute().parseAs(AlbumEntry.class);
 * }
 * }
* *

To delete an album, we use the transport to execute a DELETE request to the Picasa Web Albums * API: * *

{@code
 * public void executeDelete(HttpTransport transport) throws IOException {
 *   HttpRequest request = transport.buildDeleteRequest();
 *   request.setUrl(getEditLink());
 *   request.headers.ifMatch = etag;
 *   request.execute().ignore();
 * }
 * }
* *

NOTE: As you might guess, the library uses reflection to populate the user-defined data model. * It's not quite as fast as writing the wire format parsing code yourself can potentially be, but * it's a lot easier. * *

NOTE: If you prefer to use your favorite XML parsing library instead (there are many of them), * that's supported as well. Just call {@link com.google.api.client.http.HttpRequest#execute()} and * parse the returned byte stream. * * @since 1.0 * @author Yaniv Inbar */ @com.google.api.client.util.Beta package com.google.api.client.googleapis.xml.atom;





© 2015 - 2024 Weber Informatics LLC | Privacy Policy