示例#1
0
 /**
  * This method includes a single {@link IntegrationPoint} under the given parent <code>UIComponent
  * </code>.
  *
  * @param ctx The <code>FacesContext</code>.
  * @param parent The parent for the {@link IntegrationPoint}.
  * @param point The {@link IntegrationPoint}.
  */
 public static void includeIntegrationPoint(
     FacesContext ctx, UIComponent parent, IntegrationPoint point) {
   // Add the content
   String content = point.getContent();
   while (content.startsWith("/")) {
     content = content.substring(1);
   }
   String key = content;
   if (!key.contains("://")) {
     key = "/" + point.getConsoleConfigId() + "/" + content;
   }
   LayoutDefinition def = LayoutDefinitionManager.getLayoutDefinition(ctx, key);
   LayoutViewHandler.buildUIComponentTree(ctx, parent, def);
 }
示例#2
0
  /**
   * This handler will invoke another handler. This allows a generic handler to invoke another one
   * and return the response(s), if any.
   *
   * <p>The following are the inputs are supported:
   *
   * <ul>
   *   <li><b>handler</b> - (required) This input specifies the handler which should be invoked.
   *   <li><b>args</b> - (required) This specifies all of the arguments to be passed to the handler
   *       (both input and output arguments). The value of this should be a String formatted as a
   *       comma separated list of name-value pairs (which are themselves separated by colons (:).
   *       The value of the name-value pairs should be URL encoded (so that commas are escaped).
   *   <li><b>depth</b> - (optional) This property specifies the max depth of nesting for any output
   *       values from the handler. Output values are encoded in JSON. This prevents infinite
   *       looping in the case where an Object refers to itself (or in the case wehre there is
   *       unnecessarily deep data structures).
   * </ul>
   */
  @Handler(
      id = "gf.invokeHandler",
      input = {
        @HandlerInput(name = "handler", type = String.class, required = true),
        @HandlerInput(name = "args", type = String.class, required = true),
        @HandlerInput(name = "depth", type = Integer.class, required = false)
      },
      output = {@HandlerOutput(name = "values", type = String.class)})
  public static Object invokeHandler(HandlerContext handlerCtx) {
    // First find the HandlerDefinition
    String handlerName = (String) handlerCtx.getInputValue("handler");
    HandlerDefinition handlerDef = LayoutDefinitionManager.getGlobalHandlerDefinition(handlerName);
    if (handlerDef == null) {
      throw new IllegalArgumentException("Handler '" + handlerName + "' not found!");
    }

    // Before working with the new Handler, save the old Handler...
    com.sun.jsftemplating.layout.descriptors.handler.Handler oldHandler = handlerCtx.getHandler();

    // Create the Handler to invoke...
    com.sun.jsftemplating.layout.descriptors.handler.Handler handler =
        new com.sun.jsftemplating.layout.descriptors.handler.Handler(handlerDef);

    // Now try to get the inputs / outputs
    List<String> outputNames = new ArrayList<String>();
    String args = (String) handlerCtx.getInputValue("args");
    StringTokenizer tok = new StringTokenizer(args, ",");
    String nvp, name, value;
    Object val = null;
    int colon;
    while (tok.hasMoreTokens()) {
      // Get the NVP...
      nvp = tok.nextToken();
      colon = nvp.indexOf(':');
      if (colon == -1) {
        throw new IllegalArgumentException("Handler I/O name:value must be separated by a ':'!");
      }
      name = nvp.substring(0, colon).trim();
      value = nvp.substring(colon + 1).trim();

      // URL decode 'value'...
      try {
        value = URLDecoder.decode(value, "UTF-8");
      } catch (UnsupportedEncodingException ex) {
        throw new IllegalArgumentException("Unable to decode value, this is not normal!", ex);
      }

      // See if it is an input...
      if (handlerDef.getInputDef(name) != null) {
        // It's an input...
        if (value.startsWith("{") && value.endsWith("}")) {
          Object t = parseString(value.substring(1, (value.length()) - 1));
          val = t;
        } else {
          val = value;
        }
        handler.setInputValue(name, val);
      } else {
        // Assume it's an output mapping...
        handler.setOutputMapping(name, val.toString(), OutputTypeManager.EL_TYPE);
        outputNames.add(name);
      }
    }

    // We have the new handler (yea!), invoke it...
    List<com.sun.jsftemplating.layout.descriptors.handler.Handler> handlers =
        new ArrayList<com.sun.jsftemplating.layout.descriptors.handler.Handler>(1);
    handlers.add(handler);
    Object result = handlerCtx.getLayoutElement().dispatchHandlers(handlerCtx, handlers);

    // Now... lets get the output values from the "child" handler...
    Map<String, Object> outputValues = new HashMap<String, Object>();
    String outName;
    Iterator<String> it = outputNames.iterator();
    while (it.hasNext()) {
      // For each output specified, save it in a Map to be encoded later
      outName = it.next();
      outputValues.put(outName, handler.getOutputValue(handlerCtx, outName));
    }

    // Now we're done with the "child" Handler, restore this Handler...
    handlerCtx.setHandler(oldHandler);

    // Finally, translate the Map to JSON and set the String as an output
    Integer depth = (Integer) handlerCtx.getInputValue("depth");
    if (depth == null) {
      depth = 10;
    }
    handlerCtx.setOutputValue("values", JSONUtil.javaToJSON(outputValues, depth));

    return result;
  }