Allow RPC to support DTOs with non-public no-arg constructors.
Patch by: bobv
Review by: mmendez
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1703 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java b/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java
index 63c2c62..e01c7ed 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/CustomFieldSerializerValidator.java
@@ -78,7 +78,7 @@
serializee.getQualifiedSourceName()));
}
- if (!Shared.isDefaultInstantiable(serializee)) {
+ if (!serializee.isDefaultInstantiable() && !serializee.isAbstract()) {
if (!hasInstantiationMethod(streamReaderClass, serializer, serializee)) {
// Not default instantiable and no instantiate method was found.
reasons.add(MessageFormat.format(NO_INSTANTIATE_METHOD,
diff --git a/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java b/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
index fbe7c2f..222237b 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
@@ -385,33 +385,35 @@
*/
return;
}
+ JArrayType isArray = serializableClass.isArray();
+ JEnumType isEnum = serializableClass.isEnum();
+ boolean isNative = (isArray == null) && (isEnum == null);
- sourceWriter.print("public static ");
+ sourceWriter.print("public static" + (isNative ? " native " : " "));
String qualifiedSourceName = serializableClass.getQualifiedSourceName();
sourceWriter.print(qualifiedSourceName);
sourceWriter.print(" instantiate(");
sourceWriter.print(SerializationStreamReader.class.getName());
sourceWriter.println(" streamReader) throws "
- + SerializationException.class.getName() + "{");
+ + SerializationException.class.getName() + (isNative ? "/*-{" : "{"));
sourceWriter.indent();
- JArrayType isArray = serializableClass.isArray();
if (isArray != null) {
sourceWriter.println("int rank = streamReader.readInt();");
sourceWriter.println("return "
+ createArrayInstantiationExpression(isArray) + ";");
- } else if (serializableClass.isEnum() != null) {
+ } else if (isEnum != null) {
sourceWriter.println("int ordinal = streamReader.readInt();");
sourceWriter.println(qualifiedSourceName + "[] values = "
+ qualifiedSourceName + ".values();");
sourceWriter.println("assert (ordinal >= 0 && ordinal < values.length);");
sourceWriter.println("return values[ordinal];");
} else {
- sourceWriter.println("return new " + qualifiedSourceName + "();");
+ sourceWriter.println("return @" + qualifiedSourceName + "::new()();");
}
sourceWriter.outdent();
- sourceWriter.println("}");
+ sourceWriter.println(isNative ? "}-*/;" : "}");
sourceWriter.println();
}
diff --git a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
index f874f77..a87b145 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -828,11 +828,11 @@
return false;
}
- if (!Shared.isDefaultInstantiable(type)) {
+ if (!type.isDefaultInstantiable()) {
// Warn and return false.
logger.log(
TreeLogger.WARN,
- "Was not default instantiable (it must have a zero-argument, non-private constructor or no constructors at all)",
+ "Was not default instantiable (it must have a zero-argument constructor or no constructors at all)",
null);
return false;
}
diff --git a/user/src/com/google/gwt/user/rebind/rpc/Shared.java b/user/src/com/google/gwt/user/rebind/rpc/Shared.java
index c263436..0154fbb 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/Shared.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/Shared.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -20,7 +20,6 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JArrayType;
import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JConstructor;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
@@ -54,33 +53,6 @@
}
/**
- * Returns <code>true</code> if the type is a non-abstract class that either
- * has no constructors or it has a non-private, no argument constructor.
- *
- * @param type
- * @return <code>true</code> if the type is a non-abstract class that either
- * has no constructors or it has a non-private, no argument
- * constructor
- */
- static boolean isDefaultInstantiable(JClassType type) {
- if (type.isInterface() != null || type.isAbstract()) {
- return false;
- }
-
- boolean isDefaultInstantiable = false;
- if (type.getConstructors().length == 0) {
- isDefaultInstantiable = true;
- } else {
- JConstructor ctor = type.findConstructor(new JType[0]);
- if (ctor != null && !ctor.isPrivate()) {
- isDefaultInstantiable = true;
- }
- }
-
- return isDefaultInstantiable;
- }
-
- /**
* Returns <code>true</code> if the generated code should enforce type
* versioning.
*/
diff --git a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
index 0fa0d59..c1c0a1f 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -338,17 +338,17 @@
* Only classes with custom field serializers that do no declare
* instantiate methods get here
*/
- srcWriter.print("private static ");
+ srcWriter.print("private static native ");
srcWriter.print(type.getQualifiedSourceName());
srcWriter.print(" ");
srcWriter.print(getCreateMethodName(type));
- srcWriter.println("(SerializationStreamReader streamReader) throws SerializationException {");
+ srcWriter.println("(SerializationStreamReader streamReader) throws SerializationException /*-{");
srcWriter.indent();
- srcWriter.print("return new ");
+ srcWriter.print("return @");
srcWriter.print(type.getQualifiedSourceName());
- srcWriter.println("();");
+ srcWriter.println("::new()();");
srcWriter.outdent();
- srcWriter.println("}");
+ srcWriter.println("}-*/;");
srcWriter.println();
}
}
diff --git a/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java b/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java
index 2f56dc7..b71323d 100644
--- a/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java
+++ b/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java
@@ -23,6 +23,7 @@
import com.google.gwt.user.server.rpc.SerializationPolicyProvider;
import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -499,7 +500,8 @@
private Object instantiate(Class<?> customSerializer, Class<?> instanceClass)
throws InstantiationException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException {
+ IllegalArgumentException, InvocationTargetException,
+ NoSuchMethodException {
if (customSerializer != null) {
try {
Method instantiate = customSerializer.getMethod("instantiate",
@@ -520,7 +522,9 @@
assert (ordinal >= 0 && ordinal < enumConstants.length);
return enumConstants[ordinal];
} else {
- return instanceClass.newInstance();
+ Constructor<?> constructor = instanceClass.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ return constructor.newInstance();
}
}
diff --git a/user/test/com/google/gwt/user/client/rpc/ObjectGraphTest.java b/user/test/com/google/gwt/user/client/rpc/ObjectGraphTest.java
index e351c71..3bf3757 100644
--- a/user/test/com/google/gwt/user/client/rpc/ObjectGraphTest.java
+++ b/user/test/com/google/gwt/user/client/rpc/ObjectGraphTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -18,6 +18,7 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.rpc.TestSetFactory.SerializableDoublyLinkedNode;
+import com.google.gwt.user.client.rpc.TestSetFactory.SerializablePrivateNoArg;
/**
* TODO: document me.
@@ -82,6 +83,24 @@
}
});
}
+
+ public void testPrivateNoArg() {
+ delayTestFinish(TEST_DELAY);
+
+ ObjectGraphTestServiceAsync service = getServiceAsync();
+ final SerializablePrivateNoArg node = TestSetFactory.createPrivateNoArg();
+ service.echo_PrivateNoArg(node, new AsyncCallback() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Object result) {
+ assertNotNull(result);
+ assertTrue(TestSetValidator.isValid((SerializablePrivateNoArg) result));
+ finishTest();
+ }
+ });
+ }
public void testTrivialCyclicGraph() {
delayTestFinish(TEST_DELAY);
diff --git a/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestService.java b/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestService.java
index a956168..abaa9f2 100644
--- a/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestService.java
+++ b/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -16,6 +16,7 @@
package com.google.gwt.user.client.rpc;
import com.google.gwt.user.client.rpc.TestSetFactory.SerializableDoublyLinkedNode;
+import com.google.gwt.user.client.rpc.TestSetFactory.SerializablePrivateNoArg;
/**
* TODO: document me.
@@ -31,6 +32,8 @@
SerializableDoublyLinkedNode echo_ComplexCyclicGraph(
SerializableDoublyLinkedNode node1, SerializableDoublyLinkedNode node2);
+ SerializablePrivateNoArg echo_PrivateNoArg(SerializablePrivateNoArg node);
+
SerializableDoublyLinkedNode echo_TrivialCyclicGraph(
SerializableDoublyLinkedNode node);
}
diff --git a/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestServiceAsync.java b/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestServiceAsync.java
index db964fe..68ff8be 100644
--- a/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestServiceAsync.java
+++ b/user/test/com/google/gwt/user/client/rpc/ObjectGraphTestServiceAsync.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -16,6 +16,7 @@
package com.google.gwt.user.client.rpc;
import com.google.gwt.user.client.rpc.TestSetFactory.SerializableDoublyLinkedNode;
+import com.google.gwt.user.client.rpc.TestSetFactory.SerializablePrivateNoArg;
/**
* TODO: document me.
@@ -30,6 +31,8 @@
void echo_ComplexCyclicGraph(SerializableDoublyLinkedNode node1,
SerializableDoublyLinkedNode node2, AsyncCallback callback);
+ void echo_PrivateNoArg(SerializablePrivateNoArg node, AsyncCallback callback);
+
void echo_TrivialCyclicGraph(SerializableDoublyLinkedNode node,
AsyncCallback callback);
}
diff --git a/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java b/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java
index 2ab7811..693bfdc 100644
--- a/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java
+++ b/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -167,6 +167,24 @@
}
/**
+ * Tests that classes with a private no-arg constructor can be serialized.
+ */
+ public static class SerializablePrivateNoArg implements IsSerializable {
+ private int value;
+
+ private SerializablePrivateNoArg() {
+ }
+
+ public SerializablePrivateNoArg(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ /**
* TODO: document me.
*/
public static class SerializableSet extends HashSet implements IsSerializable {
@@ -293,6 +311,10 @@
return new short[] {
Short.MAX_VALUE, Short.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE};
}
+
+ public static SerializablePrivateNoArg createPrivateNoArg() {
+ return new SerializablePrivateNoArg(1);
+ }
public static Short[] createShortArray() {
return new Short[] {
@@ -305,8 +327,9 @@
* to make sure they are handled properly.
*/
public static String[] createStringArray() {
- return new String[] {null, "", "one", "two", "toString", "watch",
- "prototype", "eval", "valueOf", "constructor", "__proto__" };
+ return new String[] {
+ null, "", "one", "two", "toString", "watch", "prototype", "eval",
+ "valueOf", "constructor", "__proto__"};
}
public static Vector createVector() {
diff --git a/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java b/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
index 0bb64d1..010ef97 100644
--- a/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
+++ b/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -17,6 +17,7 @@
import com.google.gwt.user.client.rpc.TestSetFactory.SerializableClass;
import com.google.gwt.user.client.rpc.TestSetFactory.SerializableDoublyLinkedNode;
+import com.google.gwt.user.client.rpc.TestSetFactory.SerializablePrivateNoArg;
import java.util.ArrayList;
import java.util.HashMap;
@@ -296,6 +297,14 @@
return true;
}
+ public static boolean isValid(SerializablePrivateNoArg actual) {
+ if (actual == null) {
+ return false;
+ }
+
+ return actual.getValue() == 1;
+ }
+
public static boolean isValid(Vector expected, Vector actual) {
if (actual == null) {
return false;
diff --git a/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java
index b293bf1..5bcab6d 100644
--- a/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -18,6 +18,7 @@
import com.google.gwt.user.client.rpc.ObjectGraphTestService;
import com.google.gwt.user.client.rpc.TestSetValidator;
import com.google.gwt.user.client.rpc.TestSetFactory.SerializableDoublyLinkedNode;
+import com.google.gwt.user.client.rpc.TestSetFactory.SerializablePrivateNoArg;
/**
* TODO: document me.
@@ -52,6 +53,15 @@
return root;
}
+ public SerializablePrivateNoArg echo_PrivateNoArg(
+ SerializablePrivateNoArg node) {
+ if (!TestSetValidator.isValid(node)) {
+ throw new RuntimeException();
+ }
+
+ return node;
+ }
+
public SerializableDoublyLinkedNode echo_ComplexCyclicGraph(
SerializableDoublyLinkedNode node1, SerializableDoublyLinkedNode node2) {
if (node1 != node2) {