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 2013/07/25 19:37:14 UTC

svn commit: r1507071 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ systests/jaxrs/src/test/java/or...

Author: sergeyb
Date: Thu Jul 25 17:37:13 2013
New Revision: 1507071

URL: http://svn.apache.org/r1507071
Log:
[CXF-5135] Prototyping some initial support for Configurable/Configuration

Added:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java
      - copied, changed from r1506547, cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ConfigurableImpl.java
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java   (with props)
Removed:
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ConfigurableImpl.java
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java

Copied: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java (from r1506547, cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ConfigurableImpl.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java?p2=cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java&p1=cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ConfigurableImpl.java&r1=1506547&r2=1507071&rev=1507071&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ConfigurableImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java Thu Jul 25 17:37:13 2013
@@ -17,23 +17,37 @@
  * under the License.
  */
 
-package org.apache.cxf.jaxrs.client.spec;
+package org.apache.cxf.jaxrs.impl;
 
 import java.util.Map;
 
+import javax.ws.rs.Priorities;
+import javax.ws.rs.RuntimeType;
 import javax.ws.rs.core.Configurable;
 import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.Feature;
+import javax.ws.rs.core.FeatureContext;
 
-import org.apache.cxf.jaxrs.impl.ConfigurationImpl;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
 
 public class ConfigurableImpl<C extends Configurable<C>> implements Configurable<C> {
-    private Configuration config;
-    protected ConfigurableImpl() {
-        this(new ConfigurationImpl());
+    private ConfigurationImpl config;
+    private C configurable;
+    private Class<?>[] supportedProviderClasses;
+    public ConfigurableImpl(C configurable, RuntimeType rt, Class<?>[] supportedProviderClasses) {
+        this(configurable, rt, supportedProviderClasses, null);
     }
     
-    protected ConfigurableImpl(Configuration config) {
-        this.config = config;
+    public ConfigurableImpl(C configurable, RuntimeType rt, 
+                            Class<?>[] supportedProviderClasses, Configuration config) {
+        this.configurable = configurable;
+        this.config = config == null ? new ConfigurationImpl(rt) 
+            : new ConfigurationImpl(rt, config);
+        this.supportedProviderClasses = supportedProviderClasses;
+    }
+    
+    protected C getConfigurable() {
+        return configurable;
     }
     
     @Override
@@ -42,57 +56,141 @@ public class ConfigurableImpl<C extends 
     }
 
     @Override
-    public C property(String arg0, Object arg1) {
-        // TODO Auto-generated method stub
-        return null;
+    public C property(String name, Object value) {
+        config.setProperty(name, value);
+        return configurable;
     }
 
     @Override
-    public C register(Class<?> arg0) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Object provider) {
+        return register(provider, AnnotationUtils.getBindingPriority(provider.getClass()));
     }
 
     @Override
-    public C register(Object arg0) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Object provider, int bindingPriority) {
+        return doRegister(provider, bindingPriority, supportedProviderClasses);
     }
-
+    
     @Override
-    public C register(Class<?> arg0, int arg1) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Object provider, Class<?>... contracts) {
+        return doRegister(provider, Priorities.USER, contracts);
     }
-
+    
     @Override
-    public C register(Class<?> arg0, Class<?>... arg1) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Object provider, Map<Class<?>, Integer> contracts) {
+        for (Map.Entry<Class<?>, Integer> entry : contracts.entrySet()) {
+            doRegister(provider, entry.getValue(), entry.getKey());
+        }
+        return configurable;
     }
-
+    
     @Override
-    public C register(Class<?> arg0, Map<Class<?>, Integer> arg1) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Class<?> providerClass) {
+        return register(providerClass, AnnotationUtils.getBindingPriority(providerClass));
     }
 
     @Override
-    public C register(Object arg0, int arg1) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Class<?> providerClass, int bindingPriority) {
+        return doRegister(createProvider(providerClass), bindingPriority, supportedProviderClasses);
     }
 
     @Override
-    public C register(Object arg0, Class<?>... arg1) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Class<?> providerClass, Class<?>... contracts) {
+        return doRegister(providerClass, Priorities.USER, contracts);
     }
 
     @Override
-    public C register(Object arg0, Map<Class<?>, Integer> arg1) {
-        // TODO Auto-generated method stub
-        return null;
+    public C register(Class<?> providerClass, Map<Class<?>, Integer> contracts) {
+        return register(createProvider(providerClass), contracts);
+    }
+    
+    protected C doRegister(Object provider, int bindingPriority, Class<?>... contracts) {
+        if (provider instanceof Feature) {
+            Feature feature = (Feature)provider;
+            config.setFeature(feature);
+            feature.configure(new FeatureContextImpl(this));
+            return configurable;
+        }
+        for (Class<?> contract : contracts) {
+            if (contract.isAssignableFrom(provider.getClass())) {
+                config.register(provider, contract, bindingPriority);
+            }
+        }
+        return configurable;
+    }
+
+    private static Object createProvider(Class<?> cls) {
+        try {
+            return cls.newInstance();
+        } catch (Throwable ex) {
+            throw new RuntimeException(ex); 
+        }
+    }
+    
+    public static class FeatureContextImpl implements FeatureContext {
+        private Configurable<?> cfg;
+        public FeatureContextImpl(Configurable<?> cfg) {
+            this.cfg = cfg;
+        }
+        
+        @Override
+        public Configuration getConfiguration() {
+            return cfg.getConfiguration();
+        }
+
+        @Override
+        public FeatureContext property(String name, Object value) {
+            cfg.property(name, value);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Class<?> cls) {
+            cfg.register(cls);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Object obj) {
+            cfg.register(obj);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Class<?> cls, int priority) {
+            cfg.register(cls, priority);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Class<?> cls, Class<?>... contract) {
+            cfg.register(cls, contract);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Class<?> cls, Map<Class<?>, Integer> map) {
+            cfg.register(cls, map);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Object obj, int priority) {
+            cfg.register(obj, priority);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Object obj, Class<?>... contract) {
+            cfg.register(obj, contract);
+            return this;
+        }
+
+        @Override
+        public FeatureContext register(Object obj, Map<Class<?>, Integer> map) {
+            cfg.register(obj, map);
+            return this;
+        } 
+        
     }
-
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java?rev=1507071&r1=1507070&r2=1507071&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java Thu Jul 25 17:37:13 2013
@@ -19,6 +19,9 @@
 package org.apache.cxf.jaxrs.impl;
 
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -27,79 +30,113 @@ import javax.ws.rs.core.Configuration;
 import javax.ws.rs.core.Feature;
 
 public class ConfigurationImpl implements Configuration {
-
-    public ConfigurationImpl() {
-        
+    private Map<String, Object> props = new HashMap<String, Object>();
+    private RuntimeType runtimeType;
+    private Map<Object, Map<Class<?>, Integer>> providers = 
+        new HashMap<Object, Map<Class<?>, Integer>>(); 
+    private Set<Feature> features = new HashSet<Feature>();
+    
+    public ConfigurationImpl(RuntimeType rt) {
+        this.runtimeType = rt;
     }
     
-    public ConfigurationImpl(Configuration parent) {
-        
+    public ConfigurationImpl(RuntimeType rt, Configuration parent) {
+        props = parent.getProperties();
+        this.runtimeType = rt;
     }
     
     @Override
     public Set<Class<?>> getClasses() {
-        // TODO Auto-generated method stub
-        return null;
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+        for (Object o : getInstances()) {
+            classes.add(o.getClass());
+        }
+        return classes;
     }
 
     @Override
-    public Map<Class<?>, Integer> getContracts(Class<?> arg0) {
-        // TODO Auto-generated method stub
-        return null;
+    public Map<Class<?>, Integer> getContracts(Class<?> cls) {
+        for (Object o : getInstances()) {
+            if (cls.isAssignableFrom(o.getClass())) {
+                return Collections.unmodifiableMap(providers.get(o));
+            }
+        }
+        return Collections.emptyMap();
     }
 
     @Override
     public Set<Object> getInstances() {
-        // TODO Auto-generated method stub
-        return null;
+        return providers.keySet();
     }
 
     @Override
     public Map<String, Object> getProperties() {
-        // TODO Auto-generated method stub
-        return null;
+        return Collections.unmodifiableMap(props);
     }
 
     @Override
-    public Object getProperty(String arg0) {
-        // TODO Auto-generated method stub
-        return null;
+    public Object getProperty(String name) {
+        return props.get(name);
     }
 
     @Override
     public Collection<String> getPropertyNames() {
-        // TODO Auto-generated method stub
-        return null;
+        return props.keySet();
     }
 
     @Override
     public RuntimeType getRuntimeType() {
-        // TODO Auto-generated method stub
-        return null;
+        return runtimeType;
     }
 
     @Override
-    public boolean isEnabled(Feature arg0) {
-        // TODO Auto-generated method stub
-        return false;
+    public boolean isEnabled(Feature f) {
+        return features.contains(f);
     }
 
     @Override
-    public boolean isEnabled(Class<? extends Feature> arg0) {
-        // TODO Auto-generated method stub
+    public boolean isEnabled(Class<? extends Feature> f) {
+        for (Feature feature : features) {
+            if (feature.getClass().isAssignableFrom(f)) {
+                return true;
+            }
+        }
         return false;
     }
 
     @Override
-    public boolean isRegistered(Object arg0) {
-        // TODO Auto-generated method stub
-        return false;
+    public boolean isRegistered(Object obj) {
+        return providers.containsKey(obj);
     }
 
     @Override
-    public boolean isRegistered(Class<?> arg0) {
-        // TODO Auto-generated method stub
+    public boolean isRegistered(Class<?> cls) {
+        for (Object o : getInstances()) {
+            if (cls.isAssignableFrom(o.getClass())) {
+                return true;
+            }
+        }
         return false;
     }
 
+    public void setProperty(String name, Object value) {
+        if (name == null) {
+            props.remove(name);
+        } else {
+            props.put(name, value);
+        }
+    }
+    
+    public void setFeature(Feature f) {
+        features.add(f);
+    }
+    
+    public void register(Object provider, Class<?> contract, int bindingPriority) {
+        Map<Class<?>, Integer> metadata = providers.get(provider);
+        if (metadata == null) {
+            metadata = new HashMap<Class<?>, Integer>();
+            providers.put(provider, metadata);
+        }
+        metadata.put(contract, bindingPriority);
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java?rev=1507071&r1=1507070&r2=1507071&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java Thu Jul 25 17:37:13 2013
@@ -29,13 +29,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.ws.rs.Priorities;
 import javax.ws.rs.RuntimeType;
 import javax.ws.rs.container.ContainerRequestFilter;
 import javax.ws.rs.container.ContainerResponseFilter;
 import javax.ws.rs.container.DynamicFeature;
 import javax.ws.rs.container.PreMatching;
 import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Configurable;
 import javax.ws.rs.core.Configuration;
 import javax.ws.rs.core.Feature;
 import javax.ws.rs.core.FeatureContext;
@@ -47,6 +47,7 @@ import org.apache.cxf.Bus;
 import org.apache.cxf.BusFactory;
 import org.apache.cxf.common.util.ClassHelper;
 import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.jaxrs.impl.ConfigurableImpl;
 import org.apache.cxf.jaxrs.impl.RequestPreprocessor;
 import org.apache.cxf.jaxrs.impl.ResourceInfoImpl;
 import org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper;
@@ -60,7 +61,7 @@ import org.apache.cxf.message.Message;
 
 public final class ServerProviderFactory extends ProviderFactory {
     private static final String SHARED_SERVER_FACTORY = "jaxrs.shared.server.factory";
-    private static final Class<?>[] FILTER_INTERCEPTOR_CLASSES = 
+    private static final Class<?>[] SERVER_FILTER_INTERCEPTOR_CLASSES = 
         new Class<?>[] {ContainerRequestFilter.class,
                         ContainerResponseFilter.class,
                         ReaderInterceptor.class,
@@ -335,7 +336,7 @@ public final class ServerProviderFactory
         Set<OperationResourceInfo> oris = cri.getMethodDispatcher().getOperationResourceInfos();
         for (OperationResourceInfo ori : oris) {
             for (DynamicFeature feature : dynamicFeatures) {
-                FeatureContext methodConfigurable = new MethodConfigurable(ori);
+                FeatureContext methodConfigurable = new MethodFeatureContextImpl(ori);
                 feature.configure(new ResourceInfoImpl(ori), methodConfigurable);
             }
         }
@@ -353,14 +354,15 @@ public final class ServerProviderFactory
     
     
     
-    private class MethodConfigurable implements FeatureContext, Configuration {
-        
+    private class MethodFeatureContextImpl implements FeatureContext {
+        private Configurable<FeatureContext> configImpl;    
         private OperationResourceInfo ori;
         private String nameBinding;
         private boolean bindingSet;
         
-        public MethodConfigurable(OperationResourceInfo ori) {
+        public MethodFeatureContextImpl(OperationResourceInfo ori) {
             this.ori = ori;
+            configImpl = new MethodFeatureContextConfigurable(this);
             nameBinding = DEFAULT_FILTER_NAME_BINDING 
                 + ori.getClassResourceInfo().getServiceClass().getName()
                 + "."
@@ -370,59 +372,55 @@ public final class ServerProviderFactory
 
         @Override
         public Configuration getConfiguration() {
-            return this;
+            return configImpl.getConfiguration();
         }
         
         @Override
-        public FeatureContext register(Object provider) {
-            return register(provider, AnnotationUtils.getBindingPriority(provider.getClass()));
+        public FeatureContext property(String name, Object value) {
+            return configImpl.property(name, value);
         }
 
         @Override
-        public FeatureContext register(Object provider, int bindingPriority) {
-            return doRegister(provider, bindingPriority, FILTER_INTERCEPTOR_CLASSES);
+        public FeatureContext register(Class<?> cls) {
+            return configImpl.register(cls);
         }
-        
+
         @Override
-        public FeatureContext register(Object provider, Class<?>... contracts) {
-            return doRegister(provider, Priorities.USER, contracts);
+        public FeatureContext register(Object object) {
+            return configImpl.register(object);
         }
-        
-        
+
         @Override
-        public FeatureContext register(Object provider, Map<Class<?>, Integer> contracts) {
-            for (Map.Entry<Class<?>, Integer> entry : contracts.entrySet()) {
-                doRegister(provider, entry.getValue(), entry.getKey());
-            }
-            return this;
+        public FeatureContext register(Class<?> cls, int index) {
+            return configImpl.register(cls, index);
         }
-        
+
         @Override
-        public FeatureContext register(Class<?> providerClass) {
-            return register(providerClass, AnnotationUtils.getBindingPriority(providerClass));
+        public FeatureContext register(Class<?> cls, Class<?>... contracts) {
+            return configImpl.register(cls, contracts);
         }
 
         @Override
-        public FeatureContext register(Class<?> providerClass, int bindingPriority) {
-            return doRegister(createProvider(providerClass), bindingPriority, 
-                              FILTER_INTERCEPTOR_CLASSES);
+        public FeatureContext register(Class<?> cls, Map<Class<?>, Integer> map) {
+            return configImpl.register(cls, map);
         }
 
         @Override
-        public FeatureContext register(Class<?> providerClass, Class<?>... contracts) {
-            return doRegister(providerClass, Priorities.USER, contracts);
+        public FeatureContext register(Object object, int index) {
+            return configImpl.register(object, index);
         }
 
         @Override
-        public FeatureContext register(Class<?> providerClass, Map<Class<?>, Integer> contracts) {
-            Object provider = createProvider(providerClass);
-            for (Map.Entry<Class<?>, Integer> entry : contracts.entrySet()) {
-                doRegister(provider, entry.getValue(), entry.getKey());
-            }
-            return this;
+        public FeatureContext register(Object object, Class<?>... contracts) {
+            return configImpl.register(object, contracts);
+        }
+
+        @Override
+        public FeatureContext register(Object object, Map<Class<?>, Integer> map) {
+            return configImpl.register(object, map);
         }
         
-        private FeatureContext doRegister(Object provider, int bindingPriority, Class<?>... contracts) {
+        FeatureContext doRegister(Object provider, int bindingPriority, Class<?>... contracts) {
         
             if (provider instanceof Feature) {
                 ((Feature)provider).configure(this);
@@ -541,81 +539,19 @@ public final class ServerProviderFactory
             }
         }
         
-        @Override
-        public Set<Class<?>> getClasses() {
-            // TODO Auto-generated method stub
-            return null;
-        }
         
-        @Override
-        public Map<Class<?>, Integer> getContracts(Class<?> componentClass) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Set<Object> getInstances() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Map<String, Object> getProperties() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public boolean isEnabled(Feature feature) {
-            return false;
-        }
-        
-        @Override
-        public boolean isEnabled(Class<? extends Feature> featureClass) {
-            return false;
-        }
-        
-        @Override
-        public RuntimeType getRuntimeType() {
-            return null;
-        }
-        
-        @Override
-        public Object getProperty(String name) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-        
-        @Override
-        public Collection<String> getPropertyNames() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public boolean isRegistered(Class<?> componentClass) {
-            return false;
+    }
+    private static class MethodFeatureContextConfigurable extends ConfigurableImpl<FeatureContext> {
+        protected MethodFeatureContextConfigurable(MethodFeatureContextImpl mc) {
+            super(mc, RuntimeType.SERVER, SERVER_FILTER_INTERCEPTOR_CLASSES);
         }
-        
         @Override
-        public boolean isRegistered(Object component) {
-            return false;
+        protected FeatureContext doRegister(Object provider, int bindingPriority, Class<?>... contracts) {
+            super.doRegister(provider, bindingPriority, contracts);
+            return ((MethodFeatureContextImpl)super.getConfigurable())
+                .doRegister(provider, bindingPriority, contracts);
         }
         
-        private Object createProvider(Class<?> cls) {
-            try {
-                return cls.newInstance();
-            } catch (Throwable ex) {
-                throw new RuntimeException(ex); 
-            }
-        }
-
-        @Override
-        public FeatureContext property(String arg0, Object arg1) {
-            // TODO Auto-generated method stub
-            return null;
-        }
     }
     
-    
 }

Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java?rev=1507071&r1=1507070&r2=1507071&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java Thu Jul 25 17:37:13 2013
@@ -25,15 +25,16 @@ import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.Configurable;
 import javax.ws.rs.core.Configuration;
 
 public class ClientBuilderImpl extends ClientBuilder {
 
-    private ConfigurableImpl<ClientBuilder> configImpl = new ConfigurableImpl<ClientBuilder>();
+    private Configurable<ClientBuilder> configImpl;
     private TLSConfiguration secConfig = new TLSConfiguration();
     
     public ClientBuilderImpl() {
-        System.out.println();    
+        configImpl = new ClientConfigurableImpl<ClientBuilder>(this);
     }
     
     @Override
@@ -106,7 +107,7 @@ public class ClientBuilderImpl extends C
     @Override
     public ClientBuilder keyStore(KeyStore store, char[] password) {
         // TODO Auto-generated method stub
-        return null;
+        return this;
     }
     
     @Override
@@ -117,7 +118,7 @@ public class ClientBuilderImpl extends C
 
     @Override
     public ClientBuilder withConfig(Configuration cfg) {
-        configImpl = new ConfigurableImpl<ClientBuilder>(cfg);
+        configImpl = new ClientConfigurableImpl<ClientBuilder>(this, cfg);
         return this;
     }
 

Added: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java?rev=1507071&view=auto
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java (added)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java Thu Jul 25 17:37:13 2013
@@ -0,0 +1,51 @@
+/**
+ * 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.client.spec;
+
+import javax.ws.rs.RuntimeType;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.core.Configurable;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.ReaderInterceptor;
+import javax.ws.rs.ext.WriterInterceptor;
+
+import org.apache.cxf.jaxrs.impl.ConfigurableImpl;
+
+public class ClientConfigurableImpl<C extends Configurable<C>> extends ConfigurableImpl<C> {
+    private static final Class<?>[] CLIENT_FILTER_INTERCEPTOR_CLASSES = 
+        new Class<?>[] {ClientRequestFilter.class,
+                        ClientResponseFilter.class,
+                        MessageBodyReader.class,
+                        MessageBodyWriter.class,
+                        ReaderInterceptor.class,
+                        WriterInterceptor.class};
+    
+    
+    public ClientConfigurableImpl(C configurable) {
+        this(configurable, null);
+    }
+    
+    public ClientConfigurableImpl(C configurable, Configuration config) {
+        super(configurable, RuntimeType.CLIENT, CLIENT_FILTER_INTERCEPTOR_CLASSES, config);
+    }
+}

Propchange: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java?rev=1507071&r1=1507070&r2=1507071&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java Thu Jul 25 17:37:13 2013
@@ -19,13 +19,16 @@
 package org.apache.cxf.jaxrs.client.spec;
 
 import java.net.URI;
+import java.util.LinkedList;
 import java.util.Map;
+import java.util.UUID;
 
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.Invocation.Builder;
 import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Configurable;
 import javax.ws.rs.core.Configuration;
 import javax.ws.rs.core.Link;
 import javax.ws.rs.core.MediaType;
@@ -34,13 +37,14 @@ import javax.ws.rs.core.UriBuilder;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.client.WebClient;
 
-public class ClientImpl extends ConfigurableImpl<Client> implements Client {
+public class ClientImpl implements Client {
+    private Configurable<Client> configImpl;
     private TLSConfiguration secConfig;
     private boolean closed;
     private WebClient template;
     public ClientImpl(Configuration config,
                       TLSConfiguration secConfig) {
-        super(config);
+        configImpl = new ClientConfigurableImpl<Client>(this, config);
         this.secConfig = secConfig;
     }
     
@@ -73,9 +77,18 @@ public class ClientImpl extends Configur
         // This is done to make the creation of individual targets really easy
         if (template == null) {
             JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
-            bean.setAddress("http://tempuri");
-            // handle Configuration providers
+            // To make sure that each Client has its own set of JAX-RS providers
+            // We may end up having CXF AbstractClient specific ClientProviderFactory
+            // if even WebTargets will be allowed to have its own specific providers
+            
+            bean.setAddress("http://tempuri/" + UUID.randomUUID().toString());
+            
+            Configuration cfg = getConfiguration();
+            bean.setProperties(cfg.getProperties());
+            bean.setProviders(new LinkedList<Object>(cfg.getInstances()));
+            
             this.template = bean.createWebClient();
+            WebClient.getConfig(template).getConduit();
         }
     }
     
@@ -112,15 +125,66 @@ public class ClientImpl extends Configur
             throw new IllegalStateException();
         }
     }
+
+    @Override
+    public Configuration getConfiguration() {
+        return configImpl.getConfiguration();
+    }
+
+    @Override
+    public Client property(String name, Object value) {
+        return configImpl.property(name, value);
+    }
+
+    @Override
+    public Client register(Class<?> cls) {
+        return configImpl.register(cls);
+    }
+
+    @Override
+    public Client register(Object object) {
+        return configImpl.register(object);
+    }
+
+    @Override
+    public Client register(Class<?> cls, int index) {
+        return configImpl.register(cls, index);
+    }
+
+    @Override
+    public Client register(Class<?> cls, Class<?>... contracts) {
+        return configImpl.register(cls, contracts);
+    }
+
+    @Override
+    public Client register(Class<?> cls, Map<Class<?>, Integer> map) {
+        return configImpl.register(cls, map);
+    }
+
+    @Override
+    public Client register(Object object, int index) {
+        return configImpl.register(object, index);
+    }
+
+    @Override
+    public Client register(Object object, Class<?>... contracts) {
+        return configImpl.register(object, contracts);
+    }
+
+    @Override
+    public Client register(Object object, Map<Class<?>, Integer> map) {
+        return configImpl.register(object, map);
+    }
     
-    class WebTargetImpl extends ConfigurableImpl<WebTarget> implements WebTarget {
+    class WebTargetImpl implements WebTarget {
+        private Configurable<WebTarget> configImpl;
         private UriBuilder uriBuilder;
         private WebClient template; 
         
         public WebTargetImpl(UriBuilder uriBuilder, 
                               Configuration config, 
                               WebClient template) {
-            super(config);
+            configImpl = new ClientConfigurableImpl<WebTarget>(this, config);
             this.uriBuilder = uriBuilder.clone();
             this.template = template;
         }
@@ -129,6 +193,10 @@ public class ClientImpl extends Configur
         public Builder request() {
             checkClosed();
             WebClient wc = WebClient.fromClient(template).to(uriBuilder.build().toString(), false);
+            WebClient.getConfig(wc).getRequestContext().putAll(
+                configImpl.getConfiguration().getProperties());
+            // Can WebTarget have its own specific providers ?
+            
             return new InvocationBuilderImpl(wc);
         }
 
@@ -210,5 +278,55 @@ public class ClientImpl extends Configur
         private WebTarget newWebTarget(UriBuilder newBuilder) {
             return new WebTargetImpl(newBuilder, getConfiguration(), template);
         }
+        
+        @Override
+        public Configuration getConfiguration() {
+            return configImpl.getConfiguration();
+        }
+
+        @Override
+        public WebTarget property(String name, Object value) {
+            return configImpl.property(name, value);
+        }
+
+        @Override
+        public WebTarget register(Class<?> cls) {
+            return configImpl.register(cls);
+        }
+
+        @Override
+        public WebTarget register(Object object) {
+            return configImpl.register(object);
+        }
+
+        @Override
+        public WebTarget register(Class<?> cls, int index) {
+            return configImpl.register(cls, index);
+        }
+
+        @Override
+        public WebTarget register(Class<?> cls, Class<?>... contracts) {
+            return configImpl.register(cls, contracts);
+        }
+
+        @Override
+        public WebTarget register(Class<?> cls, Map<Class<?>, Integer> map) {
+            return configImpl.register(cls, map);
+        }
+
+        @Override
+        public WebTarget register(Object object, int index) {
+            return configImpl.register(object, index);
+        }
+
+        @Override
+        public WebTarget register(Object object, Class<?>... contracts) {
+            return configImpl.register(object, contracts);
+        }
+
+        @Override
+        public WebTarget register(Object object, Map<Class<?>, Integer> map) {
+            return configImpl.register(object, map);
+        }
     }
 }

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java?rev=1507071&r1=1507070&r2=1507071&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java Thu Jul 25 17:37:13 2013
@@ -20,6 +20,9 @@
 package org.apache.cxf.systest.jaxrs;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -27,6 +30,7 @@ import java.util.concurrent.ExecutionExc
 import java.util.concurrent.Future;
 
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.client.ClientRequestContext;
 import javax.ws.rs.client.ClientRequestFilter;
@@ -38,7 +42,9 @@ import javax.ws.rs.core.GenericEntity;
 import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.ReaderInterceptor;
 import javax.ws.rs.ext.ReaderInterceptorContext;
 import javax.ws.rs.ext.WriterInterceptor;
@@ -46,6 +52,8 @@ import javax.ws.rs.ext.WriterInterceptor
 import javax.xml.ws.Holder;
 
 import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.systest.jaxrs.BookStore.BookInfo;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 
 import org.junit.BeforeClass;
@@ -112,6 +120,16 @@ public class JAXRS20ClientServerBookTest
     }
     
     @Test
+    public void testGetBookSpecProvider() {
+        String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple";
+        Client client = ClientBuilder.newClient();
+        client.register(new BookInfoReader());
+        BookInfo book = client.target(address)
+            .request("application/xml").get(BookInfo.class);
+        assertEquals(124L, book.getId());
+    }
+    
+    @Test
     public void testGetBookSyncWithAsync() {
         String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple";
         doTestGetBook(address, true);
@@ -562,4 +580,21 @@ public class JAXRS20ClientServerBookTest
         }
         
     }
+    
+    private static class BookInfoReader implements MessageBodyReader<BookInfo> {
+
+        @Override
+        public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) {
+            return true;
+        }
+
+        @Override
+        public BookInfo readFrom(Class<BookInfo> arg0, Type arg1, Annotation[] anns, MediaType mt,
+                                 MultivaluedMap<String, String> headers, InputStream is) throws IOException,
+            WebApplicationException {
+            Book book = new JAXBElementProvider<Book>().readFrom(Book.class, Book.class, anns, mt, headers, is);
+            return new BookInfo(book);
+        }
+        
+    }
 }