cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject [cxf] branch 3.1.x-fixes updated: [CXF-7473] Workawround to avoid picking up wrong ExceptionMappers
Date Thu, 01 Feb 2018 13:23:16 GMT
This is an automated email from the ASF dual-hosted git repository.

sergeyb pushed a commit to branch 3.1.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/3.1.x-fixes by this push:
     new 070f214  [CXF-7473] Workawround to avoid picking up wrong ExceptionMappers
070f214 is described below

commit 070f214efd5bee3e3c4dee9f434da93c7b1eff0b
Author: Sergey Beryozkin <sberyozkin@gmail.com>
AuthorDate: Thu Feb 1 13:01:58 2018 +0000

    [CXF-7473] Workawround to avoid picking up wrong ExceptionMappers
---
 .../apache/cxf/jaxrs/provider/ProviderFactory.java |  26 +++++-
 .../cxf/jaxrs/provider/ServerProviderFactory.java  |   2 +-
 ...iderFactoryHierarchicalExceptionMapperTest.java | 104 +++++++++++++++++++++
 3 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
index a038f84..e1cc66c 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
@@ -291,13 +291,22 @@ public abstract class ProviderFactory {
                                        Message m, 
                                        Class<?> providerClass,
                                        boolean injectContext) {
-        
+        return handleMapper(em, expectedType, m, providerClass, null, injectContext);
+    }
+    
+    protected <T> boolean handleMapper(ProviderInfo<T> em,
+                                       Class<?> expectedType,
+                                       Message m,
+                                       Class<?> providerClass,
+                                       Class<?> commonBaseClass,
+                                       boolean injectContext) {
+
         Class<?> mapperClass = ClassHelper.getRealClass(bus, em.getProvider());
         Type[] types = null;
         if (m != null && MessageUtils.isTrue(m.getContextualProperty(IGNORE_TYPE_VARIABLES)))
{
             types = new Type[]{mapperClass};
         } else {
-            types = getGenericInterfaces(mapperClass, expectedType);
+            types = getGenericInterfaces(mapperClass, expectedType, commonBaseClass);
         }
         for (Type t : types) {
             if (t instanceof ParameterizedType) {
@@ -1045,6 +1054,10 @@ public abstract class ProviderFactory {
     }
     
     private static Type[] getGenericInterfaces(Class<?> cls, Class<?> expectedClass)
{
+        return getGenericInterfaces(cls, expectedClass, Object.class);
+    }
+    private static Type[] getGenericInterfaces(Class<?> cls, Class<?> expectedClass,
+                                               Class<?> commonBaseCls) {
         if (Object.class == cls) {
             return new Type[]{};
         }
@@ -1054,8 +1067,11 @@ public abstract class ProviderFactory {
                 Class<?> actualType = InjectionUtils.getActualType(genericSuperType);
                 if (actualType != null && actualType.isAssignableFrom(expectedClass))
{
                     return new Type[]{genericSuperType};
-                } else if (expectedClass.isAssignableFrom(actualType)) {
-                    return new Type[]{};    
+                } else if (commonBaseCls != null && commonBaseCls != Object.class

+                           && commonBaseCls.isAssignableFrom(expectedClass)
+                           && commonBaseCls.isAssignableFrom(actualType)
+                           || expectedClass.isAssignableFrom(actualType)) {
+                    return new Type[]{};
                 }
             }
         }
@@ -1063,7 +1079,7 @@ public abstract class ProviderFactory {
         if (types.length > 0) {
             return types;
         }
-        return getGenericInterfaces(cls.getSuperclass(), expectedClass);
+        return getGenericInterfaces(cls.getSuperclass(), expectedClass, commonBaseCls);
     }
     
     protected static class AbstractPriorityComparator {
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
index bb57122a..b850d0b 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
@@ -183,7 +183,7 @@ public final class ServerProviderFactory extends ProviderFactory {
                                                                           Message m) {
         List<ProviderInfo<ExceptionMapper<?>>> candidates = new LinkedList<ProviderInfo<ExceptionMapper<?>>>();
         for (ProviderInfo<ExceptionMapper<?>> em : exceptionMappers) {
-            if (handleMapper(em, exceptionType, m, ExceptionMapper.class, true)) {
+            if (handleMapper(em, exceptionType, m, ExceptionMapper.class, Throwable.class,
true)) {
                 candidates.add(em);
             }
         }
diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryHierarchicalExceptionMapperTest.java
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryHierarchicalExceptionMapperTest.java
new file mode 100644
index 0000000..13850ea
--- /dev/null
+++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryHierarchicalExceptionMapperTest.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.jaxrs.provider;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+
+import org.apache.cxf.message.MessageImpl;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Testcase for CXF-7473
+ */
+public class ProviderFactoryHierarchicalExceptionMapperTest {
+    private ServerProviderFactory pf;
+
+    @Before
+    public void setUp() throws Exception {
+        pf = ServerProviderFactory.getInstance();
+        pf.registerUserProvider(new IllegalArgumentExceptionMapper());
+        pf.registerUserProvider(new IllegalStateExceptionMapper());
+    }
+
+    @Test
+    public void testExceptionMapperInHierarchy() {
+        ExceptionMapper<?> exceptionMapper = pf.createExceptionMapper(IllegalArgumentException.class,
+                new MessageImpl());
+        Assert.assertNotNull(exceptionMapper);
+        Assert.assertEquals("Wrong mapper found for IllegalArgumentException",
+                IllegalArgumentExceptionMapper.class, exceptionMapper.getClass());
+    }
+
+    @Test
+    public void testSimpleExceptionMapperWhenHierarchyPresent() {
+        ExceptionMapper<?> exceptionMapper = pf.createExceptionMapper(IllegalStateException.class,
+                new MessageImpl());
+        Assert.assertNotNull(exceptionMapper);
+        Assert.assertEquals("Wrong mapper found for IllegalStateException",
+                IllegalStateExceptionMapper.class, exceptionMapper.getClass());
+    }
+
+    @Test
+    public void testNoMatch() {
+        ExceptionMapper<?> exceptionMapper = pf.createExceptionMapper(UnmappedRuntimeException.class,
+                new MessageImpl());
+        Assert.assertNull(exceptionMapper);
+    }
+
+    public abstract class AbstractExceptionMapper<E extends Throwable> implements ExceptionMapper<E>
{
+        @Override
+        public Response toResponse(E exception) {
+            return toResponse0(exception);
+        }
+
+        protected abstract Response toResponse0(E exception);
+    }
+
+    public class IllegalArgumentExceptionMapper extends AbstractExceptionMapper<IllegalArgumentException>
{
+        @Override
+        protected Response toResponse0(IllegalArgumentException exception) {
+            return Response
+                    .serverError()
+                    .entity("Processed by IllegalArgumentExceptionMapper: " + exception.getMessage())
+                    .build();
+        }
+    }
+
+    public class IllegalStateExceptionMapper implements ExceptionMapper<IllegalStateException>
{
+        @Override
+        public Response toResponse(IllegalStateException exception) {
+            return Response
+                    .serverError()
+                    .entity("Processed by IllegalStateExceptionMapper: " + exception.getMessage())
+                    .build();
+        }
+    }
+
+    public class UnmappedRuntimeException extends RuntimeException {
+        private static final long serialVersionUID = 1L;
+
+        public UnmappedRuntimeException(String message) {
+            super(message);
+        }
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
sergeyb@apache.org.

Mime
View raw message