/** * 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); }
/** * 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; }