View Javadoc
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