fixed HTTP invoker to support resolution of multi-level primitive array classes again
This commit is contained in:
parent
57874a6050
commit
35c36dda4b
|
@ -39,9 +39,9 @@ import java.util.Set;
|
|||
* framework; consider Jakarta's Commons Lang for a more comprehensive suite
|
||||
* of class utilities.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Keith Donald
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1
|
||||
* @see TypeUtils
|
||||
* @see ReflectionUtils
|
||||
|
@ -51,8 +51,11 @@ public abstract class ClassUtils {
|
|||
/** Suffix for array class names: "[]" */
|
||||
public static final String ARRAY_SUFFIX = "[]";
|
||||
|
||||
/** Prefix for internal array class names: "[L" */
|
||||
private static final String INTERNAL_ARRAY_PREFIX = "[L";
|
||||
/** Prefix for internal array class names: "[" */
|
||||
private static final String INTERNAL_ARRAY_PREFIX = "[";
|
||||
|
||||
/** Prefix for internal non-primitive array class names: "[L" */
|
||||
private static final String NON_PRIMITIVE_ARRAY_PREFIX = "[L";
|
||||
|
||||
/** The package separator character '.' */
|
||||
private static final char PACKAGE_SEPARATOR = '.';
|
||||
|
@ -85,6 +88,12 @@ public abstract class ClassUtils {
|
|||
*/
|
||||
private static final Map<String, Class> primitiveTypeNameMap = new HashMap<String, Class>(16);
|
||||
|
||||
/**
|
||||
* Map with common "java.lang" class name as key and corresponding Class as value.
|
||||
* Primarily for efficient deserialization of remote invocations.
|
||||
*/
|
||||
private static final Map<String, Class> commonClassCache = new HashMap<String, Class>(32);
|
||||
|
||||
|
||||
static {
|
||||
primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
|
||||
|
@ -98,6 +107,7 @@ public abstract class ClassUtils {
|
|||
|
||||
for (Map.Entry<Class, Class> entry : primitiveWrapperTypeMap.entrySet()) {
|
||||
primitiveTypeToWrapperMap.put(entry.getValue(), entry.getKey());
|
||||
registerCommonClasses(entry.getKey());
|
||||
}
|
||||
|
||||
Set<Class> primitiveTypes = new HashSet<Class>(16);
|
||||
|
@ -108,9 +118,25 @@ public abstract class ClassUtils {
|
|||
for (Class primitiveType : primitiveTypes) {
|
||||
primitiveTypeNameMap.put(primitiveType.getName(), primitiveType);
|
||||
}
|
||||
|
||||
registerCommonClasses(Boolean[].class, Byte[].class, Character[].class, Double[].class,
|
||||
Float[].class, Integer[].class, Long[].class, Short[].class);
|
||||
registerCommonClasses(Number.class, Number[].class, String.class, String[].class,
|
||||
Object.class, Object[].class, Class.class, Class[].class);
|
||||
registerCommonClasses(Throwable.class, Exception.class, RuntimeException.class,
|
||||
Error.class, StackTraceElement.class, StackTraceElement[].class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register the given common classes with the ClassUtils cache.
|
||||
*/
|
||||
private static void registerCommonClasses(Class... commonClasses) {
|
||||
for (Class clazz : commonClasses) {
|
||||
commonClassCache.put(clazz.getName(), clazz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default ClassLoader to use: typically the thread context
|
||||
* ClassLoader, if available; the ClassLoader that loaded the ClassUtils
|
||||
|
@ -188,6 +214,9 @@ public abstract class ClassUtils {
|
|||
Assert.notNull(name, "Name must not be null");
|
||||
|
||||
Class clazz = resolvePrimitiveClassName(name);
|
||||
if (clazz == null) {
|
||||
clazz = commonClassCache.get(name);
|
||||
}
|
||||
if (clazz != null) {
|
||||
return clazz;
|
||||
}
|
||||
|
@ -200,16 +229,16 @@ public abstract class ClassUtils {
|
|||
}
|
||||
|
||||
// "[Ljava.lang.String;" style arrays
|
||||
int internalArrayMarker = name.indexOf(INTERNAL_ARRAY_PREFIX);
|
||||
if (internalArrayMarker != -1 && name.endsWith(";")) {
|
||||
String elementClassName = null;
|
||||
if (internalArrayMarker == 0) {
|
||||
elementClassName = name.substring(INTERNAL_ARRAY_PREFIX.length(), name.length() - 1);
|
||||
}
|
||||
else if (name.startsWith("[")) {
|
||||
elementClassName = name.substring(1);
|
||||
}
|
||||
Class elementClass = forName(elementClassName, classLoader);
|
||||
if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {
|
||||
String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
|
||||
Class elementClass = forName(elementName, classLoader);
|
||||
return Array.newInstance(elementClass, 0).getClass();
|
||||
}
|
||||
|
||||
// "[[I" or "[[Ljava.lang.String;" style arrays
|
||||
if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
|
||||
String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
|
||||
Class elementClass = forName(elementName, classLoader);
|
||||
return Array.newInstance(elementClass, 0).getClass();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -47,6 +47,22 @@ public interface ITestBean {
|
|||
|
||||
void setStringArray(String[] stringArray);
|
||||
|
||||
Integer[][] getNestedIntegerArray();
|
||||
|
||||
Integer[] getSomeIntegerArray();
|
||||
|
||||
void setSomeIntegerArray(Integer[] someIntegerArray);
|
||||
|
||||
void setNestedIntegerArray(Integer[][] nestedIntegerArray);
|
||||
|
||||
int[] getSomeIntArray();
|
||||
|
||||
void setSomeIntArray(int[] someIntArray);
|
||||
|
||||
int[][] getNestedIntArray();
|
||||
|
||||
void setNestedIntArray(int[][] someNestedArray);
|
||||
|
||||
/**
|
||||
* Throws a given (non-null) exception.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -66,6 +66,12 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
|||
|
||||
private Integer[] someIntegerArray;
|
||||
|
||||
private Integer[][] nestedIntegerArray;
|
||||
|
||||
private int[] someIntArray;
|
||||
|
||||
private int[][] nestedIntArray;
|
||||
|
||||
private Date date = new Date();
|
||||
|
||||
private Float myFloat = new Float(0.0);
|
||||
|
@ -98,7 +104,6 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
|||
|
||||
private List pets;
|
||||
|
||||
|
||||
public TestBean() {
|
||||
}
|
||||
|
||||
|
@ -246,6 +251,30 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
|||
this.someIntegerArray = someIntegerArray;
|
||||
}
|
||||
|
||||
public Integer[][] getNestedIntegerArray() {
|
||||
return nestedIntegerArray;
|
||||
}
|
||||
|
||||
public void setNestedIntegerArray(Integer[][] nestedIntegerArray) {
|
||||
this.nestedIntegerArray = nestedIntegerArray;
|
||||
}
|
||||
|
||||
public int[] getSomeIntArray() {
|
||||
return someIntArray;
|
||||
}
|
||||
|
||||
public void setSomeIntArray(int[] someIntArray) {
|
||||
this.someIntArray = someIntArray;
|
||||
}
|
||||
|
||||
public int[][] getNestedIntArray() {
|
||||
return nestedIntArray;
|
||||
}
|
||||
|
||||
public void setNestedIntArray(int[][] nestedIntArray) {
|
||||
this.nestedIntArray = nestedIntArray;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -28,7 +28,6 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.util.Arrays;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -97,6 +96,18 @@ public class HttpInvokerTests extends TestCase {
|
|||
assertEquals(50, proxy.getAge());
|
||||
proxy.setStringArray(new String[] {"str1", "str2"});
|
||||
assertTrue(Arrays.equals(new String[] {"str1", "str2"}, proxy.getStringArray()));
|
||||
proxy.setSomeIntegerArray(new Integer[] {1, 2, 3});
|
||||
assertTrue(Arrays.equals(new Integer[] {1, 2, 3}, proxy.getSomeIntegerArray()));
|
||||
proxy.setNestedIntegerArray(new Integer[][] {{1, 2, 3}, {4, 5, 6}});
|
||||
Integer[][] integerArray = proxy.getNestedIntegerArray();
|
||||
assertTrue(Arrays.equals(new Integer[] {1, 2, 3}, integerArray[0]));
|
||||
assertTrue(Arrays.equals(new Integer[] {4, 5, 6}, integerArray[1]));
|
||||
proxy.setSomeIntArray(new int[] {1, 2, 3});
|
||||
assertTrue(Arrays.equals(new int[] {1, 2, 3}, proxy.getSomeIntArray()));
|
||||
proxy.setNestedIntArray(new int[][] {{1, 2, 3}, {4, 5, 6}});
|
||||
int[][] intArray = proxy.getNestedIntArray();
|
||||
assertTrue(Arrays.equals(new int[] {1, 2, 3}, intArray[0]));
|
||||
assertTrue(Arrays.equals(new int[] {4, 5, 6}, intArray[1]));
|
||||
|
||||
try {
|
||||
proxy.exceptional(new IllegalStateException());
|
||||
|
|
Loading…
Reference in New Issue