0001: /* ****************************************************************************
0002: * JavaDataSource.java
0003: * ****************************************************************************/
0004:
0005: /* J_LZ_COPYRIGHT_BEGIN *******************************************************
0006: * Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. *
0007: * Use is subject to license terms. *
0008: * J_LZ_COPYRIGHT_END *********************************************************/
0009:
0010: /*
0011: * The Apache Software License, Version 1.1
0012: *
0013: *
0014: * Copyright(c) 2002 The Apache Software Foundation. All rights
0015: * reserved.
0016: *
0017: * Redistribution and use in source and binary forms, with or without
0018: * modification, are permitted provided that the following conditions
0019: * are met:
0020: *
0021: * 1. Redistributions of source code must retain the above copyright
0022: * notice, this list of conditions and the following disclaimer.
0023: *
0024: * 2. Redistributions in binary form must reproduce the above copyright
0025: * notice, this list of conditions and the following disclaimer in
0026: * the documentation and/or other materials provided with the
0027: * distribution.
0028: *
0029: * 3. The end-user documentation included with the redistribution,
0030: * if any, must include the following acknowledgment:
0031: * "This product includes software developed by the
0032: * Apache Software Foundation(http://www.apache.org/)."
0033: * Alternately, this acknowledgment may appear in the software itself,
0034: * if and wherever such third-party acknowledgments normally appear.
0035: *
0036: * 4. The names "XML-RPC" and "Apache Software Foundation" must
0037: * not be used to endorse or promote products derived from this
0038: * software without prior written permission. For written
0039: * permission, please contact apache@apache.org.
0040: *
0041: * 5. Products derived from this software may not be called "Apache",
0042: * nor may "Apache" appear in their name, without prior written
0043: * permission of the Apache Software Foundation.
0044: *
0045: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0046: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0047: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0048: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0049: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0050: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT
0051: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0052: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0053: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0054: * OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0055: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0056: * SUCH DAMAGE.
0057: * ====================================================================
0058: *
0059: * This software consists of voluntary contributions made by many
0060: * individuals on behalf of the Apache Software Foundation. For more
0061: * information on the Apache Software Foundation, please see
0062: * <http://www.apache.org/>.
0063: */
0064: package org.openlaszlo.data;
0065:
0066: import java.io.*;
0067: import java.lang.reflect.*;
0068: import java.util.*;
0069: import java.net.MalformedURLException;
0070: import javax.servlet.http.*;
0071: import org.apache.xmlrpc.*;
0072: import org.openlaszlo.server.LPS;
0073: import org.openlaszlo.server.Option;
0074: import org.openlaszlo.xml.*;
0075: import org.openlaszlo.xml.internal.*;
0076: import org.openlaszlo.utils.*;
0077: import org.openlaszlo.remote.*; // LoadCount belongs in utils
0078: import org.openlaszlo.servlets.LoadCount;
0079: import org.openlaszlo.media.MimeType;
0080: import org.apache.log4j.*;
0081:
0082: /**
0083: * Data source for java direct calls.
0084: */
0085: public class JavaDataSource extends DataSource {
0086: private static Logger mLogger = Logger
0087: .getLogger(JavaDataSource.class);
0088:
0089: private static String OBJECTS = "__lzobj";
0090:
0091: //------------------------------------------------------------
0092: // Begin javarpc info variables
0093: //------------------------------------------------------------
0094:
0095: final public static int LOAD_INVOKE = 0x01;
0096: final public static int LOAD_STATIC_GET_PROTO = 0x02;
0097: final public static int LOAD_INSTANCE_CREATE_PROTO = 0x04;
0098: final public static int LOAD_INSTANCE_GET_PROTO = 0x08;
0099: final public static int LOAD_INSTANCE_DESTROY_PROTO = 0x10;
0100: final public static int LOAD_INSTANCE_GET_INVOKE_TARGET = 0x20;
0101: final public static int LOAD_RETURN_OBJECT_ENCODE = 0x40;
0102:
0103: static long mLastCleared = -1;
0104:
0105: // Map of SWF prototypes for session objects.
0106: public static VersionMap mSessionPrototypes = new VersionMap();
0107: // Map of SWF prototypes for webapp objects.
0108: public static VersionMap mWebAppPrototypes = new VersionMap();
0109: // Map of SWF prototypes for static objects.
0110: public static VersionMap mStaticPrototypes = new VersionMap();
0111:
0112: // Count of sessions. Also used by SessionBindingMap.
0113: public static ThreadSafeCounter mSessionCounter = new ThreadSafeCounter();
0114: // Count of system-wide objects. Also used by SessionBindingMap.
0115: public static ThreadSafeCounter mSessionObjectsCounter = new ThreadSafeCounter();
0116: // Count of webapp objects.
0117: public static ThreadSafeCounter mWebAppObjectsCounter = new ThreadSafeCounter();
0118:
0119: public static LoadCount mJavaRPCLoad = new LoadCount(10);
0120: public static LoadCount mInvokeLoad = new LoadCount(10);
0121: public static LoadCount mReturnObjectEncodeLoad = new LoadCount(10);
0122: public static LoadCount mStaticProtoGetLoad = new LoadCount(10);
0123: public static LoadCount mInstanceProtoCreateLoad = new LoadCount(10);
0124: public static LoadCount mInstanceProtoGetLoad = new LoadCount(10);
0125: public static LoadCount mInstanceProtoDestroyLoad = new LoadCount(
0126: 10);
0127: public static LoadCount mInstanceGetInvokeTargetLoad = new LoadCount(
0128: 10);
0129:
0130: //------------------------------------------------------------
0131: // End javarpc info variables
0132: //------------------------------------------------------------
0133:
0134: static final String UNKNOWN = "unknown";
0135: static final String SESSION = "session";
0136: static final String WEBAPP = "webapp";
0137: static final String NONE = "none";
0138:
0139: static final int SCOPE_UNKNOWN = -1;
0140: static final int SCOPE_SESSION = 0;
0141: static final int SCOPE_WEBAPP = 1;
0142: static final int SCOPE_NONE = 2;
0143:
0144: HashMap mVoidMap = null;
0145: ObjectData DEFAULT_VOID;
0146:
0147: public JavaDataSource() {
0148: clearLoadInfo();
0149: try {
0150: DEFAULT_VOID = new ObjectData(XMLRPCCompiler
0151: .compileResponse(0, "void",
0152: LPS.mSWFVersionNumDefault));
0153: } catch (IOException e) {
0154: mLogger.error(
0155: /* (non-Javadoc)
0156: * @i18n.test
0157: * @org-mes="exception: " + p[0]
0158: */
0159: org.openlaszlo.i18n.LaszloMessages.getMessage(
0160: JavaDataSource.class.getName(), "051018-161",
0161: new Object[] { e.getMessage() }), e);
0162: throw new RuntimeException(e.getMessage());
0163: }
0164: }
0165:
0166: /**
0167: * @return unique name of this data source
0168: */
0169: public String name() {
0170: return "java";
0171: }
0172:
0173: /**
0174: * Sends system information to client.
0175: *
0176: * @throws DataSourceException if there was a problem retrieving or sending
0177: * the data.
0178: */
0179: public Data getData(String app, HttpServletRequest req,
0180: HttpServletResponse res, long lastModifiedTime)
0181: throws DataSourceException {
0182: mLogger.debug(
0183: /* (non-Javadoc)
0184: * @i18n.test
0185: * @org-mes="getData"
0186: */
0187: org.openlaszlo.i18n.LaszloMessages.getMessage(
0188: JavaDataSource.class.getName(), "051018-190"));
0189:
0190: int swfversion = LPS.getSWFVersionNum(req);
0191: String runtime = req.getParameter("lzr");
0192:
0193: if (!req.getMethod().equals("POST"))
0194: return compileFault(
0195: /* (non-Javadoc)
0196: * @i18n.test
0197: * @org-mes="request must be POST"
0198: */
0199: org.openlaszlo.i18n.LaszloMessages.getMessage(
0200: JavaDataSource.class.getName(), "051018-202"),
0201: runtime, swfversion);
0202:
0203: String url;
0204: try {
0205: url = getURL(req);
0206: } catch (MalformedURLException e) {
0207: return compileFault(
0208: /* (non-Javadoc)
0209: * @i18n.test
0210: * @org-mes="malformed url"
0211: */
0212: org.openlaszlo.i18n.LaszloMessages.getMessage(
0213: JavaDataSource.class.getName(), "051018-215"), e,
0214: runtime, swfversion);
0215: }
0216:
0217: String cname = getClassName(url);
0218: if (cname == null)
0219: return compileFault(
0220: /* (non-Javadoc)
0221: * @i18n.test
0222: * @org-mes="invalid class or bad url: " + p[0]
0223: */
0224: org.openlaszlo.i18n.LaszloMessages.getMessage(
0225: JavaDataSource.class.getName(), "051018-227",
0226: new Object[] { url }), runtime, swfversion);
0227:
0228: if (!isClassOk(cname, req.getServletPath()))
0229: return compileFault(
0230: /* (non-Javadoc)
0231: * @i18n.test
0232: * @org-mes="forbidden class: " + p[0]
0233: */
0234: org.openlaszlo.i18n.LaszloMessages.getMessage(
0235: JavaDataSource.class.getName(), "051018-237",
0236: new Object[] { cname }), runtime, swfversion);
0237:
0238: Class targetClass = getClass(cname);
0239: if (targetClass == null)
0240: return compileFault(
0241: /* (non-Javadoc)
0242: * @i18n.test
0243: * @org-mes="no such class " + p[0]
0244: */
0245: org.openlaszlo.i18n.LaszloMessages.getMessage(
0246: JavaDataSource.class.getName(), "051018-248",
0247: new Object[] { cname }), runtime, swfversion);
0248:
0249: int scope = getScope(req);
0250: if (scope == SCOPE_UNKNOWN)
0251: return compileFault(
0252: /* (non-Javadoc)
0253: * @i18n.test
0254: * @org-mes="no scope request parameter"
0255: */
0256: org.openlaszlo.i18n.LaszloMessages.getMessage(
0257: JavaDataSource.class.getName(), "051018-259"),
0258: runtime, swfversion);
0259:
0260: String postbody = req.getParameter("lzpostbody");
0261: if (postbody == null || postbody.equals(""))
0262: return compileFault(
0263: /* (non-Javadoc)
0264: * @i18n.test
0265: * @org-mes="no post body"
0266: */
0267: org.openlaszlo.i18n.LaszloMessages.getMessage(
0268: JavaDataSource.class.getName(), "051018-270"),
0269: runtime, swfversion);
0270:
0271: // one of 'pojo' or 'javabean'
0272: String objectReturnType = req.getParameter("objectreturntype");
0273: if (objectReturnType == null || "".equals(objectReturnType)) {
0274: objectReturnType = "pojo";
0275: }
0276:
0277: if (mLogger.isDebugEnabled()) {
0278: mLogger.debug(
0279: /* (non-Javadoc)
0280: * @i18n.test
0281: * @org-mes="class name: " + p[0]
0282: */
0283: org.openlaszlo.i18n.LaszloMessages.getMessage(
0284: JavaDataSource.class.getName(), "051018-286",
0285: new Object[] { cname }));
0286: mLogger.debug(
0287: /* (non-Javadoc)
0288: * @i18n.test
0289: * @org-mes="object return type: " + p[0]
0290: */
0291: org.openlaszlo.i18n.LaszloMessages.getMessage(
0292: JavaDataSource.class.getName(), "051018-294",
0293: new Object[] { objectReturnType }));
0294: mLogger.debug(
0295: /* (non-Javadoc)
0296: * @i18n.test
0297: * @org-mes="POST body:\n" + p[0]
0298: */
0299: org.openlaszlo.i18n.LaszloMessages.getMessage(
0300: JavaDataSource.class.getName(), "051018-302",
0301: new Object[] { postbody }));
0302: }
0303:
0304: XmlRpcRequest xr = new LZXmlRpcRequestProcessor()
0305: .processRequest(new ByteArrayInputStream(postbody
0306: .getBytes()));
0307:
0308: long t0, t1;
0309: t0 = System.currentTimeMillis();
0310: mJavaRPCLoad.increment();
0311: try {
0312: return execute(req, res, targetClass, scope,
0313: objectReturnType, swfversion, xr.getMethodName(),
0314: xr.getParameters());
0315: } catch (IOException e) {
0316: return compileFault(
0317: /* (non-Javadoc)
0318: * @i18n.test
0319: * @org-mes="exception executing " + p[0]
0320: */
0321: org.openlaszlo.i18n.LaszloMessages.getMessage(
0322: JavaDataSource.class.getName(), "051018-322",
0323: new Object[] { xr.getMethodName() }), e, runtime,
0324: swfversion);
0325: } finally {
0326: t1 = System.currentTimeMillis();
0327: mJavaRPCLoad.decrement((int) (t1 - t0));
0328: }
0329: }
0330:
0331: /**
0332: * Check to see if class is allowed.
0333: */
0334: public boolean isClassOk(String cname, String path) {
0335: return LPS.configuration.optionAllows(path, "security", cname,
0336: false);
0337: }
0338:
0339: /**
0340: * This code borrows from Apache's XMLRPC
0341: * org.apache.xmlrpc.Invoker.execute() method.
0342: */
0343: public Data execute(HttpServletRequest req,
0344: HttpServletResponse res, Class targetClass, int scope,
0345: String objectReturnType, int swfversion, String methodName,
0346: Vector params) throws IOException {
0347:
0348: String runtime = req.getParameter("lzr");
0349:
0350: if (mLogger.isDebugEnabled()) {
0351: StringBuffer p = new StringBuffer(" ");
0352: for (int i = 0; i < params.size(); i++) {
0353: p.append(params.get(i)).append(" ");
0354: }
0355: mLogger.debug(
0356: /* (non-Javadoc)
0357: * @i18n.test
0358: * @org-mes="execute(" + p[0] + ", [" + p[1] + "],context)"
0359: */
0360: org.openlaszlo.i18n.LaszloMessages.getMessage(
0361: JavaDataSource.class.getName(), "051018-358",
0362: new Object[] { methodName, p.toString() }));
0363: }
0364:
0365: Class[] argClasses = null;
0366: Object[] argValues = null;
0367:
0368: String _doreq = req.getParameter("doreq");
0369: String _dores = req.getParameter("dores");
0370: boolean doreq = (_doreq != null && (_doreq.equals("1") || _doreq
0371: .equals("true")));
0372: boolean dores = (_dores != null && (_dores.equals("1") || _dores
0373: .equals("true")));
0374:
0375: int reqPos = -1; // position of request in parameter list
0376: int resPos = -1; // position of response in parameter list
0377:
0378: int httpCount = 0; // count of request and response passed in
0379:
0380: int paramCount = (params != null ? params.size() : 0);
0381:
0382: // if request exists, place request following the last parameter
0383: if (doreq) {
0384: mLogger.debug(
0385: /* (non-Javadoc)
0386: * @i18n.test
0387: * @org-mes="adding request to method"
0388: */
0389: org.openlaszlo.i18n.LaszloMessages.getMessage(
0390: JavaDataSource.class.getName(), "051018-385"));
0391: reqPos = paramCount;
0392: httpCount++;
0393: }
0394:
0395: // if response exists, place response after it, else
0396: // place it following the last parameter
0397: if (dores) {
0398: mLogger.debug(
0399: /* (non-Javadoc)
0400: * @i18n.test
0401: * @org-mes="adding response to method"
0402: */
0403: org.openlaszlo.i18n.LaszloMessages.getMessage(
0404: JavaDataSource.class.getName(), "051018-400"));
0405: resPos = (reqPos != -1 ? reqPos + 1 : paramCount);
0406: httpCount++;
0407: }
0408:
0409: // create arrays for argument classes and values.
0410: int count = paramCount + httpCount;
0411: argClasses = new Class[count];
0412: argValues = new Object[count];
0413:
0414: if (doreq) {
0415: argClasses[reqPos] = HttpServletRequest.class;
0416: argValues[reqPos] = req;
0417: }
0418:
0419: if (dores) {
0420: argClasses[resPos] = HttpServletResponse.class;
0421: argValues[resPos] = res;
0422: }
0423:
0424: if (params != null) {
0425: for (int i = 0; i < params.size(); i++) {
0426: argValues[i] = params.elementAt(i);
0427: if (argValues[i] instanceof Integer) {
0428: argClasses[i] = Integer.TYPE;
0429: } else if (argValues[i] instanceof Double) {
0430: argClasses[i] = Double.TYPE;
0431: } else if (argValues[i] instanceof Boolean) {
0432: argClasses[i] = Boolean.TYPE;
0433: } else {
0434: argClasses[i] = argValues[i].getClass();
0435: }
0436: }
0437: }
0438:
0439: Method method = null;
0440: Object invokeTarget = targetClass;
0441: long t0, t1;
0442:
0443: String op = req.getParameter("op");
0444: if (op != null) {
0445:
0446: String cname = targetClass.getName();
0447: String oname = req.getParameter("oname");
0448: if (scope == SCOPE_NONE)
0449: oname = NONE;
0450: if (oname == null || "".equals(oname))
0451: return compileFault("no oname parameter", runtime,
0452: swfversion);
0453:
0454: if (scope == SCOPE_NONE) {
0455: if ("get".equals(op) || "create".equals(op)) {
0456: t0 = System.currentTimeMillis();
0457: mStaticProtoGetLoad.increment();
0458: try {
0459: return getStaticPrototype(cname, runtime,
0460: swfversion);
0461: } finally {
0462: t1 = System.currentTimeMillis();
0463: mStaticProtoGetLoad.decrement((int) (t1 - t0));
0464: }
0465: }
0466: }
0467:
0468: if (scope == SCOPE_SESSION || scope == SCOPE_WEBAPP) {
0469:
0470: if ("get".equals(op)) {
0471: t0 = System.currentTimeMillis();
0472: mInstanceProtoGetLoad.increment();
0473: try {
0474: return getInstancePrototype(cname, oname,
0475: scope, req, swfversion);
0476: } finally {
0477: t1 = System.currentTimeMillis();
0478: mInstanceProtoGetLoad
0479: .decrement((int) (t1 - t0));
0480: }
0481: }
0482:
0483: if ("create".equals(op)) {
0484: t0 = System.currentTimeMillis();
0485: mInstanceProtoCreateLoad.increment();
0486: try {
0487: return createInstancePrototype(cname, oname,
0488: scope, argClasses, argValues, req,
0489: swfversion);
0490: } finally {
0491: t1 = System.currentTimeMillis();
0492: mInstanceProtoCreateLoad
0493: .decrement((int) (t1 - t0));
0494: }
0495: }
0496:
0497: if ("destroy".equals(op)) {
0498: t0 = System.currentTimeMillis();
0499: mInstanceProtoDestroyLoad.increment();
0500: try {
0501: return destroyInstance(oname, scope, req,
0502: swfversion);
0503: } finally {
0504: t1 = System.currentTimeMillis();
0505: mInstanceProtoDestroyLoad
0506: .decrement((int) (t1 - t0));
0507: }
0508: }
0509:
0510: if ("invoke".equals(op)) {
0511: t0 = System.currentTimeMillis();
0512: mInstanceGetInvokeTargetLoad.increment();
0513: try {
0514: invokeTarget = getInvokeTarget(oname, scope,
0515: req);
0516: } finally {
0517: t1 = System.currentTimeMillis();
0518: mInstanceGetInvokeTargetLoad
0519: .decrement((int) (t1 - t0));
0520: }
0521: if (invokeTarget == null) {
0522: String errmsg =
0523: /* (non-Javadoc)
0524: * @i18n.test
0525: * @org-mes="could not find " + p[0] + " instance " + p[1]
0526: */
0527: org.openlaszlo.i18n.LaszloMessages.getMessage(
0528: JavaDataSource.class.getName(),
0529: "051018-516", new Object[] {
0530: getScopeName(scope), oname });
0531: mLogger.error(errmsg);
0532: return compileFault(errmsg, runtime, swfversion);
0533: }
0534: }
0535: }
0536: }
0537:
0538: t0 = System.currentTimeMillis();
0539: mInvokeLoad.increment();
0540: Object returnValue = null;
0541: try {
0542: // The last element of the XML-RPC method name is the Java
0543: // method name.
0544: int dot = methodName.lastIndexOf('.');
0545: if (dot > -1 && dot + 1 < methodName.length()) {
0546: methodName = methodName.substring(dot + 1);
0547: }
0548:
0549: if (mLogger.isDebugEnabled()) {
0550: mLogger.debug(
0551: /* (non-Javadoc)
0552: * @i18n.test
0553: * @org-mes="Searching for method: " + p[0] + " in class " + p[1]
0554: */
0555: org.openlaszlo.i18n.LaszloMessages.getMessage(
0556: JavaDataSource.class.getName(), "051018-542",
0557: new Object[] { methodName,
0558: targetClass.getName() }));
0559: if (argClasses.length != 0) {
0560: for (int i = 0; i < argClasses.length; i++) {
0561: mLogger.debug(
0562: /* (non-Javadoc)
0563: * @i18n.test
0564: * @org-mes="Parameter " + p[0] + ": " + p[1] + " (" + p[2] + ")"
0565: */
0566: org.openlaszlo.i18n.LaszloMessages.getMessage(
0567: JavaDataSource.class.getName(),
0568: "051018-551", new Object[] {
0569: new Integer(i), argValues[i],
0570: argClasses[i] }));
0571: }
0572: }
0573: }
0574:
0575: try {
0576: method = getMethod(targetClass, methodName, argClasses);
0577: } catch (NoSuchMethodException e) {
0578: mLogger.error(
0579: /* (non-Javadoc)
0580: * @i18n.test
0581: * @org-mes="NoSuchMethodException"
0582: */
0583: org.openlaszlo.i18n.LaszloMessages.getMessage(
0584: JavaDataSource.class.getName(), "051018-565"),
0585: e);
0586: return compileFault(e.getMessage(), e, runtime,
0587: swfversion);
0588: } catch (SecurityException e) {
0589: mLogger.error(
0590: /* (non-Javadoc)
0591: * @i18n.test
0592: * @org-mes="SecurityException"
0593: */
0594: org.openlaszlo.i18n.LaszloMessages.getMessage(
0595: JavaDataSource.class.getName(), "051018-575"),
0596: e);
0597: return compileFault(e.getMessage(), e, runtime,
0598: swfversion);
0599: }
0600:
0601: // Make all public methods callable except those defined in
0602: // java.lang.Object.
0603: if (method.getDeclaringClass() == Object.class) {
0604: return compileFault(
0605: /* (non-Javadoc)
0606: * @i18n.test
0607: * @org-mes="Can't call methods in java.lang.Object"
0608: */
0609: org.openlaszlo.i18n.LaszloMessages.getMessage(
0610: JavaDataSource.class.getName(), "051018-589"),
0611: runtime, swfversion);
0612: }
0613:
0614: // invoke
0615: try {
0616: returnValue = method.invoke(invokeTarget, argValues);
0617: } catch (IllegalAccessException e) {
0618: mLogger.error("IllegalAccessException", e);
0619: return compileFault(e.getMessage(), e, runtime,
0620: swfversion);
0621: } catch (IllegalArgumentException e) {
0622: mLogger.error("IllegalArgumentException", e);
0623: return compileFault(e.getMessage(), e, runtime,
0624: swfversion);
0625: } catch (InvocationTargetException e) {
0626: mLogger.error("InvocationTargetException", e);
0627: Throwable cause = e.getCause();
0628: if (cause != null)
0629: return compileFault(cause, runtime, swfversion);
0630: return compileFault(e.getMessage(), e, runtime,
0631: swfversion);
0632: } catch (Exception e) {
0633: mLogger.error("Exception", e);
0634: return compileFault(e.getMessage(), e, runtime,
0635: swfversion);
0636: } catch (Error e) {
0637: mLogger.error("Error", e);
0638: return compileFault(e.getMessage(), e, runtime,
0639: swfversion);
0640: }
0641: } finally {
0642: t1 = System.currentTimeMillis();
0643: mInvokeLoad.decrement((int) (t1 - t0));
0644: }
0645:
0646: t0 = System.currentTimeMillis();
0647: mReturnObjectEncodeLoad.increment();
0648: try {
0649: Class returnType = method.getReturnType();
0650: if (returnType == Void.TYPE) {
0651: return getVoid(runtime);
0652: } else if (returnType == DataEncoder.class
0653: && returnValue != null) {
0654: return new EncoderData((DataEncoder) returnValue);
0655: }
0656:
0657: if ("dhtml".equals(runtime)) {
0658: return new ObjectData(
0659: org.openlaszlo.remote.json.LZReturnObject
0660: .createObject(returnValue,
0661: objectReturnType));
0662: } else {
0663: return new ObjectData(
0664: org.openlaszlo.remote.swf.LZReturnObject
0665: .createObject(returnValue,
0666: objectReturnType, swfversion));
0667: }
0668:
0669: } catch (IOException e) {
0670: mLogger.error("IOException", e);
0671: return compileFault(e.getMessage(), e, runtime, swfversion);
0672: } finally {
0673: t1 = System.currentTimeMillis();
0674: mReturnObjectEncodeLoad.decrement((int) (t1 - t0));
0675: }
0676: }
0677:
0678: synchronized ObjectData getVoid(String runtime) {
0679: if (mVoidMap == null) {
0680: mVoidMap = new HashMap();
0681: }
0682: ObjectData voidobj;
0683: try {
0684: voidobj = (ObjectData) mVoidMap.get(runtime);
0685: if (voidobj == null) {
0686: mLogger.debug("creating void for runtime " + runtime);
0687: if ("swf7".equals(runtime) || "swf8".equals(runtime)) {
0688: int swfversion = "swf7".equals(runtime) ? 7 : 8;
0689: voidobj = new ObjectData(XMLRPCCompiler
0690: .compileResponse(0, "void", swfversion));
0691: } else if ("dhtml".equals(runtime)) {
0692: voidobj = new ObjectData(XMLRPCJSONCompiler
0693: .compileResponse(0, "void", runtime));
0694: } else {
0695: voidobj = DEFAULT_VOID;
0696: }
0697:
0698: mVoidMap.put(runtime, voidobj);
0699: }
0700: } catch (Exception e) {
0701: mLogger.warn(
0702: /* (non-Javadoc)
0703: * @i18n.test
0704: * @org-mes="using default void"
0705: */
0706: org.openlaszlo.i18n.LaszloMessages.getMessage(
0707: JavaDataSource.class.getName(), "051018-663"), e);
0708: voidobj = DEFAULT_VOID;
0709: }
0710: return voidobj;
0711: }
0712:
0713: /**
0714: * for scope == SCOPE_NONE (static objects).
0715: */
0716: Data getStaticPrototype(String cname, String runtime, int swfversion) {
0717: if (mLogger.isDebugEnabled()) {
0718: mLogger.debug(
0719: /* (non-Javadoc)
0720: * @i18n.test
0721: * @org-mes="getStaticPrototype(" + p[0] + ")"
0722: */
0723: org.openlaszlo.i18n.LaszloMessages.getMessage(
0724: JavaDataSource.class.getName(), "051018-681",
0725: new Object[] { cname }));
0726: }
0727: return getPrototype(cname, SCOPE_NONE, runtime, swfversion);
0728: }
0729:
0730: /**
0731: * Return prototype for session and webapp if object was
0732: * previously created.
0733: */
0734: Data getInstancePrototype(String cname, String oname, int scope,
0735: HttpServletRequest req, int swfversion) {
0736:
0737: String runtime = req.getParameter("lzr");
0738:
0739: if (mLogger.isDebugEnabled()) {
0740: mLogger.debug(
0741: /* (non-Javadoc)
0742: * @i18n.test
0743: * @org-mes="getInstancePrototype(" + p[0] + "," + p[1] + ")"
0744: */
0745: org.openlaszlo.i18n.LaszloMessages.getMessage(
0746: JavaDataSource.class.getName(), "051018-702",
0747: new Object[] { cname, oname }));
0748: }
0749:
0750: Integer swfv = new Integer(swfversion);
0751: if (getJavaObject(req.getSession(false), scope, oname) != null) {
0752: if (scope == SCOPE_WEBAPP) {
0753: return (Data) mWebAppPrototypes.get(swfv, cname);
0754: } else if (scope == SCOPE_SESSION) {
0755: return (Data) mSessionPrototypes.get(swfv, cname);
0756: }
0757: }
0758:
0759: String errmsg =
0760: /* (non-Javadoc)
0761: * @i18n.test
0762: * @org-mes="couldn't find " + p[0] + " instance " + p[1]
0763: */
0764: org.openlaszlo.i18n.LaszloMessages.getMessage(
0765: JavaDataSource.class.getName(), "051018-721",
0766: new Object[] { getScopeName(scope), oname });
0767: mLogger.error(errmsg);
0768: return compileFault(errmsg, runtime, swfversion);
0769: }
0770:
0771: /**
0772: * creates a client swf object (remoteobject create)
0773: */
0774: Data createInstancePrototype(String cname, String oname, int scope,
0775: Class[] argClasses, Object[] argValues,
0776: HttpServletRequest req, int swfversion) {
0777:
0778: String runtime = req.getParameter("lzr");
0779:
0780: if (mLogger.isDebugEnabled()) {
0781: mLogger.debug(
0782: /* (non-Javadoc)
0783: * @i18n.test
0784: * @org-mes="createInstancePrototype(" + p[0] + "," + p[1] + ")"
0785: */
0786: org.openlaszlo.i18n.LaszloMessages.getMessage(
0787: JavaDataSource.class.getName(), "051018-742",
0788: new Object[] { cname, oname }));
0789: }
0790:
0791: // create session here, if it doesn't exist
0792: HttpSession session = req.getSession(true);
0793:
0794: String _clobber = req.getParameter("clobber");
0795: boolean clobber = (_clobber != null && ("1".equals(_clobber) || "true"
0796: .equals(_clobber)));
0797:
0798: Object o = null;
0799: if (!clobber) {
0800: o = getJavaObject(session, scope, oname);
0801: if (o != null) {
0802: if (mLogger.isDebugEnabled()) {
0803: mLogger.debug(
0804: /* (non-Javadoc)
0805: * @i18n.test
0806: * @org-mes="not clobbering existing " + p[0] + " object " + p[1]
0807: */
0808: org.openlaszlo.i18n.LaszloMessages.getMessage(
0809: JavaDataSource.class.getName(),
0810: "051018-763", new Object[] {
0811: getScopeName(scope), oname }));
0812: }
0813: return getPrototype(cname, scope, runtime, swfversion);
0814: }
0815: }
0816:
0817: // send back client object.
0818: try {
0819: o = getServerInstance(cname, argClasses, argValues);
0820: setJavaObject(session, scope, oname, o);
0821: } catch (Exception e) {
0822: return compileFault(
0823: /* (non-Javadoc)
0824: * @i18n.test
0825: * @org-mes="could not create instance of " + p[0]
0826: */
0827: org.openlaszlo.i18n.LaszloMessages.getMessage(
0828: JavaDataSource.class.getName(), "051018-780",
0829: new Object[] { cname }), e, runtime, swfversion);
0830: }
0831:
0832: return getPrototype(cname, scope, runtime, swfversion);
0833: }
0834:
0835: /**
0836: * Get client prototype.
0837: */
0838: synchronized Data getPrototype(String cname, int scope,
0839: String runtime, int swfversion) {
0840: try {
0841: Data data;
0842: // need to dispatch on runtime
0843: if (scope == SCOPE_NONE) {
0844: data = (Data) mStaticPrototypes.get(runtime, cname);
0845: } else if (scope == SCOPE_WEBAPP) {
0846: data = (Data) mWebAppPrototypes.get(runtime, cname);
0847: } else {
0848: data = (Data) mSessionPrototypes.get(runtime, cname);
0849: }
0850:
0851: if (data == null) {
0852: mLogger.debug(
0853: /* (non-Javadoc)
0854: * @i18n.test
0855: * @org-mes="creating client prototype for " + p[0]
0856: */
0857: org.openlaszlo.i18n.LaszloMessages.getMessage(
0858: JavaDataSource.class.getName(), "051018-809",
0859: new Object[] { cname }));
0860:
0861: //// if ("dhtml".equals(runtime)) { }
0862: byte[] b;
0863: if ("dhtml".equals(runtime)) {
0864:
0865: b = org.openlaszlo.remote.json.LZClientObject
0866: .createObject(cname, getScopeName(scope),
0867: swfversion);
0868: } else {
0869: b = org.openlaszlo.remote.swf.LZClientObject
0870: .createObject(cname, getScopeName(scope),
0871: swfversion);
0872:
0873: }
0874: data = new ObjectData(b);
0875: if (scope == SCOPE_NONE) {
0876: mStaticPrototypes.put(runtime, cname, data);
0877: } else if (scope == SCOPE_WEBAPP) {
0878: mWebAppPrototypes.put(runtime, cname, data);
0879: } else {
0880: mSessionPrototypes.put(runtime, cname, data);
0881: }
0882: }
0883:
0884: return data;
0885: } catch (Exception e) {
0886: return compileFault(
0887: /* (non-Javadoc)
0888: * @i18n.test
0889: * @org-mes="could not get " + p[0] + " in scope " + p[1]
0890: */
0891: org.openlaszlo.i18n.LaszloMessages.getMessage(
0892: JavaDataSource.class.getName(), "051018-831",
0893: new Object[] { cname, getScopeName(scope) }), e,
0894: runtime, swfversion);
0895: }
0896: }
0897:
0898: /**
0899: * removes client swf object from session attribute or webapp attribute.
0900: * Note: swfversion not used but may be if we have different versions of
0901: * object cached.
0902: */
0903: //--------------------------------------------------------------------
0904: // TODO [2005-02-16 pkang]: think about what happens if swf version
0905: // requested is different from the instance prototype we have cached.
0906: //--------------------------------------------------------------------
0907: Data destroyInstance(String oname, int scope,
0908: HttpServletRequest req, int swfversion) {
0909:
0910: if (mLogger.isDebugEnabled()) {
0911: mLogger.debug(
0912: /* (non-Javadoc)
0913: * @i18n.test
0914: * @org-mes="destroyInstance(" + p[0] + ", " + p[1]
0915: */
0916: org.openlaszlo.i18n.LaszloMessages.getMessage(
0917: JavaDataSource.class.getName(), "051018-858",
0918: new Object[] { oname, new Integer(scope) }));
0919: }
0920: removeJavaObject(req.getSession(false), scope, oname);
0921: String runtime = req.getParameter("lzr");
0922: return getVoid(runtime);
0923: }
0924:
0925: /*
0926: * Get the invocation target for the session or webapp scope.
0927: */
0928: Object getInvokeTarget(String oname, int scope,
0929: HttpServletRequest req) {
0930: return getJavaObject(req.getSession(false), scope, oname);
0931: }
0932:
0933: String getClassName(String url) {
0934: if (url.startsWith("java://"))
0935: return url.substring(7);
0936: return null;
0937: }
0938:
0939: Class getClass(String cname) {
0940: try {
0941: return Class.forName(cname);
0942: } catch (ClassNotFoundException e) {
0943: mLogger.error(
0944: /* (non-Javadoc)
0945: * @i18n.test
0946: * @org-mes="class not found: " + p[0]
0947: */
0948: org.openlaszlo.i18n.LaszloMessages.getMessage(
0949: JavaDataSource.class.getName(), "051018-888",
0950: new Object[] { cname }));
0951: }
0952: return null;
0953: }
0954:
0955: /**
0956: * pt1 and pt2 are assumed not to be null. If param types are 0, array length
0957: * is 0.
0958: */
0959: boolean paramTypesMatch(Class[] pt1, Class[] pt2) {
0960: if (pt1.length != pt2.length)
0961: return false;
0962:
0963: for (int i = 0; i < pt1.length; i++) {
0964: if (!pt1[i].isAssignableFrom(pt2[i])) {
0965: return false;
0966: }
0967: }
0968: return true;
0969: }
0970:
0971: /**
0972: * Create instance by calling constructor.
0973: */
0974: Object getServerInstance(String classname, Class[] argClasses,
0975: Object[] argValues) throws Exception {
0976:
0977: if (mLogger.isDebugEnabled()) {
0978: mLogger.debug("getServerInstance(" + classname + ")");
0979: }
0980:
0981: Class cl = Class.forName(classname);
0982:
0983: Constructor constructor = null;
0984: Constructor[] carr = cl.getConstructors();
0985: for (int i = 0; i < carr.length; i++) {
0986: Class[] ptarr = carr[i].getParameterTypes();
0987: if (paramTypesMatch(ptarr, argClasses)) {
0988: constructor = carr[i];
0989: break;
0990: }
0991: }
0992:
0993: if (constructor == null) {
0994: StringBuffer buf = new StringBuffer();
0995: for (int i = 0; i < argClasses.length; i++) {
0996: if (i != 0)
0997: buf.append(",");
0998: buf.append(argClasses[i].toString());
0999: }
1000: String msg =
1001: /* (non-Javadoc)
1002: * @i18n.test
1003: * @org-mes="no such constructor found: " + p[0] + "(" + p[1] + ")"
1004: */
1005: org.openlaszlo.i18n.LaszloMessages.getMessage(
1006: JavaDataSource.class.getName(), "051018-946",
1007: new Object[] { classname, buf.toString() });
1008: mLogger.error(msg);
1009: throw new Exception(msg);
1010: }
1011:
1012: return constructor.newInstance(argValues);
1013: }
1014:
1015: /**
1016: * Like Class.getMethod() except we allow params that are derived.
1017: */
1018: Method getMethod(Class cl, String methodName, Class[] params)
1019: throws NoSuchMethodException {
1020:
1021: // targetClass.getMethod(methodName, argClasses);
1022:
1023: Method[] classMethods = cl.getMethods();
1024: for (int m = 0; m < classMethods.length; m++) {
1025:
1026: // find matching method
1027: mLogger.debug("getMethod looking for " + methodName
1028: + " ==? " + classMethods[m].getName());
1029:
1030: if (!methodName.equals(classMethods[m].getName()))
1031: continue;
1032: mLogger.debug("getMethod match found " + methodName
1033: + " class=" + cl.getName());
1034:
1035: // make sure params match
1036: Class[] classParams = classMethods[m].getParameterTypes();
1037: mLogger.debug("[1] getMethod " + methodName
1038: + " classParams.length = " + classParams.length
1039: + " params.length=" + params.length);
1040: if (classParams.length == 0 && params == null)
1041: return classMethods[m];
1042:
1043: if (classParams.length == params.length) {
1044: boolean ok = true;
1045: for (int p = 0; p < classParams.length; p++) {
1046: mLogger.debug("[2] checking isAssignableFrom "
1047: + classParams[p].getName()
1048: + " isAssignableFrom "
1049: + (params[p].getName())
1050: + " ? = "
1051: + classParams[p]
1052: .isAssignableFrom(params[p]));
1053: if (!classParams[p].isAssignableFrom(params[p])) {
1054: ok = false;
1055: break;
1056: }
1057: }
1058: if (ok)
1059: return classMethods[m];
1060: }
1061: }
1062:
1063: StringBuffer buf = new StringBuffer();
1064: for (int i = 0; i < params.length; i++) {
1065: if (i != 0)
1066: buf.append(", ");
1067: buf.append(params[i].toString());
1068: }
1069: throw new NoSuchMethodException(
1070: /* (non-Javadoc)
1071: * @i18n.test
1072: * @org-mes=p[0] + "(" + p[1] + "): no such method"
1073: */
1074: org.openlaszlo.i18n.LaszloMessages.getMessage(
1075: JavaDataSource.class.getName(), "051018-999",
1076: new Object[] { methodName, buf.toString() }));
1077: }
1078:
1079: String getScopeName(int scope) {
1080: if (SCOPE_SESSION == scope)
1081: return SESSION;
1082: if (SCOPE_WEBAPP == scope)
1083: return WEBAPP;
1084: if (SCOPE_NONE == scope)
1085: return NONE;
1086: return UNKNOWN;
1087: }
1088:
1089: int getScope(HttpServletRequest req) {
1090: String scope = req.getParameter("scope");
1091: if (scope == null)
1092: return SCOPE_UNKNOWN;
1093: if (SESSION.equals(scope))
1094: return SCOPE_SESSION;
1095: if (WEBAPP.equals(scope))
1096: return SCOPE_WEBAPP;
1097: if (NONE.equals(scope))
1098: return SCOPE_NONE;
1099: return SCOPE_UNKNOWN;
1100: }
1101:
1102: Object getJavaObject(HttpSession session, int scope, String oname) {
1103: if (session == null)
1104: return null;
1105: Map map = null;
1106: if (scope == SCOPE_SESSION) {
1107: map = (Map) session.getAttribute(OBJECTS);
1108: } else if (scope == SCOPE_WEBAPP) {
1109: map = (Map) session.getServletContext().getAttribute(
1110: OBJECTS);
1111: }
1112: return (map == null ? null : map.get(oname));
1113: }
1114:
1115: /**
1116: * Add a java object to a session or webapp context.
1117: */
1118: void setJavaObject(HttpSession session, int scope, String oname,
1119: Object val) {
1120: if (session == null) {
1121: if (mLogger.isDebugEnabled()) {
1122: mLogger.debug(
1123: /* (non-Javadoc)
1124: * @i18n.test
1125: * @org-mes="setting java object with no session in scope " + p[0]
1126: */
1127: org.openlaszlo.i18n.LaszloMessages.getMessage(
1128: JavaDataSource.class.getName(), "051018-1045",
1129: new Object[] { getScopeName(scope) }));
1130: }
1131: return;
1132: }
1133: Map map = null;
1134: if (scope == SCOPE_SESSION) {
1135: map = (Map) session.getAttribute(OBJECTS);
1136: if (map == null) {
1137: map = new SessionBindingMap();
1138: session.setAttribute(OBJECTS, map);
1139: // session counter increments happen through SessionBindingMap.
1140: }
1141: } else if (scope == SCOPE_WEBAPP) {
1142: map = (Map) session.getServletContext().getAttribute(
1143: OBJECTS);
1144: if (map == null) {
1145: map = new HashMap();
1146: session.getServletContext().setAttribute(OBJECTS, map);
1147: }
1148: } else {
1149: mLogger.warn(
1150: /* (non-Javadoc)
1151: * @i18n.test
1152: * @org-mes="tried setting object with scope " + p[0] + "(" + p[1] + ")"
1153: */
1154: org.openlaszlo.i18n.LaszloMessages.getMessage(
1155: JavaDataSource.class.getName(), "051018-1070",
1156: new Object[] { getScopeName(scope),
1157: new Integer(scope) }));
1158: return;
1159: }
1160:
1161: // if a previous object didn't exist, increment object counter.
1162: if (map != null) {
1163: Object oldVal = map.put(oname, val);
1164: if (oldVal == null) {
1165: if (scope == SCOPE_SESSION) {
1166: mSessionObjectsCounter.increment();
1167: } else if (scope == SCOPE_WEBAPP) {
1168: mWebAppObjectsCounter.increment();
1169: }
1170: }
1171: }
1172: }
1173:
1174: /**
1175: * Remove a java object from session or webapp context.
1176: */
1177: void removeJavaObject(HttpSession session, int scope, String oname) {
1178: if (session == null) {
1179: if (mLogger.isDebugEnabled()) {
1180: mLogger.debug(
1181: /* (non-Javadoc)
1182: * @i18n.test
1183: * @org-mes="tried removing java object with no session in scope " + p[0] + "(" + p[1] + ")"
1184: */
1185: org.openlaszlo.i18n.LaszloMessages.getMessage(
1186: JavaDataSource.class.getName(), "051018-1100",
1187: new Object[] { getScopeName(scope),
1188: new Integer(scope) }));
1189: }
1190: return;
1191: }
1192: Map map = null;
1193: if (scope == SCOPE_SESSION) {
1194: map = (Map) session.getAttribute(OBJECTS);
1195: // session counter decrements happen through SessionBindingMap.
1196: } else if (scope == SCOPE_WEBAPP) {
1197: map = (Map) session.getServletContext().getAttribute(
1198: OBJECTS);
1199: } else {
1200: mLogger.warn(
1201: /* (non-Javadoc)
1202: * @i18n.test
1203: * @org-mes="tried removing object with scope " + p[0]
1204: */
1205: org.openlaszlo.i18n.LaszloMessages.getMessage(
1206: JavaDataSource.class.getName(), "051018-1118",
1207: new Object[] { getScopeName(scope) }));
1208: return;
1209: }
1210: if (map != null) {
1211: Object oldVal = map.remove(oname);
1212: // if there was an existing one, decrement object counter.
1213: if (oldVal != null) {
1214: if (scope == SCOPE_SESSION) {
1215: mSessionObjectsCounter.decrement();
1216: } else if (scope == SCOPE_WEBAPP) {
1217: mWebAppObjectsCounter.decrement();
1218: }
1219: }
1220: }
1221: }
1222:
1223: /**
1224: * Compile fault exception message.
1225: */
1226: Data compileFault(Throwable e, String runtime, int swfversion) {
1227: mLogger.error("compileFault", e);
1228: return compileFault(e.getMessage(), runtime, swfversion);
1229: }
1230:
1231: Data compileFault(String mesg, String runtime, int swfversion) {
1232: return compileFault(mesg, null, runtime, swfversion);
1233: }
1234:
1235: /**
1236: * Compile fault response.
1237: */
1238: Data compileFault(String mesg, Throwable e, String runtime,
1239: int swfversion) {
1240: if (e == null) {
1241: mLogger.error(
1242: /* (non-Javadoc)
1243: * @i18n.test
1244: * @org-mes="compileFault mesg: " + p[0]
1245: */
1246: org.openlaszlo.i18n.LaszloMessages.getMessage(
1247: JavaDataSource.class.getName(), "051018-1159",
1248: new Object[] { mesg }));
1249: } else {
1250: mLogger.error(
1251: /* (non-Javadoc)
1252: * @i18n.test
1253: * @org-mes="compileFault mesg: " + p[0]
1254: */
1255: org.openlaszlo.i18n.LaszloMessages.getMessage(
1256: JavaDataSource.class.getName(), "051018-1159",
1257: new Object[] { mesg }), e);
1258: }
1259: try {
1260:
1261: /*
1262: return new ObjectData
1263: ( XMLRPCCompiler.compileFault(XMLUtils.escapeXml(mesg),
1264: swfversion) );
1265: */
1266:
1267: if ("dhtml".equals(runtime)) {
1268: byte[] d = XMLRPCJSONCompiler.compileFault(XMLUtils
1269: .escapeXml(mesg), runtime);
1270: return new ObjectData(d);
1271: } else {
1272: byte[] d = XMLRPCCompiler.compileFault(XMLUtils
1273: .escapeXml(mesg), swfversion);
1274: return new ObjectData(d);
1275: }
1276:
1277: } catch (Exception ex) {
1278: mLogger.error("Exception", ex);
1279: // this is an error since we can't build a fault response
1280: throw new Error(e.getMessage());
1281: }
1282: }
1283:
1284: /**
1285: * Helper function for toXML().
1286: */
1287: static void toXML(StringBuffer sb, String nodeName, VersionMap m,
1288: ThreadSafeCounter objects, ThreadSafeCounter sessions) {
1289: sb.append("<").append(nodeName);
1290: if (objects != null) {
1291: sb.append(" objects=\"").append(objects.getCount()).append(
1292: "\"");
1293: }
1294: if (sessions != null) {
1295: sb.append(" sessions=\"").append(sessions.getCount())
1296: .append("\"");
1297: }
1298: sb.append(">");
1299:
1300: Iterator iter = m.keySet().iterator();
1301: while (iter.hasNext()) {
1302: String k = (String) iter.next();
1303: Map versions = (Map) m.getVersions(k);
1304: Iterator viter = versions.keySet().iterator();
1305: sb.append("<prototype class=\"").append(k).append("\"")
1306: .append(" versions=\"");
1307: while (viter.hasNext()) {
1308: Integer swfv = (Integer) viter.next();
1309: sb.append(swfv).append(",");
1310: }
1311: sb.deleteCharAt(sb.length() - 1).append("\"/>");
1312: }
1313: sb.append("</").append(nodeName).append(">");
1314: }
1315:
1316: public static void clearLoadInfo() {
1317: mJavaRPCLoad.reset();
1318: mInvokeLoad.reset();
1319: mReturnObjectEncodeLoad.reset();
1320: mStaticProtoGetLoad.reset();
1321: mInstanceProtoCreateLoad.reset();
1322: mInstanceProtoGetLoad.reset();
1323: mInstanceProtoDestroyLoad.reset();
1324: mInstanceGetInvokeTargetLoad.reset();
1325: mLastCleared = System.currentTimeMillis();
1326: }
1327:
1328: static boolean doXML(int options, int mask) {
1329: return (options & mask) == mask;
1330: }
1331:
1332: /**
1333: * XML string with relevant statistics about JavaDataSource.
1334: */
1335: synchronized static public String toXML(int options) {
1336: StringBuffer sb = new StringBuffer();
1337: Date lc = new Date(mLastCleared);
1338: sb.append("<javarpcinfo ").append(" last-cleared=\"")
1339: .append(lc).append("\"").append(">");
1340: {
1341: toXML(sb, "session", mSessionPrototypes,
1342: mSessionObjectsCounter, mSessionCounter);
1343: toXML(sb, "webapp", mWebAppPrototypes,
1344: mWebAppObjectsCounter, null);
1345: toXML(sb, "static", mStaticPrototypes, null, null);
1346:
1347: sb.append(mJavaRPCLoad.toXML("javarpc_load"));
1348:
1349: if (doXML(options, LOAD_INVOKE)) {
1350: sb.append(mInvokeLoad.toXML("invoke_load"));
1351: }
1352: if (doXML(options, LOAD_STATIC_GET_PROTO)) {
1353: sb.append(mStaticProtoGetLoad
1354: .toXML("static_get_proto_load"));
1355: }
1356: if (doXML(options, LOAD_INSTANCE_CREATE_PROTO)) {
1357: sb.append(mInstanceProtoCreateLoad
1358: .toXML("instance_create_proto_load"));
1359: }
1360: if (doXML(options, LOAD_INSTANCE_GET_PROTO)) {
1361: sb.append(mInstanceProtoGetLoad
1362: .toXML("instance_get_proto_load"));
1363: }
1364: if (doXML(options, LOAD_INSTANCE_DESTROY_PROTO)) {
1365: sb.append(mInstanceProtoDestroyLoad
1366: .toXML("instance_destroy_proto_load"));
1367: }
1368: if (doXML(options, LOAD_INSTANCE_GET_INVOKE_TARGET)) {
1369: sb.append(mInstanceGetInvokeTargetLoad
1370: .toXML("instance_get_invoke_target_load"));
1371: }
1372: if (doXML(options, LOAD_RETURN_OBJECT_ENCODE)) {
1373: sb.append(mReturnObjectEncodeLoad
1374: .toXML("return_object_encode_load"));
1375: }
1376: }
1377: sb.append("</javarpcinfo>");
1378: return sb.toString();
1379: }
1380:
1381: public class EncoderData extends Data {
1382: DataEncoder mDataEncoder;
1383: long mSize;
1384:
1385: public EncoderData(DataEncoder dataEncoder) throws IOException {
1386: mDataEncoder = dataEncoder;
1387: mSize = dataEncoder.getSize();
1388: }
1389:
1390: public String getMimeType() {
1391: return MimeType.SWF;
1392: }
1393:
1394: /**
1395: * @return the encoded XML
1396: */
1397: public InputStream getInputStream() throws IOException {
1398: return mDataEncoder.getInputStream();
1399: }
1400:
1401: public long size() {
1402: return mSize;
1403: }
1404: }
1405:
1406: /**
1407: * A data object to hold session object.
1408: */
1409: public class ObjectData extends Data {
1410: byte[] mObject;
1411:
1412: public ObjectData(byte[] object) {
1413: mObject = object;
1414: }
1415:
1416: public String getMimeType() {
1417: return MimeType.SWF;
1418: }
1419:
1420: public InputStream getInputStream() throws IOException {
1421: return new ByteArrayInputStream(mObject);
1422: }
1423:
1424: public long size() {
1425: return mObject.length;
1426: }
1427: }
1428: }
|