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;
 }
Beispiel #2
0
  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();
    }
  }
Beispiel #4
0
  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());
 }