All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.admingui.common.gadget.GadgetHandlers Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.admingui.common.gadget;

import com.sun.jsftemplating.annotation.Handler;
import com.sun.jsftemplating.annotation.HandlerInput;
import com.sun.jsftemplating.annotation.HandlerOutput;
import com.sun.jsftemplating.layout.LayoutDefinitionManager;
import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext;
import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition;
import com.sun.jsftemplating.layout.descriptors.handler.OutputTypeManager;
import com.sun.jsftemplating.util.FileUtil;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.glassfish.admingui.common.util.GuiUtil;
import org.glassfish.admingui.common.util.JSONUtil;
import org.glassfish.admingui.connector.GadgetModule;
import org.jvnet.hk2.config.ConfigParser;
import org.jvnet.hk2.config.DomDocument;

/**
 *  

This class provides access to {@link GadgetModule}s. It also has a * nice JSON utility for converting JavaBean Objects (and primitives, * Collections, Maps, Strings, etc.) to JSON.

* * @author Ken Paulsen ([email protected]) */ public class GadgetHandlers { /** *

Default constructor.

*/ public GadgetHandlers() { } /** *

This handler returns a {@link GadgetModule} for the named * gadget. The name should either be a complete URL, * or a context-root relative path to the gadget XML file (this * also includes .xml files stored in .jar's / plugins).

*/ @Handler(id="gf.getGadgetModule", input = { @HandlerInput(name="name", type=String.class, required=true) }, output = { @HandlerOutput(name="module", type=GadgetModule.class) }) public static void getGadgetModule(HandlerContext handlerCtx) { String gadgetName = (String) handlerCtx.getInputValue("name"); URL url = null; try { if (!gadgetName.contains("://")) { // Treat as a path... url = FileUtil.searchForFile(gadgetName, null); } if (url == null) { url = new URL(gadgetName); } } catch (Exception ex) { throw new IllegalArgumentException("Cannot creaqte URL from '" + gadgetName + "'!", ex); } GadgetModule module = getGadgetModule(url); handlerCtx.setOutputValue("module", module); } /** *

This method returns a {@link GadgetModule} for the given URL.

*/ public static GadgetModule getGadgetModule(URL url) { if (url == null) { return null; } // FIXME: Cache? // Get our parser... ConfigParser parser = new ConfigParser(GuiUtil.getHabitat()); // Read the document... DomDocument doc = parser.parse(url); // Get the GadgetModule GadgetModule module = (GadgetModule) doc.getRoot().get(); return module; } /** *

This handler will invoke another handler. This allows a generic * handler to invoke another one and return the response(s), if * any.

* *

The following are the inputs are supported:

*
  • handler - (required) This input specifies the * handler which should be invoked.
  • *
  • args - (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).
  • *
  • depth - (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).
*/ @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 outputNames = new ArrayList(); 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 handlers = new ArrayList(1); handlers.add(handler); Object result = handlerCtx.getLayoutElement(). dispatchHandlers(handlerCtx, handlers); // Now... lets get the output values from the "child" handler... Map outputValues = new HashMap(); String outName; Iterator 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; } public static Object parseString(String test) { Map newMap = new HashMap(); String[] strs = test.split(","); for (String str : strs) { str = str.trim(); int end = str.length(); int index = str.indexOf("="); newMap.put(str.substring(0, index), str.substring(index+1, end)); } return newMap; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy