1 45 package org.openejb.webadmin.clienttools; 46 47 import java.io.ByteArrayOutputStream ; 48 import java.io.IOException ; 49 import java.io.PrintStream ; 50 import java.io.PrintWriter ; 51 import java.lang.reflect.InvocationTargetException ; 52 import java.lang.reflect.Method ; 53 import java.lang.reflect.Modifier ; 54 import java.util.HashMap ; 55 import java.util.Iterator ; 56 import java.util.Set ; 57 58 import org.openejb.webadmin.HttpRequest; 59 import org.openejb.webadmin.HttpResponse; 60 import org.openejb.webadmin.HttpSession; 61 import org.openejb.webadmin.WebAdminBean; 62 63 66 public class InvokeObjectBean extends WebAdminBean implements Constants { 67 68 private PrintWriter out; 69 private static String invLock = "lock"; 70 private static int invCount; 71 72 private HttpSession session; 73 74 public void preProcess(HttpRequest request, HttpResponse response) 75 throws IOException { 76 } 77 78 public void postProcess(HttpRequest request, HttpResponse response) 79 throws IOException { 80 } 81 82 public void writeHtmlTitle(PrintWriter out) throws IOException { 83 out.write("Client Tools -- Object Invoker"); 84 } 85 86 public void writePageTitle(PrintWriter out) throws IOException { 87 out.write("Object Invoker"); 88 } 89 90 public void writeBody(PrintWriter out) throws IOException { 91 this.out = out; 92 try{ 93 synchronized (this) { 94 main(request.getSession(), out); 95 } 96 } catch (Exception e){ 97 out.println("FAIL"); 98 return; 100 } 101 } 102 103 class Invocation { 104 105 protected String id = "inv"; 106 protected String objID; 107 protected Class clazz; 108 protected Object target; 109 protected Method method; 110 protected Object [] args; 111 protected Object result; 112 113 protected Invocation(){ 114 synchronized (invLock){ 115 id += ++invCount; 116 } 117 } 118 119 public Object invoke() throws Exception { 120 if (target == null || method == null || args == null) { 121 throw new Exception ("This invocation contains null objects."); 122 } 123 return method.invoke(target,args); 124 } 125 } 126 127 130 public void main(HttpSession session, PrintWriter out) throws Exception { 131 this.session = session; 132 this.out = out; 133 134 printObjectSection(); 135 } 136 137 142 public void printObjectSection() throws Exception { 143 String removeID = request.getQueryParameter("remove"); 144 if (removeID != null) { 145 removeObject(removeID); 146 } 147 148 Invocation inv = null; 149 String invID = request.getQueryParameter("inv"); 150 151 if (invID == null) { 152 String objID = request.getQueryParameter("obj"); 153 if (objID != null) { 154 inv = new Invocation(); 155 inv.target = getObject(objID); 156 inv.objID = objID; 157 setInvocation(inv.id,inv); 158 } 159 } else { 160 inv = getInvocation(invID); 161 } 162 163 if (inv == null || inv.target == null) { 164 printObjectList(); 166 167 } else { 168 out.print("<b>Object:</b><br>"); 169 out.print(tab+inv.objID+" <a HREF='"+INVOKE_OBJ+"'>[change]</a><br><br>"); 170 171 printMethodSection(inv); 173 } 174 } 175 176 179 public void printObjectList() throws Exception { 180 181 HashMap objects = getObjectMap(); 182 if (objects.size() == 0){ 183 out.print("<b>No object have been created</b><br>"); 184 out.print("<table>"); 185 printRow(pepperImg,"<A HREF='"+VIEW_JNDI+"'>Browse for an EJB</A>"); 186 out.print("</table>"); 187 188 } else { 189 out.print("<b>Pick and object to invoke</b><br>"); 190 191 Set keys = objects.keySet(); 193 Iterator iterator = keys.iterator(); 194 out.print("<table>"); 195 while (iterator.hasNext()) { 196 String entry = (String )iterator.next(); 197 printRow(tab+"<a HREF='"+INVOKE_OBJ+"?obj="+entry+"'>"+entry+"</a>", 198 "<a HREF='"+INVOKE_OBJ+"?remove="+entry+"'>[remove]</a>"); 199 } 200 out.print("</table>"); 201 } 202 } 203 208 public void printMethodSection(Invocation inv) throws Exception { 209 String methodID = request.getQueryParameter("m"); 210 211 if (methodID != null) { 212 int method = Integer.parseInt(methodID); 213 Method [] methods = inv.clazz.getMethods(); 214 if (method > -1 && method < methods.length) { 215 inv.method = methods[method]; 216 } else { 217 inv.method = null; 218 inv.args = null; 219 } 220 } 221 222 if (inv.method == null) { 223 printMethodList(inv); 225 226 } else { 227 out.print("<b>Method:</b><br>"); 228 out.print(tab+formatMethod(inv.method)+" <a HREF='"+INVOKE_OBJ+"?m=-1&inv="+inv.id+"'>[change]</a><br><br>"); 229 230 printArgumentSection(inv); 232 } 233 234 } 235 236 239 public void printMethodList(Invocation inv) throws Exception { 240 out.print("<b>Pick a method to invoke</b><br>"); 241 243 Object obj = inv.target; 244 Class clazz = inv.target.getClass(); 245 if (obj instanceof javax.ejb.EJBHome ) { 246 clazz = obj.getClass().getInterfaces()[0]; 247 } else if (obj instanceof javax.ejb.EJBObject ) { 248 clazz = obj.getClass().getInterfaces()[0]; 249 } else { 250 clazz = obj.getClass(); 251 } 252 inv.clazz = clazz; 253 254 out.print("<table>"); 255 Method [] methods = clazz.getMethods(); 256 for (int i=0; i < methods.length; i++){ 257 Method m = methods[i]; 258 if (Modifier.isPublic(m.getModifiers())){ 259 out.print("<tr><td><font size='2'>"); 260 out.print(tab+"<a HREF='"+INVOKE_OBJ+"?inv="+inv.id+"&m="+i+"'>"+formatMethod(m)+"</a><br>"); 261 out.print("</font></td></tr>"); 262 } 263 } 264 out.print("</table>"); 265 } 266 267 272 public void printArgumentSection(Invocation inv) throws Exception { 273 String args = request.getQueryParameter("args"); 274 275 if (args != null) { 276 parseArgs(inv); 277 } 278 279 if (inv.method.getParameterTypes().length == 0) { 280 inv.args = new Object []{}; 281 } 282 283 if (inv.args == null) { 284 printArgumentList(inv); 285 } else { 286 out.print("<b>Arguments:</b><br>"); 287 if (inv.args.length == 0) { 288 out.print(tab+"none<br>"); 289 } 290 for (int i=0; i < inv.args.length; i++){ 291 String val = formatObject(inv.args[i]); 292 out.print(tab+"arg"+i+" <i>"+val+"</i><br>"); 293 } 294 out.print("<br>"); 295 printInvokeSection(inv); 296 } 297 } 298 299 public void parseArgs(Invocation inv) throws Exception { 300 Class [] pTypes = inv.method.getParameterTypes(); 301 inv.args = new Object [pTypes.length]; 302 303 for (int i=0; i < pTypes.length; i++){ 304 Class type = pTypes[i]; 305 String unparsedArg = request.getQueryParameter("arg"+i); 306 inv.args[i] = getConverter(type).convert(type, unparsedArg); 307 } 308 } 309 310 public void printArgumentList(Invocation inv) throws Exception { 311 out.print("<b>Fill in the arguments</b><br>"); 312 Class [] pTypes = inv.method.getParameterTypes(); 313 out.print("<FORM NAME='args' METHOD='GET' ACTION='"+INVOKE_OBJ+"'>"); 314 out.print("<INPUT type='HIDDEN' NAME='inv' VALUE='"+inv.id+"'>"); 315 out.print("<table>"); 316 for (int i=0; i < pTypes.length; i++){ 317 Converter con = getConverter(pTypes[i]); 318 out.print("<tr>"); 319 out.print("<td align='right'><font size='2'>"); 320 out.print(tab+getShortClassRef(pTypes[i])); 321 out.print("</font></td>"); 322 out.print("<td><font size='2'>"); 323 out.print(" arg"+i); 324 out.print("</font></td>"); 325 out.print("<td><font size='2'>"); 326 out.print(" "+con.getInputControl(i,pTypes[i])); 327 out.print("</font></td>"); 328 } 329 out.print("</table>"); 330 331 out.print("<br><br>"); 332 out.print("<INPUT type='SUBMIT' NAME='args' value='Continue'>"); 333 out.print("</form>"); 334 335 } 336 337 342 public void printInvokeSection(Invocation inv) throws Exception { 343 String doInvoke = request.getQueryParameter("invoke"); 344 if (doInvoke != null) { 345 invoke(inv); 346 } else { 347 out.print("<FORM NAME='invoke' METHOD='GET' ACTION='"+INVOKE_OBJ+"'>"); 348 out.print("<INPUT type='HIDDEN' NAME='inv' VALUE='"+inv.id+"'>"); 349 out.print("<INPUT type='SUBMIT' NAME='invoke' value='Invoke'>"); 350 out.print("</FORM>"); 351 } 352 353 } 354 String pepperImg = "<img SRC='/images/pepper.gif' border='0'>"; 355 public void invoke(Invocation inv) throws Exception { 356 357 try{ 358 inv.result = inv.invoke(); 359 360 out.print("<b>Result:</b><br>"); 361 if (inv.method.getReturnType() == java.lang.Void.TYPE) { 362 out.print(tab+"Done"); 363 } else if (inv.result == null) { 364 out.print(tab+"<i>null</i>"); 365 } else { 366 String clazz = inv.result.getClass().getName(); 367 String objID = getObjectID(inv.result); 368 setObject(objID,inv.result); 369 370 out.print("<table>"); 371 printRow("<i>id</i>",objID); 372 printRow("<i>class</i>","<a HREF='"+VIEW_CLASS+"?class="+clazz+"'>"+clazz+"</a>"); 373 printRow("<i>toString</i>",formatObject(inv.result)); 374 out.print("</table>"); 375 376 out.print("<br><br><b>Actions:</b><br>"); 377 out.print("<table>"); 378 String invokerURL = "<a HREF='"+INVOKE_OBJ+"?obj="+objID+"'>Invoke a method on the object</a>"; 379 printRow(pepperImg,invokerURL); 380 String discardURL = "<a HREF='"+INVOKE_OBJ+"?remove="+objID+"'>Discard the object</a>"; 381 printRow(pepperImg,discardURL); 382 out.print("</table>"); 383 } 384 } catch (InvocationTargetException e){ 385 out.print("<b>Exception:</b><br><br>"); 386 Throwable t = e.getTargetException(); 387 out.print("Received a "+t.getClass().getName()); 388 if (t instanceof java.rmi.RemoteException ) { 390 out.print(" <a HREF='re-help.html'>[Tip]</a><br><br>"); 391 java.rmi.RemoteException re = (java.rmi.RemoteException )t; 392 out.print("<i>RemoteException message:</i><br>"); 393 out.print(t.getMessage()+"<br><br>"); 394 out.print("<i>Nested exception's stack trace:</i><br>"); 395 396 while (t instanceof java.rmi.RemoteException ) { 397 t = ((java.rmi.RemoteException )t).detail; 398 } 399 out.print(formatThrowable(t)); 400 } else { 401 out.print("<br><br>"+formatThrowable(t)); 402 } 403 404 } catch (Throwable e){ 405 out.print("<b>Exception:</b><br><br>"); 406 out.print(formatObject(e)); 407 } 408 } 409 410 public String formatThrowable(Throwable err) throws Exception { 411 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 412 err.printStackTrace(new PrintStream (baos)); 413 byte[] bytes = baos.toByteArray(); 414 StringBuffer sb = new StringBuffer (bytes.length); 415 for (int i=0; i < bytes.length; i++){ 416 char c = (char)bytes[i]; 417 switch (c) { 418 case ' ': sb.append(" "); break; 419 case '\n': sb.append("<br>"); break; 420 case '\r': break; 421 default: sb.append(c); 422 } 423 } 424 return sb.toString(); 425 } 426 427 428 public String formatObject(Object obj) throws Exception { 429 int max = 75; 430 String val = obj.toString(); 431 val = (val.length() > max)? val.substring(0,max-3)+"...":val; 432 char[] chars = new char[val.length()]; 433 val.getChars(0,chars.length,chars,0); 434 435 StringBuffer sb = new StringBuffer (chars.length); 436 for (int j=0; j < chars.length; j++){ 437 char c = chars[j]; 438 switch (c) { 439 case '<': sb.append("<"); break; 440 case '>': sb.append(">"); break; 441 case '&': sb.append("&"); break; 442 default: sb.append(c); 443 } 444 } 445 return sb.toString(); 446 } 447 448 449 451 public String formatMethod(Method m) throws Exception { 452 StringBuffer sb = new StringBuffer (); 453 454 sb.append(getShortClassName(m.getReturnType())+" "); 455 sb.append(m.getName()); 456 457 Class [] params = m.getParameterTypes(); 458 sb.append("("); 459 for (int j=0; j < params.length; j++){ 460 sb.append(getShortClassName(params[j])); 461 if (j != params.length-1) { 462 sb.append(", "); 463 } 464 } 465 sb.append(")"); 466 467 Class [] excp = m.getExceptionTypes(); 468 if (excp.length > 0) { 469 sb.append(" throws "); 470 for (int j=0; j < excp.length; j++){ 471 sb.append(getShortClassName(excp[j])); 472 if (j != excp.length-1) { 473 sb.append(", "); 474 } 475 } 476 } 477 return sb.toString(); 478 } 479 480 481 483 public String getShortClassName(Class clazz) throws Exception { 484 if (clazz.isPrimitive()) { 485 return clazz.getName(); 486 } else if (clazz.isArray() && clazz.getComponentType().isPrimitive()) { 487 return clazz.getComponentType()+"[]"; 488 } else if (clazz.isArray()) { 489 String name = clazz.getComponentType().getName(); 490 int dot = name.lastIndexOf(".")+1; 491 String shortName = name.substring(dot,name.length()); 492 return shortName+"[]"; 493 } else { 494 String name = clazz.getName(); 495 int dot = name.lastIndexOf(".")+1; 496 String shortName = name.substring(dot,name.length()); 497 return shortName; 498 } 499 } 500 501 public String getShortClassRef(Class clazz) throws Exception { 502 if (clazz.isPrimitive()) { 503 return "<font color='gray'>"+clazz.getName()+"</font>"; 504 } else if (clazz.isArray() && clazz.getComponentType().isPrimitive()) { 505 return "<font color='gray'>"+clazz.getComponentType()+"[]</font>"; 506 } else if (clazz.isArray()) { 507 String name = clazz.getComponentType().getName(); 508 int dot = name.lastIndexOf(".")+1; 509 String shortName = name.substring(dot,name.length()); 510 return "<a HREF='"+VIEW_CLASS+"?class="+name+"'>"+shortName+"[]</a>"; 511 } else { 512 String name = clazz.getName(); 513 int dot = name.lastIndexOf(".")+1; 514 String shortName = name.substring(dot,name.length()); 515 return "<a HREF='"+VIEW_CLASS+"?class="+name+"'>"+shortName+"</a>"; 516 } 517 } 518 519 protected void printRow(String col1, String col2) throws Exception { 520 out.print("<tr><td><font size='2'>" ); 521 out.print(col1); 522 out.print("</font></td><td><font size='2'>"); 523 out.print(col2); 524 out.print("</font></td></tr>"); 525 } 526 527 528 530 public String getObjectID(Object obj){ 531 Class clazz = obj.getClass(); 532 if (obj instanceof javax.ejb.EJBHome ) { 533 clazz = obj.getClass().getInterfaces()[0]; 534 } else if (obj instanceof javax.ejb.EJBObject ) { 535 clazz = obj.getClass().getInterfaces()[0]; 536 } 537 return clazz.getName()+"@"+obj.hashCode(); 538 } 539 540 public Object getObject(String objID){ 541 return getObjectMap().get(objID); 542 } 543 544 public void setObject(String objID, Object obj){ 545 getObjectMap().put(objID, obj); 546 } 547 548 public void removeObject(String objID){ 549 getObjectMap().remove(objID); 550 } 551 552 public HashMap getObjectMap(){ 553 HashMap objects = (HashMap )session.getAttribute("objects"); 554 if (objects == null) { 555 objects = new HashMap (); 556 session.setAttribute("objects",objects); 557 } 558 return objects; 559 } 560 561 562 564 public Invocation getInvocation(String invID) { 565 return (Invocation)getInvocationMap().get(invID); 566 } 567 568 public void setInvocation(String invID, Invocation obj){ 569 getInvocationMap().put(invID, obj); 570 } 571 572 public HashMap getInvocationMap(){ 573 HttpSession session = request.getSession(); 574 HashMap invocations = (HashMap )session.getAttribute("invocations"); 575 if (invocations == null) { 576 invocations = new HashMap (); 577 session.setAttribute("invocations",invocations); 578 } 579 return invocations; 580 } 581 582 583 585 final HashMap converters = initConverters(); 586 587 public Converter getConverter(Class type){ 588 Converter con = (Converter) converters.get(type); 589 if (con == null) { 590 con = defaultConverter; 591 } 592 return con; 593 } 594 595 final Converter defaultConverter = new ObjectConverter(); 596 597 private HashMap initConverters(){ 598 HashMap map = new HashMap (); 599 600 map.put(String .class, new StringConverter()); 601 map.put(Character .class, new CharacterConverter()); 602 map.put(Boolean .class, new BooleanConverter()); 603 map.put(Byte .class, new ByteConverter()); 604 map.put(Short .class, new ShortConverter()); 605 map.put(Integer .class, new IntegerConverter()); 606 map.put(Long .class, new LongConverter()); 607 map.put(Float .class, new FloatConverter()); 608 map.put(Double .class, new DoubleConverter()); 609 map.put(Object .class, new ObjectConverter()); 610 map.put(Character.TYPE, map.get(Character .class)); 611 map.put(Boolean.TYPE, map.get(Boolean .class)); 612 map.put(Byte.TYPE, map.get(Byte .class)); 613 map.put(Short.TYPE, map.get(Short .class)); 614 map.put(Integer.TYPE, map.get(Integer .class)); 615 map.put(Long.TYPE, map.get(Long .class)); 616 map.put(Float.TYPE, map.get(Float .class)); 617 map.put(Double.TYPE, map.get(Double .class)); 618 619 return map; 620 } 621 622 623 abstract class Converter { 624 public abstract Object convert(Class type, String raw) throws Exception ; 625 public String getInputControl(int argNumber, Class type) throws Exception { 626 return "<INPUT type='text' NAME='arg"+argNumber+"'>"; 627 } 628 } 629 630 class StringConverter extends Converter{ 631 public Object convert(Class type, String raw) throws Exception { 632 return raw; 633 } 634 } 635 636 class CharacterConverter extends Converter{ 637 public Object convert(Class type, String raw) throws Exception { 638 return new Character (raw.charAt(0)); 639 } 640 } 641 642 class BooleanConverter extends Converter{ 643 public Object convert(Class type, String raw) throws Exception { 644 return new Boolean (raw); 645 } 646 } 647 648 class ByteConverter extends Converter{ 649 public Object convert(Class type, String raw) throws Exception { 650 return new Byte (raw); 651 } 652 } 653 654 class ShortConverter extends Converter{ 655 public Object convert(Class type, String raw) throws Exception { 656 return new Short (raw); 657 } 658 } 659 660 class IntegerConverter extends Converter{ 661 public Object convert(Class type, String raw) throws Exception { 662 return new Integer (raw); 663 } 664 } 665 666 class LongConverter extends Converter{ 667 public Object convert(Class type, String raw) throws Exception { 668 return new Long (raw); 669 } 670 } 671 672 class FloatConverter extends Converter{ 673 public Object convert(Class type, String raw) throws Exception { 674 return new Float (raw); 675 } 676 } 677 678 class DoubleConverter extends Converter{ 679 public Object convert(Class type, String raw) throws Exception { 680 return new Double (raw); 681 } 682 } 683 684 class ObjectConverter extends Converter{ 685 public Object convert(Class type, String raw) throws Exception { 686 return raw; 687 } 688 } 689 } 690 | Popular Tags |