001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    package org.codehaus.activesoap;
019    
020    import org.codehaus.activesoap.impl.ClientHandler;
021    import org.codehaus.activesoap.impl.ClientProxy;
022    import org.codehaus.activesoap.transport.Invocation;
023    import org.codehaus.activesoap.transport.LocalTransportClient;
024    import org.codehaus.activesoap.transport.TransportClient;
025    
026    import javax.xml.stream.XMLStreamReader;
027    import javax.xml.stream.XMLStreamWriter;
028    import java.lang.reflect.Proxy;
029    
030    /**
031     * Represents a client interface to REST services
032     *
033     * @version $Revision: 1.8 $
034     */
035    public class RestClient {
036        private RestService service;
037        private TransportClient transport;
038        private ClientHandler clientHandler;
039    
040        /**
041         * Factory method to create a new client to an in memory RestService
042         */
043        public static RestClient newLocalClient(RestService restService) {
044            return new RestClient(new LocalTransportClient(restService), restService);
045        }
046    
047        public RestClient(TransportClient transport, RestService service) {
048            this.transport = transport;
049            this.service = service;
050        }
051    
052        public MessageExchange createMessageExchange() {
053            return new MessageExchange(service, null, null);
054        }
055    
056        public MessageExchange createMessageExchange(XMLStreamReader in, XMLStreamWriter out) {
057            return new MessageExchange(service, in, out);
058        }
059    
060        public void invokeOneWay(Handler generateBodyHandler) throws Exception {
061            MessageExchange exchange = createMessageExchange(null, null);
062            invokeOneWay(exchange, generateBodyHandler);
063        }
064    
065        public void invokeOneWay(MessageExchange exchange, Handler generateBodyHandler) throws Exception {
066            Invocation request = transport.createInvocation();
067            XMLStreamWriter out = request.getOut();
068            processBody(exchange, out, generateBodyHandler);
069            request.invokeOneWay();
070        }
071    
072        public XMLStreamReader invokeRequestReply(Handler generateBodyHandler) throws Exception {
073            Invocation request = transport.createInvocation();
074            XMLStreamWriter out = request.getOut();
075            MessageExchange exchange = createMessageExchange(null, out);
076    
077            return invokeRequestReply(exchange, out, generateBodyHandler, request);
078        }
079    
080        public XMLStreamReader invokeRequestReply(MessageExchange exchange, Handler generateBodyHandler) throws Exception {
081            Invocation request = transport.createInvocation();
082            XMLStreamWriter out = request.getOut();
083    
084            return invokeRequestReply(exchange, out, generateBodyHandler, request);
085        }
086    
087        /**
088         * Performs a request using a generic message object
089         */
090        public void invokeOneWay(Object object) throws Exception {
091            checkClientHandler();
092            Handler handler = clientHandler.createBodyHandler(object);
093            invokeOneWay(handler);
094        }
095    
096        /**
097         * Performs a request-response using a generic message object API
098         */
099        public Object invokeRequestReply(Object argument) throws Exception {
100            checkClientHandler();
101            Handler handler = clientHandler.createBodyHandler(argument);
102            XMLStreamReader in = invokeRequestReply(handler);
103            return parseResponse(in);
104        }
105    
106        /**
107         * Performs a request-response using a generic message object API
108         */
109        public Object invokeRequestReply(MessageExchange exchange, Object argument) throws Exception {
110            checkClientHandler();
111            Handler handler = clientHandler.createBodyHandler(argument);
112            XMLStreamReader in = invokeRequestReply(exchange, handler);
113            return parseResponse(in);
114        }
115    
116        /**
117         * Creates a dynamic proxy of the given interface which when invoked
118         * will perform a web services invocation.
119         *
120         * @param interfaceClass is the interface of the proxy to create
121         * @return
122         */
123        public Object createProxy(Class interfaceClass) {
124            checkClientHandler();
125            return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
126                    new Class[]{interfaceClass},
127                    new ClientProxy(this, clientHandler));
128        }
129    
130        /**
131         * Internal method used to process a SOAP response
132         */
133        public Object parseResponse(XMLStreamReader in) throws Exception {
134            return clientHandler.parseResponse(in);
135        }
136    
137        /**
138         * Closes down the client freeing any resources
139         */
140        public void close() throws Exception {
141            transport.close();
142        }
143    
144        // Properties
145        //-------------------------------------------------------------------------
146        public ClientHandler getClientHandler() {
147            return clientHandler;
148        }
149    
150        public void setClientHandler(ClientHandler clientHandler) {
151            this.clientHandler = clientHandler;
152        }
153    
154        // Implementation methods
155        //-------------------------------------------------------------------------
156        public RestService getService() {
157            return service;
158        }
159    
160        protected void checkClientHandler() {
161            if (clientHandler == null) {
162                throw new IllegalArgumentException("Cannot create a dyamic proxy without configuring the 'clientHandler' property");
163            }
164        }
165    
166        protected XMLStreamReader invokeRequestReply(MessageExchange exchange, XMLStreamWriter out, Handler generateBodyHandler, Invocation request) throws Exception {
167            processBody(exchange, out, generateBodyHandler);
168            return request.invokeRequest();
169        }
170    
171        protected void processBody(MessageExchange exchange, XMLStreamWriter out, Handler generateBodyHandler) throws Exception {
172            generateBodyHandler.invoke(exchange.newInstance(null, out));
173        }
174    
175    }