📄 jsonrpcbridge.java
字号:
"(" + argSignature(method[i]) + ")"); } catch (Exception e) { if(debug) log.fine("xxx " + e.getMessage() + " in " + methodName + "(" + argSignature(method[i]) + ")"); } } MethodCandidate best = null; for(int i=0; i < candidate.size(); i++) { MethodCandidate c = (MethodCandidate)candidate.get(i); if (best == null) { best = c; continue; } final ObjectMatch bestMatch = best.getMatch(); final ObjectMatch cMatch = c.getMatch(); if(bestMatch.mismatch > cMatch.mismatch) best = c; else if (bestMatch.mismatch == cMatch.mismatch) best = betterSignature(best, c); } if(best != null) { Method m = best.method; if(debug) log.fine("found method " + methodName + "(" + argSignature(m) + ")"); return m; } return null; } private MethodCandidate betterSignature(MethodCandidate methodCandidate, MethodCandidate methodCandidate1) { final Method method = methodCandidate.method; final Method method1 = methodCandidate1.method; final Class[] parameters = method.getParameterTypes(); final Class[] parameters1 = method1.getParameterTypes(); int c = 0, c1 = 0; for (int i = 0; i < parameters.length; i++) { final Class parameterClass = parameters[i]; final Class parameterClass1 = parameters1[i]; if (parameterClass != parameterClass1) { if (parameterClass.isAssignableFrom(parameterClass1)) c1++; else c++; } } if (c1 > c) return methodCandidate1; else return methodCandidate; } private static String argSignature(Method method) { Class param[] = method.getParameterTypes(); StringBuffer buf = new StringBuffer(); for(int i=0; i < param.length; i++) { if(i > 0) buf.append(","); buf.append(param[i].getName()); } return buf.toString(); } private static String argSignature(JSONArray arguments) { StringBuffer buf = new StringBuffer(); for(int i=0; i < arguments.length(); i += 1) { if(i > 0) buf.append(","); Object jso = arguments.get(i); if (jso == null) { buf.append("java.lang.Object"); } else if (jso instanceof String) { buf.append("java.lang.String"); } else if (jso instanceof Number) { buf.append("java.lang.Number"); } else if (jso instanceof JSONArray) { buf.append("java.lang.Object[]"); } else { buf.append("java.lang.Object"); } } return buf.toString(); } private MethodCandidate tryUnmarshallArgs(Method method, JSONArray arguments) throws UnmarshallException { MethodCandidate candidate = new MethodCandidate(method); Class param[] = method.getParameterTypes(); int i = 0, j = 0; HashSet resolverSet; try { for(; i < param.length; i++) { SerializerState state = new SerializerState(); synchronized(localArgResolverMap) { resolverSet = (HashSet)localArgResolverMap.get(param[i]); } if(resolverSet != null) candidate.match[i] = ObjectMatch.OKAY; else candidate.match[i] = ser.tryUnmarshall(state, param[i], arguments.get(j++)); } } catch(UnmarshallException e) { throw new UnmarshallException ("arg " + (i+1) + " " + e.getMessage()); } return candidate; } private Object resolveLocalArg(Object context[], HashSet resolverSet) throws UnmarshallException { Iterator i = resolverSet.iterator(); while(i.hasNext()) { LocalArgResolverData resolverData = (LocalArgResolverData)i.next(); for(int j=0; j< context.length; j++) { if(resolverData.understands(context[j])) { try { return resolverData.argResolver.resolveArg(context[j]); } catch (LocalArgResolveException e) { throw new UnmarshallException ("error resolving local argument: " + e); } } } } throw new UnmarshallException("couldn't find local arg resolver"); } private Object[] unmarshallArgs(Object context[], Method method, JSONArray arguments) throws UnmarshallException { Class param[] = method.getParameterTypes(); Object javaArgs[] = new Object[param.length]; int i = 0, j = 0; HashSet resolverSet; try { for(; i < param.length; i++) { SerializerState state = new SerializerState(); synchronized(localArgResolverMap) { resolverSet = (HashSet)localArgResolverMap.get(param[i]); } if(resolverSet != null) javaArgs[i] = resolveLocalArg(context, resolverSet); else javaArgs[i] = ser.unmarshall(state, param[i], arguments.get(j++)); } } catch(UnmarshallException e) { throw new UnmarshallException ("arg " + (i+1) + " " + e.getMessage()); } return javaArgs; } private void preInvokeCallback(Object context, Object instance, Method m, Object arguments[]) throws Exception { synchronized (callbackSet) { Iterator i = callbackSet.iterator(); while(i.hasNext()) { CallbackData cbdata = (CallbackData)i.next(); if(cbdata.understands(context)) cbdata.cb.preInvoke(context, instance, m, arguments); } } } private void postInvokeCallback(Object context, Object instance, Method m, Object result) throws Exception { synchronized (callbackSet) { Iterator i = callbackSet.iterator(); while(i.hasNext()) { CallbackData cbdata = (CallbackData)i.next(); if(cbdata.understands(context)) cbdata.cb.postInvoke(context, instance, m, result); } } } public JSONRPCResult call(Object context[], JSONObject jsonReq) { JSONRPCResult result = null; String encodedMethod = null; Object requestId = null; JSONArray arguments = null; try { // Get method name, arguments and request id encodedMethod = jsonReq.getString("method"); arguments = jsonReq.getJSONArray("params"); requestId = jsonReq.opt("id"); } catch (NoSuchElementException e) { log.severe("no method or parameters in request"); return new JSONRPCResult(JSONRPCResult.CODE_ERR_NOMETHOD, null, JSONRPCResult.MSG_ERR_NOMETHOD); } if(isDebug()) log.fine("call " + encodedMethod + "(" + arguments + ")" + ", requestId=" + requestId); String className = null; String methodName = null; int objectID = 0; // Parse the class and methodName StringTokenizer t = new StringTokenizer(encodedMethod, "."); if(t.hasMoreElements()) className = t.nextToken(); if(t.hasMoreElements()) methodName = t.nextToken(); // See if we have an object method in the format ".obj#<objectID>" if(encodedMethod.startsWith(".obj#")) { t = new StringTokenizer(className, "#"); t.nextToken(); objectID = Integer.parseInt(t.nextToken()); } ObjectInstance oi = null; ClassData cd = null; HashMap methodMap = null; Method method = null; Object itsThis = null; if(objectID == 0) { // Handle "system.listMethods" if(encodedMethod.equals("system.listMethods")) { HashSet m = new HashSet(); globalBridge.allInstanceMethods(m); if (globalBridge != this) { globalBridge.allStaticMethods(m); globalBridge.allInstanceMethods(m); } allStaticMethods(m); allInstanceMethods(m); JSONArray methods = new JSONArray(); Iterator i = m.iterator(); while(i.hasNext()) methods.put((String)i.next()); return new JSONRPCResult (JSONRPCResult.CODE_SUCCESS, requestId, methods); } // Look up the class, object instance and method objects if(className == null || methodName == null || ((oi = resolveObject(className)) == null && (cd = resolveClass(className)) == null)) return new JSONRPCResult(JSONRPCResult.CODE_ERR_NOMETHOD, requestId, JSONRPCResult.MSG_ERR_NOMETHOD); if(oi != null) { itsThis = oi.o; methodMap = oi.classData().methodMap; } else { methodMap = cd.staticMethodMap; } } else { if((oi = resolveObject(new Integer(objectID))) == null) return new JSONRPCResult(JSONRPCResult.CODE_ERR_NOMETHOD, requestId, JSONRPCResult.MSG_ERR_NOMETHOD); itsThis = oi.o; methodMap = oi.classData().methodMap; // Handle "system.listMethods" if(methodName.equals("listMethods")) { HashSet m = new HashSet(); uniqueMethods(m, "", oi.classData().staticMethodMap); uniqueMethods(m, "", oi.classData().methodMap); JSONArray methods = new JSONArray(); Iterator i = m.iterator(); while(i.hasNext()) methods.put((String)i.next()); return new JSONRPCResult(JSONRPCResult.CODE_SUCCESS, requestId, methods); } } if((method = resolveMethod(methodMap, methodName, arguments)) == null) return new JSONRPCResult(JSONRPCResult.CODE_ERR_NOMETHOD, requestId, JSONRPCResult.MSG_ERR_NOMETHOD); // Call the method try { if(debug) log.fine("invoking " + method.getReturnType().getName() + " " + method.getName() + "(" + argSignature(method) + ")"); Object javaArgs[] = unmarshallArgs(context, method, arguments); for(int i=0; i< context.length; i++) preInvokeCallback(context[i], itsThis, method, javaArgs); Object o = method.invoke(itsThis, javaArgs); for(int i=0; i< context.length; i++) postInvokeCallback(context[i], itsThis, method, o); SerializerState state = new SerializerState(); result = new JSONRPCResult(JSONRPCResult.CODE_SUCCESS, requestId, ser.marshall(state, o)); } catch (UnmarshallException e) { for(int i=0; i< context.length; i++) errorCallback(context[i], itsThis, method, e); result = new JSONRPCResult(JSONRPCResult.CODE_ERR_UNMARSHALL, requestId, e.getMessage()); } catch (MarshallException e) { for(int i=0; i< context.length; i++) errorCallback(context[i], itsThis, method, e); result = new JSONRPCResult(JSONRPCResult.CODE_ERR_MARSHALL, requestId, e.getMessage()); } catch (Throwable e) { if(e instanceof InvocationTargetException) e = ((InvocationTargetException)e).getTargetException(); for(int i=0; i< context.length; i++) errorCallback(context[i], itsThis, method, e); result = new JSONRPCResult(JSONRPCResult.CODE_REMOTE_EXCEPTION, requestId, e); } // Return the results return result; } /** * Calls the 'invocation Error' callback handler. * @param context The transport context (the HttpServletRequest object in the case of the HTTP transport). * @param instance The object instance or null if it is a static method. * @param method Method that failed the invocation. * @param error Error resulting from the invocation. * @author connorb (Axxia) */ private void errorCallback(Object context, Object instance, Method method, Throwable error) { synchronized (callbackSet) { Iterator i = callbackSet.iterator(); while (i.hasNext()) { CallbackData cbdata = (CallbackData)i.next(); if (cbdata.understands(context) && (cbdata.cb instanceof ErrorInvocationCallback)) { ErrorInvocationCallback ecb = (ErrorInvocationCallback)cbdata.cb; try { ecb.invocationError(context, instance, method, error); } catch (Throwable th) { // Ignore all errors in callback, don't want // event listener to bring everything to its knees. } } } } } private void uniqueMethods(HashSet m, String prefix, HashMap methodMap) { Iterator i = methodMap.entrySet().iterator(); while(i.hasNext()) { Map.Entry mentry = (Map.Entry)i.next(); MethodKey mk = (MethodKey)mentry.getKey(); m.add(prefix + mk.methodName); } } private void allStaticMethods(HashSet m) { synchronized (classMap) { Iterator i = classMap.entrySet().iterator(); while(i.hasNext()) { Map.Entry cdentry = (Map.Entry)i.next(); String name = (String)cdentry.getKey(); Class clazz = (Class)cdentry.getValue(); ClassData cd = getClassData(clazz); uniqueMethods(m, name + ".", cd.staticMethodMap); } } } private void allInstanceMethods(HashSet m) { synchronized (objectMap) { Iterator i = objectMap.entrySet().iterator(); while(i.hasNext()) { Map.Entry oientry = (Map.Entry)i.next(); Object key = oientry.getKey(); if (!(key instanceof String)) continue; String name = (String)key; ObjectInstance oi = (ObjectInstance)oientry.getValue(); uniqueMethods(m, name + ".", oi.classData().methodMap); uniqueMethods(m, name + ".", oi.classData().staticMethodMap); } } } public JSONSerializer getSerializer() { return ser; } public void setSerializer(JSONSerializer ser) { this.ser = ser; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -