001 package com.mockrunner.mock.jms; 002 003 import java.util.Arrays; 004 import java.util.Collections; 005 import java.util.Stack; 006 import java.util.Vector; 007 008 import javax.jms.JMSException; 009 import javax.jms.MessageEOFException; 010 import javax.jms.MessageFormatException; 011 import javax.jms.MessageNotReadableException; 012 import javax.jms.MessageNotWriteableException; 013 import javax.jms.StreamMessage; 014 015 import com.mockrunner.util.common.ArrayUtil; 016 017 /** 018 * Mock implementation of JMS <code>StreamMessage</code>. 019 */ 020 public class MockStreamMessage extends MockMessage implements StreamMessage 021 { 022 private Stack data; 023 024 public MockStreamMessage() 025 { 026 data = new Stack(); 027 } 028 029 public boolean readBoolean() throws JMSException 030 { 031 if(isInWriteMode()) 032 { 033 throw new MessageNotReadableException("Message is in write mode"); 034 } 035 if(data.empty()) 036 { 037 throw new MessageEOFException("No more data"); 038 } 039 Object value = readObject(); 040 if(null == value) return Boolean.valueOf(null).booleanValue(); 041 if(value instanceof Boolean) 042 { 043 return ((Boolean)value).booleanValue(); 044 } 045 if(value instanceof String) 046 { 047 return Boolean.valueOf((String)value).booleanValue(); 048 } 049 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to boolean"); 050 } 051 052 public byte readByte() throws JMSException 053 { 054 if(isInWriteMode()) 055 { 056 throw new MessageNotReadableException("Message is in write mode"); 057 } 058 if(data.empty()) 059 { 060 throw new MessageEOFException("No more data"); 061 } 062 Object value = readObject(); 063 if(null == value) return Byte.valueOf(null).byteValue(); 064 if(value instanceof Byte) 065 { 066 return ((Byte)value).byteValue(); 067 } 068 if(value instanceof String) 069 { 070 return Byte.valueOf((String)value).byteValue(); 071 } 072 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to byte"); 073 } 074 075 public short readShort() throws JMSException 076 { 077 if(isInWriteMode()) 078 { 079 throw new MessageNotReadableException("Message is in write mode"); 080 } 081 if(data.empty()) 082 { 083 throw new MessageEOFException("No more data"); 084 } 085 Object value = readObject(); 086 if(null == value) return Short.valueOf(null).shortValue(); 087 if((value instanceof Byte) || (value instanceof Short)) 088 { 089 return ((Number)value).shortValue(); 090 } 091 if(value instanceof String) 092 { 093 return Short.valueOf((String)value).shortValue(); 094 } 095 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to short"); 096 } 097 098 public char readChar() throws JMSException 099 { 100 if(isInWriteMode()) 101 { 102 throw new MessageNotReadableException("Message is in write mode"); 103 } 104 if(data.empty()) 105 { 106 throw new MessageEOFException("No more data"); 107 } 108 Object value = readObject(); 109 if(null == value) 110 { 111 throw new NullPointerException(); 112 } 113 if(value instanceof Character) 114 { 115 return ((Character)value).charValue(); 116 } 117 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to char"); 118 } 119 120 public int readInt() throws JMSException 121 { 122 if(isInWriteMode()) 123 { 124 throw new MessageNotReadableException("Message is in write mode"); 125 } 126 if(data.empty()) 127 { 128 throw new MessageEOFException("No more data"); 129 } 130 Object value = readObject(); 131 if(null == value) return Integer.valueOf(null).intValue(); 132 if((value instanceof Byte) || (value instanceof Short) || (value instanceof Integer)) 133 { 134 return ((Number)value).intValue(); 135 } 136 if(value instanceof String) 137 { 138 return Integer.valueOf((String)value).intValue(); 139 } 140 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to int"); 141 } 142 143 public long readLong() throws JMSException 144 { 145 if(isInWriteMode()) 146 { 147 throw new MessageNotReadableException("Message is in write mode"); 148 } 149 if(data.empty()) 150 { 151 throw new MessageEOFException("No more data"); 152 } 153 Object value = readObject(); 154 if(null == value) return Long.valueOf(null).longValue(); 155 if((value instanceof Byte) || (value instanceof Short) || (value instanceof Integer) || (value instanceof Long)) 156 { 157 return ((Number)value).longValue(); 158 } 159 if(value instanceof String) 160 { 161 return Long.valueOf((String)value).longValue(); 162 } 163 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to long"); 164 } 165 166 public float readFloat() throws JMSException 167 { 168 if(isInWriteMode()) 169 { 170 throw new MessageNotReadableException("Message is in write mode"); 171 } 172 if(data.empty()) 173 { 174 throw new MessageEOFException("No more data"); 175 } 176 Object value = readObject(); 177 if(null == value) return Float.valueOf(null).floatValue(); 178 if(value instanceof Float) 179 { 180 return ((Float)value).floatValue(); 181 } 182 if(value instanceof String) 183 { 184 return Float.valueOf((String)value).floatValue(); 185 } 186 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to float"); 187 } 188 189 public double readDouble() throws JMSException 190 { 191 if(isInWriteMode()) 192 { 193 throw new MessageNotReadableException("Message is in write mode"); 194 } 195 if(data.empty()) 196 { 197 throw new MessageEOFException("No more data"); 198 } 199 Object value = readObject(); 200 if(null == value) return Double.valueOf(null).doubleValue(); 201 if((value instanceof Float) || (value instanceof Double)) 202 { 203 return ((Number)value).doubleValue(); 204 } 205 if(value instanceof String) 206 { 207 return Double.valueOf((String)value).doubleValue(); 208 } 209 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to double"); 210 } 211 212 public String readString() throws JMSException 213 { 214 if(isInWriteMode()) 215 { 216 throw new MessageNotReadableException("Message is in write mode"); 217 } 218 if(data.empty()) 219 { 220 throw new MessageEOFException("No more data"); 221 } 222 Object value = readObject(); 223 if(null == value) return null; 224 if(value instanceof byte[]) 225 { 226 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to String"); 227 } 228 return value.toString(); 229 } 230 231 public int readBytes(byte[] byteData) throws JMSException 232 { 233 if(isInWriteMode()) 234 { 235 throw new MessageNotReadableException("Message is in write mode"); 236 } 237 if(data.empty()) 238 { 239 throw new MessageEOFException("No more data"); 240 } 241 if(null == byteData) return -1; 242 if(0 == byteData.length) return 0; 243 Object value = readObject(); 244 if(null == value) 245 { 246 throw new NullPointerException(); 247 } 248 if(!(value instanceof byte[])) 249 { 250 throw new MessageFormatException(value.getClass().getName() + " cannot be converted to byte[]"); 251 } 252 int length = Math.min(byteData.length, ((byte[])value).length); 253 System.arraycopy(value, 0, byteData, 0, length); 254 return length; 255 } 256 257 public Object readObject() throws JMSException 258 { 259 if(isInWriteMode()) 260 { 261 throw new MessageNotReadableException("Message is in write mode"); 262 } 263 if(data.empty()) 264 { 265 throw new MessageEOFException("No more data"); 266 } 267 return data.pop(); 268 } 269 270 public void writeBoolean(boolean value) throws JMSException 271 { 272 if(!isInWriteMode()) 273 { 274 throw new MessageNotWriteableException("Message is in read mode"); 275 } 276 writeObject(new Boolean(value)); 277 } 278 279 public void writeByte(byte value) throws JMSException 280 { 281 if(!isInWriteMode()) 282 { 283 throw new MessageNotWriteableException("Message is in read mode"); 284 } 285 writeObject(new Byte(value)); 286 } 287 288 public void writeShort(short value) throws JMSException 289 { 290 if(!isInWriteMode()) 291 { 292 throw new MessageNotWriteableException("Message is in read mode"); 293 } 294 writeObject(new Short(value)); 295 } 296 297 public void writeChar(char value) throws JMSException 298 { 299 if(!isInWriteMode()) 300 { 301 throw new MessageNotWriteableException("Message is in read mode"); 302 } 303 writeObject(new Character(value)); 304 } 305 306 public void writeInt(int value) throws JMSException 307 { 308 if(!isInWriteMode()) 309 { 310 throw new MessageNotWriteableException("Message is in read mode"); 311 } 312 writeObject(new Integer(value)); 313 } 314 315 public void writeLong(long value) throws JMSException 316 { 317 if(!isInWriteMode()) 318 { 319 throw new MessageNotWriteableException("Message is in read mode"); 320 } 321 writeObject(new Long(value)); 322 } 323 324 public void writeFloat(float value) throws JMSException 325 { 326 if(!isInWriteMode()) 327 { 328 throw new MessageNotWriteableException("Message is in read mode"); 329 } 330 writeObject(new Float(value)); 331 } 332 333 public void writeDouble(double value) throws JMSException 334 { 335 if(!isInWriteMode()) 336 { 337 throw new MessageNotWriteableException("Message is in read mode"); 338 } 339 writeObject(new Double(value)); 340 } 341 342 public void writeString(String value) throws JMSException 343 { 344 if(!isInWriteMode()) 345 { 346 throw new MessageNotWriteableException("Message is in read mode"); 347 } 348 writeObject(value); 349 } 350 351 public void writeBytes(byte[] data) throws JMSException 352 { 353 if(!isInWriteMode()) 354 { 355 throw new MessageNotWriteableException("Message is in read mode"); 356 } 357 writeObject(data); 358 } 359 360 public void writeBytes(byte[] data, int offset, int length) throws JMSException 361 { 362 if(!isInWriteMode()) 363 { 364 throw new MessageNotWriteableException("Message is in read mode"); 365 } 366 if(null == data) 367 { 368 writeObject(null); 369 return; 370 } 371 writeObject(ArrayUtil.truncateArray(data, offset, length)); 372 } 373 374 public void writeObject(Object object) throws JMSException 375 { 376 if(!isInWriteMode()) 377 { 378 throw new MessageNotWriteableException("Message is in read mode"); 379 } 380 if(null == object) 381 { 382 data.push(object); 383 return; 384 } 385 if((object instanceof String) || (object instanceof Number) || (object instanceof Character) || (object instanceof Boolean)) 386 { 387 data.push(object); 388 return; 389 } 390 if(object instanceof byte[]) 391 { 392 byte[] arrayData = (byte[])((byte[])object).clone(); 393 data.push(arrayData); 394 return; 395 } 396 throw new MessageFormatException(object.getClass() + " not a valid type"); 397 } 398 399 public void reset() throws JMSException 400 { 401 setReadOnly(true); 402 Collections.reverse(data); 403 } 404 405 public void clearBody() throws JMSException 406 { 407 super.clearBody(); 408 data = new Stack(); 409 } 410 411 /** 412 * Compares the underlying stream data. 413 */ 414 public boolean equals(Object otherObject) 415 { 416 if(null == otherObject) return false; 417 if(!(otherObject instanceof MockStreamMessage)) return false; 418 MockStreamMessage otherMessage = (MockStreamMessage)otherObject; 419 if(data.size() != otherMessage.data.size()) return false; 420 Vector otherData = otherMessage.data; 421 if(isInWriteMode() != otherMessage.isInWriteMode()) 422 { 423 otherData = new Vector(otherData); 424 Collections.reverse(otherData); 425 } 426 for(int ii = 0; ii < data.size(); ii++) 427 { 428 Object nextValue = data.get(ii); 429 Object otherValue = otherData.get(ii); 430 if(null == nextValue) 431 { 432 if(null != otherValue) return false; 433 } 434 else if(nextValue instanceof byte[]) 435 { 436 if(null == otherValue) return false; 437 if(!(otherValue instanceof byte[])) return false; 438 if(!Arrays.equals((byte[])nextValue, (byte[])otherValue)) return false; 439 } 440 else 441 { 442 if(!nextValue.equals(otherValue)) return false; 443 } 444 } 445 return true; 446 } 447 448 public int hashCode() 449 { 450 int value = 0; 451 for(int ii = 0; ii < data.size(); ii++) 452 { 453 Object nextValue = data.get(ii); 454 if(nextValue instanceof byte[]) 455 { 456 for(int yy = 0; yy < ((byte[])nextValue).length; yy++) 457 { 458 value += 31 * ((byte[])nextValue)[yy]; 459 } 460 } 461 else if(nextValue != null) 462 { 463 value += 31 * nextValue.hashCode(); 464 } 465 } 466 return value; 467 } 468 469 public Object clone() 470 { 471 MockStreamMessage message = (MockStreamMessage)super.clone(); 472 message.data = new Stack(); 473 for(int ii = 0; ii < data.size(); ii++) 474 { 475 Object nextValue = data.get(ii); 476 if(nextValue instanceof byte[]) 477 { 478 message.data.add(((byte[])nextValue).clone()); 479 } 480 else 481 { 482 message.data.add(nextValue); 483 } 484 } 485 return message; 486 } 487 488 public String toString() 489 { 490 return this.getClass().getName() + ": " + data.toString(); 491 } 492 }