1 4 5 9 10 64 package org.openlaszlo.data; 65 66 import java.io.*; 67 import java.lang.reflect.*; 68 import java.util.*; 69 import java.net.MalformedURLException ; 70 import javax.servlet.http.*; 71 import org.apache.xmlrpc.*; 72 import org.openlaszlo.server.LPS; 73 import org.openlaszlo.server.Option; 74 import org.openlaszlo.xml.*; 75 import org.openlaszlo.xml.internal.*; 76 import org.openlaszlo.utils.*; 77 import org.openlaszlo.remote.*; 78 import org.openlaszlo.servlets.LoadCount; 80 import org.openlaszlo.media.MimeType; 81 import org.apache.log4j.*; 82 83 86 public class JavaDataSource extends DataSource 87 { 88 private static Logger mLogger = Logger.getLogger(JavaDataSource.class); 89 90 private static String OBJECTS = "__lzobj"; 91 92 96 final public static int LOAD_INVOKE = 0x01; 97 final public static int LOAD_STATIC_GET_PROTO = 0x02; 98 final public static int LOAD_INSTANCE_CREATE_PROTO = 0x04; 99 final public static int LOAD_INSTANCE_GET_PROTO = 0x08; 100 final public static int LOAD_INSTANCE_DESTROY_PROTO = 0x10; 101 final public static int LOAD_INSTANCE_GET_INVOKE_TARGET = 0x20; 102 final public static int LOAD_RETURN_OBJECT_ENCODE = 0x40; 103 104 static long mLastCleared = -1; 105 106 public static VersionMap mSessionPrototypes = new VersionMap(); 108 public static VersionMap mWebAppPrototypes = new VersionMap(); 110 public static VersionMap mStaticPrototypes = new VersionMap(); 112 113 public static ThreadSafeCounter mSessionCounter 115 = new ThreadSafeCounter(); 116 public static ThreadSafeCounter mSessionObjectsCounter 118 = new ThreadSafeCounter(); 119 public static ThreadSafeCounter mWebAppObjectsCounter = 121 new ThreadSafeCounter(); 122 123 public static LoadCount mJavaRPCLoad = new LoadCount(10); 124 public static LoadCount mInvokeLoad = new LoadCount(10); 125 public static LoadCount mReturnObjectEncodeLoad = new LoadCount(10); 126 public static LoadCount mStaticProtoGetLoad = new LoadCount(10); 127 public static LoadCount mInstanceProtoCreateLoad = new LoadCount(10); 128 public static LoadCount mInstanceProtoGetLoad = new LoadCount(10); 129 public static LoadCount mInstanceProtoDestroyLoad = new LoadCount(10); 130 public static LoadCount mInstanceGetInvokeTargetLoad = new LoadCount(10); 131 132 136 static final String UNKNOWN = "unknown"; 137 static final String SESSION = "session"; 138 static final String WEBAPP = "webapp"; 139 static final String NONE = "none"; 140 141 static final int SCOPE_UNKNOWN = -1; 142 static final int SCOPE_SESSION = 0; 143 static final int SCOPE_WEBAPP = 1; 144 static final int SCOPE_NONE = 2; 145 146 HashMap mVoidMap = null; 147 ObjectData DEFAULT_VOID; 148 149 public JavaDataSource() { 150 clearLoadInfo(); 151 try { 152 DEFAULT_VOID = new ObjectData 153 (XMLRPCCompiler.compileResponse(0, "void", 154 LPS.mSWFVersionNumDefault)); 155 } catch (IOException e) { 156 mLogger.error("exception: " + e.getMessage(), e); 157 throw new RuntimeException (e.getMessage()); 158 } 159 } 160 161 164 public String name() 165 { 166 return "java"; 167 } 168 169 175 public Data getData(String app, HttpServletRequest req, 176 HttpServletResponse res, long lastModifiedTime) 177 throws DataSourceException { 178 mLogger.debug("getData"); 179 180 int swfversion = LPS.getSWFVersionNum(req); 181 182 if (! req.getMethod().equals("POST")) 183 return compileFault("request must be POST", swfversion); 184 185 String url; 186 try { 187 url = getURL(req); 188 } catch (MalformedURLException e) { 189 return compileFault("malformed url", e, swfversion); 190 } 191 192 String cname = getClassName(url); 193 if (cname == null) 194 return compileFault("invalid class or bad url: " + url, swfversion); 195 196 if (! isClassOk(cname, req.getServletPath())) 197 return compileFault("forbidden class: " + cname, swfversion); 198 199 Class targetClass = getClass(cname); 200 if (targetClass == null) 201 return compileFault("no such class " + cname, swfversion); 202 203 int scope = getScope(req); 204 if (scope == SCOPE_UNKNOWN) 205 return compileFault("no scope request parameter", swfversion); 206 207 String postbody = req.getParameter("lzpostbody"); 208 if (postbody == null || postbody.equals("")) 209 return compileFault("no post body", swfversion); 210 211 String objectReturnType = req.getParameter("objectreturntype"); 213 if (objectReturnType == null || "".equals(objectReturnType)) { 214 objectReturnType = "pojo"; 215 } 216 217 if (mLogger.isDebugEnabled()) { 218 mLogger.debug("class name: " + cname); 219 mLogger.debug("object return type: " + objectReturnType); 220 mLogger.debug("POST body:\n" + postbody); 221 } 222 223 XmlRpcRequest xr = new LZXmlRpcRequestProcessor() 224 .processRequest(new ByteArrayInputStream(postbody.getBytes())); 225 226 long t0, t1; 227 t0 = System.currentTimeMillis(); 228 mJavaRPCLoad.increment(); 229 try { 230 return execute(req, res, targetClass, scope, objectReturnType, 231 swfversion, xr.getMethodName(), xr.getParameters()); 232 } catch (IOException e) { 233 return compileFault("exception executing " + xr.getMethodName(), e, 234 swfversion); 235 } finally { 236 t1 = System.currentTimeMillis(); 237 mJavaRPCLoad.decrement((int)(t1-t0)); 238 } 239 } 240 241 244 public boolean isClassOk(String cname, String path) { 245 return LPS.configuration.optionAllows(path, "security", cname, false); 246 } 247 248 252 public Data execute(HttpServletRequest req, HttpServletResponse res, 253 Class targetClass, int scope, String objectReturnType, 254 int swfversion, String methodName, 255 Vector params) throws IOException { 256 257 if (mLogger.isDebugEnabled()) { 258 StringBuffer p = new StringBuffer (" "); 259 for (int i=0; i < params.size(); i++) { 260 p.append(params.get(i)).append(" "); 261 } 262 mLogger.debug("execute(" + methodName 263 + ", [" + p.toString() + "],context)"); 264 } 265 266 Class [] argClasses = null; 267 Object [] argValues = null; 268 269 String _doreq = req.getParameter("doreq"); 270 String _dores = req.getParameter("dores"); 271 boolean doreq = (_doreq != null && _doreq.equals("1")); 272 boolean dores = (_dores != null && _dores.equals("1")); 273 274 int reqPos = -1; int resPos = -1; 277 int httpCount = 0; 279 int paramCount = (params != null ? params.size() : 0); 280 281 if (doreq) { 283 mLogger.debug("adding request to method"); 284 reqPos = paramCount; 285 httpCount++; 286 } 287 288 if (dores) { 291 mLogger.debug("adding response to method"); 292 resPos = (reqPos != -1 ? reqPos + 1 : paramCount); 293 httpCount++; 294 } 295 296 int count = paramCount + httpCount; 298 argClasses = new Class [count]; 299 argValues = new Object [count]; 300 301 if (doreq) { 302 argClasses[reqPos] = HttpServletRequest.class; 303 argValues[reqPos] = req; 304 } 305 306 if (dores) { 307 argClasses[resPos] = HttpServletResponse.class; 308 argValues[resPos] = res; 309 } 310 311 if (params != null) { 312 for (int i = 0; i < params.size(); i++) { 313 argValues[i] = params.elementAt(i); 314 if (argValues[i] instanceof Integer ) { 315 argClasses[i] = Integer.TYPE; 316 } else if (argValues[i] instanceof Double ) { 317 argClasses[i] = Double.TYPE; 318 } else if (argValues[i] instanceof Boolean ) { 319 argClasses[i] = Boolean.TYPE; 320 } else { 321 argClasses[i] = argValues[i].getClass(); 322 } 323 } 324 } 325 326 Method method = null; 327 Object invokeTarget = targetClass; 328 long t0, t1; 329 330 String op = req.getParameter("op"); 331 if (op != null) { 332 333 String cname = targetClass.getName(); 334 String oname = req.getParameter("oname"); 335 if (scope == SCOPE_NONE) oname= NONE; 336 if (oname == null || "".equals(oname)) 337 return compileFault("no oname parameter", swfversion); 338 339 if (scope == SCOPE_NONE) { 340 if ("get".equals(op) || "create".equals(op)) { 341 t0 = System.currentTimeMillis(); 342 mStaticProtoGetLoad.increment(); 343 try { 344 return getStaticPrototype(cname, swfversion); 345 } finally { 346 t1 = System.currentTimeMillis(); 347 mStaticProtoGetLoad.decrement((int)(t1-t0)); 348 } 349 } 350 } 351 352 if ( scope == SCOPE_SESSION || scope == SCOPE_WEBAPP ) { 353 354 if ("get".equals(op)) { 355 t0 = System.currentTimeMillis(); 356 mInstanceProtoGetLoad.increment(); 357 try { 358 return getInstancePrototype(cname, oname, scope, req, 359 swfversion); 360 } finally { 361 t1 = System.currentTimeMillis(); 362 mInstanceProtoGetLoad.decrement((int)(t1-t0)); 363 } 364 } 365 366 if ("create".equals(op)) { 367 t0 = System.currentTimeMillis(); 368 mInstanceProtoCreateLoad.increment(); 369 try { 370 return createInstancePrototype(cname, oname, scope, 371 argClasses, argValues, req, 372 swfversion); 373 } finally { 374 t1 = System.currentTimeMillis(); 375 mInstanceProtoCreateLoad.decrement((int)(t1-t0)); 376 } 377 } 378 379 if ("destroy".equals(op)) { 380 t0 = System.currentTimeMillis(); 381 mInstanceProtoDestroyLoad.increment(); 382 try { 383 return destroyInstance(oname, scope, req, swfversion); 384 } finally { 385 t1 = System.currentTimeMillis(); 386 mInstanceProtoDestroyLoad.decrement((int)(t1-t0)); 387 } 388 } 389 390 if ("invoke".equals(op)) { 391 t0 = System.currentTimeMillis(); 392 mInstanceGetInvokeTargetLoad.increment(); 393 try { 394 invokeTarget = getInvokeTarget(oname, scope, req); 395 } finally { 396 t1 = System.currentTimeMillis(); 397 mInstanceGetInvokeTargetLoad.decrement((int)(t1-t0)); 398 } 399 if (invokeTarget == null) { 400 String errmsg = "could not find " + getScopeName(scope) 401 + " instance " + oname; 402 mLogger.error(errmsg); 403 return compileFault(errmsg, swfversion); 404 } 405 } 406 } 407 } 408 409 t0 = System.currentTimeMillis(); 410 mInvokeLoad.increment(); 411 Object returnValue = null; 412 try { 413 int dot = methodName.lastIndexOf('.'); 416 if (dot > -1 && dot + 1 < methodName.length()) { 417 methodName = methodName.substring(dot + 1); 418 } 419 420 if (mLogger.isDebugEnabled()) { 421 mLogger.debug("Searching for method: " + methodName + 422 " in class " + targetClass.getName()); 423 if (argClasses.length != 0) { 424 for (int i = 0; i < argClasses.length; i++) { 425 mLogger.debug("Parameter " + i + ": " + argValues[i] 426 + " (" + argClasses[i] + ')'); 427 } 428 } 429 } 430 431 try { 432 method = getMethod(targetClass, methodName, argClasses); 433 } catch(NoSuchMethodException e) { 434 mLogger.error("NoSuchMethodException", e); 435 return compileFault(e.getMessage(), e, swfversion); 436 } catch(SecurityException e) { 437 mLogger.error("SecurityException", e); 438 return compileFault(e.getMessage(), e, swfversion); 439 } 440 441 if (method.getDeclaringClass() == Object .class) { 444 return compileFault("Can't call methods in java.lang.Object", swfversion); 445 } 446 447 try { 449 returnValue = method.invoke(invokeTarget, argValues); 450 } catch (IllegalAccessException e) { 451 mLogger.error("IllegalAccessException", e); 452 return compileFault(e.getMessage(), e, swfversion); 453 } catch (IllegalArgumentException e) { 454 mLogger.error("IllegalArgumentException", e); 455 return compileFault(e.getMessage(), e, swfversion); 456 } catch (InvocationTargetException e) { 457 mLogger.error("InvocationTargetException", e); 458 Throwable cause = e.getCause(); 459 if (cause != null) return compileFault(cause, swfversion); 460 return compileFault(e.getMessage(), e, swfversion); 461 } catch (Exception e) { 462 mLogger.error("Exception", e); 463 return compileFault(e.getMessage(), e, swfversion); 464 } catch (Error e) { 465 mLogger.error("Error", e); 466 return compileFault(e.getMessage(), e, swfversion); 467 } 468 } finally { 469 t1 = System.currentTimeMillis(); 470 mInvokeLoad.decrement((int)(t1-t0)); 471 } 472 473 t0 = System.currentTimeMillis(); 474 mReturnObjectEncodeLoad.increment(); 475 try { 476 Class returnType = method.getReturnType(); 477 if (returnType == Void.TYPE) { 478 return getVoid(swfversion); 479 } else if (returnType == DataEncoder.class && returnValue != null) { 480 return new EncoderData((DataEncoder)returnValue); 481 } 482 483 return new ObjectData 484 (LZReturnObject.createObject(returnValue, objectReturnType, 485 swfversion)); 486 } catch (IOException e) { 487 mLogger.error("IOException", e); 488 return compileFault(e.getMessage(), e, swfversion); 489 } finally { 490 t1 = System.currentTimeMillis(); 491 mReturnObjectEncodeLoad.decrement((int)(t1-t0)); 492 } 493 } 494 495 496 synchronized ObjectData getVoid(int swfversion) { 497 if (mVoidMap == null) { 498 mVoidMap = new HashMap(); 499 } 500 ObjectData voidobj; 501 try { 502 Integer _swfversion = new Integer (swfversion); 503 voidobj = (ObjectData)mVoidMap.get(_swfversion); 504 if (voidobj == null) { 505 mLogger.debug("creating void for swf " + swfversion); 506 voidobj = new ObjectData 507 (XMLRPCCompiler.compileResponse(0, "void", swfversion)); 508 mVoidMap.put(_swfversion, voidobj); 509 } 510 } catch (Exception e) { 511 mLogger.warn("using default void", e); 512 voidobj = DEFAULT_VOID; 513 } 514 return voidobj; 515 } 516 517 520 Data getStaticPrototype(String cname, int swfversion) { 521 if (mLogger.isDebugEnabled()) { 522 mLogger.debug("getStaticPrototype(" + cname + ")"); 523 } 524 return getPrototype(cname, SCOPE_NONE, swfversion); 525 } 526 527 528 532 Data getInstancePrototype(String cname, String oname, int scope, 533 HttpServletRequest req, int swfversion) { 534 535 if (mLogger.isDebugEnabled()) { 536 mLogger.debug("getInstancePrototype(" + cname + "," + oname + ")"); 537 } 538 539 Integer swfv = new Integer (swfversion); 540 if (getJavaObject(req.getSession(false), scope, oname) != null) { 541 if (scope == SCOPE_WEBAPP) { 542 return (Data)mWebAppPrototypes.get(swfv, cname); 543 } else if (scope == SCOPE_SESSION) { 544 return (Data)mSessionPrototypes.get(swfv, cname); 545 } 546 } 547 548 String errmsg = "couldn't find "+getScopeName(scope)+" instance "+oname; 549 mLogger.error(errmsg); 550 return compileFault(errmsg, swfversion); 551 } 552 553 554 557 Data createInstancePrototype(String cname, String oname, int scope, 558 Class [] argClasses, Object [] argValues, 559 HttpServletRequest req, int swfversion) { 560 561 if (mLogger.isDebugEnabled()) { 562 mLogger.debug("createInstancePrototype(" + cname + "," + oname + ")"); 563 } 564 565 HttpSession session = req.getSession(true); 567 568 String _clobber = req.getParameter("clobber"); 569 boolean clobber = (_clobber != null && "1".equals(_clobber)); 570 571 Object o = null; 572 if (! clobber ) { 573 o = getJavaObject(session, scope, oname); 574 if (o != null) { 575 if (mLogger.isDebugEnabled()) { 576 mLogger.debug("not clobbering existing " + 577 getScopeName(scope) + 578 " object " + oname ); 579 } 580 return getPrototype(cname, scope, swfversion); 581 } 582 } 583 584 try { 586 o = getServerInstance(cname, argClasses, argValues); 587 setJavaObject(session, scope, oname, o); 588 } catch (Exception e) { 589 return compileFault("could not create instance of " + cname, e, 590 swfversion); 591 } 592 593 return getPrototype(cname, scope, swfversion); 594 } 595 596 597 600 synchronized Data getPrototype(String cname, int scope, int swfversion) { 601 Integer swfv = new Integer (swfversion); 602 try { 603 Data data; 604 if (scope == SCOPE_NONE) { 605 data = (Data)mStaticPrototypes.get(swfv, cname); 606 } else if (scope == SCOPE_WEBAPP) { 607 data = (Data)mWebAppPrototypes.get(swfv, cname); 608 } else { 609 data = (Data)mSessionPrototypes.get(swfv, cname); 610 } 611 612 if (data == null) { 613 mLogger.debug("creating client prototype for " + cname); 614 byte[] b = LZClientObject.createObject(cname, getScopeName(scope), 615 swfversion); 616 data = new ObjectData(b); 617 if (scope == SCOPE_NONE) { 618 mStaticPrototypes.put(swfv, cname, data); 619 } else if (scope == SCOPE_WEBAPP) { 620 mWebAppPrototypes.put(swfv, cname, data); 621 } else { 622 mSessionPrototypes.put(swfv, cname, data); 623 } 624 } 625 626 return data; 627 } catch (Exception e) { 628 return compileFault("could not get " + cname + 629 " in scope " + getScopeName(scope), e, 630 swfversion); 631 } 632 } 633 634 635 636 641 Data destroyInstance(String oname, int scope, HttpServletRequest req, 646 int swfversion) { 647 648 if (mLogger.isDebugEnabled()) { 649 mLogger.debug("destroyInstance(" + oname + ", " + scope); 650 } 651 removeJavaObject(req.getSession(false), scope, oname); 652 return getVoid(swfversion); 653 } 654 655 658 Object getInvokeTarget(String oname, int scope, HttpServletRequest req) { 659 return getJavaObject(req.getSession(false), scope, oname); 660 } 661 662 663 String getClassName(String url) { 664 if (url.startsWith("java://")) return url.substring(7); 665 return null; 666 } 667 668 Class getClass(String cname) { 669 try { 670 return Class.forName(cname); 671 } catch (ClassNotFoundException e) { 672 mLogger.error("class not found: " + cname); 673 } 674 return null; 675 } 676 677 678 679 683 boolean paramTypesMatch(Class [] pt1, Class [] pt2) { 684 if (pt1.length != pt2.length) 685 return false; 686 687 for (int i=0; i < pt1.length; i++) { 688 if ( ! pt1[i].isAssignableFrom(pt2[i]) ) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 698 Object getServerInstance(String classname, Class [] argClasses, Object [] argValues) 699 throws Exception { 700 701 if (mLogger.isDebugEnabled()) { 702 mLogger.debug("getServerInstance(" + classname + ")"); 703 } 704 705 Class cl = Class.forName(classname); 706 707 Constructor constructor = null; 708 Constructor[] carr = cl.getConstructors(); 709 for (int i=0; i < carr.length; i++) { 710 Class [] ptarr = carr[i].getParameterTypes(); 711 if ( paramTypesMatch(ptarr, argClasses) ) { 712 constructor = carr[i]; 713 break; 714 } 715 } 716 717 if (constructor == null) { 718 StringBuffer buf = new StringBuffer (); 719 for (int i=0; i < argClasses.length; i++) { 720 if (i != 0) buf.append(","); 721 buf.append(argClasses[i].toString()); 722 } 723 String msg = "no such constructor found: " + classname + 724 "(" + buf.toString() + ")"; 725 mLogger.error(msg); 726 throw new Exception (msg); 727 } 728 729 return constructor.newInstance(argValues); 730 } 731 732 733 734 735 738 Method getMethod(Class cl, String methodName, Class [] params) 739 throws NoSuchMethodException { 740 741 743 Method[] classMethods = cl.getMethods(); 744 for (int m=0; m < classMethods.length; m++) { 745 746 if ( ! methodName.equals(classMethods[m].getName()) ) continue; 748 749 Class [] classParams = classMethods[m].getParameterTypes(); 751 if (classParams.length == 0 && params == null) 752 return classMethods[m]; 753 754 if (classParams.length == params.length) { 755 boolean ok = true; 756 for (int p=0; p < classParams.length; p++) { 757 if ( ! classParams[p].isAssignableFrom(params[p]) ) { 758 ok = false; 759 break; 760 } 761 } 762 if (ok) return classMethods[m]; 763 } 764 } 765 766 StringBuffer buf = new StringBuffer (); 767 for (int i=0; i < params.length; i++) { 768 if (i != 0) buf.append(", "); 769 buf.append(params[i].toString()); 770 } 771 throw new NoSuchMethodException (methodName + "(" + buf.toString() + "): no such method"); 772 } 773 774 775 String getScopeName(int scope) { 776 if (SCOPE_SESSION == scope) return SESSION; 777 if (SCOPE_WEBAPP == scope) return WEBAPP; 778 if (SCOPE_NONE == scope) return NONE; 779 return UNKNOWN; 780 } 781 782 int getScope(HttpServletRequest req) { 783 String scope = req.getParameter("scope"); 784 if (scope == null) return SCOPE_UNKNOWN; 785 if (SESSION.equals(scope)) return SCOPE_SESSION; 786 if (WEBAPP.equals(scope)) return SCOPE_WEBAPP; 787 if (NONE.equals(scope)) return SCOPE_NONE; 788 return SCOPE_UNKNOWN; 789 } 790 791 792 Object getJavaObject(HttpSession session, int scope, String oname) { 793 if (session == null) return null; 794 Map map = null; 795 if (scope == SCOPE_SESSION) { 796 map = (Map)session.getAttribute(OBJECTS); 797 } else if (scope == SCOPE_WEBAPP) { 798 map = (Map)session.getServletContext().getAttribute(OBJECTS); 799 } 800 return ( map == null ? null : map.get(oname) ); 801 } 802 803 804 807 void setJavaObject(HttpSession session, int scope, String oname, Object val){ 808 if (session == null) { 809 if (mLogger.isDebugEnabled()) { 810 mLogger.debug("setting java object with no session in scope " 811 + getScopeName(scope)); 812 } 813 return; 814 } 815 Map map = null; 816 if (scope == SCOPE_SESSION) { 817 map = (Map)session.getAttribute(OBJECTS); 818 if ( map == null ) { 819 map = new SessionBindingMap(); 820 session.setAttribute(OBJECTS, map); 821 } 823 } else if (scope == SCOPE_WEBAPP) { 824 map = (Map)session.getServletContext().getAttribute(OBJECTS); 825 if ( map == null ) { 826 map = new HashMap(); 827 session.getServletContext().setAttribute(OBJECTS, map); 828 } 829 } else { 830 mLogger.warn("tried setting object with scope " + getScopeName(scope) 831 + "(" + scope + ")"); 832 return; 833 } 834 835 if (map != null) { 837 Object oldVal = map.put(oname, val); 838 if (oldVal == null) { 839 if (scope == SCOPE_SESSION) { 840 mSessionObjectsCounter.increment(); 841 } else if (scope == SCOPE_WEBAPP) { 842 mWebAppObjectsCounter.increment(); 843 } 844 } 845 } 846 } 847 848 851 void removeJavaObject(HttpSession session, int scope, String oname){ 852 if (session == null) { 853 if (mLogger.isDebugEnabled()) { 854 mLogger.debug("tried removing java object with no session in scope " 855 + getScopeName(scope) + "(" + scope + ")"); 856 } 857 return; 858 } 859 Map map = null; 860 if (scope == SCOPE_SESSION) { 861 map = (Map)session.getAttribute(OBJECTS); 862 } else if (scope == SCOPE_WEBAPP) { 864 map = (Map)session.getServletContext().getAttribute(OBJECTS); 865 } else { 866 mLogger.warn("tried removing object with scope " + getScopeName(scope)); 867 return; 868 } 869 if (map != null) { 870 Object oldVal = map.remove(oname); 871 if (oldVal != null) { 873 if (scope == SCOPE_SESSION) { 874 mSessionObjectsCounter.decrement(); 875 } else if (scope == SCOPE_WEBAPP) { 876 mWebAppObjectsCounter.decrement(); 877 } 878 } 879 } 880 } 881 882 883 886 Data compileFault(Throwable e, int swfversion) { 887 mLogger.error("compileFault", e); 888 return compileFault(e.getMessage(), swfversion); 889 } 890 891 Data compileFault(String mesg, int swfversion) { 892 return compileFault(mesg, null, swfversion); 893 } 894 895 898 Data compileFault(String mesg, Throwable e, int swfversion) { 899 if (e == null) { 900 mLogger.error("compileFault mesg: " + mesg); 901 } else { 902 mLogger.error("compileFault mesg: " + mesg, e); 903 } 904 try { 905 return new ObjectData 906 ( XMLRPCCompiler.compileFault(XMLUtils.escapeXml(mesg), 907 swfversion) ); 908 } catch (Exception ex) { 909 mLogger.error("Exception", ex); 910 throw new Error (e.getMessage()); 912 } 913 } 914 915 916 919 static void toXML(StringBuffer sb, String nodeName, 920 VersionMap m, ThreadSafeCounter objects, 921 ThreadSafeCounter sessions){ 922 sb.append("<").append(nodeName); 923 if (objects != null) { 924 sb.append(" objects=\"").append(objects.getCount()).append("\""); 925 } 926 if (sessions != null) { 927 sb.append(" sessions=\"").append(sessions.getCount()).append("\""); 928 } 929 sb.append(">"); 930 931 Iterator iter = m.keySet().iterator(); 932 while (iter.hasNext()) { 933 String k = (String )iter.next(); 934 Map versions = (Map)m.getVersions(k); 935 Iterator viter = versions.keySet().iterator(); 936 sb.append("<prototype class=\"").append(k).append("\"") 937 .append(" versions=\""); 938 while (viter.hasNext()) { 939 Integer swfv = (Integer )viter.next(); 940 sb.append(swfv).append(","); 941 } 942 sb.deleteCharAt(sb.length()-1).append("\"/>"); 943 } 944 sb.append("</").append(nodeName).append(">"); 945 } 946 947 948 public static void clearLoadInfo() { 949 mJavaRPCLoad.reset(); 950 mInvokeLoad.reset(); 951 mReturnObjectEncodeLoad.reset(); 952 mStaticProtoGetLoad.reset(); 953 mInstanceProtoCreateLoad.reset(); 954 mInstanceProtoGetLoad.reset(); 955 mInstanceProtoDestroyLoad.reset(); 956 mInstanceGetInvokeTargetLoad.reset(); 957 mLastCleared = System.currentTimeMillis(); 958 } 959 960 static boolean doXML( int options, int mask ) { 961 return ( options & mask ) == mask; 962 } 963 964 967 synchronized static public String toXML( int options ) { 968 StringBuffer sb = new StringBuffer (); 969 Date lc = new Date(mLastCleared); 970 sb.append("<javarpcinfo ") 971 .append(" last-cleared=\"").append(lc).append("\"") 972 .append(">"); 973 { 974 toXML(sb, "session", mSessionPrototypes, mSessionObjectsCounter, 975 mSessionCounter); 976 toXML(sb, "webapp", mWebAppPrototypes, mWebAppObjectsCounter, null); 977 toXML(sb, "static", mStaticPrototypes, null, null); 978 979 sb.append(mJavaRPCLoad.toXML("javarpc_load")); 980 981 if ( doXML(options, LOAD_INVOKE) ) { 982 sb.append(mInvokeLoad.toXML("invoke_load")); 983 } 984 if ( doXML(options, LOAD_STATIC_GET_PROTO) ) { 985 sb.append(mStaticProtoGetLoad.toXML("static_get_proto_load")); 986 } 987 if ( doXML(options, LOAD_INSTANCE_CREATE_PROTO) ) { 988 sb.append(mInstanceProtoCreateLoad.toXML("instance_create_proto_load")); 989 } 990 if ( doXML(options, LOAD_INSTANCE_GET_PROTO) ) { 991 sb.append(mInstanceProtoGetLoad.toXML("instance_get_proto_load")); 992 } 993 if ( doXML(options, LOAD_INSTANCE_DESTROY_PROTO) ) { 994 sb.append(mInstanceProtoDestroyLoad.toXML("instance_destroy_proto_load")); 995 } 996 if ( doXML(options, LOAD_INSTANCE_GET_INVOKE_TARGET) ) { 997 sb.append(mInstanceGetInvokeTargetLoad.toXML("instance_get_invoke_target_load")); 998 } 999 if ( doXML(options, LOAD_RETURN_OBJECT_ENCODE) ) { 1000 sb.append(mReturnObjectEncodeLoad.toXML("return_object_encode_load")); 1001 } 1002 } 1003 sb.append("</javarpcinfo>"); 1004 return sb.toString(); 1005 } 1006 1007 1008 1009 public class EncoderData extends Data 1010 { 1011 DataEncoder mDataEncoder; 1012 long mSize; 1013 public EncoderData(DataEncoder dataEncoder) 1014 throws IOException { 1015 mDataEncoder = dataEncoder; 1016 mSize = dataEncoder.getSize(); 1017 } 1018 1019 public String getMimeType() { 1020 return MimeType.SWF; 1021 } 1022 1023 1026 public InputStream getInputStream() 1027 throws IOException { 1028 return mDataEncoder.getInputStream(); 1029 } 1030 1031 public long size() { 1032 return mSize; 1033 } 1034 } 1035 1036 1037 1040 public class ObjectData extends Data 1041 { 1042 byte[] mObject; 1043 public ObjectData(byte[] object) { 1044 mObject = object; 1045 } 1046 1047 public String getMimeType() { 1048 return MimeType.SWF; 1049 } 1050 1051 public InputStream getInputStream() 1052 throws IOException { 1053 return new ByteArrayInputStream(mObject); 1054 } 1055 1056 public long size() { 1057 return mObject.length; 1058 } 1059 } 1060} 1061 | Popular Tags |