1 /***
2 * Copyright (c) 2002, Reuters America Inc. All rights reserved.<p>
3 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
4 * conditions are met:<p>
5 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
7 * in the documentation and/or other materials provided with the distribution. Neither the name of Reuters America Inc. nor the
8 * names of its contributors may be used to endorse or promote products derived from this software without specific prior written
9 * permission.<p>
10 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
11 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
12 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
14 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<p>
16 */
17
18 package com.reuters.rc.db.adb;
19
20 import com.reuters.rc.db.*;
21 import com.tibco.tibrv.*;
22
23 /***
24 * This class represents a request sent to ADB. Each instance of this class is immutable - instances can be freely shared among threads.
25 * This class depends on <code>DbManager</code> to pick up transport/queue/timeout defaults. An easy way for the application to provide
26 * consistent transport/queue/timeout parameters across modules is to configure the DbManager once.
27 * @see com.reuters.rc.db.DbManager
28 * @author Jawaid Hakim.
29 */
30 public class AdbRequest implements DbRequest
31 {
32 /***
33 * Constructor. A reference to the parameter is stored so be careful about
34 * modifying the data.
35 * @param stmt Request statement.
36 */
37 public AdbRequest(DbRequestStmt stmt)
38 {
39 init(stmt, DbManager.getDefaultTimeout(), null);
40 }
41
42 /***
43 * Constructor. A reference to the parameter is stored so be careful about
44 * modifying the data.
45 * @param stmt Request statement.
46 * @param timeout Maximum time interval - in seconds - for which to
47 * wait for reply in request/reply mode.
48 */
49 public AdbRequest(DbRequestStmt stmt, double timeout)
50 {
51 init(stmt, timeout, null);
52 }
53
54 /***
55 * Constructor. A reference to the parameter is stored so be careful about
56 * modifying the data.
57 * @param stmt Request statement.
58 * @param timeout Maximum time interval - in seconds - for which to wait for
59 * reply in request/reply mode.
60 * @param closure Closure argument. In asynchronous request/reply mode, the closure
61 * is returned with the response to the application callback.
62 * @see #sendRequest(TibrvTransport, String, TibrvQueue, DbRequestCallback, String) throws AdbException
63 * @see DbRequestCallback
64 */
65 public AdbRequest(DbRequestStmt stmt, double timeout, Object closure)
66 {
67 init(stmt, timeout, closure);
68 }
69
70 /***
71 * Constructor. A reference to the parameters is stored so be careful about
72 * modifying the data.
73 * @param stmts Request statements.
74 */
75 public AdbRequest(DbRequestStmt[] stmts)
76 {
77 init(stmts, DbManager.getDefaultTimeout(), null);
78 }
79
80 /***
81 * Constructor. A reference to the parameters is stored so be careful about
82 * modifying the data.
83 * @param stmts Request statements.
84 * @param timeout Maximum time interval - in seconds - for which to
85 * wait for reply in request/reply mode.
86 */
87 public AdbRequest(DbRequestStmt[] stmts, double timeout)
88 {
89 init(stmts, timeout, null);
90 }
91
92 /***
93 * Constructor. A reference to the parameters is stored so be careful about
94 * modifying the data.
95 * @param stmts Request statements.
96 * @param timeout Maximum time interval - in seconds - for which to
97 * wait for reply in request/reply mode.
98 * @param closure Closure argument. In asynchronous request/reply mode, the closure
99 * is returned with the response to the application callback.
100 * @see #sendRequest(TibrvTransport, String, TibrvQueue, DbRequestCallback, String) throws AdbException
101 * @see DbRequestCallback
102 */
103 public AdbRequest(DbRequestStmt[] stmts, double timeout, Object closure)
104 {
105 init(stmts, timeout, closure);
106 }
107
108 /***
109 * This method is a NO-OP and exists to satisfy interface requirements.
110 */
111 public void setReplySize(int replySize)
112 {
113 }
114
115 /***
116 * Initialize.
117 * @param stmt Request statement.
118 * @param timeout Maximum time interval - in seconds - for which to
119 * wait for reply.
120 * @param closure Closure argument. In asynchronous request/reply mode, the closure
121 * is returned with the response to the application callback.
122 * @see #sendRequest(TibrvTransport, String, TibrvQueue, DbRequestCallback, String) throws AdbSystemException
123 * @see DbRequestCallback
124 */
125 private void init(DbRequestStmt stmt, double timeout, Object closure)
126 {
127 DbRequestStmt[] stmts = new DbRequestStmt[1];
128 stmts[0] = stmt;
129 init(stmts, timeout, closure);
130 }
131
132 /***
133 * Initialize.
134 * @param stmts Request statements.
135 * @param timeout Maximum time interval - in seconds - for which to
136 * wait for reply.
137 * @param closure Closure argument. In asynchronous request/reply mode, the closure
138 * is returned with the response to the application callback.
139 * @see #sendRequest(TibrvTransport, String, TibrvQueue, DbRequestCallback, String)
140 * @see DbRequestCallback
141 */
142 private void init(DbRequestStmt[] stmts, double timeout, Object closure)
143 {
144 stmts_ = stmts;
145 timeout_ = timeout;
146 closure_ = closure;
147 }
148
149 /***
150 * Get the closure argument.
151 * @return Closure argument
152 */
153 public final Object getClosure()
154 {
155 return closure_;
156 }
157
158 /***
159 * Get the maximum time interval for which to wait for reply.
160 * @return Maximum timeout interval - in seconds.
161 */
162 public final double getTimeout()
163 {
164 return timeout_;
165 }
166
167 /***
168 * Set the maximum time interval for which to wait for reply.
169 * @param timeout Maximum time interval - in seconds - for which to
170 * wait for reply.
171 */
172 public final void setTimeout(double timeout)
173 {
174 timeout_ = timeout;
175 }
176
177 /***
178 * Get the statement(s) associated with this request.
179 * @return Request statement(s) associated with this request. A reference
180 * to the request statements is returned so be careful about modifying the
181 * data.
182 */
183 public final DbRequestStmt[] getRequest()
184 {
185 return stmts_;
186 }
187
188 /***
189 * Send the request to ADB and return the reply. Wait for the reply until timeout
190 * period expires. Throws exception if request times out.
191 * @param rvTrans Transport used to send the request.
192 * @param sendSubject Send subject.
193 * @return Reply from ADB.
194 * @see #setTimeout(double)
195 */
196 public final DbReply sendRequest(TibrvTransport rvTrans, String sendSubject) throws AdbBusinessException, AdbSystemException
197 {
198 try
199 {
200 if (rvTrans == null)
201 throw new AdbBusinessException("NULL transport");
202
203 TibrvMsg replyMsg = rvTrans.sendRequest(buildRequest(sendSubject, null), getTimeout());
204 if (replyMsg == null)
205 throw new AdbBusinessException("ADB request timed out");
206
207 return new AdbReply(replyMsg);
208 }
209 catch (TibrvException ex)
210 {
211 throw new AdbSystemException(ex);
212 }
213 }
214
215 /***
216 * Send the request to ADB and return the reply. Wait for the reply until timeout
217 * period expires. The default transport is used to send the request. Throws exception
218 * if no default transport has been registered or if request times out.
219 * @param sendSubject Send subject.
220 * @return Reply from ADB.
221 * @see #setDefault(TibrvTransport)
222 * @see #setTimeout(double)
223 */
224 public final DbReply sendRequest(String sendSubject) throws AdbBusinessException, AdbSystemException
225 {
226 return sendRequest(DbManager.getDefaultTransport(), sendSubject);
227 }
228
229 /***
230 * Send the request to ADB without waiting for a reply.
231 * @param rvTrans Transport used to send the request.
232 * @param sendSubject Send subject.
233 */
234 public final void send(TibrvTransport rvTrans, String sendSubject) throws AdbBusinessException, AdbSystemException
235 {
236 try
237 {
238 if (rvTrans == null)
239 throw new AdbBusinessException("NULL transport");
240
241 rvTrans.send(buildRequest(sendSubject, null));
242 }
243 catch (TibrvException ex)
244 {
245 throw new AdbSystemException(ex);
246 }
247 }
248
249 /***
250 * Send the request to ADB without waiting for a reply. The default transport is used to send the
251 * request. Throws exception if no default transport has been registered or if request times out.
252 * @param sendSubject Send subject.
253 * @see #setDefault(TibrvTransport)
254 * @see #setDefault(TibrvTransport, TibrvQueue)
255 * @see #send(TibrvTransport, String)
256 */
257 public final void send(String sendSubject) throws AdbBusinessException, AdbSystemException
258 {
259 send(DbManager.getDefaultTransport(), sendSubject);
260 }
261
262 /***
263 * Send the request to ADB without waiting for a reply.
264 * @param rvTrans Transport.
265 * @param sendSubject Send subject.
266 * @param replySubject Reply subject.
267 * @see #send(String, String)
268 */
269 public final void send(TibrvTransport rvTrans, String sendSubject, String replySubject) throws AdbBusinessException, AdbSystemException
270 {
271 try
272 {
273 if (rvTrans == null)
274 throw new AdbBusinessException("NULL transport");
275
276 rvTrans.send(buildRequest(sendSubject, replySubject));
277 }
278 catch (TibrvException ex)
279 {
280 throw new AdbSystemException(ex);
281 }
282 }
283
284 /***
285 * Send the request to ADB using the default transport.
286 * @param sendSubject Send subject.
287 * @param replySubject Reply subject.
288 * @see #setDefault(TibrvTransport)
289 * @see #setDefault(TibrvTransport, TibrvQueue)
290 * @see #send(TibrvTransport, String, String)
291 */
292 public final void send(String sendSubject, String replySubject) throws AdbBusinessException, AdbSystemException
293 {
294 send(DbManager.getDefaultTransport(), sendSubject, replySubject);
295 }
296
297 /***
298 * Async. Request/Reply. Send the request to ADB, get the reply asynchronously,
299 * and return the reply to application callback. The application callback should
300 * destroy the TibrvListsner if it wishes to close the subscription.
301 * @param rvTrans Transport used to send the request.
302 * @param sendSubject Send subject.
303 * @param rvQueue Queue on which the reply is received. Caller must dispatch
304 * from this queue.
305 * @param adbCb Callback function.
306 * @param replySubject Listen for reply from ADB on this subject.
307 * @see DbRequestCallback
308 */
309 public final void sendRequest(TibrvTransport rvTrans, String sendSubject, TibrvQueue rvQueue, DbRequestCallback adbCb, String replySubject) throws AdbBusinessException, AdbSystemException
310 {
311 try
312 {
313 if (rvTrans_ == null)
314 throw new AdbBusinessException("NULL transport");
315
316 if (rvQueue_ == null)
317 throw new AdbBusinessException("NULL queue");
318
319 new TibrvListener(rvQueue, new AdbMsgCallback(adbCb), rvTrans, replySubject, getClosure());
320 rvTrans.send(buildRequest(sendSubject, replySubject));
321 }
322 catch (TibrvException ex)
323 {
324 throw new AdbSystemException(ex);
325 }
326 }
327
328 /***
329 * Async. Request/Reply. Send the request to ADB, get the reply asynchronously,
330 * and return the reply to callback. The application callback should destroy the
331 * TibrvListsner if it wishes to close the subscription.
332 * @param sendSubject Send subject.
333 * @param adbCb Callback function.
334 * @param replySubject Listen for reply from ADB on this subject.
335 * @see DbRequestCallback
336 */
337 public final void sendRequest(String sendSubject, DbRequestCallback adbCb, String replySubject) throws AdbBusinessException, AdbSystemException
338 {
339 sendRequest(DbManager.getDefaultTransport(), sendSubject, DbManager.getDefaultQueue(), adbCb, replySubject);
340 }
341
342 /***
343 * Pretty Print the request message.
344 * @return Pretty Printed value.
345 */
346 public final String toPrettyPrintString()
347 {
348 StringBuffer buf = new StringBuffer(256);
349 buf.append("{\n");
350 for (int i = 0; i < stmts_.length; ++i)
351 {
352 buf.append(" {\n");
353 buf.append(" ").append(stmts_[i].getSql()).append("\n");
354 buf.append(" }\n");
355 }
356 buf.append("}\n");
357
358 return buf.toString();
359 }
360
361 /***
362 * Build request message.
363 * @param sendSubject Send subject.
364 * @param replySubject Reply subject.
365 * @return Request message.
366 * @see com.tibco.tibrv.TibrvMsg
367 * @see com.tibco.tibrv.TibrvException
368 */
369 private final TibrvMsg buildRequest(String sendSubject, String replySubject) throws AdbBusinessException, AdbSystemException
370 {
371 try
372 {
373 // One or more statements required.
374 if (stmts_ == null || stmts_.length == 0)
375 throw new AdbBusinessException("No request statement");
376
377 // Create top-level request
378 TibrvMsg reqMsg = new TibrvMsg();
379
380 reqMsg.setSendSubject(sendSubject);
381
382 if (replySubject != null)
383 reqMsg.setReplySubject(replySubject);
384
385 if (getClosure() != null)
386 reqMsg.add(ADB_CLOSURE, getClosure());
387
388 // Add nested sql statement(s) to request
389 for (int i = 0; i < stmts_.length; ++i)
390 {
391 if (stmts_[i] != null)
392 reqMsg.add(ADB_STMT, stmts_[i].getStmt());
393 else
394 throw new AdbBusinessException("NULL request statement");
395 }
396
397 return reqMsg;
398 }
399 catch (TibrvException ex)
400 {
401 throw new AdbSystemException(ex);
402 }
403 catch (DbBaseException ex)
404 {
405 throw new AdbSystemException(ex);
406 }
407 }
408
409 /***
410 * Default TibrvTransport.
411 */
412 private static TibrvTransport rvTrans_;
413
414 /***
415 * Default TibrvQueue.
416 */
417 private static TibrvQueue rvQueue_;
418
419 /***
420 * Name of nested SQL statement message.
421 */
422 private static final String ADB_STMT = "stmt";
423
424 /***
425 * Name of message field containing the closure option.
426 */
427 private static final String ADB_CLOSURE = "closure";
428
429 /***
430 * Default timeout in seconds.
431 * @todo Read from a config file.
432 */
433 private static double DEFAULT_TIMEOUT = 60;
434
435 /***
436 * Maximum timeout value for request/reply.
437 */
438 private double timeout_;
439
440 /***
441 * Closure option value.
442 */
443 private Object closure_;
444
445 /***
446 * Multiple request statements
447 */
448 private DbRequestStmt[] stmts_;
449 }
450
451 /***
452 * Callback class to receive async. reply from ADB.
453 */
454 class AdbMsgCallback implements TibrvMsgCallback
455 {
456 /***
457 * Constructor.
458 * @param cb Application callback.
459 * @throws <code>NullPointerException</code> If the callback reference is
460 * <code>null</code>.
461 */
462 public AdbMsgCallback(DbRequestCallback cb)
463 {
464 if (cb == null)
465 throw new NullPointerException("NULL callback");
466
467 cb_ = cb;
468 }
469
470 /***
471 * Callback.
472 * @param listener Listener.
473 * @param msg Message.
474 * @see com.tibco.tibrv.TibrvMsgCallback
475 */
476 public void onMsg(TibrvListener listener, TibrvMsg msg)
477 {
478 cb_.onMsg(listener, new AdbReply(msg));
479
480 // Zap the listener if it has not been destroyed
481 if (listener.isValid())
482 listener.destroy();
483 }
484
485 /***
486 * Application callback - blank final initialized by the constructor.
487 */
488 private final DbRequestCallback cb_;
489 }
This page was automatically generated by Maven