1 22 package org.jboss.invocation; 23 24 import java.io.DataOutputStream ; 25 import java.io.ByteArrayOutputStream ; 26 import java.io.IOException ; 27 import java.lang.reflect.Method ; 28 import java.security.DigestOutputStream ; 29 import java.security.MessageDigest ; 30 import java.security.Principal ; 31 import java.security.PrivilegedAction ; 32 import java.security.AccessController ; 33 import java.util.Map ; 34 import java.util.Iterator ; 35 import java.util.HashMap ; 36 import java.util.WeakHashMap ; 37 import javax.transaction.Transaction ; 38 39 54 public class MarshalledInvocation 55 extends Invocation 56 implements java.io.Externalizable 57 { 58 60 61 static final long serialVersionUID = -718723094688127810L; 62 65 static boolean useFullHashMode = true; 66 67 static Map hashMap = new WeakHashMap (); 68 69 70 protected Object tpc; 71 72 73 protected transient Map methodMap; 74 75 protected transient long methodHash = 0; 77 protected transient MarshalledValue marshalledArgs = null; 78 79 82 public static boolean getUseFullHashMode() 83 { 84 return useFullHashMode; 85 } 86 97 public static void setUseFullHashMode(boolean flag) 98 { 99 useFullHashMode = flag; 100 } 101 102 110 public static Map getInterfaceHashes(Class intf) 111 { 112 Method [] methods = null; 114 if( System.getSecurityManager() != null ) 115 { 116 DeclaredMethodsAction action = new DeclaredMethodsAction(intf); 117 methods = (Method []) AccessController.doPrivileged(action); 118 } 119 else 120 { 121 methods = intf.getDeclaredMethods(); 122 } 123 124 HashMap map = new HashMap (); 125 for (int i = 0; i < methods.length; i++) 126 { 127 Method method = methods[i]; 128 Class [] parameterTypes = method.getParameterTypes(); 129 String methodDesc = method.getName() + "("; 130 for (int j = 0; j < parameterTypes.length; j++) 131 { 132 methodDesc += getTypeString(parameterTypes[j]); 133 } 134 methodDesc += ")" + getTypeString(method.getReturnType()); 135 136 try 137 { 138 long hash = 0; 139 ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream (512); 140 MessageDigest messagedigest = MessageDigest.getInstance("SHA"); 141 DataOutputStream dataoutputstream = new DataOutputStream (new DigestOutputStream (bytearrayoutputstream, messagedigest)); 142 dataoutputstream.writeUTF(methodDesc); 143 dataoutputstream.flush(); 144 byte abyte0[] = messagedigest.digest(); 145 for (int j = 0; j < Math.min(8, abyte0.length); j++) 146 hash += (long) (abyte0[j] & 0xff) << j * 8; 147 map.put(method.toString(), new Long (hash)); 148 } 149 catch (Exception e) 150 { 151 e.printStackTrace(); 152 } 153 } 154 155 return map; 156 } 157 158 165 public static Map getFullInterfaceHashes(Class intf) 166 { 167 Method [] methods = null; 169 if( System.getSecurityManager() != null ) 170 { 171 DeclaredMethodsAction action = new DeclaredMethodsAction(intf); 172 methods = (Method []) AccessController.doPrivileged(action); 173 } 174 else 175 { 176 methods = intf.getDeclaredMethods(); 177 } 178 179 HashMap map = new HashMap (); 180 for (int i = 0; i < methods.length; i++) 181 { 182 Method method = methods[i]; 183 String methodDesc = method.toString(); 184 185 try 186 { 187 long hash = 0; 188 ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream (512); 189 MessageDigest messagedigest = MessageDigest.getInstance("SHA"); 190 DataOutputStream dataoutputstream = new DataOutputStream (new DigestOutputStream (bytearrayoutputstream, messagedigest)); 191 dataoutputstream.writeUTF(methodDesc); 192 dataoutputstream.flush(); 193 byte abyte0[] = messagedigest.digest(); 194 for (int j = 0; j < Math.min(8, abyte0.length); j++) 195 hash += (long) (abyte0[j] & 0xff) << j * 8; 196 map.put(method.toString(), new Long (hash)); 197 } 198 catch (Exception e) 199 { 200 e.printStackTrace(); 201 } 202 } 203 204 return map; 205 } 206 207 214 public static Map methodToHashesMap(Class c) 215 { 216 Method [] methods = null; 218 if( System.getSecurityManager() != null ) 219 { 220 DeclaredMethodsAction action = new DeclaredMethodsAction(c); 221 methods = (Method []) AccessController.doPrivileged(action); 222 } 223 else 224 { 225 methods = c.getDeclaredMethods(); 226 } 227 228 HashMap map = new HashMap (); 229 for (int i = 0; i < methods.length; i++) 230 { 231 Method method = methods[i]; 232 String methodDesc = method.toString(); 233 234 try 235 { 236 long hash = 0; 237 ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream (512); 238 MessageDigest messagedigest = MessageDigest.getInstance("SHA"); 239 DataOutputStream dataoutputstream = new DataOutputStream (new DigestOutputStream (bytearrayoutputstream, messagedigest)); 240 dataoutputstream.writeUTF(methodDesc); 241 dataoutputstream.flush(); 242 byte abyte0[] = messagedigest.digest(); 243 for (int j = 0; j < Math.min(8, abyte0.length); j++) 244 hash += (long) (abyte0[j] & 0xff) << j * 8; 245 map.put(new Long (hash), method); 246 } 247 catch (Exception e) 248 { 249 e.printStackTrace(); 250 } 251 } 252 253 return map; 254 } 255 256 static String getTypeString(Class cl) 257 { 258 if (cl == Byte.TYPE) 259 { 260 return "B"; 261 } 262 else if (cl == Character.TYPE) 263 { 264 return "C"; 265 } 266 else if (cl == Double.TYPE) 267 { 268 return "D"; 269 } 270 else if (cl == Float.TYPE) 271 { 272 return "F"; 273 } 274 else if (cl == Integer.TYPE) 275 { 276 return "I"; 277 } 278 else if (cl == Long.TYPE) 279 { 280 return "J"; 281 } 282 else if (cl == Short.TYPE) 283 { 284 return "S"; 285 } 286 else if (cl == Boolean.TYPE) 287 { 288 return "Z"; 289 } 290 else if (cl == Void.TYPE) 291 { 292 return "V"; 293 } 294 else if (cl.isArray()) 295 { 296 return "[" + getTypeString(cl.getComponentType()); 297 } 298 else 299 { 300 return "L" + cl.getName().replace('.', '/') + ";"; 301 } 302 } 303 304 310 public static long calculateHash(Method method) 311 { 312 Map methodHashes = (Map ) hashMap.get(method.getDeclaringClass()); 313 314 if (methodHashes == null) 315 { 316 if( useFullHashMode == true ) 318 methodHashes = getFullInterfaceHashes(method.getDeclaringClass()); 319 else 320 methodHashes = getInterfaceHashes(method.getDeclaringClass()); 321 synchronized (hashMap) 322 { 323 hashMap.put(method.getDeclaringClass(), methodHashes); 324 } 325 } 326 327 Long hash = (Long ) methodHashes.get(method.toString()); 328 return hash.longValue(); 329 } 330 331 332 335 public static void removeHashes(Class declaringClass) 336 { 337 synchronized (hashMap) 338 { 339 hashMap.remove(declaringClass); 340 } 341 } 342 343 public MarshalledInvocation() 345 { 346 } 348 349 public MarshalledInvocation(Invocation invocation) 350 { 351 this.payload = invocation.payload; 352 this.as_is_payload = invocation.as_is_payload; 353 this.method = invocation.getMethod(); 354 this.objectName = invocation.getObjectName(); 355 this.args = invocation.getArguments(); 356 this.invocationType = invocation.getType(); 357 } 358 359 360 public MarshalledInvocation( 361 Object id, 362 Method m, 363 Object [] args, 364 Transaction tx, 365 Principal identity, 366 Object credential) 367 { 368 super(id, m, args, tx, identity, credential); 369 } 370 371 public Method getMethod() 372 { 373 if (this.method != null) 374 return this.method; 375 376 this.method = (Method ) methodMap.get(new Long (methodHash)); 378 379 if (this.method == null) 381 { 382 throw new IllegalStateException ("Failed to find method for hash:" + methodHash + " available=" + methodMap); 383 } 384 return this.method; 385 } 386 387 public void setMethodMap(Map methods) 388 { 389 methodMap = methods; 390 } 391 392 public void setTransactionPropagationContext(Object tpc) 394 { 395 this.tpc = tpc; 396 } 397 398 public Object getTransactionPropagationContext() 399 { 400 return tpc; 401 } 402 403 405 410 public Object getValue(Object key) 411 { 412 413 Object value = super.getValue(key); 414 415 if (value instanceof MarshalledValue) 417 { 418 try 419 { 420 MarshalledValue mv = (MarshalledValue) value; 421 value = mv.get(); 422 } 423 catch (Exception e) 424 { 425 JBossLazyUnmarshallingException ise = new JBossLazyUnmarshallingException("getValue failed"); 426 ise.initCause(e); 427 throw ise; 428 } 429 } 430 return value; 431 } 432 433 438 public Object getPayloadValue(Object key) 439 { 440 441 Object value = getPayload().get(key); 442 443 if (value instanceof MarshalledValue) 445 { 446 try 447 { 448 MarshalledValue mv = (MarshalledValue) value; 449 value = mv.get(); 450 } 451 catch (Exception e) 452 { 453 JBossLazyUnmarshallingException ise = new JBossLazyUnmarshallingException("getPayloadValue failed"); 454 ise.initCause(e); 455 throw ise; 456 } 457 } 458 return value; 459 } 460 461 public Object [] getArguments() 462 { 463 if (this.args == null) 464 { 465 try 466 { 467 this.args = (Object []) marshalledArgs.get(); 468 } 469 catch (Exception e) 470 { 471 JBossLazyUnmarshallingException ise = new JBossLazyUnmarshallingException("getArguments failed"); 472 ise.initCause(e); 473 throw ise; 474 } 475 } 476 return args; 477 } 478 479 public void writeExternal(java.io.ObjectOutput out) 481 throws IOException 482 { 483 getAsIsPayload().put(InvocationKey.TYPE, invocationType); 486 out.writeObject(tpc); 489 490 long methodHash = this.methodHash; 491 if(methodHash == 0) 492 { 493 methodHash = calculateHash(this.method); 494 } 495 496 out.writeLong(methodHash); 497 498 out.writeObject(this.objectName); 499 500 if(this.args == null && this.marshalledArgs != null) 501 { 502 out.writeObject(this.marshalledArgs); 503 } 504 else 505 { 506 out.writeObject(new MarshalledValue(this.args)); 507 } 508 509 510 if (payload == null) 519 out.writeInt(0); 520 else 521 { 522 out.writeInt(payload.size()); 523 Iterator keys = payload.keySet().iterator(); 524 while (keys.hasNext()) 525 { 526 Object currentKey = keys.next(); 527 528 531 out.writeObject(currentKey); 532 Object value = payload.get(currentKey); 533 if(!(value instanceof MarshalledValue)) 535 { 536 value = new MarshalledValue(value); 537 } 538 539 out.writeObject(value); 540 } 541 } 542 543 if (as_is_payload == null) 546 out.writeInt(0); 547 else 548 { 549 out.writeInt(as_is_payload.size()); 550 551 Iterator keys = as_is_payload.keySet().iterator(); 552 while (keys.hasNext()) 553 { 554 Object currentKey = keys.next(); 555 out.writeObject(currentKey); 556 out.writeObject(as_is_payload.get(currentKey)); 557 } 558 } 559 } 560 561 public void readExternal(java.io.ObjectInput in) 562 throws IOException , ClassNotFoundException 563 { 564 tpc = in.readObject(); 565 this.methodHash = in.readLong(); 566 567 this.objectName = in.readObject(); 568 569 marshalledArgs = (MarshalledValue) in.readObject(); 570 571 int payloadSize = in.readInt(); 572 if (payloadSize > 0) 573 { 574 payload = new HashMap (); 575 for (int i = 0; i < payloadSize; i++) 576 { 577 Object key = in.readObject(); 578 Object value = in.readObject(); 579 payload.put(key, value); 580 } 581 } 582 583 int as_is_payloadSize = in.readInt(); 584 if (as_is_payloadSize > 0) 585 { 586 as_is_payload = new HashMap (); 587 for (int i = 0; i < as_is_payloadSize; i++) 588 { 589 Object key = in.readObject(); 590 Object value = in.readObject(); 591 as_is_payload.put(key, value); 592 } 593 } 594 invocationType = (InvocationType)getAsIsValue(InvocationKey.TYPE); 597 } 598 599 private static class DeclaredMethodsAction implements PrivilegedAction 600 { 601 Class c; 602 DeclaredMethodsAction(Class c) 603 { 604 this.c = c; 605 } 606 public Object run() 607 { 608 Method [] methods = c.getDeclaredMethods(); 609 c = null; 610 return methods; 611 } 612 } 613 } 614 | Popular Tags |