📄 jsonrpcbridge.java
字号:
referenceSer = new ReferenceSerializer(this); ser.registerSerializer(referenceSer); } } /** * Registers a class to be returned by reference and not by value * as is done by default. * <p /> * The JSONBridge will take a references to these objects and return * an opaque object to the JSON-RPC client. When the opaque object * is passed back through the bridge in subsequent calls, the * original object is substitued in calls to Java methods. This * should be used for any objects that contain security information * or complex types that are not required in the Javascript client * but need to be passed as a reference in methods of exported objects. * <p /> * A Reference in JSON format looks like this: * <p /> * <code>{ "javaClass":"com.metaparadigm.test.Foo",<br /> * "objectID":5535614,<br /> * "JSONRPCType":"Reference" }</code> * * @param clazz The class object that should be marshalled as a reference. */ public void registerReference(Class clazz) throws Exception { synchronized (referenceSet) { referenceSet.add(clazz); } if(debug) log.info("registered reference " + clazz.getName()); } protected boolean isReference(Class clazz) { if(referenceSet.contains(clazz)) return true; if(this == globalBridge) return false; return globalBridge.isReference(clazz); } /** * Registers a class to be returned as a callable reference. * * The JSONBridge will return a callable reference to the JSON-RPC client * for registered classes instead of passing them by value. The JSONBridge * will take a references to these objects and the JSON-RPC client will * create an invocation proxy for objects of this class for which methods * will be called on the instance on the server. * <p /> * <b>Note:</b> A limitation exists in the JSON-RPC client where only * the top most object returned from a method can be made into a proxy. * <p /> * A Callable Reference in JSON format looks like this: * <p /> * <code>{ "javaClass":"com.metaparadigm.test.Bar",<br /> * "objectID":4827452,<br /> * "JSONRPCType":"CallableReference" }</code> * * @param clazz The class object that should be marshalled as a callable * reference. */ public void registerCallableReference(Class clazz) throws Exception { synchronized (callableReferenceSet) { callableReferenceSet.add(clazz); } if(debug) log.info("registered callable reference " + clazz.getName()); } protected boolean isCallableReference(Class clazz) { if(callableReferenceSet.contains(clazz)) return true; if(this == globalBridge) return false; return globalBridge.isCallableReference(clazz); } /** * Registers a class to export static methods. * * The JSONBridge will export all static methods of the class. * This is useful for exporting factory classes that may then * return CallableReferences to the JSON-RPC client. * <p /> * To export instance methods you need to use registerObject. * * @param name The named prefix to export the class as * @param clazz The class to export static methods from. */ public void registerClass(String name, Class clazz) throws Exception { synchronized (classMap) { Class exists = (Class)classMap.get(name); if(exists != null && exists != clazz) throw new Exception ("different class registered as " + name); if(exists == null) classMap.put(name, clazz); } if(debug) log.info("registered class " + clazz.getName() + " as " + name); } /** * Unregisters a class exported with registerClass. * * The JSONBridge will unexport all static methods of the class. * * @param name The registered name of the class to unexport static * methods from. */ public void unregisterClass(String name) throws Exception { Class clazz = null; synchronized (classMap) { clazz = (Class)classMap.get(name); if(clazz != null) { classMap.remove(name); if(debug) log.info("unregistered class " + clazz.getName() + " from " + name); } } } /** * Lookup a class that is registered with this bridge. * * @param name The registered name of the class to lookup. */ public Class lookupClass(String name) throws Exception { synchronized (classMap) { return (Class)classMap.get(name); } } private ClassData resolveClass(String className) { Class clazz = null; ClassData cd = null; synchronized (classMap) { clazz = (Class)classMap.get(className); } if (clazz != null) cd = getClassData(clazz); if (cd != null) { if(debug) log.fine("found class " + cd.clazz.getName() + " named " + className); return cd; } if(this != globalBridge) return globalBridge.resolveClass(className); return null; } /** * Registers an object to export all instance methods and static methods. * * The JSONBridge will export all instance methods and static methods * of the particular object under the name passed in as a key. * <p /> * This will make available all methods of the object as * <code><key>.<methodnames></code> to JSON-RPC clients. * * @param key The named prefix to export the object as * @param o The object instance to be called upon */ public void registerObject(Object key, Object o) { Class clazz = o.getClass(); ObjectInstance oi = new ObjectInstance(o); synchronized (objectMap) { objectMap.put(key, oi); } if(debug) log.info("registered object " + o.hashCode() + " of class " + clazz.getName() + " as " + key); } /** * Registers an object to export all instance methods defined by interfaceClass. * * The JSONBridge will export all instance methods defined by interfaceClass * of the particular object under the name passed in as a key. * * This will make available these methods of the object as * <code><key>.<methodnames></code> to JSON-RPC clients. * * @param key The named prefix to export the object as * @param o The object instance to be called upon * @param interfaceClass The type that this object should be registered as. * * This can be used to restrict the exported methods to the methods * defined in a specific superclass or interface. */ public void registerObject(Object key, Object o, Class interfaceClass) { ObjectInstance inst = new ObjectInstance(o, interfaceClass); synchronized (objectMap) { objectMap.put(key, inst); } if(debug) { log.info("registered object " + o.hashCode() + " of class " + interfaceClass.getName() + " as " + key); } } /** * Unregisters an object exported with registerObject. * * The JSONBridge will unexport all instance methods and static methods * of the particular object under the name passed in as a key. * * @param key The named prefix of the object to unexport */ public void unregisterObject(Object key) { ObjectInstance oi = null; synchronized (objectMap) { oi = (ObjectInstance)objectMap.get(key); if(oi != null) { objectMap.remove(key); Class clazz = oi.o.getClass(); if(debug) log.info("unregistered object " + oi.o.hashCode() + " of class " + clazz.getName() + " from " + key); } } } /** * Lookup an object that is registered with this bridge. * * @param key The registered name of the object to lookup. */ public Object lookupObject(String key) throws Exception { synchronized (objectMap) { ObjectInstance oi = (ObjectInstance)objectMap.get(key); if(oi != null) return oi.o; } return null; } private ObjectInstance resolveObject(Object key) { ObjectInstance oi; synchronized (objectMap) { oi = (ObjectInstance)objectMap.get(key); } if(debug && oi != null) log.fine("found object " + oi.o.hashCode() + " of class " + oi.classData().clazz.getName() + " with key " + key); if(oi == null && this != globalBridge) return globalBridge.resolveObject(key); else return oi; } /** * Registers a callback to be called before and after method invocation * * @param callback The object implementing the InvocationCallback Interface * @param contextInterface The type of transport Context interface the callback is interested in eg. HttpServletRequest.class for the servlet transport. */ public void registerCallback(InvocationCallback callback, Class contextInterface) { synchronized (callbackSet) { callbackSet.add(new CallbackData(callback, contextInterface)); } if(debug) log.info("registered callback " + callback.getClass().getName() + " with context interface " + contextInterface.getName()); } /** * Unregisters a callback * * @param callback The previously registered InvocationCallback object * @param contextInterface The previously registered transport Context * interface. */ public void unregisterCallback(InvocationCallback callback, Class contextInterface) { synchronized (callbackSet) { callbackSet.remove(new CallbackData(callback, contextInterface)); } if(debug) log.info("unregistered callback " + callback.getClass().getName() + " with context " + contextInterface.getName()); } /** * Registers a Class to be removed from the exported method signatures * and instead be resolved locally using context information * from the transport. * * @param argClazz The class to be resolved locally * @param argResolver The user defined class that resolves the * and returns the method argument using transport context information * @param contextInterface The type of transport Context object the * callback is interested in eg. HttpServletRequest.class for the * servlet transport */ public static void registerLocalArgResolver(Class argClazz, Class contextInterface, LocalArgResolver argResolver) { synchronized (localArgResolverMap) { HashSet resolverSet = (HashSet)localArgResolverMap.get(argClazz); if(resolverSet == null) { resolverSet = new HashSet(); localArgResolverMap.put(argClazz, resolverSet); } resolverSet.add(new LocalArgResolverData(argResolver, argClazz, contextInterface)); classCache = new HashMap(); // invalidate class cache } log.info("registered local arg resolver " + argResolver.getClass().getName() + " for local class " + argClazz.getName() + " with context " + contextInterface.getName()); } /** * Unregisters a LocalArgResolver</b>. * * @param argClazz The previously registered local class * @param argResolver The previously registered LocalArgResolver object * @param contextInterface The previously registered transport Context * interface. */ public static void unregisterLocalArgResolver(Class argClazz, Class contextInterface, LocalArgResolver argResolver) { synchronized (localArgResolverMap) { HashSet resolverSet = (HashSet)localArgResolverMap.get(argClazz); if(resolverSet == null || !resolverSet.remove(new LocalArgResolverData(argResolver, argClazz, contextInterface))) { log.warning("local arg resolver " + argResolver.getClass().getName() + " not registered for local class " + argClazz.getName() + " with context " + contextInterface.getName()); return; } if(resolverSet.isEmpty()) localArgResolverMap.remove(argClazz); classCache = new HashMap(); // invalidate class cache } log.info("unregistered local arg resolver " + argResolver.getClass().getName() + " for local class " + argClazz.getName() + " with context " + contextInterface.getName()); } private Method resolveMethod(HashMap methodMap, String methodName, JSONArray arguments) { Method method[] = null; MethodKey mk = new MethodKey(methodName, arguments.length()); Object o = methodMap.get(mk); if(o instanceof Method) { Method m = (Method)o; if(debug) log.fine("found method " + methodName + "(" + argSignature(m) + ")"); return m; } else if (o instanceof Method[]) method = (Method[])o; else return null; ArrayList candidate = new ArrayList(); if(debug) log.fine("looking for method " + methodName + "(" + argSignature(arguments) + ")"); for(int i=0; i < method.length; i++) { try { candidate.add(tryUnmarshallArgs(method[i], arguments)); if(debug) log.fine("+++ possible match with method " + methodName +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -