Merge r9309 and r9312 to GWT 2.1 branch. UTF-8 fix and ProxyAutoBean hotspots. git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/2.1@9314 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/autobean/server/MethodPropertyContext.java b/user/src/com/google/gwt/autobean/server/MethodPropertyContext.java index ac2653b..315e185 100644 --- a/user/src/com/google/gwt/autobean/server/MethodPropertyContext.java +++ b/user/src/com/google/gwt/autobean/server/MethodPropertyContext.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Type; import java.util.Collection; import java.util.Map; +import java.util.WeakHashMap; /** * A base type to handle analyzing the return value of a getter method. The @@ -30,47 +31,61 @@ */ abstract class MethodPropertyContext implements CollectionPropertyContext, MapPropertyContext { - private final Class<?> keyType; - private final Class<?> valueType; - private final Class<?> elementType; - private final Class<?> type; + private static class Data { + Class<?> keyType; + Class<?> valueType; + Class<?> elementType; + Class<?> type; + } + + /** + * Save prior instances in order to decrease the amount of data computed. + */ + private static final Map<Method, Data> cache = new WeakHashMap<Method, Data>(); + + private final Data data; public MethodPropertyContext(Method getter) { - this.type = getter.getReturnType(); + synchronized (cache) { + Data previous = cache.get(getter); + if (previous != null) { + this.data = previous; + return; + } - // Compute collection element type - if (Collection.class.isAssignableFrom(getType())) { - elementType = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization( - Collection.class, getter.getGenericReturnType(), - getter.getReturnType())); - keyType = valueType = null; - } else if (Map.class.isAssignableFrom(getType())) { - Type[] types = TypeUtils.getParameterization(Map.class, - getter.getGenericReturnType()); - keyType = TypeUtils.ensureBaseType(types[0]); - valueType = TypeUtils.ensureBaseType(types[1]); - elementType = null; - } else { - elementType = keyType = valueType = null; + this.data = new Data(); + data.type = getter.getReturnType(); + // Compute collection element type + if (Collection.class.isAssignableFrom(getType())) { + data.elementType = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization( + Collection.class, getter.getGenericReturnType(), + getter.getReturnType())); + } else if (Map.class.isAssignableFrom(getType())) { + Type[] types = TypeUtils.getParameterization(Map.class, + getter.getGenericReturnType()); + data.keyType = TypeUtils.ensureBaseType(types[0]); + data.valueType = TypeUtils.ensureBaseType(types[1]); + } + cache.put(getter, data); } } public abstract boolean canSet(); public Class<?> getElementType() { - return elementType; + return data.elementType; } public Class<?> getKeyType() { - return keyType; + return data.keyType; } public Class<?> getType() { - return type; + return data.type; } public Class<?> getValueType() { - return valueType; + return data.valueType; } public abstract void set(Object value);
diff --git a/user/src/com/google/gwt/autobean/server/ProxyAutoBean.java b/user/src/com/google/gwt/autobean/server/ProxyAutoBean.java index 7c4772d..0992adc 100644 --- a/user/src/com/google/gwt/autobean/server/ProxyAutoBean.java +++ b/user/src/com/google/gwt/autobean/server/ProxyAutoBean.java
@@ -28,9 +28,10 @@ import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.WeakHashMap; /** * An implementation of an AutoBean that uses reflection. @@ -38,9 +39,60 @@ * @param <T> the type of interface being wrapped */ class ProxyAutoBean<T> extends AbstractAutoBean<T> { + private static class Data { + final List<Method> getters = new ArrayList<Method>(); + final List<String> getterNames = new ArrayList<String>(); + final List<PropertyType> propertyType = new ArrayList<PropertyType>(); + } + + private enum PropertyType { + VALUE, REFERENCE, COLLECTION, MAP; + } + + private static final Map<Class<?>, Data> cache = new WeakHashMap<Class<?>, Data>(); + + private static Data calculateData(Class<?> beanType) { + Data toReturn; + synchronized (cache) { + toReturn = cache.get(beanType); + if (toReturn == null) { + toReturn = new Data(); + for (Method method : beanType.getMethods()) { + if (BeanMethod.GET.matches(method)) { + toReturn.getters.add(method); + + String name; + PropertyName annotation = method.getAnnotation(PropertyName.class); + if (annotation != null) { + name = annotation.value(); + } else { + name = method.getName(); + name = Character.toLowerCase(name.charAt(3)) + + (name.length() >= 5 ? name.substring(4) : ""); + } + toReturn.getterNames.add(name); + + Class<?> returnType = method.getReturnType(); + if (TypeUtils.isValueType(returnType)) { + toReturn.propertyType.add(PropertyType.VALUE); + } else if (Collection.class.isAssignableFrom(returnType)) { + toReturn.propertyType.add(PropertyType.COLLECTION); + } else if (Map.class.isAssignableFrom(returnType)) { + toReturn.propertyType.add(PropertyType.MAP); + } else { + toReturn.propertyType.add(PropertyType.REFERENCE); + } + } + } + cache.put(beanType, toReturn); + } + } + return toReturn; + } + private final Class<T> beanType; private final Configuration configuration; - private final List<Method> getters; + private final Data data; private final T shim; // These constructors mirror the generated constructors. @@ -50,7 +102,7 @@ super(factory); this.beanType = (Class<T>) beanType; this.configuration = configuration; - this.getters = calculateGetters(); + this.data = calculateData(beanType); this.shim = createShim(); } @@ -63,7 +115,7 @@ } this.beanType = (Class<T>) beanType; this.configuration = configuration; - this.getters = calculateGetters(); + this.data = calculateData(beanType); this.shim = createShim(); } @@ -71,7 +123,7 @@ super(toClone, deep); this.beanType = toClone.beanType; this.configuration = toClone.configuration; - this.getters = toClone.getters; + this.data = toClone.data; this.shim = createShim(); } @@ -156,16 +208,15 @@ // TODO: Port to model-based when class-based TypeOracle is available. @Override protected void traverseProperties(AutoBeanVisitor visitor, OneShotContext ctx) { - for (final Method getter : getters) { - String name; - PropertyName annotation = getter.getAnnotation(PropertyName.class); - if (annotation != null) { - name = annotation.value(); - } else { - name = getter.getName(); - name = Character.toLowerCase(name.charAt(3)) - + (name.length() >= 5 ? name.substring(4) : ""); - } + assert data.getters.size() == data.getterNames.size() + && data.getters.size() == data.propertyType.size(); + Iterator<Method> getterIt = data.getters.iterator(); + Iterator<String> nameIt = data.getterNames.iterator(); + Iterator<PropertyType> typeIt = data.propertyType.iterator(); + while (getterIt.hasNext()) { + Method getter = getterIt.next(); + String name = nameIt.next(); + PropertyType propertyType = typeIt.next(); // Use the shim to handle automatic wrapping Object value; @@ -184,42 +235,51 @@ MethodPropertyContext x = isUsingSimplePeer() ? new BeanPropertyContext( this, getter) : new GetterPropertyContext(this, getter); - if (TypeUtils.isValueType(x.getType())) { - if (visitor.visitValueProperty(name, value, x)) { - } - visitor.endVisitValueProperty(name, value, x); - } else if (Collection.class.isAssignableFrom(x.getType())) { - // Workaround for generics bug in mac javac 1.6.0_22 - @SuppressWarnings("rawtypes") - AutoBean temp = AutoBeanUtils.getAutoBean((Collection) value); - @SuppressWarnings("unchecked") - AutoBean<Collection<?>> bean = (AutoBean<Collection<?>>) temp; - if (visitor.visitCollectionProperty(name, bean, x)) { - if (value != null) { - ((ProxyAutoBean<?>) bean).traverse(visitor, ctx); + switch (propertyType) { + case VALUE: { + if (visitor.visitValueProperty(name, value, x)) { } + visitor.endVisitValueProperty(name, value, x); + break; } - visitor.endVisitCollectionProperty(name, bean, x); - } else if (Map.class.isAssignableFrom(x.getType())) { - // Workaround for generics bug in mac javac 1.6.0_22 - @SuppressWarnings("rawtypes") - AutoBean temp = AutoBeanUtils.getAutoBean((Map) value); - @SuppressWarnings("unchecked") - AutoBean<Map<?, ?>> bean = (AutoBean<Map<?, ?>>) temp; - if (visitor.visitMapProperty(name, bean, x)) { - if (value != null) { - ((ProxyAutoBean<?>) bean).traverse(visitor, ctx); + case COLLECTION: { + // Workaround for generics bug in mac javac 1.6.0_22 + @SuppressWarnings("rawtypes") + AutoBean temp = AutoBeanUtils.getAutoBean((Collection) value); + @SuppressWarnings("unchecked") + AutoBean<Collection<?>> bean = (AutoBean<Collection<?>>) temp; + if (visitor.visitCollectionProperty(name, bean, x)) { + if (value != null) { + ((ProxyAutoBean<?>) bean).traverse(visitor, ctx); + } } + visitor.endVisitCollectionProperty(name, bean, x); + break; } - visitor.endVisitMapProperty(name, bean, x); - } else { - ProxyAutoBean<?> bean = (ProxyAutoBean<?>) AutoBeanUtils.getAutoBean(value); - if (visitor.visitReferenceProperty(name, bean, x)) { - if (value != null) { - bean.traverse(visitor, ctx); + case MAP: { + // Workaround for generics bug in mac javac 1.6.0_22 + @SuppressWarnings("rawtypes") + AutoBean temp = AutoBeanUtils.getAutoBean((Map) value); + @SuppressWarnings("unchecked") + AutoBean<Map<?, ?>> bean = (AutoBean<Map<?, ?>>) temp; + if (visitor.visitMapProperty(name, bean, x)) { + if (value != null) { + ((ProxyAutoBean<?>) bean).traverse(visitor, ctx); + } } + visitor.endVisitMapProperty(name, bean, x); + break; } - visitor.endVisitReferenceProperty(name, bean, x); + case REFERENCE: { + ProxyAutoBean<?> bean = (ProxyAutoBean<?>) AutoBeanUtils.getAutoBean(value); + if (visitor.visitReferenceProperty(name, bean, x)) { + if (value != null) { + bean.traverse(visitor, ctx); + } + } + visitor.endVisitReferenceProperty(name, bean, x); + break; + } } } } @@ -232,16 +292,6 @@ return values; } - private List<Method> calculateGetters() { - List<Method> toReturn = new ArrayList<Method>(); - for (Method method : beanType.getMethods()) { - if (BeanMethod.GET.matches(method)) { - toReturn.add(method); - } - } - return Collections.unmodifiableList(toReturn); - } - private T createShim() { T toReturn = AutoBeanFactoryMagic.makeProxy(beanType, new ShimHandler<T>( this, getWrapped()));
diff --git a/user/src/com/google/gwt/autobean/shared/ValueCodex.java b/user/src/com/google/gwt/autobean/shared/ValueCodex.java index 19ef456..d4a452f 100644 --- a/user/src/com/google/gwt/autobean/shared/ValueCodex.java +++ b/user/src/com/google/gwt/autobean/shared/ValueCodex.java
@@ -237,8 +237,7 @@ private static <T> Type findType(Class<T> clazz) { Type type = typesByClass.get(clazz); if (type == null) { - // Necessary due to lack of Class.isAssignable() in client-side - if (clazz.getEnumConstants() != null) { + if (clazz.isEnum()) { return Type.ENUM; } }
diff --git a/user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java b/user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java index 9f65e5e..15ce275 100644 --- a/user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java +++ b/user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java
@@ -17,7 +17,8 @@ import com.google.gwt.autobean.server.impl.JsonSplittable; import com.google.gwt.autobean.shared.Splittable; -import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter; + +import org.json.JSONObject; /** * This class has a super-source version with a client-only implementation. @@ -27,7 +28,7 @@ * Create a quoted JSON string. */ public static String quote(String raw) { - return ServerSerializationStreamWriter.escapeString(raw); + return JSONObject.quote(raw); } public static Splittable split(String payload) {
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java b/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java index c0e1418..4ad67c1 100644 --- a/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java +++ b/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
@@ -130,7 +130,6 @@ if (DUMP_PAYLOAD) { System.out.println(">>> " + jsonRequestString); } - PrintWriter writer = response.getWriter(); try { // Check that user is logged in before proceeding @@ -146,6 +145,8 @@ response.setHeader("userId", String.format("%s", userInfo.getId())); response.setStatus(HttpServletResponse.SC_OK); response.setContentType(RequestFactory.JSON_CONTENT_TYPE_UTF8); + // The Writer must be obtained after setting the content type + PrintWriter writer = response.getWriter(); writer.print(payload); writer.flush(); }
diff --git a/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java b/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java index c158123..61d7071 100644 --- a/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java +++ b/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java
@@ -21,6 +21,7 @@ import com.google.gwt.requestfactory.server.LocatorJreTest; import com.google.gwt.requestfactory.server.RequestFactoryInterfaceValidatorTest; import com.google.gwt.requestfactory.server.RequestFactoryJreTest; +import com.google.gwt.requestfactory.server.RequestFactoryUnicodeEscapingJreTest; import com.google.gwt.requestfactory.shared.impl.SimpleEntityProxyIdTest; import junit.framework.Test; @@ -40,6 +41,7 @@ suite.addTestSuite(SimpleEntityProxyIdTest.class); suite.addTestSuite(RequestFactoryInterfaceValidatorTest.class); suite.addTestSuite(RequestFactoryModelTest.class); + suite.addTestSuite(RequestFactoryUnicodeEscapingJreTest.class); return suite; } }
diff --git a/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java b/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java index cbb5558..884d005 100644 --- a/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java +++ b/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
@@ -20,6 +20,7 @@ import com.google.gwt.requestfactory.client.RequestFactoryExceptionHandlerTest; import com.google.gwt.requestfactory.client.RequestFactoryPolymorphicTest; import com.google.gwt.requestfactory.client.RequestFactoryTest; +import com.google.gwt.requestfactory.client.RequestFactoryUnicodeEscapingTest; import com.google.gwt.requestfactory.client.ui.EditorTest; import com.google.gwt.requestfactory.shared.ComplexKeysTest; import com.google.gwt.requestfactory.shared.LocatorTest; @@ -40,6 +41,7 @@ suite.addTestSuite(RequestFactoryTest.class); suite.addTestSuite(RequestFactoryExceptionHandlerTest.class); suite.addTestSuite(RequestFactoryPolymorphicTest.class); + suite.addTestSuite(RequestFactoryUnicodeEscapingTest.class); return suite; } }
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java index b512857..0eea7a2 100644 --- a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java +++ b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
@@ -730,6 +730,7 @@ * Make sure our stock RF logging service keeps receiving. */ public void testLoggingService() { + delayTestFinish(DELAY_TEST_FINISH); String logRecordJson = new StringBuilder("{") // .append("\"level\": \"ALL\", ") // .append("\"loggerName\": \"logger\", ") // @@ -2041,6 +2042,7 @@ * in a static method on UserInformation). */ public void testUserInfo() { + delayTestFinish(DELAY_TEST_FINISH); req.userInformationRequest().getCurrentUserInformation("").fire( new Receiver<UserInformationProxy>() { @Override @@ -2050,6 +2052,7 @@ assertEquals("Dummy User", response.getName()); assertEquals("", response.getLoginUrl()); assertEquals("", response.getLogoutUrl()); + finishTestAndReset(); } }); }
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryUnicodeEscapingTest.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryUnicodeEscapingTest.java new file mode 100644 index 0000000..44de4ed --- /dev/null +++ b/user/test/com/google/gwt/requestfactory/client/RequestFactoryUnicodeEscapingTest.java
@@ -0,0 +1,142 @@ +/* + * Copyright 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. + */ +package com.google.gwt.requestfactory.client; + +import com.google.gwt.requestfactory.shared.Receiver; +import com.google.gwt.requestfactory.shared.ServerFailure; +import com.google.gwt.user.client.rpc.UnicodeEscapingService.InvalidCharacterException; +import com.google.gwt.user.client.rpc.UnicodeEscapingTest; + +import java.util.ArrayList; +import java.util.List; + +/** + * Runs through a portion of the Basic Multilingual Plane. + */ +public class RequestFactoryUnicodeEscapingTest extends RequestFactoryTestBase { + private static final int TEST_FINISH_DELAY_MS = 5000; + private final UnicodeEscapingTest test = new UnicodeEscapingTest() { + + @Override + protected void clientToServerVerifyRange(int start, final int end, + final int size, final int step) throws InvalidCharacterException { + current = start; + int blockEnd = Math.min(end, current + size); + req.unicodeTestRequest().verifyStringContainingCharacterRange(current, + blockEnd, getStringContainingCharacterRange(start, blockEnd)).fire( + new Receiver<Void>() { + List<ServerFailure> fails = new ArrayList<ServerFailure>(); + + @Override + public void onFailure(ServerFailure error) { + fails.add(error); + onSuccess(null); + } + + @Override + public void onSuccess(Void response) { + current += step; + if (current < end) { + delayTestFinish(TEST_FINISH_DELAY_MS); + int blockEnd = Math.min(end, current + size); + req.unicodeTestRequest().verifyStringContainingCharacterRange( + current, blockEnd, + getStringContainingCharacterRange(current, blockEnd)).fire( + this); + } else if (!fails.isEmpty()) { + StringBuilder msg = new StringBuilder(); + for (ServerFailure error : fails) { + msg.append(error.getMessage()).append("\n"); + } + throw new RuntimeException(msg.toString()); + } else { + finishTest(); + } + } + }); + } + + @Override + protected void serverToClientVerify(int start, final int end, + final int size, final int step) { + current = start; + req.unicodeTestRequest().getStringContainingCharacterRange(start, + Math.min(end, current + size)).fire(new Receiver<String>() { + List<ServerFailure> fails = new ArrayList<ServerFailure>(); + + @Override + public void onFailure(ServerFailure error) { + fails.add(error); + nextBatch(); + } + + @Override + public void onSuccess(String response) { + try { + verifyStringContainingCharacterRange(current, + Math.min(end, current + size), response); + } catch (InvalidCharacterException e) { + fails.add(new ServerFailure(e.getMessage(), null, null)); + } + nextBatch(); + } + + private void nextBatch() { + current += step; + if (current < end) { + delayTestFinish(TEST_FINISH_DELAY_MS); + req.unicodeTestRequest().getStringContainingCharacterRange(current, + Math.min(end, current + size)).fire(this); + } else if (!fails.isEmpty()) { + StringBuilder msg = new StringBuilder(); + for (ServerFailure t : fails) { + msg.append(t.getMessage()).append("\n"); + } + throw new RuntimeException(msg.toString()); + } else { + finishTest(); + } + } + }); + } + }; + + @Override + public String getModuleName() { + return "com.google.gwt.requestfactory.RequestFactorySuite"; + } + + public void testClientToServerBMPHigh() throws InvalidCharacterException { + test.testClientToServerBMPHigh(); + } + + public void testClientToServerBMPLow() throws InvalidCharacterException { + test.testClientToServerBMPLow(); + } + + public void testClientToServerNonBMP() throws InvalidCharacterException { + test.testClientToServerNonBMP(); + } + + public void testServerToClientBMP() { + test.testServerToClientBMP(); + } + + public void testServerToClientNonBMP() { + test.testServerToClientNonBMP(); + } + +}
diff --git a/user/test/com/google/gwt/requestfactory/server/RequestFactoryUnicodeEscapingJreTest.java b/user/test/com/google/gwt/requestfactory/server/RequestFactoryUnicodeEscapingJreTest.java new file mode 100644 index 0000000..06a4d50 --- /dev/null +++ b/user/test/com/google/gwt/requestfactory/server/RequestFactoryUnicodeEscapingJreTest.java
@@ -0,0 +1,35 @@ +/* + * Copyright 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. + */ +package com.google.gwt.requestfactory.server; + +import com.google.gwt.requestfactory.client.RequestFactoryUnicodeEscapingTest; +import com.google.gwt.requestfactory.shared.SimpleRequestFactory; + +/** + * A JRE implementation of {@link RequestFactoryUnicodeEscapingTest}. + */ +public class RequestFactoryUnicodeEscapingJreTest extends + RequestFactoryUnicodeEscapingTest { + @Override + public String getModuleName() { + return null; + } + + @Override + protected SimpleRequestFactory createFactory() { + return RequestFactoryJreTest.createInProcess(SimpleRequestFactory.class); + } +}
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java b/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java index 082f3a1..c62b5a5 100644 --- a/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java +++ b/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java
@@ -24,4 +24,6 @@ SimpleBarRequest simpleBarRequest(); SimpleFooRequest simpleFooRequest(); + + UnicodeTestRequest unicodeTestRequest(); }
diff --git a/user/test/com/google/gwt/requestfactory/shared/UnicodeTestRequest.java b/user/test/com/google/gwt/requestfactory/shared/UnicodeTestRequest.java new file mode 100644 index 0000000..fe9e38e --- /dev/null +++ b/user/test/com/google/gwt/requestfactory/shared/UnicodeTestRequest.java
@@ -0,0 +1,29 @@ +/* + * Copyright 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. + */ +package com.google.gwt.requestfactory.shared; + +import com.google.gwt.user.client.rpc.UnicodeEscapingTest; + +/** + * Provides access to the static test methods in {@link UnicodeEscapingTes}. + */ +@Service(UnicodeEscapingTest.class) +public interface UnicodeTestRequest extends RequestContext { + Request<String> getStringContainingCharacterRange(int start, int end); + + Request<Void> verifyStringContainingCharacterRange(int start, int end, + String str); +}
diff --git a/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java b/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java index 1303260..0a8c7fa 100644 --- a/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java +++ b/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java
@@ -108,7 +108,7 @@ } /** start of current block being tested. */ - private int current; + protected int current; @Override public String getModuleName() { @@ -234,7 +234,7 @@ NON_BMP_TEST_INCREMENT); } - private void clientToServerVerifyRange(final int start, final int end, + protected void clientToServerVerifyRange(final int start, final int end, final int size, final int step) throws InvalidCharacterException { current = start; int blockEnd = Math.min(end, current + size); @@ -274,7 +274,7 @@ }); } - private void serverToClientVerify(final int start, final int end, + protected void serverToClientVerify(final int start, final int end, final int size, final int step) { current = start; getService().getStringContainingCharacterRange(start,