protected JSONRPCBridge createBridgeForComponent( JSONComponent component, String componentName, String componentInstance, Map<String, JSONRPCBridge> componentBridges) throws Exception { JSONRPCBridge jsonBridge = JSONBridge.createBridge(); jsonBridge.registerCallableReference(JSONComponent.class); jsonBridge.registerObject("component", component); String componentNameAndInstance = JSONRequestHandler.componentNameAndInstance(componentName, componentInstance); componentBridges.put(componentNameAndInstance, jsonBridge); return jsonBridge; }
protected void activate(ComponentContext ctxt) { this.ctxt = ctxt; this.bc = ctxt.getBundleContext(); jsonRpcBridge = JSONRPCBridge.getGlobalBridge(); try { registryProxy = new ServiceRegistryProxy(this.bc, jsonRpcBridge); jsonRpcBridge.registerObject("OSGi", registryProxy); } catch (Throwable e) { LOG.error("Exception on activate", e); } }
/** * Recursively registers all return types to be accessible, down to the java.lang.Class. By * calling this function you ensure a) that all returned objects are accessible from JavaScript, * no matter how nested they are and b) memory leaks. * * @param brdge * @param reg * @param start */ private static void registerCallableRecursively( JSONRPCBridge brdge, Collection<Class<?>> reg, Class<?> start, int levelOfRecursion) { if (levelOfRecursion == 0) return; try { Collection<Class<?>> allRelatedClasses = getAllRelatedClasses(start); // = start.getDeclaredClasses(); // Method[] methods = start.getMethods(); // for (Method method : methods) { for (Class<?> returnType : allRelatedClasses) { // Class<?> returnType = method.getReturnType(); if (reg.contains(returnType)) continue; // I think these classes are already serialized by JSON, so don't make them accessible. if (returnType.equals(String.class)) continue; if (returnType.equals(Void.class)) continue; if (returnType.equals(Float.class)) continue; if (returnType.equals(Double.class)) continue; if (returnType.equals(Integer.class)) continue; if (returnType.equals(ArrayList.class)) continue; if (returnType.equals(Array.class)) continue; reg.add(returnType); brdge.registerCallableReference(returnType); registerCallableRecursively(brdge, reg, returnType, levelOfRecursion - 1); } } catch (Exception e1) { e1.printStackTrace(); } }
protected void deactivate(ComponentContext ctxt) { LOG.debug("deactivated"); if (this.registryProxy != null) { jsonRpcBridge.unregisterObject("OSGi"); this.registryProxy.close(); } }
/** * Registers all of the methods of the given class to be available for services to call (see * JSONRPCBridge). * * @param name the namespace to register the methods under * @param clazz the class to register * @throws Exception if the registration fails */ public static void registerClass(String name, Class clazz) throws Exception { JSONRPCBridge.getGlobalBridge().registerClass(name, clazz); }
/** * Registers a custom serializer into the global JSON serializers (see JSONRPCBridge). * * @param serializer the serializer to register * @throws Exception if the registration fails */ public static void registerSerializer(Serializer serializer) throws Exception { JSONRPCBridge.getSerializer().registerSerializer(serializer); }
@SuppressWarnings("unchecked") @Override public WOResponse handleRequest(WORequest request) { WOApplication application = WOApplication.application(); application.awake(); try { WOContext context = application.createContextForRequest(request); WOResponse response = application.createResponseInContext(context); Object output; try { String inputString = request.contentString(); JSONObject input = new JSONObject(inputString); String wosid = request.cookieValueForKey("wosid"); if (wosid == null) { ERXMutableURL url = new ERXMutableURL(); url.setQueryParameters(request.queryString()); wosid = url.queryParameter("wosid"); if (wosid == null && input.has("wosid")) { wosid = input.getString("wosid"); } } context._setRequestSessionID(wosid); WOSession session = null; if (context._requestSessionID() != null) { session = WOApplication.application().restoreSessionWithID(wosid, context); } if (session != null) { session.awake(); } try { JSONComponentCallback componentCallback = null; ERXDynamicURL url = new ERXDynamicURL(request._uriDecomposed()); String requestHandlerPath = url.requestHandlerPath(); JSONRPCBridge jsonBridge; if (requestHandlerPath != null && requestHandlerPath.length() > 0) { String componentNameAndInstance = requestHandlerPath; String componentInstance; String componentName; int slashIndex = componentNameAndInstance.indexOf('/'); if (slashIndex == -1) { componentName = componentNameAndInstance; componentInstance = null; } else { componentName = componentNameAndInstance.substring(0, slashIndex); componentInstance = componentNameAndInstance.substring(slashIndex + 1); } if (session == null) { session = context.session(); } String bridgesKey = (componentInstance == null) ? "_JSONGlobalBridges" : "_JSONInstanceBridges"; Map<String, JSONRPCBridge> componentBridges = (Map<String, JSONRPCBridge>) session.objectForKey(bridgesKey); if (componentBridges == null) { int limit = ERXProperties.intForKeyWithDefault( (componentInstance == null) ? "er.ajax.json.globalBacktrackCacheSize" : "er.ajax.json.backtrackCacheSize", WOApplication.application().pageCacheSize()); componentBridges = new LRUMap<String, JSONRPCBridge>(limit); session.setObjectForKey(componentBridges, bridgesKey); } jsonBridge = componentBridges.get(componentNameAndInstance); if (jsonBridge == null) { Class componentClass = _NSUtilities.classWithName(componentName); JSONComponent component; if (JSONComponent.class.isAssignableFrom(componentClass)) { component = (JSONComponent) _NSUtilities.instantiateObject( componentClass, new Class[] {WOContext.class}, new Object[] {context}, true, false); } else { throw new SecurityException( "There is no JSON component named '" + componentName + "'."); } jsonBridge = createBridgeForComponent( component, componentName, componentInstance, componentBridges); } componentCallback = new JSONComponentCallback(context); jsonBridge.registerCallback(componentCallback, WOContext.class); } else { jsonBridge = _sharedBridge; } try { output = jsonBridge.call(new Object[] {request, response, context}, input); } finally { if (componentCallback != null) { jsonBridge.unregisterCallback(componentCallback, WOContext.class); } } if (context._session() != null) { WOSession contextSession = context._session(); // If this is a new session, then we have to force it to be a cookie session if (wosid == null) { boolean storesIDsInCookies = contextSession.storesIDsInCookies(); try { contextSession.setStoresIDsInCookies(true); contextSession._appendCookieToResponse(response); } finally { contextSession.setStoresIDsInCookies(storesIDsInCookies); } } else { contextSession._appendCookieToResponse(response); } } if (output != null) { response.appendContentString(output.toString()); } if (response != null) { response._finalizeInContext(context); response.disableClientCaching(); } } finally { try { if (session != null) { session.sleep(); } } finally { if (context._session() != null) { WOApplication.application().saveSessionForContext(context); } } } } catch (NoSuchElementException e) { e.printStackTrace(); output = new JSONRPCResult( JSONRPCResult.CODE_ERR_NOMETHOD, null, JSONRPCResult.MSG_ERR_NOMETHOD); } catch (JSONException e) { e.printStackTrace(); output = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, JSONRPCResult.MSG_ERR_PARSE); } catch (Throwable t) { t.printStackTrace(); output = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, t.getMessage()); } return response; } finally { application.sleep(); } }
/** * Registers the given object in the shared JSON bridge. The shared JSON bridge is used for * stateless JSON services. As an example, if you call registerService("myExampleService", new * ExampleService()) you can then call json.myExampleService.someMethodInExampleService from your * Javascript. The same instance is shared across all of your service users, so you should not * store any state in this class. * * @param name the name to register the object as * @param serviceObject the instance to register */ public void registerService(String name, Object serviceObject) { _sharedBridge.registerObject(name, serviceObject); }
@Override public void unregister(JSONRPCBridge bridge) { bridge.unregisterObject("registerBackService"); }
@Override public void register(JSONRPCBridge bridge) { bridge.registerObject("registerBackService", getRegisterBackService()); }