tag the 2.4.0 release
git-svn-id: https://google-web-toolkit.googlecode.com/svn/tags/2.4.0@10547 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/ExternalPermutationWorkerFactory.java b/dev/core/src/com/google/gwt/dev/ExternalPermutationWorkerFactory.java
index 66b02fa..a4109e1 100644
--- a/dev/core/src/com/google/gwt/dev/ExternalPermutationWorkerFactory.java
+++ b/dev/core/src/com/google/gwt/dev/ExternalPermutationWorkerFactory.java
@@ -21,7 +21,7 @@
import com.google.gwt.dev.jjs.UnifiedAst;
import com.google.gwt.dev.util.FileBackedObject;
import com.google.gwt.dev.util.Util;
-import com.google.gwt.util.tools.Utility;
+import com.google.gwt.util.tools.shared.StringUtils;
import java.io.BufferedReader;
import java.io.EOFException;
@@ -254,7 +254,7 @@
byte[] cookieBytes = new byte[16];
random.nextBytes(cookieBytes);
- String cookie = Utility.toHexString(cookieBytes);
+ String cookie = StringUtils.toHexString(cookieBytes);
// Cook up the classpath, main class, and extra args
args.addAll(Arrays.asList("-classpath",
diff --git a/dev/core/src/com/google/gwt/dev/util/Util.java b/dev/core/src/com/google/gwt/dev/util/Util.java
index 5a19a38..168cbaf 100644
--- a/dev/core/src/com/google/gwt/dev/util/Util.java
+++ b/dev/core/src/com/google/gwt/dev/util/Util.java
@@ -22,6 +22,7 @@
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.util.tools.Utility;
+import com.google.gwt.util.tools.shared.StringUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
@@ -172,7 +173,7 @@
for (int i = 0; i < contents.length; i++) {
md5.update(contents[i]);
}
- return Utility.toHexString(md5.digest());
+ return StringUtils.toHexString(md5.digest());
}
public static void copy(InputStream is, OutputStream os) throws IOException {
@@ -437,11 +438,11 @@
/**
* A 4-digit hex result.
*
- * @deprecated use {@link Utility#hex4(char, StringBuffer)} instead.
+ * @deprecated use {@link StringUtils#hex4(char, StringBuffer)} instead.
*/
@Deprecated
public static void hex4(char c, StringBuffer sb) {
- Utility.hex4(c, sb);
+ StringUtils.hex4(c, sb);
}
/**
@@ -913,11 +914,11 @@
* @param bytes byte array to convert
* @return a string representation of the byte array as a series of
* hexadecimal characters
- * @deprecated use {@link Utility#toHexString(byte[])} instead.
+ * @deprecated use {@link StringUtils#toHexString(byte[])} instead.
*/
@Deprecated
public static String toHexString(byte[] bytes) {
- return Utility.toHexString(bytes);
+ return StringUtils.toHexString(bytes);
}
/**
diff --git a/dev/core/src/com/google/gwt/util/tools/Utility.java b/dev/core/src/com/google/gwt/util/tools/Utility.java
index fddb1ac..966be1e 100644
--- a/dev/core/src/com/google/gwt/util/tools/Utility.java
+++ b/dev/core/src/com/google/gwt/util/tools/Utility.java
@@ -32,8 +32,6 @@
import java.net.Socket;
import java.net.URI;
import java.net.URL;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -44,24 +42,6 @@
*/
public final class Utility {
- /**
- * Per thread MD5 instance.
- */
- private static final ThreadLocal<MessageDigest> perThreadMd5 =
- new ThreadLocal<MessageDigest>() {
- @Override
- protected MessageDigest initialValue() {
- try {
- return MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- return null;
- }
- };
- };
-
- public static char[] HEX_CHARS = new char[] {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
- 'E', 'F'};
private static String sInstallPath = null;
@@ -255,29 +235,6 @@
}
/**
- * Generate MD5 digest.
- *
- * @param input input data to be hashed.
- * @return MD5 digest.
- */
- public static byte[] getMd5Digest(byte[] input) {
- MessageDigest md5 = perThreadMd5.get();
- md5.reset();
- md5.update(input);
- return md5.digest();
- }
-
- /**
- * A 4-digit hex result.
- */
- public static void hex4(char c, StringBuffer sb) {
- sb.append(HEX_CHARS[(c & 0xF000) >> 12]);
- sb.append(HEX_CHARS[(c & 0x0F00) >> 8]);
- sb.append(HEX_CHARS[(c & 0x00F0) >> 4]);
- sb.append(HEX_CHARS[c & 0x000F]);
- }
-
- /**
* Creates a randomly-named temporary directory.
*
* @param baseDir base directory to contain the new directory. May be
@@ -342,25 +299,6 @@
}
}
- /**
- * Returns a string representation of the byte array as a series of
- * hexadecimal characters.
- *
- * @param bytes byte array to convert
- * @return a string representation of the byte array as a series of
- * hexadecimal characters
- */
- public static String toHexString(byte[] bytes) {
- char[] hexString = new char[2 * bytes.length];
- int j = 0;
- for (int i = 0; i < bytes.length; i++) {
- hexString[j++] = HEX_CHARS[(bytes[i] & 0xF0) >> 4];
- hexString[j++] = HEX_CHARS[bytes[i] & 0x0F];
- }
-
- return new String(hexString);
- }
-
public static void writeTemplateBinaryFile(File file, byte[] contents) throws IOException {
FileOutputStream o = new FileOutputStream(file);
diff --git a/dev/core/src/com/google/gwt/util/tools/shared/Md5Utils.java b/dev/core/src/com/google/gwt/util/tools/shared/Md5Utils.java
new file mode 100644
index 0000000..d0af4e1
--- /dev/null
+++ b/dev/core/src/com/google/gwt/util/tools/shared/Md5Utils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011 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.gwt.util.tools.shared;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Utility class to generate MD5 hashes using per-thread MD5
+ * {@link MessageDigest} instance.
+ */
+public class Md5Utils {
+
+ /**
+ * Per thread MD5 instance.
+ */
+ private static final ThreadLocal<MessageDigest> perThreadMd5 =
+ new ThreadLocal<MessageDigest>() {
+ @Override
+ protected MessageDigest initialValue() {
+ try {
+ return MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("MD5 implementation not found", e);
+ }
+ };
+ };
+
+ /**
+ * Generate MD5 digest.
+ *
+ * @param input input data to be hashed.
+ * @return MD5 digest.
+ */
+ public static byte[] getMd5Digest(byte[] input) {
+ MessageDigest md5 = perThreadMd5.get();
+ md5.reset();
+ md5.update(input);
+ return md5.digest();
+ }
+}
diff --git a/dev/core/src/com/google/gwt/util/tools/shared/StringUtils.java b/dev/core/src/com/google/gwt/util/tools/shared/StringUtils.java
new file mode 100644
index 0000000..c7ffb3b
--- /dev/null
+++ b/dev/core/src/com/google/gwt/util/tools/shared/StringUtils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2006 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.gwt.util.tools.shared;
+
+/**
+ * String utility methods.
+ */
+public class StringUtils {
+
+ public static char[] HEX_CHARS = new char[] {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
+ 'E', 'F'};
+
+ /**
+ * A 4-digit hex result.
+ */
+ public static void hex4(char c, StringBuffer sb) {
+ sb.append(HEX_CHARS[(c & 0xF000) >> 12]);
+ sb.append(HEX_CHARS[(c & 0x0F00) >> 8]);
+ sb.append(HEX_CHARS[(c & 0x00F0) >> 4]);
+ sb.append(HEX_CHARS[c & 0x000F]);
+ }
+
+ /**
+ * Returns a string representation of the byte array as a series of
+ * hexadecimal characters.
+ *
+ * @param bytes byte array to convert
+ * @return a string representation of the byte array as a series of
+ * hexadecimal characters
+ */
+ public static String toHexString(byte[] bytes) {
+ char[] hexString = new char[2 * bytes.length];
+ int j = 0;
+ for (int i = 0; i < bytes.length; i++) {
+ hexString[j++] = HEX_CHARS[(bytes[i] & 0xF0) >> 4];
+ hexString[j++] = HEX_CHARS[bytes[i] & 0x0F];
+ }
+ return new String(hexString);
+ }
+}
diff --git a/dev/core/src/com/google/gwt/util/tools/shared/package-info.java b/dev/core/src/com/google/gwt/util/tools/shared/package-info.java
new file mode 100644
index 0000000..201db87
--- /dev/null
+++ b/dev/core/src/com/google/gwt/util/tools/shared/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2011 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.
+ */
+
+/**
+ * Utility classes shared between gwt-dev and gwt-servlet.
+ */
+@com.google.gwt.util.PreventSpuriousRebuilds
+package com.google.gwt.util.tools.shared;
diff --git a/samples/mobilewebapp/pom.xml b/samples/mobilewebapp/pom.xml
index 38641da..773988b 100644
--- a/samples/mobilewebapp/pom.xml
+++ b/samples/mobilewebapp/pom.xml
@@ -2,14 +2,13 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <!-- POM file generated with GWT webAppCreator -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.gwt.sample.mobilewebapp</groupId>
<artifactId>MobileWebApp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>com.google.gwt.sample.mobilewebapp.MobileWebApp</name>
-
+
<properties>
<!-- Convenience property to set the GWT version -->
<gwtVersion>2.4.0</gwtVersion>
@@ -23,37 +22,15 @@
<gae.home>${user.home}/.m2/repository/com/google/appengine/appengine-java-sdk/${gae.version}/appengine-java-sdk-${gae.version}</gae.home>
<gae.application.version>1</gae.application.version>
- <!-- TODO: DataNucleus trash -->
- <datanucleus.version>1.1.5</datanucleus.version>
</properties>
<repositories>
- <!-- <repository>
+ <repository>
<id>objectify-appengine</id>
<url>http://objectify-appengine.googlecode.com/svn/maven</url>
- </repository> -->
-
- <!-- TODO: DataNucleus trash -->
- <repository>
- <id>DataNucleus_2</id>
- <url>http://www.datanucleus.org/downloads/maven2/</url>
- <name>DataNucleus</name>
- </repository>
- <repository>
- <id>JBoss Repo</id>
- <url>https://repository.jboss.org/nexus/content/repositories/releases</url>
- <name>JBoss Repo</name>
</repository>
</repositories>
- <!-- TODO: DataNucleus trash -->
- <pluginRepositories>
- <pluginRepository>
- <id>DataNucleus_2</id>
- <url>http://www.datanucleus.org/downloads/maven2/</url>
- </pluginRepository>
- </pluginRepositories>
-
<dependencies>
<dependency>
<groupId>javax.inject</groupId>
@@ -82,10 +59,21 @@
<version>${gwtVersion}</version>
<scope>provided</scope>
</dependency>
+
+ <!-- GWT projects do not usually need a dependency on gwt-dev, but MobileWebApp
+ contains a GWTC Linker (AppCacheLinker) which in turn depends on internals
+ of the GWT compiler.
+
+ This dependency has a scope of "provided" so that it only gets used as a
+ compiler dependecy. The Maven GWT Plugin does not seem to honor this scoping,
+ though. For that reason we explicitly remove gwt-dev-*.jar from the produced
+ artifacts later on.
+ -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>${gwtVersion}</version>
+ <scope>provided</scope>
</dependency>
<!-- GWT RequestFactory will use JSR 303 javax.validation if you let it -->
@@ -151,23 +139,13 @@
<version>${gae.version}</version> <scope>system</scope> <systemPath>${gae.home}/lib/appengine-tools-api.jar</systemPath>
</dependency> -->
- <!-- Who is this for? What is it? -->
-
- <dependency>
- <groupId>net.sf.jsr107cache</groupId>
- <artifactId>jsr107cache</artifactId>
- <version>1.1</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
-
<!-- Objectify for persistence. It uses the stock javax.persistence annotations -->
- <!-- <dependency>
+ <dependency>
<groupId>com.googlecode.objectify</groupId>
<artifactId>objectify</artifactId>
<version>3.0</version>
- </dependency> -->
+ </dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
@@ -187,16 +165,10 @@
<version>1.0</version>
</dependency>
- <!-- TODO: Who is using this? Is it just cruft from listwidget? -->
-
- <dependency>
- <groupId>aopalliance</groupId>
- <artifactId>aopalliance</artifactId>
- <version>1.0</version>
- </dependency>
-
- <!-- TODO: Who is using this? Just GAE? Is anyone, really? -->
-
+ <!-- GAE does not seem to have these as dependencies, but
+ running locally (i.e. 'mvn gae:run') seems to
+ require them.
+ -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
@@ -207,64 +179,6 @@
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
-
- <!-- The stuff needed by data nucleus until we can rip it out -->
-
- <dependency>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-core</artifactId>
- <version>${datanucleus.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.transaction</groupId>
- <artifactId>transaction-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-jpa</artifactId>
- <version>1.1.5</version>
- </dependency>
- <dependency>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-rdbms</artifactId>
- <version>${datanucleus.version}</version>
- </dependency>
- <dependency>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-enhancer</artifactId>
- <version>1.1.4</version>
- </dependency>
- <dependency>
- <groupId>javax.jdo</groupId>
- <artifactId>jdo2-api</artifactId>
- <version>2.3-eb</version>
- <exclusions>
- <exclusion>
- <groupId>javax.transaction</groupId>
- <artifactId>transaction-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>com.google.appengine.orm</groupId>
- <artifactId>datanucleus-appengine</artifactId>
- <version>1.0.8</version>
- </dependency>
- <!-- must be in main dependencies as well as plugin dependencies below -->
- <!-- <dependency>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-core</artifactId>
- <version>${datanucleus.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.transaction</groupId>
- <artifactId>transaction-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency> -->
-
</dependencies>
<build>
@@ -387,7 +301,7 @@
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
- <version>2.7</version> <!-- Note 2.8 does not work with AspectJ aspect path -->
+ <version>2.8</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
@@ -404,6 +318,42 @@
</configuration>
</plugin>
+ <plugin>
+ <!-- Don't deploy gwt-user nor gwt-dev jars to GAE.
+ These jars are needed to compile the
+ project and for DevMode, but not in AppEngine.
+ -->
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.3</version>
+ <executions>
+ <execution>
+ <id>default-clean</id>
+ <phase>clean</phase>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>remove-gwt-dev-jar</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ <configuration>
+ <excludeDefaultDirectories>true</excludeDefaultDirectories>
+ <filesets>
+ <fileset>
+ <directory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</directory>
+ <includes>
+ <include>gwt-dev*jar</include>
+ <include>gwt-user*jar</include>
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
</project>
diff --git a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/core/Core.gwt.xml b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/core/Core.gwt.xml
deleted file mode 100644
index 9c963e0..0000000
--- a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/core/Core.gwt.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- -->
-<!-- Copyright 2011 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 -->
-<!-- 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. License for the specific language governing permissions and -->
-<!-- limitations under the License. -->
-
-<!-- Types and resources required to support primitive system operation. -->
-<!-- -->
-<!-- Types from this module are visible to and imported into user code. -->
-<!-- Every module should directly or indirectly inherit this module. -->
-<!-- -->
-<module>
- <inherits name="com.google.gwt.core.Core" />
-</module>
diff --git a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinker.java b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinker.java
index 433c187..a453c7c 100644
--- a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinker.java
+++ b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinker.java
@@ -131,7 +131,8 @@
|| pathName.endsWith("rpc.log")
|| pathName.endsWith("gwt.rpc")
|| pathName.endsWith("manifest.txt")
- || pathName.startsWith("rpcPolicyManifest")) {
+ || pathName.startsWith("rpcPolicyManifest")
+ || pathName.startsWith("soycReport")) {
// skip these resources
} else {
publicSourcesSb.append(pathName + "\n");
diff --git a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/MobileWebApp.gwt.xml b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/MobileWebApp.gwt.xml
index c701f4a..2bf4390 100644
--- a/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/MobileWebApp.gwt.xml
+++ b/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/MobileWebApp.gwt.xml
@@ -16,7 +16,6 @@
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
<inherits name='com.google.gwt.sample.gaerequest.GaeRequest'/>
- <inherits name='com.google.gwt.sample.core.Core'/>
<inherits name='com.google.gwt.sample.ui.UI'/>
<inherits name="com.google.gwt.logging.Logging"/>
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/EMF.java
index 1fb7db8..378bc15 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/EMF.java
@@ -15,22 +15,27 @@
*/
package com.google.gwt.sample.mobilewebapp.server.domain;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
+import com.googlecode.objectify.ObjectifyService;
+import com.googlecode.objectify.util.DAOBase;
/**
* Factory for creating EntityManager.
*/
-public final class EMF {
+public final class EMF extends DAOBase {
- private static final EntityManagerFactory emfInstance =
- Persistence.createEntityManagerFactory("transactions-optional");
+ private static EMF singleton;
- public static EntityManagerFactory get() {
- return emfInstance;
+ static {
+ ObjectifyService.register(Task.class);
}
- private EMF() {
- // nothing
+ public static EMF get() {
+ if (singleton == null) {
+ singleton = new EMF();
+ }
+ return singleton;
+ }
+
+ protected EMF() {
}
}
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 149110d..75e285e 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,22 +15,26 @@
*/
package com.google.gwt.sample.mobilewebapp.server.domain;
+import com.googlecode.objectify.Query;
+import com.googlecode.objectify.annotation.Entity;
+
import java.util.Date;
import java.util.List;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityManager;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
import javax.persistence.Id;
-import javax.persistence.Query;
-import javax.persistence.Version;
+import javax.persistence.PrePersist;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
- * A task used in the task list.
+ * A task used in the task list. This is a monolothic implementation of a data object
+ * for use with {@code RequestFactory}. Better patterns make use of Locators and
+ * ServiceLocators to simplify the boilerplate required to expose a data object.
+ * <p>
+ * See <a
+ * href='http://turbomanage.wordpress.com/2011/03/25/using-gwt-requestfactory-with-objectify/'
+ * >this fine blog post</a>,
+ * for an example.
*/
@Entity
public class Task {
@@ -40,31 +44,23 @@
*/
@SuppressWarnings("unchecked")
public static List<Task> findAllTasks() {
- EntityManager em = entityManager();
- try {
- Query query = em.createQuery("select o from Task o where o.userId=:userId");
- query.setParameter("userId", UserServiceWrapper.get().getCurrentUserId());
- List<Task> list = query.getResultList();
+ // TODO: move this method to a service object and get rid of EMF (e.g. use a ServiceLocator)
+ EMF emf = EMF.get();
- /*
- * If this is the first time running the app, populate the datastore with
- * some default tasks and re-query the datastore for them.
- */
- if (list.size() == 0) {
- populateDatastore();
- list = query.getResultList();
+ Query<Task> q = emf.ofy().query(Task.class).filter("userId", currentUserId());
- /*
- * Workaround for this issue:
- * http://code.google.com/p/datanucleus-appengine/issues/detail?id=24
- */
- list.size();
- }
-
- return list;
- } finally {
- em.close();
+ List<Task> list = q.list();
+ /*
+ * If this is the first time running the app, populate the datastore with
+ * some default tasks and re-query the datastore for them.
+ */
+ if (list.size() == 0) {
+ populateDatastore();
+ q = emf.ofy().query(Task.class).filter("userId", currentUserId());
+ list = q.list();
}
+
+ return list;
}
/**
@@ -74,29 +70,22 @@
* @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;
}
- EntityManager em = entityManager();
- try {
- Task task = em.find(Task.class, id);
- if (task != null && UserServiceWrapper.get().getCurrentUserId().equals(task.userId)) {
- return task;
- }
+ EMF emf = EMF.get();
+ Task task = emf.ofy().find(Task.class, id);
+ if (task != null && task.userId.equals(currentUserId())) {
+ return task;
+ } else {
return null;
- } finally {
- em.close();
}
}
- /**
- * Create an entity manager to interact with the database.
- *
- * @return an {@link EntityManager} instance
- */
- private static EntityManager entityManager() {
- return EMF.get().createEntityManager();
+ private static String currentUserId() {
+ return UserServiceWrapper.get().getCurrentUserId();
}
/**
@@ -105,58 +94,63 @@
*/
@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();
task0.setName("Beat Angry Birds");
task0.setNotes("This game is impossible!");
task0.setDueDate(new Date(100, 4, 20));
- task0.persist();
+ task0.userId = currentUserId();
+ emf.ofy().put(task0);
}
{
// Task 1.
Task task1 = new Task();
task1.setName("Make a million dollars");
task1.setNotes("Then spend it all on Android apps");
- task1.persist();
+ task1.userId = currentUserId();
+ emf.ofy().put(task1);
}
{
// Task 2.
Task task2 = new Task();
task2.setName("Buy a dozen eggs");
task2.setNotes("of the chicken variety");
- task2.persist();
+ task2.userId = currentUserId();
+ emf.ofy().put(task2);
}
{
// Task 3.
Task task3 = new Task();
task3.setName("Complete all tasks");
- task3.persist();
+ task3.userId = currentUserId();
+ emf.ofy().put(task3);
}
}
@Id
- @Column(name = "id")
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- /**
- * The unique ID of the user who owns this task.
- */
- private String userId;
-
- @Version
- @Column(name = "version")
- private Integer version;
+ Long id;
private Date dueDate;
@NotNull(message = "You must specify a name")
@Size(min = 3, message = "Name must be at least 3 characters long")
private String name;
+
private String notes;
/**
+ * The unique ID of the user who owns this task.
+ */
+ private String userId;
+
+ // TODO: Move this field to a superclass that implements a persistence layer
+ private Integer version = 0;
+
+ /**
* Get the due date of the Task.
*/
public Date getDueDate() {
@@ -188,6 +182,7 @@
* Get the version of this datastore object.
*/
public Integer getVersion() {
+ // TODO: Move this method to a superclass that implements a persistence layer
return version;
}
@@ -195,20 +190,20 @@
* Persist this object in the data store.
*/
public void persist() {
- EntityManager em = entityManager();
- try {
- // Set the user id if this is a new task.
- String curUserId = UserServiceWrapper.get().getCurrentUserId();
- if (userId == null) {
- userId = curUserId;
- }
+ // TODO: Move this method to a superclass that implements a persistence layer
+ EMF emf = EMF.get();
- // Verify the current user owns the task before updating it.
- if (curUserId.equals(userId)) {
- em.persist(this);
- }
- } finally {
- em.close();
+ ++version;
+
+ // Set the user id if this is a new task.
+ String curUserId = currentUserId();
+ if (userId == null) {
+ userId = curUserId;
+ }
+
+ // Verify the current user owns the task before updating it.
+ if (curUserId.equals(userId)) {
+ emf.ofy().put(this);
}
}
@@ -216,16 +211,13 @@
* Remove this object from the data store.
*/
public void remove() {
- EntityManager em = entityManager();
- try {
- Task task = em.find(Task.class, this.id);
+ // TODO: Move this method to a superclass that implements a persistence layer
+ EMF emf = EMF.get();
- // Verify the current user owns the task before removing it.
- if (UserServiceWrapper.get().getCurrentUserId().equals(task.userId)) {
- em.remove(task);
- }
- } finally {
- em.close();
+ Task task = emf.ofy().find(Task.class, this.id);
+
+ if (currentUserId().equals(task.userId)) {
+ emf.ofy().delete(task);
}
}
@@ -260,7 +252,9 @@
this.notes = notes;
}
- public void setVersion(Integer version) {
- this.version = version;
+ @PrePersist
+ void onPersist() {
+ // TODO: Move this method to a superclass that implements a persistence layer
+ ++this.version;
}
}
diff --git a/samples/mobilewebapp/src/test/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinkerTest.java b/samples/mobilewebapp/src/test/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinkerTest.java
index 0c029ed..fb826f7 100644
--- a/samples/mobilewebapp/src/test/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinkerTest.java
+++ b/samples/mobilewebapp/src/test/java/com/google/gwt/sample/core/linker/SimpleAppCacheLinkerTest.java
@@ -144,6 +144,7 @@
SimpleAppCacheLinker linker = new SimpleAppCacheLinker();
// Some non-cacheable artifacts
+ artifacts.add(new SyntheticArtifact(SimpleAppCacheLinker.class, "soycReport.baz", new byte[0]));
artifacts.add(new SyntheticArtifact(SimpleAppCacheLinker.class, "foo.symbolMap", new byte[0]));
artifacts.add(new SyntheticArtifact(SimpleAppCacheLinker.class, "foo.xml.gz", new byte[0]));
artifacts.add(new SyntheticArtifact(SimpleAppCacheLinker.class, "foo.rpc.log", new byte[0]));
@@ -152,8 +153,9 @@
ArtifactSet result = linker.link(TreeLogger.NULL, new MockLinkerContext(), artifacts, false);
- assertEquals(7, result.size());
+ assertEquals(8, result.size());
assertHasOneManifest(result);
+ assertFalse(getManifestContents(result).contains("soycReport"));
assertFalse(getManifestContents(result).contains("symbolMap"));
assertFalse(getManifestContents(result).contains("xml.gz"));
assertFalse(getManifestContents(result).contains("rpc.log"));
diff --git a/samples/mobilewebapp/user-build.xml b/samples/mobilewebapp/user-build.xml
deleted file mode 100644
index c01ec76..0000000
--- a/samples/mobilewebapp/user-build.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<project name="MobileWebApp" default="build" basedir=".">
- <property file="local.properties" />
- <!-- Arguments to gwtc and devmode targets -->
- <property name="gwt.args" value="" />
- <property name="src.dir" value="src/main" />
- <property name="src.dev.dir" value="src/dev" />
- <property name="war.dir" value="war" />
- <property name="gwt.sdk" value="../.." />
-
- <fail unless="appengine.sdk">Missing property:
- The property 'appengine.sdk' is not set.
- Either specity the property by passing an argument
-
- -Dappengine.sdk="path-to-your-appengine-sdk"
-
- or create a 'local.properties' file containing the
- location of the App Engine SDK. i.e. the line:
-
- appengine.sdk=path-to-your-appengine-sdk
- </fail>
-
- <!-- Configure AppEngine macros -->
- <import file="${appengine.sdk}/config/user/ant-macros.xml" />
-
- <path id="project.class.path">
- <pathelement location="${war.dir}/WEB-INF/classes"/>
- <pathelement location="${gwt.sdk}/gwt-user.jar"/>
- <fileset dir="${gwt.sdk}" includes="gwt-dev*.jar"/>
- <fileset dir="${gwt.sdk}" includes="validation-api-1.0.0.GA-sources.jar"/>
- <fileset dir="${gwt.sdk}" includes="validation-api-1.0.0.GA.jar"/>
- <!-- Add any additional non-server libs (such as JUnit) -->
- <fileset dir="${war.dir}/WEB-INF/lib" includes="**/*.jar"/>
- </path>
-
- <path id="tools.class.path">
- <path refid="project.class.path"/>
- <pathelement location="${appengine.sdk}/lib/appengine-tools-api.jar"/>
- <fileset dir="${appengine.sdk}/lib/tools">
- <include name="**/asm-*.jar"/>
- <include name="**/datanucleus-enhancer-*.jar"/>
- </fileset>
- </path>
-
- <target name="appengine-copyjars"
- description="Copies the App Engine JARs to the WAR.">
- <copy
- todir="${war.dir}/WEB-INF/lib"
- flatten="true">
- <fileset dir="${appengine.sdk}/lib/user">
- <include name="**/*.jar" />
- </fileset>
- </copy>
- </target>
-
- <target name="libs" description="Copy libs to WEB-INF/lib">
- <mkdir dir="${war.dir}/WEB-INF/lib" />
- <copy todir="${war.dir}/WEB-INF/lib" file="${gwt.sdk}/gwt-servlet.jar" />
- <copy todir="${war.dir}/WEB-INF/lib" file="${gwt.sdk}/gwt-servlet-deps.jar" />
- <copy todir="${war.dir}/WEB-INF/lib" file="${gwt.sdk}/validation-api-1.0.0.GA.jar"/>
- <copy todir="${war.dir}/WEB-INF/lib" file="${gwt.sdk}/validation-api-1.0.0.GA-sources.jar"/>
- <!-- Add any additional server libs that need to be copied -->
- </target>
-
- <target name="javac" depends="libs,appengine-copyjars" description="Compile java source to bytecode">
- <mkdir dir="${war.dir}/WEB-INF/classes"/>
- <javac srcdir="${src.dir}/" includes="**" encoding="utf-8"
- destdir="${war.dir}/WEB-INF/classes"
- source="1.6" target="1.6" nowarn="true"
- debug="true" debuglevel="lines,vars,source">
- <classpath refid="project.class.path"/>
- </javac>
- <copy todir="${war.dir}/WEB-INF/classes">
- <fileset dir="${src.dir}/" excludes="**/*.java"/>
- </copy>
- </target>
-
- <target name="javac-dev" description="Compile gwtc related classes">
- <mkdir dir="build/dev-classes"/>
- <javac srcdir="${src.dev.dir}" includes="**" encoding="utf-8"
- destdir="build/dev-classes"
- source="1.6" target="1.6" nowarn="true"
- debug="true" debuglevel="lines,vars,source">
- <classpath refid="project.class.path"/>
- </javac>
- </target>
-
- <target name="gwtc" depends="javac,javac-dev" description="GWT compile to JavaScript (production mode)">
- <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
- <classpath>
- <path location="build/dev-classes"/>
- <pathelement location="${src.dir}/"/>
- <path refid="project.class.path"/>
- </classpath>
- <!-- add jvmarg -Xss16M or similar if you see a StackOverflowError -->
- <jvmarg value="-Xmx256M"/>
- <arg line="-war"/>
- <arg value="${war.dir}/"/>
- <!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
- <arg line="${gwt.args}"/>
- <arg value="com.google.gwt.sample.mobilewebapp.MobileWebApp"/>
- </java>
- </target>
-
- <target name="datanucleusenhance" depends="javac"
- description="Performs JDO enhancement on compiled data classes.">
- <enhance_war war="${war.dir}/" />
- </target>
-
- <target name="devmode" depends="javac,javac-dev,datanucleusenhance" description="Run development mode">
- <java failonerror="true" fork="true" classname="com.google.gwt.dev.DevMode">
- <classpath>
- <path location="build/dev-classes"/>
- <pathelement location="${src.dir}/"/>
- <path refid="project.class.path"/>
- <path refid="tools.class.path"/>
- </classpath>
- <jvmarg value="-Xmx256M"/>
- <jvmarg value="-javaagent:${appengine.sdk}/lib/agent/appengine-agent.jar"/>
- <arg value="-startupUrl"/>
- <arg value="MobileWebApp.html"/>
- <arg line="-war"/>
- <arg value="${war.dir}/"/>
- <arg value="-server"/>
- <arg value="com.google.appengine.tools.development.gwt.AppEngineLauncher"/>
- <!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
- <arg line="${gwt.args}"/>
- <arg value="com.google.gwt.sample.mobilewebapp.MobileWebApp"/>
- </java>
- </target>
-
- <target name="build" depends="gwtc,datanucleusenhance" description="Build this project" />
-
- <target name="war" depends="build" description="Create a war file">
- <zip destfile="MobileWebApp.war" basedir="${war.dir}/"/>
- </target>
-
- <target name="clean" description="Cleans this project">
- <delete file="MobileWebApp.war" failonerror="false" />
- <delete dir="war/WEB-INF/appengine-generated/" failonerror="false" />
- <delete dir="war/WEB-INF/classes/com" failonerror="false" />
- <delete dir="war/WEB-INF/classes/META-INF" failonerror="false" />
- <delete file="war/WEB-INF/classes/log4j.properties" failonerror="false" />
- <delete dir="war/WEB-INF/deploy/" failonerror="false" />
- <delete dir="war/mobilewebapp/" failonerror="false" />
- <delete dir="build/" failonerror="false" />
- </target>
-
-</project>
diff --git a/servlet/build.xml b/servlet/build.xml
index dcb9a83..f274e05 100755
--- a/servlet/build.xml
+++ b/servlet/build.xml
@@ -27,6 +27,7 @@
<include name="com/google/gwt/dev/asm/**" />
<include name="com/google/gwt/dev/util/Name*.class" />
<include name="com/google/gwt/dev/util/StringKey.class" />
+ <include name="com/google/gwt/util/tools/shared/**" />
</fileset>
<fileset dir="${gwt.user.bin}">
<exclude name="**/rebind/**" />
diff --git a/user/src/com/google/gwt/i18n/rebind/keygen/MD5KeyGenerator.java b/user/src/com/google/gwt/i18n/rebind/keygen/MD5KeyGenerator.java
index ff3bf48..71cc694 100644
--- a/user/src/com/google/gwt/i18n/rebind/keygen/MD5KeyGenerator.java
+++ b/user/src/com/google/gwt/i18n/rebind/keygen/MD5KeyGenerator.java
@@ -15,7 +15,7 @@
*/
package com.google.gwt.i18n.rebind.keygen;
-import com.google.gwt.util.tools.Utility;
+import com.google.gwt.util.tools.shared.StringUtils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
@@ -55,6 +55,6 @@
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 unsupported", e);
}
- return Utility.toHexString(md5.digest());
+ return StringUtils.toHexString(md5.digest());
}
}
diff --git a/user/src/com/google/gwt/i18n/server/keygen/MD5KeyGenerator.java b/user/src/com/google/gwt/i18n/server/keygen/MD5KeyGenerator.java
index 3849027..24c6e09 100644
--- a/user/src/com/google/gwt/i18n/server/keygen/MD5KeyGenerator.java
+++ b/user/src/com/google/gwt/i18n/server/keygen/MD5KeyGenerator.java
@@ -17,7 +17,7 @@
import com.google.gwt.i18n.server.KeyGenerator;
import com.google.gwt.i18n.server.Message;
-import com.google.gwt.util.tools.Utility;
+import com.google.gwt.util.tools.shared.StringUtils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
@@ -55,6 +55,6 @@
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 unsupported", e);
}
- return Utility.toHexString(md5.digest());
+ return StringUtils.toHexString(md5.digest());
}
}
diff --git a/user/src/com/google/gwt/user/server/rpc/XsrfProtectedServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/XsrfProtectedServiceServlet.java
index 5a6c062..43702cc 100644
--- a/user/src/com/google/gwt/user/server/rpc/XsrfProtectedServiceServlet.java
+++ b/user/src/com/google/gwt/user/server/rpc/XsrfProtectedServiceServlet.java
@@ -19,7 +19,8 @@
import com.google.gwt.user.client.rpc.RpcTokenException;
import com.google.gwt.user.client.rpc.XsrfToken;
import com.google.gwt.user.server.Util;
-import com.google.gwt.util.tools.Utility;
+import com.google.gwt.util.tools.shared.Md5Utils;
+import com.google.gwt.util.tools.shared.StringUtils;
import java.lang.reflect.Method;
@@ -111,8 +112,8 @@
"Unable to verify XSRF cookie");
}
- String expectedToken = Utility.toHexString(
- Utility.getMd5Digest(sessionCookie.getValue().getBytes()));
+ String expectedToken = StringUtils.toHexString(
+ Md5Utils.getMd5Digest(sessionCookie.getValue().getBytes()));
XsrfToken xsrfToken = (XsrfToken) token;
if (!expectedToken.equals(xsrfToken.getToken())) {
diff --git a/user/src/com/google/gwt/user/server/rpc/XsrfTokenServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/XsrfTokenServiceServlet.java
index fa5343d..265b96f 100644
--- a/user/src/com/google/gwt/user/server/rpc/XsrfTokenServiceServlet.java
+++ b/user/src/com/google/gwt/user/server/rpc/XsrfTokenServiceServlet.java
@@ -19,7 +19,8 @@
import com.google.gwt.user.client.rpc.XsrfToken;
import com.google.gwt.user.client.rpc.XsrfTokenService;
import com.google.gwt.user.server.Util;
-import com.google.gwt.util.tools.Utility;
+import com.google.gwt.util.tools.shared.Md5Utils;
+import com.google.gwt.util.tools.shared.StringUtils;
import javax.servlet.http.Cookie;
@@ -195,7 +196,7 @@
"Unable to generate XSRF cookie");
}
byte[] cookieBytes = sessionCookie.getValue().getBytes();
- return Utility.toHexString(Utility.getMd5Digest(cookieBytes));
+ return StringUtils.toHexString(Md5Utils.getMd5Digest(cookieBytes));
}
/**