Added getAsyc() to the Access interface with a default implementation
that returns an immediate future.

Change-Id: I35abd8ea1a5594d6a5b57dfbbc133183deb05127
diff --git a/pom.xml b/pom.xml
index a244144..24300af 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
   <groupId>gwtorm</groupId>
   <artifactId>gwtorm</artifactId>
   <packaging>jar</packaging>
-  <version>1.2</version>
+  <version>1.3-SNAPSHOT</version>
   <name>gwtorm</name>
   <description>Tiny ORM</description>
   <url>http://android.git.kernel.org/?p=tools/gwtorm.git</url>
@@ -304,6 +304,13 @@
     </dependency>
 
     <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>11.0.2</version>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
       <groupId>org.antlr</groupId>
       <artifactId>antlr</artifactId>
       <version>3.1.1</version>
diff --git a/src/main/java/com/google/gwtorm/client/Access.java b/src/main/java/com/google/gwtorm/client/Access.java
index b6872ff..36f1541 100644
--- a/src/main/java/com/google/gwtorm/client/Access.java
+++ b/src/main/java/com/google/gwtorm/client/Access.java
@@ -14,6 +14,8 @@
 
 package com.google.gwtorm.client;
 
+import com.google.common.util.concurrent.CheckedFuture;
+
 import java.util.Map;
 
 /**
@@ -92,6 +94,21 @@
   T get(K key) throws OrmException;
 
   /**
+   * Lookup a single entity asynchronously via its primary key.
+   * <p>
+   * This method is only implemented if the entity's primary key is defined to
+   * be an implementation of the {@link Key} interface. Otherwise the method
+   * throws {@link UnsupportedOperationException}.
+   *
+   * @param key the primary key instance; must not be null.
+   * @return a {@link CheckedFuture} for the entity; the
+   *         {@link CheckedFuture#get()} will return null if no entity has
+   *         this key.
+   * @throws UnsupportedOperationException the key type doesn't implement Key.
+   */
+  CheckedFuture<T, OrmException> getAsync(K key);
+
+  /**
    * Lookup multiple entities via their primary key.
    * <p>
    * This method is only implemented if the entity's primary key is defined to
diff --git a/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java b/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java
index 287c816..0ab85d1 100644
--- a/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java
+++ b/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java
@@ -14,6 +14,8 @@
 
 package com.google.gwtorm.client.impl;
 
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
 import com.google.gwtorm.client.Access;
 import com.google.gwtorm.client.AtomicUpdate;
 import com.google.gwtorm.client.Key;
@@ -35,6 +37,14 @@
     // Do nothing by default.
   }
 
+  public CheckedFuture<E, OrmException> getAsync(K key) {
+    try {
+      return Futures.immediateCheckedFuture(get(key));
+    } catch (OrmException e) {
+      return Futures.immediateFailedCheckedFuture(e);
+    }
+  }
+
   public ResultSet<E> get(final Iterable<K> keys) throws OrmException {
     final ArrayList<E> r = new ArrayList<E>();
     for (final K key : keys) {
diff --git a/src/test/java/com/google/gwtorm/nosql/NoSqlPhoneBookTest.java b/src/test/java/com/google/gwtorm/nosql/NoSqlPhoneBookTest.java
index 8532809..e3c4911 100644
--- a/src/test/java/com/google/gwtorm/nosql/NoSqlPhoneBookTest.java
+++ b/src/test/java/com/google/gwtorm/nosql/NoSqlPhoneBookTest.java
@@ -133,6 +133,18 @@
     assertEquals(sp.primaryKey(p1), sp.primaryKey(p2));
   }
 
+  public void testGetAsyncOnePerson() throws Exception {
+    final PhoneBookDb schema = open();
+    final PersonAccess sp = schema.people();
+    final TestPerson p1 = new TestPerson(new TestPerson.Key("Bob"), 18);
+    sp.insert(Collections.singleton(p1));
+
+    final TestPerson p2 = sp.getAsync(sp.primaryKey(p1)).get();
+    assertNotNull(p2);
+    assertNotSame(p1, p2);
+    assertEquals(sp.primaryKey(p1), sp.primaryKey(p2));
+  }
+
   public void testGetOnePersonIterator() throws Exception {
     final PhoneBookDb schema = open();
     final PersonAccess sp = schema.people();
diff --git a/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java b/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
index d87d54d..3d87b26 100644
--- a/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
+++ b/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
@@ -172,6 +172,18 @@
     assertEquals(sp.primaryKey(p1), sp.primaryKey(p2));
   }
 
+  public void testGetAsyncOnePerson() throws Exception {
+    final PhoneBookDb schema = openAndCreate();
+    final PersonAccess sp = schema.people();
+    final TestPerson p1 = new TestPerson(new TestPerson.Key("Bob"), 18);
+    sp.insert(Collections.singleton(p1));
+
+    final TestPerson p2 = sp.getAsync(sp.primaryKey(p1)).get();
+    assertNotNull(p2);
+    assertNotSame(p1, p2);
+    assertEquals(sp.primaryKey(p1), sp.primaryKey(p2));
+  }
+
   public void testGetOnePersonIterator() throws Exception {
     final PhoneBookDb schema = openAndCreate();
     final PersonAccess sp = schema.people();