Repository: cxf Updated Branches: refs/heads/master d7cb53720 -> 190b89b86
Fixed CXF-5722: JAXB generated Enum throws IllegalArgumentException by unmarshalling as @QueryParam Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/190b89b8 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/190b89b8 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/190b89b8 Branch: refs/heads/master Commit: 190b89b8630ca5f630c6af377f83db39e2cb1273 Parents: d7cb537 Author: Andrei Shakirin <[email protected]> Authored: Thu May 1 12:03:35 2014 +0200 Committer: Andrei Shakirin <[email protected]> Committed: Thu May 1 12:03:35 2014 +0200 ---------------------------------------------------------------------- .../apache/cxf/jaxrs/utils/InjectionUtils.java | 55 +++++++++++++------- .../cxf/jaxrs/utils/InjectionUtilsTest.java | 35 ++++++++++++- 2 files changed, 71 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/190b89b8/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java index 2a3114c..0a7b11b 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java @@ -408,12 +408,7 @@ public final class InjectionUtils { String[] methodNames = cls.isEnum() ? new String[] {"fromString", "fromValue", "valueOf"} : new String[] {"valueOf", "fromString"}; - for (String mName : methodNames) { - result = evaluateFactoryMethod(value, cls, pType, mName); - if (result != null) { - break; - } - } + result = evaluateFactoryMethods(value, pType, result, cls, methodNames); } if (adapterHasToBeUsed) { @@ -433,7 +428,6 @@ public final class InjectionUtils { return pClass.cast(result); } - private static <T> T createFromParameterHandler(String value, Class<T> pClass, Annotation[] anns, @@ -466,25 +460,50 @@ public final class InjectionUtils { .entity(errorMessage.toString()).build(); throw ExceptionUtils.toInternalServerErrorException(null, r); } - + + private static Object evaluateFactoryMethods(String value, ParameterType pType, Object result, + Class<?> cls, String[] methodNames) { + Exception factoryMethodEx = null; + for (String mName : methodNames) { + try { + result = evaluateFactoryMethod(value, cls, pType, mName); + if (result != null) { + break; + } + } catch (Exception ex) { + // Don't throw exception immediately, but store it and try other factory methods + factoryMethodEx = ex; + } + } + if ((factoryMethodEx != null) && (result == null)) { + Throwable t = getOrThrowActualException(factoryMethodEx); + LOG.severe(new org.apache.cxf.common.i18n.Message("CLASS_VALUE_OF_FAILURE", + BUNDLE, + cls.getName()).toString()); + throw new WebApplicationException(t, HttpUtils.getParameterFailureStatus(pType)); + } else { + return result; + } + } + private static <T> T evaluateFactoryMethod(String value, - Class<T> pClass, - ParameterType pType, - String methodName) { + Class<T> pClass, + ParameterType pType, + String methodName) + throws InvocationTargetException { try { Method m = pClass.getMethod(methodName, new Class<?>[]{String.class}); if (Modifier.isStatic(m.getModifiers())) { return pClass.cast(m.invoke(null, new Object[]{value})); } } catch (NoSuchMethodException ex) { - // no luck - } catch (Exception ex) { - Throwable t = getOrThrowActualException(ex); - LOG.severe(new org.apache.cxf.common.i18n.Message("CLASS_VALUE_OF_FAILURE", - BUNDLE, - pClass.getName()).toString()); - throw new WebApplicationException(t, HttpUtils.getParameterFailureStatus(pType)); + // no luck: try another factory methods + } catch (IllegalAccessException ex) { + // factory method is not accessible: try another + } catch (IllegalArgumentException ex) { + // String argument doesn't fit to factory method: try another } + return null; } http://git-wip-us.apache.org/repos/asf/cxf/blob/190b89b8/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java index 6bdf145..3ee89bf 100644 --- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java +++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java @@ -42,7 +42,6 @@ import org.apache.cxf.message.ExchangeImpl; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageImpl; import org.easymock.EasyMock; - import org.junit.Assert; import org.junit.Test; @@ -137,6 +136,13 @@ public class InjectionUtilsTest extends Assert { assertTrue(map.get("d.s").contains("set2")); } + @Test + public void testInstantiateJAXBEnum() { + CarType carType = InjectionUtils.handleParameter("AUDI", false, CarType.class, null, + ParameterType.QUERY, null); + assertEquals("Type is wrong", CarType.AUDI, carType); + } + static class CustomerBean1 { private String a; private Long b; @@ -270,4 +276,31 @@ public class InjectionUtilsTest extends Assert { } } + + public static enum CarType { + + AUDI("Audi"), + GOLF("Golf"), + BMW("BMW"); + private final String value; + + CarType(String v) { + value = v; + } + + public String value() { + return value; + } + + public static CarType fromValue(String v) { + for (CarType c: CarType.values()) { + if (c.value.equals(v)) { + return c; + } + } + throw new IllegalArgumentException(v); + } + + } + }
