Update MobileWebApp sample with Objectify 5.1.13 (from 3.0)

Also update AppEngine SDK to latest version (1.9.40)

Change-Id: If928499d0e18e8112ab61d1a120d9540d9fed451
diff --git a/samples/mobilewebapp/pom.xml b/samples/mobilewebapp/pom.xml
index 8517f57..81bc407 100644
--- a/samples/mobilewebapp/pom.xml
+++ b/samples/mobilewebapp/pom.xml
@@ -22,7 +22,7 @@
     <maven.compiler.target>1.7</maven.compiler.target>
 
     <!-- App Engine properties -->
-    <appengine.version>1.9.30</appengine.version>
+    <appengine.version>1.9.40</appengine.version>
     <appengine.application.version>1</appengine.application.version>
 
     <!-- Don't let your Mac use a crazy non-standard encoding -->
@@ -138,11 +138,11 @@
       <version>${appengine.version}</version>
     </dependency>
 
-    <!-- Objectify for persistence. It uses the stock javax.persistence annotations -->
+    <!-- Objectify for persistence -->
     <dependency>
       <groupId>com.googlecode.objectify</groupId>
       <artifactId>objectify</artifactId>
-      <version>3.0</version>
+      <version>5.1.13</version>
     </dependency>
     <dependency>
       <groupId>javax.persistence</groupId>
@@ -242,10 +242,6 @@
 
   <repositories>
     <repository>
-      <id>objectify-appengine</id>
-      <url>http://objectify-appengine.googlecode.com/svn/maven</url>
-    </repository>
-    <repository>
       <id>google-snapshots</id>
       <url>https://oss.sonatype.org/content/repositories/google-snapshots/</url>
       <releases>
diff --git a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/EMF.java b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/ObjectifyManager.java
similarity index 72%
rename from samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/EMF.java
rename to samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/ObjectifyManager.java
index 378bc15..8905417 100644
--- a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/EMF.java
+++ b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/ObjectifyManager.java
@@ -15,27 +15,19 @@
  */
 package com.google.gwt.sample.mobilewebapp.server.domain;
 
+import com.googlecode.objectify.Objectify;
 import com.googlecode.objectify.ObjectifyService;
-import com.googlecode.objectify.util.DAOBase;
 
 /**
- * Factory for creating EntityManager.
+ * Manager for registering @com.googlecode.objectify.annotation.Entity.
  */
-public final class EMF extends DAOBase {
-
-  private static EMF singleton;
+public final class ObjectifyManager {
 
   static {
     ObjectifyService.register(Task.class);
   }
 
-  public static EMF get() {
-    if (singleton == null) {
-      singleton = new EMF();
-    }
-    return singleton;
-  }
-
-  protected EMF() {
+  public static Objectify ofy() {
+    return ObjectifyService.ofy();
   }
 }
diff --git a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/Task.java b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/Task.java
index 75e285e..3f008cc 100644
--- a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/Task.java
+++ b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/server/domain/Task.java
@@ -15,14 +15,17 @@
  */
 package com.google.gwt.sample.mobilewebapp.server.domain;
 
-import com.googlecode.objectify.Query;
+import static com.google.gwt.sample.mobilewebapp.server.domain.ObjectifyManager.ofy;
+
 import com.googlecode.objectify.annotation.Entity;
+import com.googlecode.objectify.annotation.Id;
+import com.googlecode.objectify.annotation.Index;
+import com.googlecode.objectify.annotation.OnSave;
+import com.googlecode.objectify.cmd.Query;
 
 import java.util.Date;
 import java.util.List;
 
-import javax.persistence.Id;
-import javax.persistence.PrePersist;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 
@@ -44,10 +47,7 @@
    */
   @SuppressWarnings("unchecked")
   public static List<Task> findAllTasks() {
-    // TODO: move this method to a service object and get rid of EMF (e.g. use a ServiceLocator)
-    EMF emf = EMF.get();
-
-    Query<Task> q = emf.ofy().query(Task.class).filter("userId", currentUserId());
+    Query<Task> q = ofy().load().type(Task.class).filter("userId", currentUserId());
 
     List<Task> list = q.list();
     /*
@@ -56,7 +56,7 @@
      */
     if (list.size() == 0) {
       populateDatastore();
-      q = emf.ofy().query(Task.class).filter("userId", currentUserId());
+      q = ofy().load().type(Task.class).filter("userId", currentUserId());
       list = q.list();
     }
 
@@ -70,13 +70,11 @@
    * @return the associated {@link Task}, or null if not found
    */
   public static Task findTask(Long id) {
-    // TODO: move this method to a service object and get rid of EMF (e.g. use a ServiceLocator)
     if (id == null) {
       return null;
     }
 
-    EMF emf = EMF.get();
-    Task task = emf.ofy().find(Task.class, id);
+    Task task = ofy().load().type(Task.class).id(id).now();
     if (task != null && task.userId.equals(currentUserId())) {
       return task;
     } else {
@@ -94,9 +92,6 @@
    */
   @SuppressWarnings("deprecation")
   private static void populateDatastore() {
-    // TODO: move this method to a service object (e.g. use a ServiceLocator)
-    EMF emf = EMF.get();
-
     {
       // Task 0.
       Task task0 = new Task();
@@ -104,7 +99,7 @@
       task0.setNotes("This game is impossible!");
       task0.setDueDate(new Date(100, 4, 20));
       task0.userId = currentUserId();
-      emf.ofy().put(task0);
+      ofy().save().entity(task0);
     }
     {
       // Task 1.
@@ -112,7 +107,7 @@
       task1.setName("Make a million dollars");
       task1.setNotes("Then spend it all on Android apps");
       task1.userId = currentUserId();
-      emf.ofy().put(task1);
+      ofy().save().entity(task1);
     }
     {
       // Task 2.
@@ -120,14 +115,14 @@
       task2.setName("Buy a dozen eggs");
       task2.setNotes("of the chicken variety");
       task2.userId = currentUserId();
-      emf.ofy().put(task2);
+      ofy().save().entity(task2);
     }
     {
       // Task 3.
       Task task3 = new Task();
       task3.setName("Complete all tasks");
       task3.userId = currentUserId();
-      emf.ofy().put(task3);
+      ofy().save().entity(task3);
     }
   }
 
@@ -145,6 +140,7 @@
   /**
    * The unique ID of the user who owns this task.
    */
+  @Index
   private String userId;
 
   // TODO: Move this field to a superclass that implements a persistence layer
@@ -190,9 +186,6 @@
    * Persist this object in the data store.
    */
   public void persist() {
-    // TODO: Move this method to a superclass that implements a persistence layer
-    EMF emf = EMF.get();
-
     ++version;
 
     // Set the user id if this is a new task.
@@ -203,7 +196,7 @@
 
     // Verify the current user owns the task before updating it.
     if (curUserId.equals(userId)) {
-      emf.ofy().put(this);
+      ofy().save().entity(this);
     }
   }
 
@@ -211,13 +204,10 @@
    * Remove this object from the data store.
    */
   public void remove() {
-    // TODO: Move this method to a superclass that implements a persistence layer
-    EMF emf = EMF.get();
-
-    Task task = emf.ofy().find(Task.class, this.id);
+    Task task = ofy().load().type(Task.class).id(this.id).now();
 
     if (currentUserId().equals(task.userId)) {
-      emf.ofy().delete(task);
+      ofy().delete().entity(task);
     }
   }
 
@@ -252,7 +242,7 @@
     this.notes = notes;
   }
 
-  @PrePersist
+  @OnSave
   void onPersist() {
     // TODO: Move this method to a superclass that implements a persistence layer
     ++this.version;
diff --git a/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml b/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml
index 7490828..d45e170 100644
--- a/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml
+++ b/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml
@@ -42,10 +42,22 @@
     -->
     <filter-class>com.google.gwt.sample.gaerequest.server.GaeAuthFilter</filter-class>
   </filter>
+  <filter>
+    <!--
+      Objectify requires a filter to clean up any thread-local transaction contexts and pending 
+      asynchronous operations that remain at the end of a request.
+    -->
+    <filter-name>ObjectifyFilter</filter-name>
+    <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
+  </filter>
   <filter-mapping>
     <filter-name>GaeAuthFilter</filter-name>
     <url-pattern>/gwtRequest/*</url-pattern>
   </filter-mapping>
+  <filter-mapping>
+    <filter-name>ObjectifyFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
 
   <!-- Default page to serve -->
   <welcome-file-list>