001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. 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 */ 017package org.apache.activemq.command; 018 019import java.io.IOException; 020import java.io.UnsupportedEncodingException; 021import java.util.Enumeration; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025import java.util.Vector; 026 027import javax.jms.DeliveryMode; 028import javax.jms.Destination; 029import javax.jms.JMSException; 030import javax.jms.MessageFormatException; 031import javax.jms.MessageNotWriteableException; 032 033import org.apache.activemq.ActiveMQConnection; 034import org.apache.activemq.ScheduledMessage; 035import org.apache.activemq.broker.scheduler.CronParser; 036import org.apache.activemq.filter.PropertyExpression; 037import org.apache.activemq.state.CommandVisitor; 038import org.apache.activemq.util.Callback; 039import org.apache.activemq.util.JMSExceptionSupport; 040import org.apache.activemq.util.TypeConversionSupport; 041import org.fusesource.hawtbuf.UTF8Buffer; 042 043/** 044 * 045 * @openwire:marshaller code="23" 046 */ 047public class ActiveMQMessage extends Message implements org.apache.activemq.Message, ScheduledMessage { 048 public static final byte DATA_STRUCTURE_TYPE = CommandTypes.ACTIVEMQ_MESSAGE; 049 public static final String DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY = "dlqDeliveryFailureCause"; 050 public static final String BROKER_PATH_PROPERTY = "JMSActiveMQBrokerPath"; 051 052 private static final Map<String, PropertySetter> JMS_PROPERTY_SETERS = new HashMap<String, PropertySetter>(); 053 054 protected transient Callback acknowledgeCallback; 055 056 @Override 057 public byte getDataStructureType() { 058 return DATA_STRUCTURE_TYPE; 059 } 060 061 @Override 062 public Message copy() { 063 ActiveMQMessage copy = new ActiveMQMessage(); 064 copy(copy); 065 return copy; 066 } 067 068 protected void copy(ActiveMQMessage copy) { 069 super.copy(copy); 070 copy.acknowledgeCallback = acknowledgeCallback; 071 } 072 073 @Override 074 public int hashCode() { 075 MessageId id = getMessageId(); 076 if (id != null) { 077 return id.hashCode(); 078 } else { 079 return super.hashCode(); 080 } 081 } 082 083 @Override 084 public boolean equals(Object o) { 085 if (this == o) { 086 return true; 087 } 088 if (o == null || o.getClass() != getClass()) { 089 return false; 090 } 091 092 ActiveMQMessage msg = (ActiveMQMessage) o; 093 MessageId oMsg = msg.getMessageId(); 094 MessageId thisMsg = this.getMessageId(); 095 return thisMsg != null && oMsg != null && oMsg.equals(thisMsg); 096 } 097 098 @Override 099 public void acknowledge() throws JMSException { 100 if (acknowledgeCallback != null) { 101 try { 102 acknowledgeCallback.execute(); 103 } catch (JMSException e) { 104 throw e; 105 } catch (Throwable e) { 106 throw JMSExceptionSupport.create(e); 107 } 108 } 109 } 110 111 @Override 112 public void clearBody() throws JMSException { 113 setContent(null); 114 readOnlyBody = false; 115 } 116 117 @Override 118 public String getJMSMessageID() { 119 MessageId messageId = this.getMessageId(); 120 if (messageId == null) { 121 return null; 122 } 123 return messageId.toString(); 124 } 125 126 /** 127 * Seems to be invalid because the parameter doesn't initialize MessageId 128 * instance variables ProducerId and ProducerSequenceId 129 * 130 * @param value 131 * @throws JMSException 132 */ 133 @Override 134 public void setJMSMessageID(String value) throws JMSException { 135 if (value != null) { 136 try { 137 MessageId id = new MessageId(value); 138 this.setMessageId(id); 139 } catch (NumberFormatException e) { 140 // we must be some foreign JMS provider or strange user-supplied 141 // String 142 // so lets set the IDs to be 1 143 MessageId id = new MessageId(); 144 id.setTextView(value); 145 this.setMessageId(id); 146 } 147 } else { 148 this.setMessageId(null); 149 } 150 } 151 152 /** 153 * This will create an object of MessageId. For it to be valid, the instance 154 * variable ProducerId and producerSequenceId must be initialized. 155 * 156 * @param producerId 157 * @param producerSequenceId 158 * @throws JMSException 159 */ 160 public void setJMSMessageID(ProducerId producerId, long producerSequenceId) throws JMSException { 161 MessageId id = null; 162 try { 163 id = new MessageId(producerId, producerSequenceId); 164 this.setMessageId(id); 165 } catch (Throwable e) { 166 throw JMSExceptionSupport.create("Invalid message id '" + id + "', reason: " + e.getMessage(), e); 167 } 168 } 169 170 @Override 171 public long getJMSTimestamp() { 172 return this.getTimestamp(); 173 } 174 175 @Override 176 public void setJMSTimestamp(long timestamp) { 177 this.setTimestamp(timestamp); 178 } 179 180 @Override 181 public String getJMSCorrelationID() { 182 return this.getCorrelationId(); 183 } 184 185 @Override 186 public void setJMSCorrelationID(String correlationId) { 187 this.setCorrelationId(correlationId); 188 } 189 190 @Override 191 public byte[] getJMSCorrelationIDAsBytes() throws JMSException { 192 return encodeString(this.getCorrelationId()); 193 } 194 195 @Override 196 public void setJMSCorrelationIDAsBytes(byte[] correlationId) throws JMSException { 197 this.setCorrelationId(decodeString(correlationId)); 198 } 199 200 @Override 201 public String getJMSXMimeType() { 202 return "jms/message"; 203 } 204 205 protected static String decodeString(byte[] data) throws JMSException { 206 try { 207 if (data == null) { 208 return null; 209 } 210 return new String(data, "UTF-8"); 211 } catch (UnsupportedEncodingException e) { 212 throw new JMSException("Invalid UTF-8 encoding: " + e.getMessage()); 213 } 214 } 215 216 protected static byte[] encodeString(String data) throws JMSException { 217 try { 218 if (data == null) { 219 return null; 220 } 221 return data.getBytes("UTF-8"); 222 } catch (UnsupportedEncodingException e) { 223 throw new JMSException("Invalid UTF-8 encoding: " + e.getMessage()); 224 } 225 } 226 227 @Override 228 public Destination getJMSReplyTo() { 229 return this.getReplyTo(); 230 } 231 232 @Override 233 public void setJMSReplyTo(Destination destination) throws JMSException { 234 this.setReplyTo(ActiveMQDestination.transform(destination)); 235 } 236 237 @Override 238 public Destination getJMSDestination() { 239 return this.getDestination(); 240 } 241 242 @Override 243 public void setJMSDestination(Destination destination) throws JMSException { 244 this.setDestination(ActiveMQDestination.transform(destination)); 245 } 246 247 @Override 248 public int getJMSDeliveryMode() { 249 return this.isPersistent() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT; 250 } 251 252 @Override 253 public void setJMSDeliveryMode(int mode) { 254 this.setPersistent(mode == DeliveryMode.PERSISTENT); 255 } 256 257 @Override 258 public boolean getJMSRedelivered() { 259 return this.isRedelivered(); 260 } 261 262 @Override 263 public void setJMSRedelivered(boolean redelivered) { 264 this.setRedelivered(redelivered); 265 } 266 267 @Override 268 public String getJMSType() { 269 return this.getType(); 270 } 271 272 @Override 273 public void setJMSType(String type) { 274 this.setType(type); 275 } 276 277 @Override 278 public long getJMSExpiration() { 279 return this.getExpiration(); 280 } 281 282 @Override 283 public void setJMSExpiration(long expiration) { 284 this.setExpiration(expiration); 285 } 286 287 @Override 288 public int getJMSPriority() { 289 return this.getPriority(); 290 } 291 292 @Override 293 public void setJMSPriority(int priority) { 294 this.setPriority((byte) priority); 295 } 296 297 @Override 298 public void clearProperties() { 299 super.clearProperties(); 300 readOnlyProperties = false; 301 } 302 303 @Override 304 public boolean propertyExists(String name) throws JMSException { 305 try { 306 return (this.getProperties().containsKey(name) || getObjectProperty(name)!= null); 307 } catch (IOException e) { 308 throw JMSExceptionSupport.create(e); 309 } 310 } 311 312 @Override 313 @SuppressWarnings("rawtypes") 314 public Enumeration getPropertyNames() throws JMSException { 315 try { 316 Vector<String> result = new Vector<String>(this.getProperties().keySet()); 317 if( getRedeliveryCounter()!=0 ) { 318 result.add("JMSXDeliveryCount"); 319 } 320 if( getGroupID()!=null ) { 321 result.add("JMSXGroupID"); 322 } 323 if( getGroupID()!=null ) { 324 result.add("JMSXGroupSeq"); 325 } 326 if( getUserID()!=null ) { 327 result.add("JMSXUserID"); 328 } 329 return result.elements(); 330 } catch (IOException e) { 331 throw JMSExceptionSupport.create(e); 332 } 333 } 334 335 /** 336 * return all property names, including standard JMS properties and JMSX properties 337 * @return Enumeration of all property names on this message 338 * @throws JMSException 339 */ 340 @SuppressWarnings("rawtypes") 341 public Enumeration getAllPropertyNames() throws JMSException { 342 try { 343 Vector<String> result = new Vector<String>(this.getProperties().keySet()); 344 result.addAll(JMS_PROPERTY_SETERS.keySet()); 345 return result.elements(); 346 } catch (IOException e) { 347 throw JMSExceptionSupport.create(e); 348 } 349 } 350 351 interface PropertySetter { 352 void set(Message message, Object value) throws MessageFormatException; 353 } 354 355 static { 356 JMS_PROPERTY_SETERS.put("JMSXDeliveryCount", new PropertySetter() { 357 @Override 358 public void set(Message message, Object value) throws MessageFormatException { 359 Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class); 360 if (rc == null) { 361 throw new MessageFormatException("Property JMSXDeliveryCount cannot be set from a " + value.getClass().getName() + "."); 362 } 363 message.setRedeliveryCounter(rc.intValue() - 1); 364 } 365 }); 366 JMS_PROPERTY_SETERS.put("JMSXGroupID", new PropertySetter() { 367 @Override 368 public void set(Message message, Object value) throws MessageFormatException { 369 String rc = (String) TypeConversionSupport.convert(value, String.class); 370 if (rc == null) { 371 throw new MessageFormatException("Property JMSXGroupID cannot be set from a " + value.getClass().getName() + "."); 372 } 373 message.setGroupID(rc); 374 } 375 }); 376 JMS_PROPERTY_SETERS.put("JMSXGroupSeq", new PropertySetter() { 377 @Override 378 public void set(Message message, Object value) throws MessageFormatException { 379 Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class); 380 if (rc == null) { 381 throw new MessageFormatException("Property JMSXGroupSeq cannot be set from a " + value.getClass().getName() + "."); 382 } 383 message.setGroupSequence(rc.intValue()); 384 } 385 }); 386 JMS_PROPERTY_SETERS.put("JMSCorrelationID", new PropertySetter() { 387 @Override 388 public void set(Message message, Object value) throws MessageFormatException { 389 String rc = (String) TypeConversionSupport.convert(value, String.class); 390 if (rc == null) { 391 throw new MessageFormatException("Property JMSCorrelationID cannot be set from a " + value.getClass().getName() + "."); 392 } 393 ((ActiveMQMessage) message).setJMSCorrelationID(rc); 394 } 395 }); 396 JMS_PROPERTY_SETERS.put("JMSDeliveryMode", new PropertySetter() { 397 @Override 398 public void set(Message message, Object value) throws MessageFormatException { 399 Integer rc = null; 400 try { 401 rc = (Integer) TypeConversionSupport.convert(value, Integer.class); 402 } catch (NumberFormatException nfe) { 403 if (value instanceof String) { 404 if (((String) value).equalsIgnoreCase("PERSISTENT")) { 405 rc = DeliveryMode.PERSISTENT; 406 } else if (((String) value).equalsIgnoreCase("NON_PERSISTENT")) { 407 rc = DeliveryMode.NON_PERSISTENT; 408 } else { 409 throw nfe; 410 } 411 } 412 } 413 if (rc == null) { 414 Boolean bool = (Boolean) TypeConversionSupport.convert(value, Boolean.class); 415 if (bool == null) { 416 throw new MessageFormatException("Property JMSDeliveryMode cannot be set from a " + value.getClass().getName() + "."); 417 } else { 418 rc = bool.booleanValue() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT; 419 } 420 } 421 ((ActiveMQMessage) message).setJMSDeliveryMode(rc); 422 } 423 }); 424 JMS_PROPERTY_SETERS.put("JMSExpiration", new PropertySetter() { 425 @Override 426 public void set(Message message, Object value) throws MessageFormatException { 427 Long rc = (Long) TypeConversionSupport.convert(value, Long.class); 428 if (rc == null) { 429 throw new MessageFormatException("Property JMSExpiration cannot be set from a " + value.getClass().getName() + "."); 430 } 431 ((ActiveMQMessage) message).setJMSExpiration(rc.longValue()); 432 } 433 }); 434 JMS_PROPERTY_SETERS.put("JMSPriority", new PropertySetter() { 435 @Override 436 public void set(Message message, Object value) throws MessageFormatException { 437 Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class); 438 if (rc == null) { 439 throw new MessageFormatException("Property JMSPriority cannot be set from a " + value.getClass().getName() + "."); 440 } 441 ((ActiveMQMessage) message).setJMSPriority(rc.intValue()); 442 } 443 }); 444 JMS_PROPERTY_SETERS.put("JMSRedelivered", new PropertySetter() { 445 @Override 446 public void set(Message message, Object value) throws MessageFormatException { 447 Boolean rc = (Boolean) TypeConversionSupport.convert(value, Boolean.class); 448 if (rc == null) { 449 throw new MessageFormatException("Property JMSRedelivered cannot be set from a " + value.getClass().getName() + "."); 450 } 451 ((ActiveMQMessage) message).setJMSRedelivered(rc.booleanValue()); 452 } 453 }); 454 JMS_PROPERTY_SETERS.put("JMSReplyTo", new PropertySetter() { 455 @Override 456 public void set(Message message, Object value) throws MessageFormatException { 457 ActiveMQDestination rc = (ActiveMQDestination) TypeConversionSupport.convert(value, ActiveMQDestination.class); 458 if (rc == null) { 459 throw new MessageFormatException("Property JMSReplyTo cannot be set from a " + value.getClass().getName() + "."); 460 } 461 ((ActiveMQMessage) message).setReplyTo(rc); 462 } 463 }); 464 JMS_PROPERTY_SETERS.put("JMSTimestamp", new PropertySetter() { 465 @Override 466 public void set(Message message, Object value) throws MessageFormatException { 467 Long rc = (Long) TypeConversionSupport.convert(value, Long.class); 468 if (rc == null) { 469 throw new MessageFormatException("Property JMSTimestamp cannot be set from a " + value.getClass().getName() + "."); 470 } 471 ((ActiveMQMessage) message).setJMSTimestamp(rc.longValue()); 472 } 473 }); 474 JMS_PROPERTY_SETERS.put("JMSType", new PropertySetter() { 475 @Override 476 public void set(Message message, Object value) throws MessageFormatException { 477 String rc = (String) TypeConversionSupport.convert(value, String.class); 478 if (rc == null) { 479 throw new MessageFormatException("Property JMSType cannot be set from a " + value.getClass().getName() + "."); 480 } 481 ((ActiveMQMessage) message).setJMSType(rc); 482 } 483 }); 484 } 485 486 @Override 487 public void setObjectProperty(String name, Object value) throws JMSException { 488 setObjectProperty(name, value, true); 489 } 490 491 public void setObjectProperty(String name, Object value, boolean checkReadOnly) throws JMSException { 492 493 if (checkReadOnly) { 494 checkReadOnlyProperties(); 495 } 496 if (name == null || name.equals("")) { 497 throw new IllegalArgumentException("Property name cannot be empty or null"); 498 } 499 500 if (value instanceof UTF8Buffer) { 501 value = value.toString(); 502 } 503 504 checkValidObject(value); 505 value = convertScheduled(name, value); 506 PropertySetter setter = JMS_PROPERTY_SETERS.get(name); 507 508 if (setter != null && value != null) { 509 setter.set(this, value); 510 } else { 511 try { 512 this.setProperty(name, value); 513 } catch (IOException e) { 514 throw JMSExceptionSupport.create(e); 515 } 516 } 517 } 518 519 public void setProperties(Map<String, ?> properties) throws JMSException { 520 for (Map.Entry<String, ?> entry : properties.entrySet()) { 521 // Lets use the object property method as we may contain standard 522 // extension headers like JMSXGroupID 523 setObjectProperty(entry.getKey(), entry.getValue()); 524 } 525 } 526 527 protected void checkValidObject(Object value) throws MessageFormatException { 528 529 boolean valid = value instanceof Boolean || value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long; 530 valid = valid || value instanceof Float || value instanceof Double || value instanceof Character || value instanceof String || value == null; 531 532 if (!valid) { 533 534 ActiveMQConnection conn = getConnection(); 535 // conn is null if we are in the broker rather than a JMS client 536 if (conn == null || conn.isNestedMapAndListEnabled()) { 537 if (!(value instanceof Map || value instanceof List)) { 538 throw new MessageFormatException("Only objectified primitive objects, String, Map and List types are allowed but was: " + value + " type: " + value.getClass()); 539 } 540 } else { 541 throw new MessageFormatException("Only objectified primitive objects and String types are allowed but was: " + value + " type: " + value.getClass()); 542 } 543 } 544 } 545 546 protected Object convertScheduled(String name, Object value) throws MessageFormatException { 547 Object result = value; 548 if (AMQ_SCHEDULED_DELAY.equals(name)){ 549 result = TypeConversionSupport.convert(value, Long.class); 550 if (result != null && (Long)result < 0) { 551 throw new MessageFormatException(name + " must not be a negative value"); 552 } 553 } 554 else if (AMQ_SCHEDULED_PERIOD.equals(name)){ 555 result = TypeConversionSupport.convert(value, Long.class); 556 if (result != null && (Long)result < 0) { 557 throw new MessageFormatException(name + " must not be a negative value"); 558 } 559 } 560 else if (AMQ_SCHEDULED_REPEAT.equals(name)){ 561 result = TypeConversionSupport.convert(value, Integer.class); 562 if (result != null && (Integer)result < 0) { 563 throw new MessageFormatException(name + " must not be a negative value"); 564 } 565 } 566 else if (AMQ_SCHEDULED_CRON.equals(name)) { 567 CronParser.validate(value.toString()); 568 } 569 return result; 570 } 571 572 @Override 573 public Object getObjectProperty(String name) throws JMSException { 574 if (name == null) { 575 throw new NullPointerException("Property name cannot be null"); 576 } 577 578 // PropertyExpression handles converting message headers to properties. 579 PropertyExpression expression = new PropertyExpression(name); 580 return expression.evaluate(this); 581 } 582 583 @Override 584 public boolean getBooleanProperty(String name) throws JMSException { 585 Object value = getObjectProperty(name); 586 if (value == null) { 587 return false; 588 } 589 Boolean rc = (Boolean) TypeConversionSupport.convert(value, Boolean.class); 590 if (rc == null) { 591 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a boolean"); 592 } 593 return rc.booleanValue(); 594 } 595 596 @Override 597 public byte getByteProperty(String name) throws JMSException { 598 Object value = getObjectProperty(name); 599 if (value == null) { 600 throw new NumberFormatException("property " + name + " was null"); 601 } 602 Byte rc = (Byte) TypeConversionSupport.convert(value, Byte.class); 603 if (rc == null) { 604 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a byte"); 605 } 606 return rc.byteValue(); 607 } 608 609 @Override 610 public short getShortProperty(String name) throws JMSException { 611 Object value = getObjectProperty(name); 612 if (value == null) { 613 throw new NumberFormatException("property " + name + " was null"); 614 } 615 Short rc = (Short) TypeConversionSupport.convert(value, Short.class); 616 if (rc == null) { 617 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a short"); 618 } 619 return rc.shortValue(); 620 } 621 622 @Override 623 public int getIntProperty(String name) throws JMSException { 624 Object value = getObjectProperty(name); 625 if (value == null) { 626 throw new NumberFormatException("property " + name + " was null"); 627 } 628 Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class); 629 if (rc == null) { 630 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as an integer"); 631 } 632 return rc.intValue(); 633 } 634 635 @Override 636 public long getLongProperty(String name) throws JMSException { 637 Object value = getObjectProperty(name); 638 if (value == null) { 639 throw new NumberFormatException("property " + name + " was null"); 640 } 641 Long rc = (Long) TypeConversionSupport.convert(value, Long.class); 642 if (rc == null) { 643 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a long"); 644 } 645 return rc.longValue(); 646 } 647 648 @Override 649 public float getFloatProperty(String name) throws JMSException { 650 Object value = getObjectProperty(name); 651 if (value == null) { 652 throw new NullPointerException("property " + name + " was null"); 653 } 654 Float rc = (Float) TypeConversionSupport.convert(value, Float.class); 655 if (rc == null) { 656 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a float"); 657 } 658 return rc.floatValue(); 659 } 660 661 @Override 662 public double getDoubleProperty(String name) throws JMSException { 663 Object value = getObjectProperty(name); 664 if (value == null) { 665 throw new NullPointerException("property " + name + " was null"); 666 } 667 Double rc = (Double) TypeConversionSupport.convert(value, Double.class); 668 if (rc == null) { 669 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a double"); 670 } 671 return rc.doubleValue(); 672 } 673 674 @Override 675 public String getStringProperty(String name) throws JMSException { 676 Object value = null; 677 if (name.equals("JMSXUserID")) { 678 value = getUserID(); 679 if (value == null) { 680 value = getObjectProperty(name); 681 } 682 } else { 683 value = getObjectProperty(name); 684 } 685 if (value == null) { 686 return null; 687 } 688 String rc = (String) TypeConversionSupport.convert(value, String.class); 689 if (rc == null) { 690 throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a String"); 691 } 692 return rc; 693 } 694 695 @Override 696 public void setBooleanProperty(String name, boolean value) throws JMSException { 697 setBooleanProperty(name, value, true); 698 } 699 700 public void setBooleanProperty(String name, boolean value, boolean checkReadOnly) throws JMSException { 701 setObjectProperty(name, Boolean.valueOf(value), checkReadOnly); 702 } 703 704 @Override 705 public void setByteProperty(String name, byte value) throws JMSException { 706 setObjectProperty(name, Byte.valueOf(value)); 707 } 708 709 @Override 710 public void setShortProperty(String name, short value) throws JMSException { 711 setObjectProperty(name, Short.valueOf(value)); 712 } 713 714 @Override 715 public void setIntProperty(String name, int value) throws JMSException { 716 setObjectProperty(name, Integer.valueOf(value)); 717 } 718 719 @Override 720 public void setLongProperty(String name, long value) throws JMSException { 721 setObjectProperty(name, Long.valueOf(value)); 722 } 723 724 @Override 725 public void setFloatProperty(String name, float value) throws JMSException { 726 setObjectProperty(name, new Float(value)); 727 } 728 729 @Override 730 public void setDoubleProperty(String name, double value) throws JMSException { 731 setObjectProperty(name, new Double(value)); 732 } 733 734 @Override 735 public void setStringProperty(String name, String value) throws JMSException { 736 setObjectProperty(name, value); 737 } 738 739 protected void checkReadOnlyProperties() throws MessageNotWriteableException { 740 if (readOnlyProperties) { 741 throw new MessageNotWriteableException("Message properties are read-only"); 742 } 743 } 744 745 protected void checkReadOnlyBody() throws MessageNotWriteableException { 746 if (readOnlyBody) { 747 throw new MessageNotWriteableException("Message body is read-only"); 748 } 749 } 750 751 public Callback getAcknowledgeCallback() { 752 return acknowledgeCallback; 753 } 754 755 public void setAcknowledgeCallback(Callback acknowledgeCallback) { 756 this.acknowledgeCallback = acknowledgeCallback; 757 } 758 759 /** 760 * Send operation event listener. Used to get the message ready to be sent. 761 */ 762 public void onSend() throws JMSException { 763 setReadOnlyBody(true); 764 setReadOnlyProperties(true); 765 } 766 767 @Override 768 public Response visit(CommandVisitor visitor) throws Exception { 769 return visitor.processMessage(this); 770 } 771 772 @Override 773 public void storeContent() { 774 } 775 776 @Override 777 public void storeContentAndClear() { 778 storeContent(); 779 } 780 781 @Override 782 protected boolean isContentMarshalled() { 783 //Always return true because ActiveMQMessage only has a content field 784 //which is already marshalled 785 return true; 786 } 787}