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 (c) 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.
 */

/**
 * 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: *

* *

<?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): *

* *

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: *

* *

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: *

* *

  private static HttpTransport setUpTransport() throws IOException {
    HttpTransport result = new NetHttpTransport();
    GoogleUtils.useMethodOverride(result);
    GoogleHeaders headers = new GoogleHeaders();
    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: *

* *

  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: *

* *

    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: *

* *

  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: *

* *

  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: *

* *

  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. *

* *

* Warning: this package is experimental, and its content may be changed in incompatible ways or * possibly entirely removed in a future version of the library *

* * @since 1.0 * @author Yaniv Inbar */ package com.google.api.client.googleapis.xml.atom;




© 2015 - 2024 Weber Informatics LLC | Privacy Policy