1 18 package org.apache.activemq.command; 19 20 import java.io.IOException ; 21 import java.io.UnsupportedEncodingException ; 22 import java.util.Enumeration ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Map ; 27 import java.util.Vector ; 28 29 import javax.jms.DeliveryMode ; 30 import javax.jms.Destination ; 31 import javax.jms.JMSException ; 32 import javax.jms.MessageFormatException ; 33 import javax.jms.MessageNotWriteableException ; 34 35 import org.apache.activemq.ActiveMQConnection; 36 import org.apache.activemq.filter.PropertyExpression; 37 import org.apache.activemq.state.CommandVisitor; 38 import org.apache.activemq.util.Callback; 39 import org.apache.activemq.util.JMSExceptionSupport; 40 import org.apache.activemq.util.TypeConversionSupport; 41 42 47 public class ActiveMQMessage extends Message implements org.apache.activemq.Message { 48 49 public static final byte DATA_STRUCTURE_TYPE = CommandTypes.ACTIVEMQ_MESSAGE; 50 51 public byte getDataStructureType() { 52 return DATA_STRUCTURE_TYPE; 53 } 54 55 transient protected Callback acknowledgeCallback; 56 transient int hashCode; 57 58 public Message copy() { 59 ActiveMQMessage copy = new ActiveMQMessage(); 60 copy(copy); 61 return copy; 62 } 63 64 65 protected void copy(ActiveMQMessage copy) { 66 super.copy(copy); 67 copy.acknowledgeCallback = acknowledgeCallback; 68 } 69 70 public int hashCode() { 71 MessageId id = getMessageId(); 72 if (id != null) { 73 return id.hashCode(); 74 } 75 else { 76 return super.hashCode(); 77 } 78 } 79 80 public boolean equals(Object o) { 81 if (this == o) 82 return true; 83 if (o == null || o.getClass() != getClass()) 84 return false; 85 86 ActiveMQMessage msg = (ActiveMQMessage) o; 87 MessageId oMsg = msg.getMessageId(); 88 MessageId thisMsg = this.getMessageId(); 89 return thisMsg != null && oMsg != null && oMsg.equals(thisMsg); 90 } 91 92 public void acknowledge() throws JMSException { 93 if (acknowledgeCallback != null) { 94 try { 95 acknowledgeCallback.execute(); 96 } catch (JMSException e) { 97 throw e; 98 } catch (Throwable e) { 99 throw JMSExceptionSupport.create(e); 100 } 101 } 102 } 103 104 public void clearBody() throws JMSException { 105 setContent(null); 106 readOnlyBody = false; 107 } 108 109 public String getJMSMessageID() { 110 MessageId messageId = this.getMessageId(); 111 if (messageId == null) { 112 return null; 113 } 114 return messageId.toString(); 115 } 116 117 124 public void setJMSMessageID(String value) throws JMSException { 125 if( value !=null ) { 126 try { 127 MessageId id = new MessageId(value); 128 this.setMessageId(id); 129 } 130 catch (NumberFormatException e) { 131 MessageId id = new MessageId(); 134 id.setTextView(value); 135 this.setMessageId(messageId); 136 } 137 } else { 138 this.setMessageId(null); 139 } 140 } 141 142 150 public void setJMSMessageID(ProducerId producerId, long producerSequenceId) throws JMSException { 151 MessageId id = null; 152 try { 153 id = new MessageId(producerId, producerSequenceId); 154 this.setMessageId(id); 155 } catch (Throwable e) { 156 throw JMSExceptionSupport.create("Invalid message id '" + id + "', reason: " + e.getMessage(), e); 157 } 158 } 159 160 public long getJMSTimestamp() { 161 return this.getTimestamp(); 162 } 163 164 public void setJMSTimestamp(long timestamp) { 165 this.setTimestamp(timestamp); 166 } 167 168 public String getJMSCorrelationID() { 169 return this.getCorrelationId(); 170 } 171 172 public void setJMSCorrelationID(String correlationId) { 173 this.setCorrelationId(correlationId); 174 } 175 176 public byte[] getJMSCorrelationIDAsBytes() throws JMSException { 177 return encodeString(this.getCorrelationId()); 178 } 179 180 public void setJMSCorrelationIDAsBytes(byte[] correlationId) throws JMSException { 181 this.setCorrelationId(decodeString(correlationId)); 182 } 183 184 public String getJMSXMimeType() { 185 return "jms/message"; 186 } 187 188 static protected String decodeString(byte[] data) throws JMSException { 189 try { 190 if (data == null) { 191 return null; 192 } 193 return new String (data, "UTF-8"); 194 } catch (UnsupportedEncodingException e) { 195 throw new JMSException ("Invalid UTF-8 encoding: " + e.getMessage()); 196 } 197 } 198 199 static protected byte[] encodeString(String data) throws JMSException { 200 try { 201 if (data == null) { 202 return null; 203 } 204 return data.getBytes("UTF-8"); 205 } catch (UnsupportedEncodingException e) { 206 throw new JMSException ("Invalid UTF-8 encoding: " + e.getMessage()); 207 } 208 } 209 210 public Destination getJMSReplyTo() { 211 return this.getReplyTo(); 212 } 213 214 public void setJMSReplyTo(Destination destination) throws JMSException { 215 this.setReplyTo(ActiveMQDestination.transform(destination)); 216 } 217 218 public Destination getJMSDestination() { 219 return this.getDestination(); 220 } 221 222 public void setJMSDestination(Destination destination) throws JMSException { 223 this.setDestination(ActiveMQDestination.transform(destination)); 224 } 225 226 public int getJMSDeliveryMode() { 227 return this.isPersistent() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT; 228 } 229 230 public void setJMSDeliveryMode(int mode) { 231 this.setPersistent(mode==DeliveryMode.PERSISTENT); 232 } 233 234 public boolean getJMSRedelivered() { 235 return this.isRedelivered(); 236 } 237 238 public void setJMSRedelivered(boolean redelivered) { 239 this.setRedelivered(redelivered); 240 } 241 242 public String getJMSType() { 243 return this.getType(); 244 } 245 246 public void setJMSType(String type) { 247 this.setType(type); 248 } 249 250 public long getJMSExpiration() { 251 return this.getExpiration(); 252 } 253 254 public void setJMSExpiration(long expiration) { 255 this.setExpiration(expiration); 256 } 257 258 public int getJMSPriority() { 259 return this.getPriority(); 260 } 261 262 public void setJMSPriority(int priority) { 263 this.setPriority((byte) priority); 264 } 265 266 public void clearProperties() { 267 super.clearProperties(); 268 readOnlyProperties = false; 269 } 270 271 public boolean propertyExists(String name) throws JMSException { 272 try { 273 return this.getProperties().containsKey(name); 274 } catch (IOException e) { 275 throw JMSExceptionSupport.create(e); 276 } 277 } 278 279 public Enumeration getPropertyNames() throws JMSException { 280 try { 281 return new Vector (this.getProperties().keySet()).elements(); 282 } catch (IOException e) { 283 throw JMSExceptionSupport.create(e); 284 } 285 } 286 287 interface PropertySetter { 288 public void set(Message message, Object value) throws MessageFormatException ; 289 } 290 291 static final private HashMap JMS_PROPERTY_SETERS = new HashMap (); 292 static { 293 JMS_PROPERTY_SETERS.put("JMSXDeliveryCount", new PropertySetter() { 294 public void set(Message message, Object value) throws MessageFormatException { 295 Integer rc = (Integer )TypeConversionSupport.convert(value, Integer .class); 296 if( rc == null ) { 297 throw new MessageFormatException ("Property JMSXDeliveryCount cannot be set from a "+value.getClass().getName()+"."); 298 } 299 message.setRedeliveryCounter(rc.intValue()-1); 300 } 301 }); 302 JMS_PROPERTY_SETERS.put("JMSXGroupID", new PropertySetter() { 303 public void set(Message message, Object value) throws MessageFormatException { 304 String rc = (String )TypeConversionSupport.convert(value, String .class); 305 if( rc == null ) { 306 throw new MessageFormatException ("Property JMSXGroupID cannot be set from a "+value.getClass().getName()+"."); 307 } 308 message.setGroupID(rc); 309 } 310 }); 311 JMS_PROPERTY_SETERS.put("JMSXGroupSeq", new PropertySetter() { 312 public void set(Message message, Object value) throws MessageFormatException { 313 Integer rc = (Integer )TypeConversionSupport.convert(value, Integer .class); 314 if( rc == null ) { 315 throw new MessageFormatException ("Property JMSXGroupSeq cannot be set from a "+value.getClass().getName()+"."); 316 } 317 message.setGroupSequence(rc.intValue()); 318 } 319 }); 320 JMS_PROPERTY_SETERS.put("JMSCorrelationID", new PropertySetter() { 321 public void set(Message message, Object value) throws MessageFormatException { 322 String rc = (String )TypeConversionSupport.convert(value, String .class); 323 if( rc == null ) { 324 throw new MessageFormatException ("Property JMSCorrelationID cannot be set from a "+value.getClass().getName()+"."); 325 } 326 ((ActiveMQMessage)message).setJMSCorrelationID(rc); 327 } 328 }); 329 JMS_PROPERTY_SETERS.put("JMSExpiration", new PropertySetter() { 330 public void set(Message message, Object value) throws MessageFormatException { 331 Long rc = (Long )TypeConversionSupport.convert(value, Long .class); 332 if( rc == null ) { 333 throw new MessageFormatException ("Property JMSExpiration cannot be set from a "+value.getClass().getName()+"."); 334 } 335 ((ActiveMQMessage)message).setJMSExpiration(rc.longValue()); 336 } 337 }); 338 JMS_PROPERTY_SETERS.put("JMSPriority", new PropertySetter() { 339 public void set(Message message, Object value) throws MessageFormatException { 340 Integer rc = (Integer )TypeConversionSupport.convert(value, Integer .class); 341 if( rc == null ) { 342 throw new MessageFormatException ("Property JMSPriority cannot be set from a "+value.getClass().getName()+"."); 343 } 344 ((ActiveMQMessage)message).setJMSPriority(rc.intValue()); 345 } 346 }); 347 JMS_PROPERTY_SETERS.put("JMSRedelivered", new PropertySetter() { 348 public void set(Message message, Object value) throws MessageFormatException { 349 Boolean rc = (Boolean )TypeConversionSupport.convert(value, Boolean .class); 350 if( rc == null ) { 351 throw new MessageFormatException ("Property JMSRedelivered cannot be set from a "+value.getClass().getName()+"."); 352 } 353 ((ActiveMQMessage)message).setJMSRedelivered(rc.booleanValue()); 354 } 355 }); 356 JMS_PROPERTY_SETERS.put("JMSReplyTo", new PropertySetter() { 357 public void set(Message message, Object value) throws MessageFormatException { 358 ActiveMQDestination rc = (ActiveMQDestination)TypeConversionSupport.convert(value, ActiveMQDestination.class); 359 if( rc == null ) { 360 throw new MessageFormatException ("Property JMSReplyTo cannot be set from a "+value.getClass().getName()+"."); 361 } 362 ((ActiveMQMessage)message).setReplyTo(rc); 363 } 364 }); 365 JMS_PROPERTY_SETERS.put("JMSTimestamp", new PropertySetter() { 366 public void set(Message message, Object value) throws MessageFormatException { 367 Long rc = (Long )TypeConversionSupport.convert(value, Long .class); 368 if( rc == null ) { 369 throw new MessageFormatException ("Property JMSTimestamp cannot be set from a "+value.getClass().getName()+"."); 370 } 371 ((ActiveMQMessage)message).setJMSTimestamp(rc.longValue()); 372 } 373 }); 374 JMS_PROPERTY_SETERS.put("JMSType", new PropertySetter() { 375 public void set(Message message, Object value) throws MessageFormatException { 376 String rc = (String )TypeConversionSupport.convert(value, String .class); 377 if( rc == null ) { 378 throw new MessageFormatException ("Property JMSType cannot be set from a "+value.getClass().getName()+"."); 379 } 380 ((ActiveMQMessage)message).setJMSType(rc); 381 } 382 }); 383 } 384 385 public void setObjectProperty(String name, Object value) throws JMSException { 386 setObjectProperty(name,value,true); 387 } 388 389 public void setObjectProperty(String name, Object value, boolean checkReadOnly) throws JMSException { 390 391 if (checkReadOnly) { 392 checkReadOnlyProperties(); 393 } 394 if (name == null || name.equals("")) { 395 throw new IllegalArgumentException ("Property name cannot be empty or null"); 396 } 397 398 checkValidObject(value); 399 PropertySetter setter = (PropertySetter) JMS_PROPERTY_SETERS.get(name); 400 401 if( setter != null ) { 402 setter.set(this,value); 403 } else { 404 try { 405 this.setProperty(name, value); 406 } catch (IOException e) { 407 throw JMSExceptionSupport.create(e); 408 } 409 } 410 } 411 412 public void setProperties(Map properties) throws JMSException { 413 for (Iterator iter = properties.entrySet().iterator(); iter.hasNext();) { 414 Map.Entry entry = (Map.Entry ) iter.next(); 415 416 setObjectProperty((String ) entry.getKey(), entry.getValue()); 418 } 419 } 420 421 422 protected void checkValidObject(Object value) throws MessageFormatException { 423 if (!(value instanceof Boolean || value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long 424 || value instanceof Float || value instanceof Double || value instanceof Character || value instanceof String || value == null)) { 425 426 ActiveMQConnection conn = getConnection(); 427 if (conn == null || conn.isNestedMapAndListEnabled()) { 429 if (!(value instanceof Map || value instanceof List )) { 430 throw new MessageFormatException ("Only objectified primitive objects, String, Map and List types are allowed but was: " + value + " type: " 431 + value.getClass()); 432 } 433 } 434 else { 435 throw new MessageFormatException ("Only objectified primitive objects and String types are allowed but was: " + value + " type: " 436 + value.getClass()); 437 } 438 } 439 } 440 441 public Object getObjectProperty(String name) throws JMSException { 442 if (name == null) { 443 throw new NullPointerException ("Property name cannot be null"); 444 } 445 446 PropertyExpression expression = new PropertyExpression(name); 448 return expression.evaluate(this); 449 } 450 451 public boolean getBooleanProperty(String name) throws JMSException { 452 Object value = getObjectProperty(name); 453 if( value == null ) 454 return false; 455 Boolean rc = (Boolean )TypeConversionSupport.convert(value, Boolean .class); 456 if( rc == null ) { 457 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as a boolean"); 458 } 459 return rc.booleanValue(); 460 } 461 462 public byte getByteProperty(String name) throws JMSException { 463 Object value = getObjectProperty(name); 464 if( value == null ) 465 throw new NumberFormatException ("property "+name+" was null"); 466 Byte rc = (Byte )TypeConversionSupport.convert(value, Byte .class); 467 if( rc == null ) { 468 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as a byte"); 469 } 470 return rc.byteValue(); 471 } 472 473 public short getShortProperty(String name) throws JMSException { 474 Object value = getObjectProperty(name); 475 if( value == null ) 476 throw new NumberFormatException ("property "+name+" was null"); 477 Short rc = (Short )TypeConversionSupport.convert(value, Short .class); 478 if( rc == null ) { 479 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as a short"); 480 } 481 return rc.shortValue(); 482 } 483 484 public int getIntProperty(String name) throws JMSException { 485 Object value = getObjectProperty(name); 486 if( value == null ) 487 throw new NumberFormatException ("property "+name+" was null"); 488 Integer rc = (Integer )TypeConversionSupport.convert(value, Integer .class); 489 if( rc == null ) { 490 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as an integer"); 491 } 492 return rc.intValue(); 493 } 494 495 public long getLongProperty(String name) throws JMSException { 496 Object value = getObjectProperty(name); 497 if( value == null ) 498 throw new NumberFormatException ("property "+name+" was null"); 499 Long rc = (Long )TypeConversionSupport.convert(value, Long .class); 500 if( rc == null ) { 501 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as a long"); 502 } 503 return rc.longValue(); 504 } 505 506 public float getFloatProperty(String name) throws JMSException { 507 Object value = getObjectProperty(name); 508 if( value == null ) 509 throw new NullPointerException ("property "+name+" was null"); 510 Float rc = (Float )TypeConversionSupport.convert(value, Float .class); 511 if( rc == null ) { 512 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as a float"); 513 } 514 return rc.floatValue(); 515 } 516 517 public double getDoubleProperty(String name) throws JMSException { 518 Object value = getObjectProperty(name); 519 if( value == null ) 520 throw new NullPointerException ("property "+name+" was null"); 521 Double rc = (Double )TypeConversionSupport.convert(value, Double .class); 522 if( rc == null ) { 523 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as a double"); 524 } 525 return rc.doubleValue(); 526 } 527 528 public String getStringProperty(String name) throws JMSException { 529 Object value = getObjectProperty(name); 530 if( value == null ) { 531 if (name.equals("JMSXUserID")) { 532 value = getUserID(); 533 } 534 } 535 if( value == null ) 536 return null; 537 String rc = (String )TypeConversionSupport.convert(value, String .class); 538 if( rc == null ) { 539 throw new MessageFormatException ("Property "+name+" was a "+value.getClass().getName()+" and cannot be read as a String"); 540 } 541 return rc; 542 } 543 544 public void setBooleanProperty(String name, boolean value) throws JMSException { 545 setBooleanProperty(name,value,true); 546 } 547 public void setBooleanProperty(String name, boolean value,boolean checkReadOnly) throws JMSException { 548 setObjectProperty(name, value ? Boolean.TRUE : Boolean.FALSE,checkReadOnly); 549 } 550 551 public void setByteProperty(String name, byte value) throws JMSException { 552 setObjectProperty(name, new Byte (value)); 553 } 554 555 public void setShortProperty(String name, short value) throws JMSException { 556 setObjectProperty(name, new Short (value)); 557 } 558 559 public void setIntProperty(String name, int value) throws JMSException { 560 setObjectProperty(name, new Integer (value)); 561 } 562 563 public void setLongProperty(String name, long value) throws JMSException { 564 setObjectProperty(name, new Long (value)); 565 } 566 567 public void setFloatProperty(String name, float value) throws JMSException { 568 setObjectProperty(name, new Float (value)); 569 } 570 571 public void setDoubleProperty(String name, double value) throws JMSException { 572 setObjectProperty(name, new Double (value)); 573 } 574 575 public void setStringProperty(String name, String value) throws JMSException { 576 setObjectProperty(name, value); 577 } 578 579 580 private void checkReadOnlyProperties() throws MessageNotWriteableException { 581 if (readOnlyProperties) { 582 throw new MessageNotWriteableException ("Message properties are read-only"); 583 } 584 } 585 586 protected void checkReadOnlyBody() throws MessageNotWriteableException { 587 if (readOnlyBody) { 588 throw new MessageNotWriteableException ("Message body is read-only"); 589 } 590 } 591 592 public boolean isExpired() { 593 long expireTime = this.getExpiration(); 594 if (expireTime > 0 && System.currentTimeMillis() > expireTime) { 595 return true; 596 } 597 return false; 598 } 599 600 public Callback getAcknowledgeCallback() { 601 return acknowledgeCallback; 602 } 603 604 public void setAcknowledgeCallback(Callback acknowledgeCallback) { 605 this.acknowledgeCallback = acknowledgeCallback; 606 } 607 608 611 public void onSend() throws JMSException { 612 setReadOnlyBody(true); 613 setReadOnlyProperties(true); 614 } 615 616 617 public Response visit(CommandVisitor visitor) throws Exception { 618 return visitor.processMessage( this ); 619 } 620 } 621 | Popular Tags |