You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2022/02/05 20:25:44 UTC

[cxf] branch 3.5.x-fixes updated: CXF-8652: Implement @ConstrainedTo annotation support (#898)

This is an automated email from the ASF dual-hosted git repository.

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


The following commit(s) were added to refs/heads/3.5.x-fixes by this push:
     new 311648d  CXF-8652: Implement @ConstrainedTo annotation support (#898)
311648d is described below

commit 311648db04e017a9a738cad1111b910a58b63032
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Sat Feb 5 10:55:45 2022 -0500

    CXF-8652: Implement @ConstrainedTo annotation support (#898)
    
    (cherry picked from commit 4a5b28143dbd6db40951193bc2cadcbc1d6e4163)
---
 .../apache/cxf/jaxrs/provider/ProviderFactory.java | 20 +++++++++++++++-
 .../cxf/jaxrs/provider/ServerProviderFactory.java  |  7 +++++-
 .../cxf/jaxrs/provider/ProviderFactoryTest.java    | 28 ++++++++++++++++++++++
 .../cxf/jaxrs/client/ClientProviderFactory.java    |  9 ++++++-
 .../jaxrs/client/ClientProviderFactoryTest.java    | 25 +++++++++++++++++++
 .../client/MicroProfileClientProviderFactory.java  |  8 ++++++-
 6 files changed, 93 insertions(+), 4 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 878b1d7..2792025 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
@@ -39,7 +39,9 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.logging.Logger;
 
+import javax.ws.rs.ConstrainedTo;
 import javax.ws.rs.Produces;
+import javax.ws.rs.RuntimeType;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.Configuration;
 import javax.ws.rs.core.MediaType;
@@ -623,7 +625,7 @@ public abstract class ProviderFactory {
     protected abstract void setProviders(boolean custom, boolean busGlobal, Object... providers);
 
     @SuppressWarnings("unchecked")
-    protected void setCommonProviders(List<ProviderInfo<? extends Object>> theProviders) {
+    protected void setCommonProviders(List<ProviderInfo<? extends Object>> theProviders, RuntimeType type) {
         List<ProviderInfo<ReaderInterceptor>> readInts =
             new LinkedList<>();
         List<ProviderInfo<WriterInterceptor>> writeInts =
@@ -631,6 +633,11 @@ public abstract class ProviderFactory {
         for (ProviderInfo<? extends Object> provider : theProviders) {
             Class<?> providerCls = ClassHelper.getRealClass(bus, provider.getProvider());
 
+            // Check if provider is constrained to runtime type
+            if (!constraintedTo(providerCls, type)) {
+                continue;
+            }
+
             if (filterContractSupported(provider, providerCls, MessageBodyReader.class)) {
                 addProviderToList(messageReaders, provider);
             }
@@ -1526,4 +1533,15 @@ public abstract class ProviderFactory {
         writerInterceptors = sortedWriterInterceptors;
     }
 
+    /**
+     * Checks the presence of {@link ConstrainedTo} annotation and, if present, applicability to 
+     * the runtime type.
+     * @param providerCls provider class
+     * @param type runtime type
+     * @return "true" if provider could be used with runtime type, "false" otherwise
+     */
+    protected static boolean constraintedTo(Class<?> providerCls, RuntimeType type) {
+        final ConstrainedTo constrained = AnnotationUtils.getClassAnnotation(providerCls, ConstrainedTo.class);
+        return constrained == null || constrained.value() == type;
+    }
 }
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 9fde2c2..27af5a9 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
@@ -240,10 +240,15 @@ public final class ServerProviderFactory extends ProviderFactory {
 
         List<ProviderInfo<? extends Object>> theProviders =
             prepareProviders(custom, busGlobal, allProviders.toArray(), application);
-        super.setCommonProviders(theProviders);
+        super.setCommonProviders(theProviders, RuntimeType.SERVER);
         for (ProviderInfo<? extends Object> provider : theProviders) {
             Class<?> providerCls = ClassHelper.getRealClass(getBus(), provider.getProvider());
 
+            // Check if provider is constrained to server
+            if (!constraintedTo(providerCls, RuntimeType.SERVER)) {
+                continue;
+            }
+
             if (filterContractSupported(provider, providerCls, ContainerRequestFilter.class)) {
                 addContainerRequestFilter(postMatchRequestFilters,
                                           (ProviderInfo<ContainerRequestFilter>)provider);
diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
index 9557194..ca35fdc 100644
--- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
+++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
@@ -37,9 +37,11 @@ import java.util.Map;
 import javax.activation.DataHandler;
 import javax.activation.DataSource;
 import javax.annotation.Priority;
+import javax.ws.rs.ConstrainedTo;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Priorities;
 import javax.ws.rs.Produces;
+import javax.ws.rs.RuntimeType;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Feature;
 import javax.ws.rs.core.MediaType;
@@ -1526,6 +1528,32 @@ public class ProviderFactoryTest {
         Object mapperResponse4 = pf.createExceptionMapper(RuntimeExceptionBB.class, new MessageImpl());
         assertSame(runtimeExceptionBMapper, mapperResponse4);
     }
+
+    @Test
+    public void testProvidersWithConstraints() {
+        ProviderFactory pf = ServerProviderFactory.getInstance();
+        
+        @ConstrainedTo(RuntimeType.SERVER)
+        class ServerWildcardReader extends WildcardReader {
+            
+        }
+        
+        @ConstrainedTo(RuntimeType.CLIENT)
+        class ClientWildcardReader extends WildcardReader {
+            
+        }
+
+        final ServerWildcardReader reader = new ServerWildcardReader();
+        pf.registerUserProvider(reader);
+        
+        List<ProviderInfo<MessageBodyReader<?>>> readers = pf.getMessageReaders();
+        assertEquals(10, readers.size());
+        assertSame(reader, readers.get(7).getProvider());
+
+        pf.registerUserProvider(new ClientWildcardReader());
+        assertEquals(10, pf.getMessageReaders().size());
+    }
+
     private static class RuntimeExceptionA extends RuntimeException {
         private static final long serialVersionUID = 1L;
     }
diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java
index 521950a..52208fe 100644
--- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java
+++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import javax.ws.rs.RuntimeType;
 import javax.ws.rs.client.ClientRequestFilter;
 import javax.ws.rs.client.ClientResponseFilter;
 import javax.ws.rs.client.RxInvokerProvider;
@@ -70,13 +71,19 @@ public final class ClientProviderFactory extends ProviderFactory {
     protected void setProviders(boolean custom, boolean busGlobal, Object... providers) {
         List<ProviderInfo<? extends Object>> theProviders =
             prepareProviders(custom, busGlobal, providers, null);
-        super.setCommonProviders(theProviders);
+        super.setCommonProviders(theProviders, RuntimeType.CLIENT);
         for (ProviderInfo<? extends Object> provider : theProviders) {
             Class<?> providerCls = ClassHelper.getRealClass(getBus(), provider.getProvider());
             if (providerCls == Object.class) {
                 // If the provider is a lambda, ClassHelper.getRealClass returns Object.class
                 providerCls = provider.getProvider().getClass();
             }
+            
+            // Check if provider is constrained to client
+            if (!constraintedTo(providerCls, RuntimeType.CLIENT)) {
+                continue;
+            }
+            
             if (filterContractSupported(provider, providerCls, ClientRequestFilter.class)) {
                 addProviderToList(clientRequestFilters, provider);
             }
diff --git a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/ClientProviderFactoryTest.java b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/ClientProviderFactoryTest.java
index 2d4815a..c5a2ad5 100644
--- a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/ClientProviderFactoryTest.java
+++ b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/ClientProviderFactoryTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.cxf.jaxrs.client;
 
+import javax.ws.rs.ConstrainedTo;
+import javax.ws.rs.RuntimeType;
 import javax.ws.rs.ext.ParamConverter;
 import javax.ws.rs.ext.ParamConverterProvider;
 
@@ -48,4 +50,27 @@ public class ClientProviderFactoryTest {
         assertSame(h2, hp);
     }
 
+    @Test
+    public void testParameterHandlerProviderWithConstraints() throws Exception {
+        final Bus bus = new ExtensionManagerBus();
+        final ProviderFactory pf = ClientProviderFactory.createInstance(bus);
+
+        @ConstrainedTo(RuntimeType.SERVER)
+        class ServerParameterHandler extends CustomerParameterHandler {
+            // Server parameter handler
+        }
+
+        @ConstrainedTo(RuntimeType.CLIENT)
+        class ClientParameterHandler extends CustomerParameterHandler {
+            // Client parameter handler
+        }
+
+        ParamConverterProvider h = new ServerParameterHandler();
+        ParamConverterProvider hp = new ClientParameterHandler();
+        pf.registerUserProvider(h);
+        pf.registerUserProvider(hp);
+        ParamConverter<Customer> h2 = pf.createParameterHandler(Customer.class, Customer.class, null,
+                                                                new MessageImpl());
+        assertSame(h2, hp);
+    }
 }
diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientProviderFactory.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientProviderFactory.java
index c7a7ac7..f54c1ed 100644
--- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientProviderFactory.java
+++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientProviderFactory.java
@@ -26,6 +26,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
 
+import javax.ws.rs.RuntimeType;
 import javax.ws.rs.core.Configuration;
 
 import org.apache.cxf.Bus;
@@ -96,10 +97,15 @@ public final class MicroProfileClientProviderFactory extends ProviderFactory {
     protected void setProviders(boolean custom, boolean busGlobal, Object... providers) {
         List<ProviderInfo<?>> theProviders =
                 prepareProviders(custom, busGlobal, providers, null);
-        super.setCommonProviders(theProviders);
+        super.setCommonProviders(theProviders, RuntimeType.CLIENT);
         for (ProviderInfo<?> provider : theProviders) {
             Class<?> providerCls = ClassHelper.getRealClass(getBus(), provider.getProvider());
 
+            // Check if provider is constrained to client
+            if (!constraintedTo(providerCls, RuntimeType.CLIENT)) {
+                continue;
+            }
+
             if (ResponseExceptionMapper.class.isAssignableFrom(providerCls)) {
                 addProviderToList(responseExceptionMappers, provider);
             }