001package ca.uhn.hl7v2.hoh.hapi.client;
002
003import java.io.IOException;
004import java.net.URL;
005import java.nio.charset.Charset;
006
007import ca.uhn.hl7v2.HL7Exception;
008import ca.uhn.hl7v2.hoh.api.DecodeException;
009import ca.uhn.hl7v2.hoh.api.EncodeException;
010import ca.uhn.hl7v2.hoh.api.IAuthorizationClientCallback;
011import ca.uhn.hl7v2.hoh.api.IClient;
012import ca.uhn.hl7v2.hoh.api.IReceivable;
013import ca.uhn.hl7v2.hoh.api.ISendable;
014import ca.uhn.hl7v2.hoh.hapi.api.MessageReceivable;
015import ca.uhn.hl7v2.hoh.hapi.api.MessageSendable;
016import ca.uhn.hl7v2.hoh.raw.client.AbstractRawClient;
017import ca.uhn.hl7v2.hoh.sign.ISigner;
018import ca.uhn.hl7v2.hoh.sockets.ISocketFactory;
019import ca.uhn.hl7v2.hoh.util.Validate;
020import ca.uhn.hl7v2.model.Message;
021import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
022import ca.uhn.hl7v2.parser.Parser;
023
024public abstract class AbstractClient<T extends AbstractRawClient> implements IClient {
025
026        private Parser myParser;
027        private T myRawClient;
028
029        /**
030         * Constructor
031         * 
032         * @param theRawClient
033         *            The Raw client to wrap (may not be null)
034         */
035        public AbstractClient(T theRawClient) {
036                this(theRawClient, null);
037        }
038
039        /**
040         * {@inheritDoc}
041         */
042        public void setKeepAlive(boolean theKeepAlive) {
043                getRawClient().setKeepAlive(theKeepAlive);
044        }
045
046        /**
047         * {@inheritDoc}
048         */
049        public boolean isKeepAlive() {
050                return getRawClient().isKeepAlive();
051        }
052
053        /**
054         * {@inheritDoc}
055         */
056        public void setSoTimeout(int theSoTimeout) {
057                getRawClient().setSoTimeout(theSoTimeout);
058        }
059
060        /**
061         * {@inheritDoc}
062         */
063        public int getSoTimeout() {
064                return getRawClient().getSoTimeout();
065        }
066
067        /**
068         * Constructor
069         * 
070         * @param theRawClient
071         *            The Raw client to wrap (may not be null)
072         * @param theParser
073         *            The parser to use (may be null, in which case the parser
074         *            contained within the sent message will be used
075         */
076        protected AbstractClient(T theRawClient, Parser theParser) {
077                Validate.notNull(theRawClient, "rawClient");
078                myRawClient = theRawClient;
079                myParser = theParser;
080        }
081
082        public String getHost() {
083                return myRawClient.getHost();
084        }
085
086        /**
087         * Returns the {@link Parser} to use to parsing and encoding messages within
088         * this client (may return null)
089         */
090        public Parser getParser() {
091                return myParser;
092        }
093
094        /**
095         * {@inheritDoc}
096         */
097        public int getPort() {
098                return myRawClient.getPort();
099        }
100
101        /**
102         * {@inheritDoc}
103         */
104        protected T getRawClient() {
105                return myRawClient;
106        }
107
108        /**
109         * {@inheritDoc}
110         */
111        public ISocketFactory getSocketFactory() {
112                return myRawClient.getSocketFactory();
113        }
114
115        /**
116         * {@inheritDoc}
117         */
118        public String getUriPath() {
119                return myRawClient.getUriPath();
120        }
121
122        /**
123         * {@inheritDoc}
124         */
125        public URL getUrl() {
126                return myRawClient.getUrl();
127        }
128
129        /**
130         * {@inheritDoc}
131         */
132        public String getUrlString() {
133                return myRawClient.getUrlString();
134        }
135
136        /**
137         * Sends a message, waits for the response, and then returns the response if
138         * any
139         * 
140         * @param theMessageToSend
141         *            The message to send
142         * @return The returned message, as well as associated metadata
143         * @throws DecodeException
144         *             If a problem occurs (read error, socket disconnect, etc.)
145         *             during communication, or the response is invalid in some way.
146         *             Note that IO errors in trying to connect to the remote host
147         *             or sending the message are thrown directly (i.e. as
148         *             {@link IOException}), but IO errors in reading the response
149         *             are thrown as DecodeException
150         * @throws IOException
151         *             If the client is unable to connect to the remote host
152         * @throws EncodeException
153         *             If a failure occurs while encoding the message into a
154         *             sendable HTTP request
155         * @throws HL7Exception
156         *             If the response can not be parsed
157         * @throws EncodingNotSupportedException
158         *             If the encoding is not supported
159         */
160        public IReceivable<Message> sendAndReceiveMessage(ISendable<Message> theMessageToSend) throws DecodeException, IOException, EncodeException, EncodingNotSupportedException, HL7Exception {
161                IReceivable<String> response = myRawClient.sendAndReceive(theMessageToSend);
162                Parser parser = myParser != null ? myParser : theMessageToSend.getMessage().getParser();
163                return new MessageReceivable(parser.parse(response.getMessage()));
164        }
165
166        /**
167         * Sends a message, waits for the response, and then returns the response if
168         * any (this method is a convenience method for {@link #sendAndReceiveMessage(ISendable)}
169         * 
170         * @param theMessageToSend
171         *            The message to send
172         * @return The returned message, as well as associated metadata
173         * @throws DecodeException
174         *             If a problem occurs (read error, socket disconnect, etc.)
175         *             during communication, or the response is invalid in some way.
176         *             Note that IO errors in trying to connect to the remote host
177         *             or sending the message are thrown directly (i.e. as
178         *             {@link IOException}), but IO errors in reading the response
179         *             are thrown as DecodeException
180         * @throws IOException
181         *             If the client is unable to connect to the remote host
182         * @throws EncodeException
183         *             If a failure occurs while encoding the message into a
184         *             sendable HTTP request
185         * @throws HL7Exception
186         *             If the response can not be parsed
187         * @throws EncodingNotSupportedException
188         *             If the encoding is not supported
189         */
190        public IReceivable<Message> sendAndReceiveMessage(Message theMessageToSend) throws DecodeException, IOException, EncodeException, EncodingNotSupportedException, HL7Exception {
191                MessageSendable sendable = new MessageSendable(theMessageToSend);
192                return sendAndReceiveMessage(sendable);
193        }
194
195        /**
196         * {@inheritDoc}
197         */
198        public void setAuthorizationCallback(IAuthorizationClientCallback theAuthorizationCallback) {
199                myRawClient.setAuthorizationCallback(theAuthorizationCallback);
200        }
201
202        /**
203         * {@inheritDoc}
204         */
205        public void setCharset(Charset theCharset) {
206                myRawClient.setCharset(theCharset);
207        }
208
209        /**
210         * {@inheritDoc}
211         */
212        public void setHost(String theHost) {
213                myRawClient.setHost(theHost);
214        }
215
216        /**
217         * Sets the {@link Parser} to use to parsing and encoding messages within
218         * this client
219         */
220        public void setParser(Parser theParser) {
221                Validate.notNull(theParser, "parser");
222                myParser = theParser;
223        }
224
225        /**
226         * {@inheritDoc}
227         */
228        public void setUriPath(String thePath) {
229                myRawClient.setUriPath(thePath);
230        }
231
232        /**
233         * {@inheritDoc}
234         */
235        public void setPort(int thePort) {
236                myRawClient.setPort(thePort);
237        }
238
239        /**
240         * {@inheritDoc}
241         */
242        public void setResponseTimeout(long theResponseTimeout) {
243                myRawClient.setResponseTimeout(theResponseTimeout);
244        }
245
246        /**
247         * {@inheritDoc}
248         */
249        public void setSigner(ISigner theSigner) {
250                myRawClient.setSigner(theSigner);
251        }
252
253        /**
254         * {@inheritDoc}
255         */
256        public void setSocketFactory(ISocketFactory theSocketFactory) {
257                myRawClient.setSocketFactory(theSocketFactory);
258        }
259
260        /**
261         * {@inheritDoc}
262         */
263        public void setUrl(URL theUrl) {
264                myRawClient.setUrl(theUrl);
265        }
266
267        /**
268         * {@inheritDoc}
269         */
270        public void setUrlString(String theString) {
271                myRawClient.setUrlString(theString);
272        }
273
274}