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 }