| 1 22 package org.jboss.mq; 23 24 import java.io.Externalizable ; 25 import java.io.IOException ; 26 import java.io.ObjectInput ; 27 import java.io.ObjectOutput ; 28 import java.io.Serializable ; 29 import java.util.Collections ; 30 import java.util.Enumeration ; 31 import java.util.HashMap ; 32 import java.util.HashSet ; 33 import java.util.Map ; 34 35 import javax.jms.Destination ; 36 import javax.jms.JMSException ; 37 import javax.jms.Message ; 38 import javax.jms.MessageFormatException ; 39 import javax.jms.MessageNotWriteableException ; 40 import javax.jms.Session ; 41 42 import org.jboss.util.Primitives; 43 import org.jboss.util.Strings; 44 45 54 public class SpyMessage implements Serializable , Message , Comparable , Cloneable , Externalizable  55 { 56 58 59 private final static long serialVersionUID = 467206190892964404L; 60 61 64 public static final String PROPERTY_DELIVERY_COUNT = "JMSXDeliveryCount"; 65 66 70 public static final String PROPERTY_SCHEDULED_DELIVERY = "JMS_JBOSS_SCHEDULED_DELIVERY"; 71 72 77 public static final String PROPERTY_REDELIVERY_DELAY = "JMS_JBOSS_REDELIVERY_DELAY"; 78 79 83 public static final String PROPERTY_REDELIVERY_COUNT = "JMS_JBOSS_REDELIVERY_COUNT"; 84 85 90 public static final String PROPERTY_REDELIVERY_LIMIT = "JMS_JBOSS_REDELIVERY_LIMIT"; 91 92 95 public static final String PROPERTY_ORIG_DESTINATION = "JBOSS_ORIG_DESTINATION"; 96 97 100 public static final String PROPERTY_ORIG_EXPIRATION = "JBOSS_ORIG_EXPIRATION"; 101 102 105 public static final String PROPERTY_ORIG_MESSAGEID = "JBOSS_ORIG_MESSAGEID"; 106 107 108 protected static final byte OBJECT_MESS = 1; 109 110 protected static final byte BYTES_MESS = 2; 111 112 protected static final byte MAP_MESS = 3; 113 114 protected static final byte TEXT_MESS = 4; 115 116 protected static final byte STREAM_MESS = 5; 117 118 protected static final byte ENCAP_MESS = 6; 119 120 protected static final byte SPY_MESS = 7; 121 122 123 protected static final int BYTE = 0; 124 125 protected static final int SHORT = 1; 126 127 protected static final int INT = 2; 128 129 protected static final int LONG = 3; 130 131 protected static final int FLOAT = 4; 132 133 protected static final int DOUBLE = 5; 134 135 protected static final int BOOLEAN = 6; 136 137 protected static final int STRING = 7; 138 139 protected static final int OBJECT = 8; 140 141 protected static final int NULL = 9; 142 143 144 private static final HashSet reservedIdentifiers = new HashSet (); 145 146 148 149 public Header header = new Header(); 150 151 152 public transient AcknowledgementRequest ack; 153 154 155 public transient SpySession session; 156 157 159 static 160 { 161 reservedIdentifiers.add("NULL"); 162 reservedIdentifiers.add("TRUE"); 163 reservedIdentifiers.add("FALSE"); 164 reservedIdentifiers.add("NOT"); 165 reservedIdentifiers.add("AND"); 166 reservedIdentifiers.add("OR"); 167 reservedIdentifiers.add("BETWEEN"); 168 reservedIdentifiers.add("LIKE"); 169 reservedIdentifiers.add("IN"); 170 reservedIdentifiers.add("IS"); 171 reservedIdentifiers.add("ESCAPE"); 172 } 173 174 181 public static void writeMessage(SpyMessage message, ObjectOutput out) throws IOException  182 { 183 if (message instanceof SpyEncapsulatedMessage) 184 out.writeByte(ENCAP_MESS); 185 else if (message instanceof SpyObjectMessage) 186 out.writeByte(OBJECT_MESS); 187 else if (message instanceof SpyBytesMessage) 188 out.writeByte(BYTES_MESS); 189 else if (message instanceof SpyMapMessage) 190 out.writeByte(MAP_MESS); 191 else if (message instanceof SpyTextMessage) 192 out.writeByte(TEXT_MESS); 193 else if (message instanceof SpyStreamMessage) 194 out.writeByte(STREAM_MESS); 195 else 196 out.writeByte(SPY_MESS); 197 message.writeExternal(out); 198 } 199 200 207 public static SpyMessage readMessage(ObjectInput in) throws IOException  208 { 209 SpyMessage message = null; 210 byte type = in.readByte(); 211 switch (type) 212 { 213 case OBJECT_MESS : 214 message = MessagePool.getObjectMessage(); 215 break; 216 case BYTES_MESS : 217 message = MessagePool.getBytesMessage(); 218 break; 219 case MAP_MESS : 220 message = MessagePool.getMapMessage(); 221 break; 222 case STREAM_MESS : 223 message = MessagePool.getStreamMessage(); 224 break; 225 case TEXT_MESS : 226 message = MessagePool.getTextMessage(); 227 break; 228 case ENCAP_MESS : 229 message = MessagePool.getEncapsulatedMessage(); 230 break; 231 default : 232 message = MessagePool.getMessage(); 233 } 234 try 235 { 236 message.readExternal(in); 237 } 238 catch (ClassNotFoundException cnf) 239 { 240 throw new IOException ("Class not found when reading in spy message."); 241 } 242 return message; 243 } 244 245 247 249 254 public void clearBody() throws JMSException  255 { 256 header.msgReadOnly = false; 258 } 259 260 265 public void acknowledge() throws JMSException  266 { 267 if (session == null) 268 throw new JMSException ("This message was not recieved from the provider"); 269 270 if (session.acknowledgeMode == Session.CLIENT_ACKNOWLEDGE) 271 doAcknowledge(); 272 } 273 274 277 public void setReadOnlyMode() 278 { 279 header.jmsPropertiesReadWrite = false; 280 header.msgReadOnly = true; 281 } 282 283 289 public SpyMessage myClone() throws JMSException  290 { 291 SpyMessage result = MessagePool.getMessage(); 292 result.copyProps(this); 293 return result; 294 } 295 296 302 public void copyProps(SpyMessage original) throws JMSException  303 { 304 try 305 { 306 this.setJMSCorrelationID(original.getJMSCorrelationID()); 307 } 308 catch (JMSException e) 309 { 310 this.setJMSCorrelationIDAsBytes(original.getJMSCorrelationIDAsBytes()); 312 } 313 this.setJMSDeliveryMode(original.getJMSDeliveryMode()); 314 this.setJMSDestination(original.getJMSDestination()); 315 this.setJMSExpiration(original.getJMSExpiration()); 316 this.setJMSMessageID(original.getJMSMessageID()); 317 this.setJMSPriority(original.getJMSPriority()); 318 this.setJMSRedelivered(original.getJMSRedelivered()); 319 this.setJMSReplyTo(original.getJMSReplyTo()); 320 this.setJMSTimestamp(original.getJMSTimestamp()); 321 this.setJMSType(original.getJMSType()); 322 this.header.jmsProperties.putAll(original.header.jmsProperties); 323 324 this.header.jmsPropertiesReadWrite = original.header.jmsPropertiesReadWrite; 326 this.header.msgReadOnly = original.header.msgReadOnly; 327 this.header.producerClientId = original.header.producerClientId; 328 if (original.header.durableSubscriberID != null) 329 this.header.durableSubscriberID = new DurableSubscriptionID(original.header.durableSubscriberID.clientID, 330 original.header.durableSubscriberID.subscriptionName, original.header.durableSubscriberID.selector); 331 } 332 333 338 public boolean isOutdated() 339 { 340 if (header.jmsExpiration == 0) 341 return false; 342 long ts = System.currentTimeMillis(); 343 return header.jmsExpiration < ts; 344 } 345 346 351 public void doAcknowledge() throws JMSException  352 { 353 session.doAcknowledge(this, getAcknowledgementRequest(true)); 354 } 355 356 359 public void createAcknowledgementRequest(int subscriptionId) 360 { 361 ack = new AcknowledgementRequest(); 362 ack.destination = header.jmsDestination; 363 ack.messageID = header.jmsMessageID; 364 ack.subscriberId = subscriptionId; 365 } 366 367 373 public AcknowledgementRequest getAcknowledgementRequest(boolean isAck) throws JMSException  374 { 375 AcknowledgementRequest item = new AcknowledgementRequest(isAck); 377 item.destination = ack.destination; 378 item.messageID = ack.messageID; 379 item.subscriberId = ack.subscriberId; 380 return item; 381 } 382 383 385 public int compareTo(Object o) 386 { 387 SpyMessage sm = (SpyMessage) o; 388 389 if (header.jmsPriority > sm.header.jmsPriority) 390 { 391 return -1; 392 } 393 if (header.jmsPriority < sm.header.jmsPriority) 394 { 395 return 1; 396 } 397 return (int) (header.messageId - sm.header.messageId); 398 } 399 400 402 public String getJMSMessageID() 403 { 404 return header.jmsMessageID; 405 } 406 407 public void setJMSMessageID(String id) throws JMSException  408 { 409 header.jmsMessageID = id; 410 } 411 412 public long getJMSTimestamp() 413 { 414 return header.jmsTimeStamp; 415 } 416 417 public void setJMSTimestamp(long timestamp) throws JMSException  418 { 419 header.jmsTimeStamp = timestamp; 420 } 421 422 public byte[] getJMSCorrelationIDAsBytes() throws JMSException  423 { 424 if (header.jmsCorrelationID) 425 throw new JMSException ("JMSCorrelationID is a string"); 426 return header.jmsCorrelationIDbyte; 427 } 428 429 public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException  430 { 431 header.jmsCorrelationID = false; 432 header.jmsCorrelationIDbyte = (byte[]) correlationID.clone(); 433 header.jmsCorrelationIDString = null; 434 } 435 436 public void setJMSCorrelationID(String correlationID) throws JMSException  437 { 438 header.jmsCorrelationID = true; 439 header.jmsCorrelationIDString = correlationID; 440 header.jmsCorrelationIDbyte = null; 441 } 442 443 public String getJMSCorrelationID() throws JMSException  444 { 445 if (!header.jmsCorrelationID) 446 throw new JMSException ("JMSCorrelationID is an array"); 447 return header.jmsCorrelationIDString; 448 } 449 450 public Destination getJMSReplyTo() 451 { 452 return header.jmsReplyTo; 453 } 454 455 public void setJMSReplyTo(Destination replyTo) throws JMSException  456 { 457 header.jmsReplyTo = replyTo; 458 } 459 460 public Destination getJMSDestination() 461 { 462 return header.jmsDestination; 463 } 464 465 public void setJMSDestination(Destination destination) throws JMSException  466 { 467 header.jmsDestination = destination; 468 } 469 470 public int getJMSDeliveryMode() 471 { 472 return header.jmsDeliveryMode; 473 } 474 475 public void setJMSDeliveryMode(int deliveryMode) throws JMSException  476 { 477 header.jmsDeliveryMode = deliveryMode; 478 } 479 480 public boolean getJMSRedelivered() 481 { 482 return header.jmsRedelivered; 483 } 484 485 public void setJMSRedelivered(boolean redelivered) throws JMSException  486 { 487 header.jmsRedelivered = redelivered; 488 } 489 490 public String getJMSType() 491 { 492 return header.jmsType; 493 } 494 495 public void setJMSType(String type) throws JMSException  496 { 497 header.jmsType = type; 498 } 499 500 public long getJMSExpiration() 501 { 502 return header.jmsExpiration; 503 } 504 505 public void setJMSExpiration(long expiration) throws JMSException  506 { 507 header.jmsExpiration = expiration; 508 } 509 510 public int getJMSPriority() 511 { 512 return header.jmsPriority; 513 } 514 515 public void setJMSPriority(int priority) throws JMSException  516 { 517 if (priority < 0 || priority > 10) 518 throw new JMSException ("Unsupported priority '" + priority + "': priority must be from 0-10"); 519 header.jmsPriority = priority; 520 } 521 522 public void clearProperties() throws JMSException  523 { 524 header.jmsProperties.clear(); 525 header.jmsPropertiesReadWrite = true; 526 } 527 528 public boolean propertyExists(String name) throws JMSException  529 { 530 return header.jmsProperties.containsKey(name); 531 } 532 533 public boolean getBooleanProperty(String name) throws JMSException  534 { 535 Object value = header.jmsProperties.get(name); 536 if (value == null) 537 return Boolean.valueOf(null).booleanValue(); 538 539 if (value instanceof Boolean ) 540 return ((Boolean ) value).booleanValue(); 541 else if (value instanceof String ) 542 return Boolean.valueOf((String ) value).booleanValue(); 543 else 544 throw new MessageFormatException ("Invalid conversion"); 545 } 546 547 public byte getByteProperty(String name) throws JMSException  548 { 549 Object value = header.jmsProperties.get(name); 550 if (value == null) 551 throw new NumberFormatException ("Message property '" + name + "' not set."); 552 553 if (value instanceof Byte ) 554 return ((Byte ) value).byteValue(); 555 else if (value instanceof String ) 556 return Byte.parseByte((String ) value); 557 else 558 throw new MessageFormatException ("Invalid conversion"); 559 } 560 561 public short getShortProperty(String name) throws JMSException  562 { 563 Object value = header.jmsProperties.get(name); 564 if (value == null) 565 throw new NumberFormatException ("Message property '" + name + "' not set."); 566 567 if (value instanceof Byte ) 568 return ((Byte ) value).shortValue(); 569 else if (value instanceof Short ) 570 return ((Short ) value).shortValue(); 571 else if (value instanceof String ) 572 return Short.parseShort((String ) value); 573 else 574 throw new MessageFormatException ("Invalid conversion"); 575 } 576 577 public int getIntProperty(String name) throws JMSException  578 { 579 Object value = header.jmsProperties.get(name); 580 if (value == null) 581 throw new NumberFormatException ("Message property '" + name + "' not set."); 582 583 if (value instanceof Byte ) 584 return ((Byte ) value).intValue(); 585 else if (value instanceof Short ) 586 return ((Short ) value).intValue(); 587 else if (value instanceof Integer ) 588 return ((Integer ) value).intValue(); 589 else if (value instanceof String ) 590 return Integer.parseInt((String ) value); 591 else 592 throw new MessageFormatException ("Invalid conversion"); 593 } 594 595 public long getLongProperty(String name) throws JMSException  596 { 597 Object value = header.jmsProperties.get(name); 598 if (value == null) 599 throw new NumberFormatException ("Message property '" + name + "' not set."); 600 601 if (value instanceof Byte ) 602 return ((Byte ) value).longValue(); 603 else if (value instanceof Short ) 604 return ((Short ) value).longValue(); 605 else if (value instanceof Integer ) 606 return ((Integer ) value).longValue(); 607 else if (value instanceof Long ) 608 return ((Long ) value).longValue(); 609 else if (value instanceof String ) 610 return Long.parseLong((String ) value); 611 else 612 throw new MessageFormatException ("Invalid conversion"); 613 } 614 615 public float getFloatProperty(String name) throws JMSException  616 { 617 Object value = header.jmsProperties.get(name); 618 if (value == null) 619 return Float.valueOf(null).floatValue(); 620 621 if (value instanceof Float ) 622 return ((Float ) value).floatValue(); 623 else if (value instanceof String ) 624 return Float.parseFloat((String ) value); 625 else 626 throw new MessageFormatException ("Invalid conversion"); 627 } 628 629 public double getDoubleProperty(String name) throws JMSException  630 { 631 Object value = header.jmsProperties.get(name); 632 if (value == null) 633 return Double.valueOf(null).doubleValue(); 634 635 if (value instanceof Float ) 636 return ((Float ) value).doubleValue(); 637 else if (value instanceof Double ) 638 return ((Double ) value).doubleValue(); 639 else if (value instanceof String ) 640 return Double.parseDouble((String ) value); 641 else 642 throw new MessageFormatException ("Invalid conversion"); 643 } 644 645 public String getStringProperty(String name) throws JMSException  646 { 647 Object value = header.jmsProperties.get(name); 648 if (value == null) 649 return null; 650 651 if (value instanceof Boolean ) 652 return ((Boolean ) value).toString(); 653 else if (value instanceof Byte ) 654 return ((Byte ) value).toString(); 655 else if (value instanceof Short ) 656 return ((Short ) value).toString(); 657 else if (value instanceof Integer ) 658 return ((Integer ) value).toString(); 659 else if (value instanceof Long ) 660 return ((Long ) value).toString(); 661 else if (value instanceof Float ) 662 return ((Float ) value).toString(); 663 else if (value instanceof Double ) 664 return ((Double ) value).toString(); 665 else if (value instanceof String ) 666 return (String ) value; 667 else 668 throw new MessageFormatException ("Invalid conversion"); 669 } 670 671 public Object getObjectProperty(String name) throws JMSException  672 { 673 Object value = header.jmsProperties.get(name); 674 return value; 675 } 676 677 public Enumeration getPropertyNames() throws JMSException  678 { 679 Enumeration names = Collections.enumeration(header.jmsProperties.keySet()); 680 return names; 681 } 682 683 public void setBooleanProperty(String name, boolean value) throws JMSException  684 { 685 if (!header.jmsPropertiesReadWrite) 686 throw new MessageNotWriteableException ("Properties are read-only"); 687 Boolean b = Primitives.valueOf(value); 688 checkProperty(name, b); 689 header.jmsProperties.put(name, b); 690 } 691 692 public void setByteProperty(String name, byte value) throws JMSException  693 { 694 if (!header.jmsPropertiesReadWrite) 695 throw new MessageNotWriteableException ("Properties are read-only"); 696 Byte b = new Byte (value); 697 checkProperty(name, b); 698 header.jmsProperties.put(name, b); 699 } 700 701 public void setShortProperty(String name, short value) throws JMSException  702 { 703 if (!header.jmsPropertiesReadWrite) 704 throw new MessageNotWriteableException ("Properties are read-only"); 705 Short s = new Short (value); 706 checkProperty(name, s); 707 header.jmsProperties.put(name, s); 708 } 709 710 public void setIntProperty(String name, int value) throws JMSException  711 { 712 if (!header.jmsPropertiesReadWrite) 713 throw new MessageNotWriteableException ("Properties are read-only"); 714 Integer i = new Integer (value); 715 checkProperty(name, i); 716 header.jmsProperties.put(name, i); 717 } 718 719 public void setLongProperty(String name, long value) throws JMSException  720 { 721 if (!header.jmsPropertiesReadWrite) 722 throw new MessageNotWriteableException ("Properties are read-only"); 723 Long l = new Long (value); 724 checkProperty(name, l); 725 header.jmsProperties.put(name, l); 726 } 727 728 public void setFloatProperty(String name, float value) throws JMSException  729 { 730 if (!header.jmsPropertiesReadWrite) 731 throw new MessageNotWriteableException ("Properties are read-only"); 732 Float f = new Float (value); 733 checkProperty(name, f); 734 header.jmsProperties.put(name, f); 735 } 736 737 public void setDoubleProperty(String name, double value) throws JMSException  738 { 739 if (!header.jmsPropertiesReadWrite) 740 throw new MessageNotWriteableException ("Properties are read-only"); 741 Double d = new Double (value); 742 checkProperty(name, d); 743 header.jmsProperties.put(name, d); 744 } 745 746 public void setStringProperty(String name, String value) throws JMSException  747 { 748 if (!header.jmsPropertiesReadWrite) 749 throw new MessageNotWriteableException ("Properties are read-only"); 750 checkProperty(name, value); 751 header.jmsProperties.put(name, value); 752 } 753 754 public void setObjectProperty(String name, Object value) throws JMSException  755 { 756 if (!header.jmsPropertiesReadWrite) 757 throw new MessageNotWriteableException ("Properties are read-only"); 758 checkProperty(name, value); 759 if (value instanceof Boolean ) 760 header.jmsProperties.put(name, value); 761 else if (value instanceof Byte ) 762 header.jmsProperties.put(name, value); 763  
|