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 }