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/02/23 17:31:21 UTC

svn commit: r747070 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/ rt/frontend/jaxrs/src/main/resources/sc...

Author: sergeyb
Date: Mon Feb 23 16:31:18 2009
New Revision: 747070

URL: http://svn.apache.org/viewvc?rev=747070&view=rev
Log:
JAXRS : introducing jaxrs:client bean definition, tightening WebClient interface

Added:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSClientFactoryBeanDefinitionParser.java   (with props)
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactory.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/NamespaceHandler.java
    cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java
    cxf/trunk/systests/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java Mon Feb 23 16:31:18 2009
@@ -119,13 +119,6 @@
         createResourceInfo(cls, isRoot);
     }
     
-    public void setResourceClassFromBean(Object o) {
-        classResourceInfos.clear();
-        Class<?> realClass = ClassHelper.getRealClass(o);
-        boolean isRoot = AnnotationUtils.getClassAnnotation(realClass, Path.class) != null;
-        createResourceInfo(realClass, isRoot);
-    }
-    
     public void setResourceClasses(List<Class> classes) {
         for (Class resourceClass : classes) {
             createResourceInfo(resourceClass, true);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Mon Feb 23 16:31:18 2009
@@ -45,6 +45,8 @@
 import javax.ws.rs.ext.MessageBodyWriter;
 
 import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.util.ModCountCopyOnWriteArrayList;
 import org.apache.cxf.endpoint.ConduitSelector;
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.helpers.IOUtils;
@@ -68,6 +70,8 @@
  */
 public class AbstractClient implements Client {
 
+    protected List<Interceptor> inInterceptors = new ModCountCopyOnWriteArrayList<Interceptor>();
+    protected List<Interceptor> outInterceptors = new ModCountCopyOnWriteArrayList<Interceptor>();
     protected ConduitSelector conduitSelector;
     protected Bus bus;
     
@@ -257,58 +261,6 @@
     }
 
     
-    public void setConduitSelector(ConduitSelector cs) {
-        this.conduitSelector = cs;
-    }
-    
-    public void setBus(Bus bus) {
-        this.bus = bus;
-    }
-    
-    protected void prepareConduitSelector(Message message) {
-        conduitSelector.prepare(message);
-        message.getExchange().put(ConduitSelector.class, conduitSelector);
-    }
-    
-    protected PhaseInterceptorChain setupInterceptorChain(Endpoint endpoint) { 
-        PhaseManager pm = bus.getExtension(PhaseManager.class);
-        List<Interceptor> i1 = bus.getOutInterceptors();
-        // TODO : make sure we don't forget the out interceptors of this client
-        List<Interceptor> i2 = endpoint.getOutInterceptors();
-        return new PhaseChainCache().get(pm.getOutPhases(), i1, i2);
-    }
-    
-    protected Message createMessage(String httpMethod, 
-                                    MultivaluedMap<String, String> headers,
-                                    String address,
-                                    MessageObserver observer) {
-        Message m = conduitSelector.getEndpoint().getBinding().createMessage();
-        m.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
-        m.put(Message.INBOUND_MESSAGE, Boolean.FALSE);
-        
-        m.put(Message.HTTP_REQUEST_METHOD, httpMethod);
-        m.put(Message.PROTOCOL_HEADERS, headers);
-        m.put(Message.ENDPOINT_ADDRESS, address);
-        m.put(Message.CONTENT_TYPE, headers.getFirst(HttpHeaders.CONTENT_TYPE));
-        
-        
-        Exchange exchange = new ExchangeImpl();
-        exchange.setSynchronous(true);
-        exchange.setOutMessage(m);
-        exchange.put(Bus.class, bus);
-        exchange.put(MessageObserver.class, observer);
-        exchange.setOneWay(false);
-        m.setExchange(exchange);
-        
-        PhaseInterceptorChain chain = setupInterceptorChain(conduitSelector.getEndpoint());
-        m.setInterceptorChain(chain);
-        
-        //setup conduit selector
-        prepareConduitSelector(m);
-        
-        return m;
-    }
-    
     protected List<MediaType> getAccept() {
         List<String> headers = requestHeaders.get(HttpHeaders.ACCEPT);
         if (headers == null || headers.size() == 0) {
@@ -459,5 +411,93 @@
             conn.setRequestProperty(entry.getKey(), b.toString());
         }
     }
+    
+    protected void setConduitSelector(ConduitSelector cs) {
+        this.conduitSelector = cs;
+    }
+    
+    protected void setBus(Bus bus) {
+        this.bus = bus;
+    }
+    
+    protected void prepareConduitSelector(Message message) {
+        conduitSelector.prepare(message);
+        message.getExchange().put(ConduitSelector.class, conduitSelector);
+    }
+    
+    protected PhaseInterceptorChain setupOutInterceptorChain(Endpoint endpoint) { 
+        PhaseManager pm = bus.getExtension(PhaseManager.class);
+        List<Interceptor> i1 = bus.getOutInterceptors();
+        List<Interceptor> i2 = outInterceptors;
+        List<Interceptor> i3 = endpoint.getOutInterceptors();
+        return new PhaseChainCache().get(pm.getOutPhases(), i1, i2, i3);
+    }
+    
+    protected PhaseInterceptorChain setupInInterceptorChain(Endpoint endpoint) { 
+        PhaseManager pm = bus.getExtension(PhaseManager.class);
+        List<Interceptor> i1 = bus.getInInterceptors();
+        List<Interceptor> i2 = inInterceptors;
+        List<Interceptor> i3 = endpoint.getInInterceptors();
+        return new PhaseChainCache().get(pm.getInPhases(), i1, i2, i3);
+    }
+    
+    protected Message createMessage(String httpMethod, 
+                                    MultivaluedMap<String, String> headers,
+                                    String address) {
+        Message m = conduitSelector.getEndpoint().getBinding().createMessage();
+        m.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
+        m.put(Message.INBOUND_MESSAGE, Boolean.FALSE);
+        
+        m.put(Message.HTTP_REQUEST_METHOD, httpMethod);
+        m.put(Message.PROTOCOL_HEADERS, headers);
+        m.put(Message.ENDPOINT_ADDRESS, address);
+        m.put(Message.CONTENT_TYPE, headers.getFirst(HttpHeaders.CONTENT_TYPE));
+        
+        
+        Exchange exchange = new ExchangeImpl();
+        exchange.setSynchronous(true);
+        exchange.setOutMessage(m);
+        exchange.put(Bus.class, bus);
+        exchange.put(MessageObserver.class, new ClientMessageObserver());
+        exchange.setOneWay(false);
+        m.setExchange(exchange);
+        
+        PhaseInterceptorChain chain = setupOutInterceptorChain(conduitSelector.getEndpoint());
+        m.setInterceptorChain(chain);
+        
+        //setup conduit selector
+        prepareConduitSelector(m);
+        
+        return m;
+    }
+
+    protected void setInInterceptors(List<Interceptor> interceptors) {
+        inInterceptors = interceptors;
+    }
+
+    protected void setOutInterceptors(List<Interceptor> interceptors) {
+        outInterceptors = interceptors;
+    }
+    
+    private class ClientMessageObserver implements MessageObserver {
 
+        public void onMessage(Message m) {
+            
+            Message message = conduitSelector.getEndpoint().getBinding().createMessage(m);
+            message.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
+            message.put(Message.INBOUND_MESSAGE, Boolean.TRUE);
+            PhaseInterceptorChain chain = setupInInterceptorChain(conduitSelector.getEndpoint());
+            message.setInterceptorChain(chain);
+            Bus origBus = BusFactory.getThreadDefaultBus(false);
+            BusFactory.setThreadDefaultBus(bus);
+
+            // execute chain
+            try {
+                chain.doIntercept(message);
+            } finally {
+                BusFactory.setThreadDefaultBus(origBus);
+            }
+        }
+        
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java Mon Feb 23 16:31:18 2009
@@ -55,14 +55,13 @@
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageContentsList;
 import org.apache.cxf.phase.Phase;
-import org.apache.cxf.transport.MessageObserver;
 import org.apache.cxf.transport.http.HTTPConduit;
 
 /**
  * Proxy-based client implementation
  *
  */
-public class ClientProxyImpl extends AbstractClient implements InvocationHandler, MessageObserver {
+public class ClientProxyImpl extends AbstractClient implements InvocationHandler {
 
     private ClassResourceInfo cri;
     private boolean inheritHeaders;
@@ -123,6 +122,8 @@
             ClientProxyImpl proxyImpl = new ClientProxyImpl(getBaseURI(), uri, subCri, inheritHeaders);
             proxyImpl.setBus(bus);
             proxyImpl.setConduitSelector(conduitSelector);
+            proxyImpl.setInInterceptors(inInterceptors);
+            proxyImpl.setOutInterceptors(outInterceptors);
             
             Object proxy = JAXRSClientFactory.create(m.getReturnType(), proxyImpl);
             if (inheritHeaders) {
@@ -376,7 +377,7 @@
     private Object doChainedInvocation(URI uri, MultivaluedMap<String, String> headers, 
                           OperationResourceInfo ori, Object[] params, int bodyIndex, 
                           MultivaluedMap<ParameterType, Parameter> types) throws Throwable {
-        Message m = createMessage(ori.getHttpMethod(), headers, uri.toString(), this);
+        Message m = createMessage(ori.getHttpMethod(), headers, uri.toString());
         
         if (bodyIndex != -1 || types.containsKey(ParameterType.FORM)) {
             m.setContent(OperationResourceInfo.class, ori);
@@ -444,10 +445,6 @@
         }
     }
 
-    public void onMessage(Message message) {
-        // just do nothing for now
-    }
-    
     // TODO : what we really need to do is to refactor JAXRSOutInterceptor so that
     // it can handle both client requests and server responses - it may need to be split into
     // several interceptors - in fact we need to do the same for JAXRSInInterceptor so that we can do

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactory.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactory.java Mon Feb 23 16:31:18 2009
@@ -63,6 +63,8 @@
      * Creates a proxy
      * @param baseURI baseURI
      * @param cls proxy class, if not interface then a CGLIB proxy will be created
+     * @param inheritHeaders if true then subresource proxies will inherit the headers
+     *        set on parent proxies 
      * @return typed proxy
      */
     public static <T> T create(URI baseURI, Class<T> cls, boolean inheritHeaders) {
@@ -82,7 +84,7 @@
         if (!direct) {
             JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
             bean.setAddress(baseURI.toString());
-            bean.setResourceClass(cls);
+            bean.setServiceClass(cls);
             bean.setInheritHeaders(inheritHeaders);
             return bean.create(cls);
         } else {
@@ -112,6 +114,7 @@
     
     /**
      * Creates a proxy, baseURI will be set to Client currentURI
+     *   
      * @param client Client instance
      * @param cls proxy class, if not interface then a CGLIB proxy will be created
      * @return typed proxy
@@ -127,7 +130,7 @@
      * Creates a proxy, baseURI will be set to Client currentURI
      * @param client Client instance
      * @param cls proxy class, if not interface then a CGLIB proxy will be created
-     * @param inheritHeaders if existing Client headers can be inherited by new proxy 
+     * @param inheritHeaders if true then existing Client headers will be inherited by new proxy 
      *        and subresource proxies if any 
      * @return typed proxy
      */
@@ -139,8 +142,9 @@
      * Creates a proxy, baseURI will be set to Client currentURI
      * @param client Client instance
      * @param cls proxy class, if not interface then a CGLIB proxy will be created
-     * @param inheritHeaders if existing Client headers can be inherited by new proxy 
+     * @param inheritHeaders if true then existing Client headers will be inherited by new proxy 
      *        and subresource proxies if any 
+     * @param direct if true then no bus and chains will be created       
      * @return typed proxy
      */
     public static <T> T fromClient(Client client, Class<T> cls, boolean inheritHeaders, boolean direct) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java Mon Feb 23 16:31:18 2009
@@ -52,11 +52,11 @@
     }
     
     public void setResourceClass(Class cls) {
-        serviceFactory.setResourceClass(cls);
+        setServiceClass(cls);
     }
     
-    public void setResourceBean(Object o) {
-        serviceFactory.setResourceClassFromBean(o);
+    public void setServiceClass(Class cls) {
+        serviceFactory.setResourceClass(cls);
     }
     
     public WebClient createWebClient() {
@@ -69,6 +69,8 @@
             WebClient client = new WebClient(getAddress());
             client.setConduitSelector(getConduitSelector(ep));
             client.setBus(getBus());
+            client.setOutInterceptors(getOutInterceptors());
+            client.setInInterceptors(getInInterceptors());
             
             return client;
         } catch (Exception ex) {
@@ -96,6 +98,8 @@
             ClientProxyImpl proxyImpl = new ClientProxyImpl(baseURI, baseURI, cri, inheritHeaders);
             proxyImpl.setConduitSelector(getConduitSelector(ep));
             proxyImpl.setBus(getBus());
+            proxyImpl.setOutInterceptors(getOutInterceptors());
+            proxyImpl.setInInterceptors(getInInterceptors());
             
             return (Client)ProxyHelper.getProxy(cri.getServiceClass().getClassLoader(),
                                         new Class[]{cri.getServiceClass(), Client.class}, 

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Mon Feb 23 16:31:18 2009
@@ -46,7 +46,6 @@
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageContentsList;
 import org.apache.cxf.phase.Phase;
-import org.apache.cxf.transport.MessageObserver;
 import org.apache.cxf.transport.http.HTTPConduit;
 
 
@@ -54,7 +53,7 @@
  * Http-centric web client
  *
  */
-public class WebClient extends AbstractClient implements MessageObserver {
+public class WebClient extends AbstractClient {
     
     /**
      * Creates WebClient
@@ -406,7 +405,7 @@
     protected Response doChainedInvocation(String httpMethod, 
         MultivaluedMap<String, String> headers, Object body, Class<?> responseClass) {
 
-        Message m = createMessage(httpMethod, headers, getCurrentURI().toString(), this);
+        Message m = createMessage(httpMethod, headers, getCurrentURI().toString());
         
         if (body != null) {
             MessageContentsList contents = new MessageContentsList(body);
@@ -473,7 +472,5 @@
         
     }
 
-    public void onMessage(Message message) {
-        // do nothing for now
-    }
+    
 }

Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSClientFactoryBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSClientFactoryBeanDefinitionParser.java?rev=747070&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSClientFactoryBeanDefinitionParser.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSClientFactoryBeanDefinitionParser.java Mon Feb 23 16:31:18 2009
@@ -0,0 +1,106 @@
+/**
+ * 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.spring;
+
+import java.util.List;
+import java.util.Map;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor;
+import org.apache.cxf.configuration.spring.AbstractFactoryBeanDefinitionParser;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+
+
+
+public class JAXRSClientFactoryBeanDefinitionParser extends AbstractFactoryBeanDefinitionParser {
+    
+    public JAXRSClientFactoryBeanDefinitionParser() {
+        super();
+        setBeanClass(Object.class);
+    }
+    
+    @Override
+    protected Class getFactoryClass() {
+        return JAXRSClientFactoryBean.class;
+    }
+
+    @Override
+    protected String getFactoryIdSuffix() {
+        return ".proxyFactory";
+    }
+
+    @Override
+    protected String getSuffix() {
+        return ".jaxrs-client";
+    }
+    
+    @Override
+    protected void mapAttribute(BeanDefinitionBuilder bean, Element e, String name, String val) {
+        mapToProperty(bean, name, val);
+    }
+
+    @Override
+    protected void mapElement(ParserContext ctx, BeanDefinitionBuilder bean, Element el, String name) {
+        if ("properties".equals(name)) {
+            Map map = ctx.getDelegate().parseMapElement(el, bean.getBeanDefinition());
+            bean.addPropertyValue(name, map);
+        } else if ("executor".equals(name)) {
+            setFirstChildAsProperty(el, ctx, bean, "serviceFactory.executor");
+        } else if ("invoker".equals(name)) {
+            setFirstChildAsProperty(el, ctx, bean, "serviceFactory.invoker");
+        } else if ("binding".equals(name)) {
+            setFirstChildAsProperty(el, ctx, bean, "bindingConfig");
+        } else if ("inInterceptors".equals(name) || "inFaultInterceptors".equals(name)
+            || "outInterceptors".equals(name) || "outFaultInterceptors".equals(name)) {
+            List list = ctx.getDelegate().parseListElement(el, bean.getBeanDefinition());
+            bean.addPropertyValue(name, list);
+        } else if ("features".equals(name) || "providers".equals(name)) {
+            List list = ctx.getDelegate().parseListElement(el, bean.getBeanDefinition());
+            bean.addPropertyValue(name, list);
+        } else {
+            setFirstChildAsProperty(el, ctx, bean, name);            
+        }        
+    }
+
+    public static class JAXRSSpringClientFactoryBean extends JAXRSClientFactoryBean
+        implements ApplicationContextAware {
+    
+        public JAXRSSpringClientFactoryBean() {
+            super();
+        }
+        
+        public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+            if (getBus() == null) {
+                Bus bus = BusFactory.getThreadDefaultBus();
+                BusWiringBeanFactoryPostProcessor.updateBusReferencesInContext(bus, ctx);
+                setBus(bus);
+            }
+        }
+    }
+
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSClientFactoryBeanDefinitionParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSClientFactoryBeanDefinitionParser.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/NamespaceHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/NamespaceHandler.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/NamespaceHandler.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/NamespaceHandler.java Mon Feb 23 16:31:18 2009
@@ -23,6 +23,7 @@
 
 public class NamespaceHandler extends NamespaceHandlerSupport {
     public void init() {
+        registerBeanDefinitionParser("client", new JAXRSClientFactoryBeanDefinitionParser());
         registerBeanDefinitionParser("server", new JAXRSServerFactoryBeanDefinitionParser());        
         registerBeanDefinitionParser("schemaLocation", new StringBeanDefinitionParser());    
     }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd Mon Feb 23 16:31:18 2009
@@ -65,6 +65,31 @@
     </xsd:complexType>
   </xsd:element>
   
+  <xsd:element name="client">
+    <xsd:complexType>
+      <xsd:complexContent>
+        <xsd:extension base="beans:identifiedType">
+          <xsd:all>
+            <xsd:element name="binding" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="executor" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="features" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="inInterceptors" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="inFaultInterceptors" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="invoker" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="outInterceptors" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="outFaultInterceptors" type="xsd:anyType" minOccurs="0"/>
+            <xsd:element name="properties" type="beans:mapType" minOccurs="0"/>
+            <xsd:element name="providers" type="xsd:anyType" minOccurs="0"/>
+          </xsd:all>
+          <xsd:attributeGroup ref="cxf-beans:beanAttributes"/>
+          <xsd:attribute name="address" type="xsd:string" />
+          <xsd:attribute name="serviceClass" type="xsd:string"/>
+          <xsd:attribute name="bus" type="xsd:string" />
+        </xsd:extension>
+      </xsd:complexContent>
+    </xsd:complexType>
+  </xsd:element>
+  
   <xsd:complexType name="schemasType">
     <xsd:sequence>
       <xsd:element name="schemaLocation" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java Mon Feb 23 16:31:18 2009
@@ -22,6 +22,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import javax.jws.WebMethod;
 import javax.servlet.http.HttpServletRequest;
@@ -29,6 +30,7 @@
 import javax.ws.rs.core.Response;
 import javax.xml.ws.WebServiceContext;
 
+import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 
 public class BookStoreSoapRestImpl implements BookStoreJaxrsJaxws {
@@ -40,16 +42,35 @@
     @Resource
     private MessageContext jaxrsContext;
     
+    @Resource(name = "restClient")
+    private BookStoreJaxrsJaxws webClient;
+    private boolean invocationInProcess;
+    
     public BookStoreSoapRestImpl() {
         init();
     }
     
-    public Book getBook(Long id) {
+    @PostConstruct
+    public void verifyWebClient() {
+        if (webClient == null) {
+            throw new RuntimeException();
+        }
+        WebClient.client(webClient).accept("application/xml");
+    }
+    
+    public Book getBook(Long id) throws BookNotFoundFault {
         if (books.get(id) == null) {
             Response r = Response.status(404).header("BOOK-HEADER", 
                 "No Book with id " + id + " is available").build();
             throw new WebApplicationException(r);
         }
+        
+        if (!invocationInProcess) {
+            invocationInProcess = true;
+            return webClient.getBook(id);
+        }
+        invocationInProcess = false;
+        
         System.out.println(getContentType());
         return books.get(id);
     }

Modified: cxf/trunk/systests/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml?rev=747070&r1=747069&r2=747070&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml (original)
+++ cxf/trunk/systests/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml Mon Feb 23 16:31:18 2009
@@ -35,6 +35,12 @@
   <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
   <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
 
+  <jaxrs:client id="restClient"
+         address="http://localhost:9092/test/services/rest"
+         serviceClass="org.apache.cxf.systest.jaxrs.BookStoreJaxrsJaxws"/>
+         
+  <bean id="bookstore" class="org.apache.cxf.systest.jaxrs.BookStoreSoapRestImpl"/>
+
   <jaxws:endpoint xmlns:s="http://books.com"
       serviceName="s:BookService"
       endpointName="s:BookPort"
@@ -48,7 +54,6 @@
       <ref bean="bookstore"/>
     </jaxrs:serviceBeans>		   
   </jaxrs:server>
-  <bean id="bookstore" class="org.apache.cxf.systest.jaxrs.BookStoreSoapRestImpl"/>
 
   <jaxws:endpoint xmlns:s="http://books.com"
       serviceName="s:BookService"