You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/04/08 12:54:55 UTC
svn commit: r763176 - in /cxf/trunk/rt/frontend/jaxrs/src:
main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
test/java/org/apache/cxf/jaxrs/Customer.java
test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
Author: sergeyb
Date: Wed Apr 8 10:54:54 2009
New Revision: 763176
URL: http://svn.apache.org/viewvc?rev=763176&view=rev
Log:
CXF-2153 : applying a patch on behalf of Craig Muchinsky
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=763176&r1=763175&r2=763176&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java Wed Apr 8 10:54:54 2009
@@ -31,7 +31,9 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -62,6 +64,7 @@
import org.apache.cxf.common.util.PrimitiveUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.ParameterHandler;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.impl.PathSegmentImpl;
import org.apache.cxf.jaxrs.impl.tl.ThreadLocalContextResolver;
import org.apache.cxf.jaxrs.impl.tl.ThreadLocalHttpHeaders;
@@ -133,6 +136,23 @@
});
}
+
+ @SuppressWarnings("unchecked")
+ public static Object extractFieldValue(final Field f,
+ final Object o) {
+ return AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ f.setAccessible(true);
+ try {
+ return f.get(o);
+ } catch (IllegalAccessException ex) {
+ reportServerError("FIELD_ACCESS_FAILURE",
+ f.getType().getName());
+ }
+ return null;
+ }
+ });
+ }
public static Class<?> getActualType(Type genericType) {
@@ -168,6 +188,19 @@
reportServerError("METHOD_INJECTION_FAILURE", method.getName());
}
}
+
+ public static Object extractFromMethod(Object requestObject,
+ Method method) {
+ try {
+ Method methodToInvoke = checkProxy(method, requestObject);
+ return methodToInvoke.invoke(requestObject);
+ } catch (IllegalAccessException ex) {
+ reportServerError("METHOD_ACCESS_FAILURE", method.getName());
+ } catch (Exception ex) {
+ reportServerError("METHOD_INJECTION_FAILURE", method.getName());
+ }
+ return null;
+ }
public static Object handleParameter(String value,
Class<?> pClass,
@@ -275,90 +308,250 @@
reportServerError("CLASS_INSTANTIATION_FAILURE", paramType.getName());
}
+ Map<String, MultivaluedMap<String, String>> parsedValues =
+ new HashMap<String, MultivaluedMap<String, String>>();
for (Map.Entry<String, List<String>> entry : values.entrySet()) {
- boolean injected = false;
- for (Method m : paramType.getMethods()) {
- if (m.getName().equalsIgnoreCase("set" + entry.getKey())
- && m.getParameterTypes().length == 1) {
- Object paramValue = handleParameter(entry.getValue().get(0),
- m.getParameterTypes()[0],
- pType, message);
- if (paramValue != null) {
- injectThroughMethod(bean, m, paramValue);
- injected = true;
- break;
- }
- }
+ String memberKey = entry.getKey();
+ String beanKey = null;
+
+ int idx = memberKey.indexOf('.');
+ if (idx == -1) {
+ beanKey = "." + memberKey;
+ } else {
+ beanKey = memberKey.substring(0, idx);
+ memberKey = memberKey.substring(idx + 1);
}
- if (injected) {
- continue;
+
+ MultivaluedMap<String, String> value = parsedValues.get(beanKey);
+ if (value == null) {
+ value = new MetadataMap<String, String>();
+ parsedValues.put(beanKey, value);
}
- for (Field f : paramType.getFields()) {
- if (f.getName().equalsIgnoreCase(entry.getKey())) {
- Object paramValue = handleParameter(entry.getValue().get(0),
- f.getType(), pType, message);
- if (paramValue != null) {
- injectFieldValue(f, bean, paramValue);
+ value.put(memberKey, entry.getValue());
+ }
+
+ if (parsedValues.size() > 0) {
+ for (Map.Entry<String, MultivaluedMap<String, String>> entry : parsedValues.entrySet()) {
+ String memberKey = entry.getKey();
+
+ boolean isbean = !memberKey.startsWith(".");
+ if (!isbean) {
+ memberKey = memberKey.substring(1);
+ }
+
+ Object setter = null;
+ Object getter = null;
+ for (Method m : paramType.getMethods()) {
+ if (m.getName().equalsIgnoreCase("set" + memberKey)
+ && m.getParameterTypes().length == 1) {
+ setter = m;
+ } else if (m.getName().equalsIgnoreCase("get" + memberKey)
+ && m.getReturnType() != Void.TYPE) {
+ getter = m;
+ }
+ if (setter != null && getter != null) {
break;
}
}
+ if (setter == null) {
+ for (Field f : paramType.getFields()) {
+ if (f.getName().equalsIgnoreCase(memberKey)) {
+ setter = f;
+ getter = f;
+ break;
+ }
+ }
+ }
+
+ if (setter != null && getter != null) {
+ Class<?> type = null;
+ Type genericType = null;
+ Object paramValue = null;
+ if (setter instanceof Method) {
+ type = Method.class.cast(setter).getParameterTypes()[0];
+ genericType = Method.class.cast(setter).getGenericParameterTypes()[0];
+ paramValue = InjectionUtils.extractFromMethod(bean, (Method) getter);
+ } else {
+ type = Field.class.cast(setter).getType();
+ genericType = Field.class.cast(setter).getGenericType();
+ paramValue = InjectionUtils.extractFieldValue((Field) getter, bean);
+ }
+
+ List<MultivaluedMap<String, String>> processedValuesList =
+ processValues(type, genericType, entry.getValue(), isbean);
+
+ for (MultivaluedMap<String, String> processedValues : processedValuesList) {
+ if (InjectionUtils.isSupportedCollectionOrArray(type)) {
+ Object appendValue = InjectionUtils.injectIntoCollectionOrArray(type,
+ genericType, processedValues,
+ isbean, true,
+ pType, message);
+ paramValue = InjectionUtils.mergeCollectionsOrArrays(paramValue, appendValue,
+ genericType);
+ } else if (isbean) {
+ paramValue = InjectionUtils.handleBean(type, processedValues,
+ pType, message);
+ } else {
+ paramValue = InjectionUtils.handleParameter(
+ processedValues.values().iterator().next().get(0),
+ type,
+ pType, message);
+ }
+
+ if (paramValue != null) {
+ if (setter instanceof Method) {
+ InjectionUtils.injectThroughMethod(bean, (Method) setter, paramValue);
+ } else {
+ InjectionUtils.injectFieldValue((Field) setter, bean, paramValue);
+ }
+ }
+ }
+ }
}
}
return bean;
}
-
- @SuppressWarnings("unchecked")
- public static Object injectIntoList(Type genericType, List<String> values,
- boolean decoded, ParameterType pathParam, Message message) {
- Class<?> realType = InjectionUtils.getActualType(genericType);
- values = checkPathSegment(values, realType, pathParam);
- List theValues = new ArrayList();
- for (String r : values) {
- String value = decodeValue(r, decoded, pathParam);
-
- Object o = InjectionUtils.handleParameter(value, realType, pathParam, message);
- if (o != null) {
- theValues.add(o);
+
+ private static List<MultivaluedMap<String, String>> processValues(Class<?> type, Type genericType,
+ MultivaluedMap<String, String> values,
+ boolean isbean) {
+ List<MultivaluedMap<String, String>> valuesList =
+ new ArrayList<MultivaluedMap<String, String>>();
+
+ if (isbean && InjectionUtils.isSupportedCollectionOrArray(type)) {
+ Class<?> realType = InjectionUtils.getActualType(genericType);
+ for (Map.Entry<String, List<String>> entry : values.entrySet()) {
+ String memberKey = entry.getKey();
+ Class<?> memberType = null;
+
+ for (Method m : realType.getMethods()) {
+ if (m.getName().equalsIgnoreCase("set" + memberKey)
+ && m.getParameterTypes().length == 1) {
+ memberType = m.getParameterTypes()[0];
+ break;
+ }
+ }
+ if (memberType == null) {
+ for (Field f : realType.getFields()) {
+ if (f.getName().equalsIgnoreCase(memberKey)) {
+ memberType = f.getType();
+ break;
+ }
+ }
+ }
+
+ // Strip values tied to collection/array fields from beans that are within
+ // collection/array themselves, the only way to support this would be to have
+ // an indexing syntax for nested beans, perhaps like this:
+ // a(0).b=1&a(0).b=2&a(1).b=3&a(1).b=4
+ // For now though we simply don't support this capability. To illustrate, the 'c'
+ // param is dropped from this multivaluedmap example since it is a list:
+ // {c=[71, 81, 91, 72, 82, 92], a=[C1, C2], b=[790, 791]}
+ if (memberType != null && InjectionUtils.isSupportedCollectionOrArray(memberType)) {
+ continue;
+ }
+
+ // Split multivaluedmap value list contents into separate multivaluedmap instances
+ // whose list contents are only 1 level deep, for example:
+ // {a=[C1, C2], b=[790, 791]}
+ // becomes these 2 separate multivaluedmap instances:
+ // {a=[C1], b=[790]} and {a=[C2], b=[791]}
+ int idx = 0;
+ for (String value : entry.getValue()) {
+ MultivaluedMap<String, String> splitValues =
+ (idx < valuesList.size()) ? valuesList.get(idx) : null;
+ if (splitValues == null) {
+ splitValues = new MetadataMap<String, String>();
+ valuesList.add(splitValues);
+ }
+ splitValues.add(memberKey, value);
+ idx++;
+ }
}
+ } else {
+ valuesList.add(values);
}
- return theValues;
+
+ return valuesList;
}
-
- public static Object injectIntoArray(Type genericType, List<String> values,
- boolean decoded, ParameterType pathParam, Message message) {
+
+ public static boolean isSupportedCollectionOrArray(Class<?> type) {
+ return List.class.isAssignableFrom(type)
+ || Set.class.isAssignableFrom(type)
+ || SortedSet.class.isAssignableFrom(type)
+ || type.isArray();
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Object mergeCollectionsOrArrays(Object first, Object second, Type genericType) {
+ if (first == null) {
+ return second;
+ } else if (first instanceof Collection) {
+ Collection.class.cast(first).addAll((Collection) second);
+ return first;
+ } else {
+ int firstLen = Array.getLength(first);
+ int secondLen = Array.getLength(second);
+ Object mergedArray = Array.newInstance(InjectionUtils.getActualType(genericType),
+ firstLen + secondLen);
+ System.arraycopy(first, 0, mergedArray, 0, firstLen);
+ System.arraycopy(second, 0, mergedArray, firstLen, secondLen);
+ return mergedArray;
+ }
+ }
+
+ private static Object injectIntoCollectionOrArray(Class<?> rawType, Type genericType,
+ MultivaluedMap<String, String> values,
+ boolean isbean, boolean decoded,
+ ParameterType pathParam, Message message) {
+ Class<?> type = null;
+ if (List.class.isAssignableFrom(rawType)) {
+ type = ArrayList.class;
+ } else if (Set.class.isAssignableFrom(rawType)) {
+ type = HashSet.class;
+ } else if (SortedSet.class.isAssignableFrom(rawType)) {
+ type = TreeSet.class;
+ }
+
Class<?> realType = InjectionUtils.getActualType(genericType);
- values = checkPathSegment(values, realType, pathParam);
- Object[] array = (Object[])Array.newInstance(realType, values.size());
- for (int i = 0; i < values.size(); i++) {
- String value = decodeValue(values.get(i), decoded, pathParam);
- Object o = InjectionUtils.handleParameter(value, realType, pathParam, message);
- if (o != null) {
- array[i] = o;
+
+ Object theValues = null;
+ if (type != null) {
+ try {
+ theValues = type.newInstance();
+ } catch (IllegalAccessException ex) {
+ reportServerError("CLASS_ACCESS_FAILURE", type.getName());
+ } catch (Exception ex) {
+ reportServerError("CLASS_INSTANTIATION_FAILURE", type.getName());
+ }
+ } else {
+ theValues = Array.newInstance(realType, isbean ? 1 : values.values().iterator().next().size());
+ }
+ if (isbean) {
+ Object o = InjectionUtils.handleBean(realType, values, pathParam, message);
+ addToCollectionValues(theValues, o, 0);
+ } else {
+ List<String> valuesList = values.values().iterator().next();
+ valuesList = checkPathSegment(valuesList, realType, pathParam);
+ for (int ind = 0; ind < valuesList.size(); ind++) {
+ String value = decodeValue(valuesList.get(ind), decoded, pathParam);
+ Object o = InjectionUtils.handleParameter(value, realType, pathParam, message);
+ addToCollectionValues(theValues, o, ind);
}
}
- return array;
+ return theValues;
}
-
@SuppressWarnings("unchecked")
- public static Object injectIntoSet(Type genericType, List<String> values,
- boolean sorted,
- boolean decoded,
- ParameterType pathParam, Message message) {
- Class<?> realType = InjectionUtils.getActualType(genericType);
-
- values = checkPathSegment(values, realType, pathParam);
-
- Set theValues = sorted ? new TreeSet() : new HashSet();
- for (String r : values) {
- String value = decodeValue(r, decoded, pathParam);
- Object o = InjectionUtils.handleParameter(value, realType, pathParam, message);
- if (o != null) {
- theValues.add(o);
+ private static void addToCollectionValues(Object theValues, Object o, int index) {
+ if (o != null) {
+ if (theValues instanceof Collection) {
+ Collection.class.cast(theValues).add(o);
+ } else {
+ ((Object[]) theValues)[index] = o;
}
}
- return theValues;
}
private static List<String> checkPathSegment(List<String> values, Class<?> type,
@@ -403,17 +596,11 @@
}
Object value = null;
- if (List.class.isAssignableFrom(paramType)) {
- value = InjectionUtils.injectIntoList(genericType, paramValues, decoded, pathParam,
- message);
- } else if (Set.class.isAssignableFrom(paramType)) {
- value = InjectionUtils.injectIntoSet(genericType, paramValues, false, decoded, pathParam,
- message);
- } else if (SortedSet.class.isAssignableFrom(paramType)) {
- value = InjectionUtils.injectIntoSet(genericType, paramValues, true, decoded, pathParam,
- message);
- } else if (paramType.isArray()) {
- value = InjectionUtils.injectIntoArray(genericType, paramValues, decoded, pathParam, message);
+ if (InjectionUtils.isSupportedCollectionOrArray(paramType)) {
+ MultivaluedMap<String, String> paramValuesMap = new MetadataMap<String, String>();
+ paramValuesMap.put("", paramValues);
+ value = InjectionUtils.injectIntoCollectionOrArray(paramType, genericType, paramValuesMap,
+ false, decoded, pathParam, message);
} else {
String result = null;
if (paramValues.size() > 0) {
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java?rev=763176&r1=763175&r2=763176&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java Wed Apr 8 10:54:54 2009
@@ -55,18 +55,35 @@
public static class CustomerBean {
private String a;
private Long b;
+ private List<String> c;
+ private CustomerBean d;
+ //CHECKSTYLE:OFF
+ public List<CustomerBean> e;
+ //CHECKSTYLE:ON
public void setA(String aString) {
this.a = aString;
}
public void setB(Long bLong) {
this.b = bLong;
}
+ public void setC(List<String> cStringList) {
+ this.c = cStringList;
+ }
+ public void setD(CustomerBean dCustomerBean) {
+ this.d = dCustomerBean;
+ }
public String getA() {
return a;
}
public Long getB() {
return b;
}
+ public List<String> getC() {
+ return c;
+ }
+ public CustomerBean getD() {
+ return d;
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java?rev=763176&r1=763175&r2=763176&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java Wed Apr 8 10:54:54 2009
@@ -630,37 +630,73 @@
Class[] argType = {Customer.CustomerBean.class};
Method m = Customer.class.getMethod("testQueryBean", argType);
MessageImpl messageImpl = new MessageImpl();
-
messageImpl.put(Message.QUERY_STRING, "a=aValue&b=123");
- List<Object> params = JAXRSUtils.processParameters(new OperationResourceInfo(m, null),
- null,
- messageImpl);
- assertEquals("Bean should be created", 1, params.size());
- Customer.CustomerBean cb = (Customer.CustomerBean)params.get(0);
- assertNotNull(cb);
-
- assertEquals("aValue", cb.getA());
- assertEquals(new Long(123), cb.getB());
+
+ MessageImpl complexMessageImpl = new MessageImpl();
+ complexMessageImpl.put(Message.QUERY_STRING, "c=1&a=A&b=123&c=2&c=3&"
+ + "d.c=4&d.a=B&d.b=456&d.c=5&d.c=6&"
+ + "e.c=41&e.a=B1&e.b=457&e.c=51&e.c=61&"
+ + "e.c=42&e.a=B2&e.b=458&e.c=52&e.c=62&"
+ + "d.d.c=7&d.d.a=C&d.d.b=789&d.d.c=8&d.d.c=9&"
+ + "d.e.c=71&d.e.a=C1&d.e.b=790&d.e.c=81&d.e.c=91&"
+ + "d.e.c=72&d.e.a=C2&d.e.b=791&d.e.c=82&d.e.c=92");
+
+ verifyParametersBean(m, null, messageImpl, null, complexMessageImpl);
}
@Test
public void testPathParametersBean() throws Exception {
Class[] argType = {Customer.CustomerBean.class};
Method m = Customer.class.getMethod("testPathBean", argType);
- MessageImpl messageImpl = new MessageImpl();
-
- MultivaluedMap<String, String> pathTamplates = new MetadataMap<String, String>();
- pathTamplates.add("a", "aValue");
- pathTamplates.add("b", "123");
- List<Object> params = JAXRSUtils.processParameters(new OperationResourceInfo(m, null),
- pathTamplates,
- messageImpl);
- assertEquals("Bean should be created", 1, params.size());
- Customer.CustomerBean cb = (Customer.CustomerBean)params.get(0);
- assertNotNull(cb);
- assertEquals("aValue", cb.getA());
- assertEquals(new Long(123), cb.getB());
+ MultivaluedMap<String, String> pathTemplates = new MetadataMap<String, String>();
+ pathTemplates.add("a", "aValue");
+ pathTemplates.add("b", "123");
+
+ MultivaluedMap<String, String> complexPathTemplates = new MetadataMap<String, String>();
+ complexPathTemplates.add("c", "1");
+ complexPathTemplates.add("a", "A");
+ complexPathTemplates.add("b", "123");
+ complexPathTemplates.add("c", "2");
+ complexPathTemplates.add("c", "3");
+
+ complexPathTemplates.add("d.c", "4");
+ complexPathTemplates.add("d.a", "B");
+ complexPathTemplates.add("d.b", "456");
+ complexPathTemplates.add("d.c", "5");
+ complexPathTemplates.add("d.c", "6");
+
+ complexPathTemplates.add("e.c", "41");
+ complexPathTemplates.add("e.a", "B1");
+ complexPathTemplates.add("e.b", "457");
+ complexPathTemplates.add("e.c", "51");
+ complexPathTemplates.add("e.c", "61");
+
+ complexPathTemplates.add("e.c", "42");
+ complexPathTemplates.add("e.a", "B2");
+ complexPathTemplates.add("e.b", "458");
+ complexPathTemplates.add("e.c", "52");
+ complexPathTemplates.add("e.c", "62");
+
+ complexPathTemplates.add("d.d.c", "7");
+ complexPathTemplates.add("d.d.a", "C");
+ complexPathTemplates.add("d.d.b", "789");
+ complexPathTemplates.add("d.d.c", "8");
+ complexPathTemplates.add("d.d.c", "9");
+
+ complexPathTemplates.add("d.e.c", "71");
+ complexPathTemplates.add("d.e.a", "C1");
+ complexPathTemplates.add("d.e.b", "790");
+ complexPathTemplates.add("d.e.c", "81");
+ complexPathTemplates.add("d.e.c", "91");
+
+ complexPathTemplates.add("d.e.c", "72");
+ complexPathTemplates.add("d.e.a", "C2");
+ complexPathTemplates.add("d.e.b", "791");
+ complexPathTemplates.add("d.e.c", "82");
+ complexPathTemplates.add("d.e.c", "92");
+
+ verifyParametersBean(m, pathTemplates, new MessageImpl(), complexPathTemplates, new MessageImpl());
}
@Test
@@ -669,15 +705,17 @@
Method m = Customer.class.getMethod("testMatrixBean", argType);
MessageImpl messageImpl = new MessageImpl();
messageImpl.put(Message.REQUEST_URI, "/bar;a=aValue/baz;b=123");
- List<Object> params = JAXRSUtils.processParameters(new OperationResourceInfo(m, null),
- new MetadataMap<String, String>(),
- messageImpl);
- assertEquals("Bean should be created", 1, params.size());
- Customer.CustomerBean cb = (Customer.CustomerBean)params.get(0);
- assertNotNull(cb);
-
- assertEquals("aValue", cb.getA());
- assertEquals(new Long(123), cb.getB());
+
+ MessageImpl complexMessageImpl = new MessageImpl();
+ complexMessageImpl.put(Message.REQUEST_URI, "/bar;c=1/bar;a=A/bar;b=123/bar;c=2/bar;c=3"
+ + "/bar;d.c=4/bar;d.a=B/bar;d.b=456/bar;d.c=5/bar;d.c=6"
+ + "/bar;e.c=41/bar;e.a=B1/bar;e.b=457/bar;e.c=51/bar;e.c=61"
+ + "/bar;e.c=42/bar;e.a=B2/bar;e.b=458/bar;e.c=52/bar;e.c=62"
+ + "/bar;d.d.c=7/bar;d.d.a=C/bar;d.d.b=789/bar;d.d.c=8/bar;d.d.c=9"
+ + "/bar;d.e.c=71/bar;d.e.a=C1/bar;d.e.b=790/bar;d.e.c=81/bar;d.e.c=91"
+ + "/bar;d.e.c=72/bar;d.e.a=C2/bar;d.e.b=791/bar;d.e.c=82/bar;d.e.c=92");
+
+ verifyParametersBean(m, null, messageImpl, null, complexMessageImpl);
}
@Test
@@ -688,15 +726,106 @@
messageImpl.put(Message.REQUEST_URI, "/bar");
String body = "a=aValue&b=123";
messageImpl.setContent(InputStream.class, new ByteArrayInputStream(body.getBytes()));
+
+ MessageImpl complexMessageImpl = new MessageImpl();
+ complexMessageImpl.put(Message.REQUEST_URI, "/bar");
+ body = "c=1&a=A&b=123&c=2&c=3&"
+ + "d.c=4&d.a=B&d.b=456&d.c=5&d.c=6&"
+ + "e.c=41&e.a=B1&e.b=457&e.c=51&e.c=61&"
+ + "e.c=42&e.a=B2&e.b=458&e.c=52&e.c=62&"
+ + "d.d.c=7&d.d.a=C&d.d.b=789&d.d.c=8&d.d.c=9&"
+ + "d.e.c=71&d.e.a=C1&d.e.b=790&d.e.c=81&d.e.c=91&"
+ + "d.e.c=72&d.e.a=C2&d.e.b=791&d.e.c=82&d.e.c=92";
+ complexMessageImpl.setContent(InputStream.class, new ByteArrayInputStream(body.getBytes()));
+
+ verifyParametersBean(m, null, messageImpl, null, complexMessageImpl);
+ }
+
+ private void verifyParametersBean(Method m,
+ MultivaluedMap<String, String> simpleValues,
+ MessageImpl simpleMessageImpl,
+ MultivaluedMap<String, String> complexValues,
+ MessageImpl complexMessageImpl) throws Exception {
List<Object> params = JAXRSUtils.processParameters(new OperationResourceInfo(m, null),
- new MetadataMap<String, String>(),
- messageImpl);
+ simpleValues,
+ simpleMessageImpl);
assertEquals("Bean should be created", 1, params.size());
Customer.CustomerBean cb = (Customer.CustomerBean)params.get(0);
assertNotNull(cb);
assertEquals("aValue", cb.getA());
assertEquals(new Long(123), cb.getB());
+
+ params = JAXRSUtils.processParameters(new OperationResourceInfo(m, null),
+ complexValues,
+ complexMessageImpl);
+ assertEquals("Bean should be created", 1, params.size());
+ Customer.CustomerBean cb1 = (Customer.CustomerBean)params.get(0);
+ assertNotNull(cb1);
+
+ assertEquals("A", cb1.getA());
+ assertEquals(new Long(123), cb1.getB());
+ List<String> list1 = (List<String>)cb1.getC();
+ assertEquals(3, list1.size());
+ assertEquals("1", list1.get(0));
+ assertEquals("2", list1.get(1));
+ assertEquals("3", list1.get(2));
+
+ Customer.CustomerBean cb2 = cb1.getD();
+ assertNotNull(cb2);
+
+ assertEquals("B", cb2.getA());
+ assertEquals(new Long(456), cb2.getB());
+ List<String> list2 = (List<String>)cb2.getC();
+ assertEquals(3, list2.size());
+ assertEquals("4", list2.get(0));
+ assertEquals("5", list2.get(1));
+ assertEquals("6", list2.get(2));
+
+ List<Customer.CustomerBean> cb2List = cb1.e;
+ assertEquals(2, cb2List.size());
+
+ int idx = 1;
+ for (Customer.CustomerBean cb2E : cb2List) {
+ assertNotNull(cb2E);
+
+ assertEquals("B" + idx, cb2E.getA());
+ assertEquals(new Long(456 + idx), cb2E.getB());
+ // ensure C was stripped properly since lists within lists are not supported
+ assertNull(cb2E.getC());
+ assertNull(cb2E.getD());
+ assertNull(cb2E.e);
+
+ idx++;
+ }
+
+ Customer.CustomerBean cb3 = cb2.getD();
+ assertNotNull(cb3);
+
+ assertEquals("C", cb3.getA());
+ assertEquals(new Long(789), cb3.getB());
+ List<String> list3 = (List<String>)cb3.getC();
+ assertEquals(3, list3.size());
+ assertEquals("7", list3.get(0));
+ assertEquals("8", list3.get(1));
+ assertEquals("9", list3.get(2));
+
+ List<Customer.CustomerBean> cb3List = cb2.e;
+ assertEquals(2, cb3List.size());
+
+ idx = 1;
+ for (Customer.CustomerBean cb3E : cb3List) {
+ assertNotNull(cb3E);
+
+ assertEquals("C" + idx, cb3E.getA());
+ assertEquals(new Long(789 + idx), cb3E.getB());
+ // ensure C was stripped properly since lists within lists are not supported
+ assertNull(cb3E.getC());
+ assertNull(cb3E.getD());
+ assertNull(cb3E.e);
+
+ idx++;
+ }
}
@Test