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

org.glassfish.admingui.common.handlers.PluginHandlers Maven / Gradle / Ivy

There is a newer version: 4.1.2.181
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.admingui.common.handlers;

import com.sun.jsftemplating.annotation.Handler;
import com.sun.jsftemplating.annotation.HandlerInput;
import com.sun.jsftemplating.annotation.HandlerOutput;
import com.sun.jsftemplating.component.ComponentUtil;
import com.sun.jsftemplating.layout.LayoutDefinitionManager;
import com.sun.jsftemplating.layout.LayoutViewHandler;
import com.sun.jsftemplating.layout.descriptors.ComponentType;
import com.sun.jsftemplating.layout.descriptors.LayoutComponent;
import com.sun.jsftemplating.layout.descriptors.LayoutDefinition;
import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext;
import com.sun.jsftemplating.util.FileUtil;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import org.glassfish.admingui.common.factories.NavigationNodeFactory;
import org.glassfish.admingui.common.util.GuiUtil;
import org.glassfish.admingui.plugin.ConsolePluginService;
import org.glassfish.admingui.connector.IntegrationPoint;
import org.glassfish.admingui.plugin.IntegrationPointComparator;
import org.glassfish.hk2.api.ServiceLocator;

/**
 *  

This class will provide JSFTemplating Handlers that * provide access to {@link IntegrationPoint}s and possibily other * information / services needed to provide plugin functionality * i.e. getting resources, etc.).

* * @author Ken Paulsen ([email protected]) */ public class PluginHandlers { // NOTE: This file used to exist at: v3/admingui/core/src/main/java/org/glassfish/handlers/PluginHandlers.java. /** *

Constructor.

*/ protected PluginHandlers() { } /** *

Find and return the ConsolePluginService. This method * uses the HK2 Habitat to locate the * ConsolePluginService.

* * @param ctx The FacesContext. * * @returns The ConsolePluginService. */ public static ConsolePluginService getPluginService(FacesContext ctx) { // We need to get the ServletContext to find the Habitat ServletContext servletCtx = (ServletContext) (ctx.getExternalContext()).getContext(); // Get the Habitat from the ServletContext ServiceLocator habitat = (ServiceLocator) servletCtx.getAttribute( org.glassfish.admingui.common.plugin.ConsoleClassLoader.HABITAT_ATTRIBUTE); // System.out.println("Habitat:" + habitat); return habitat.getService(ConsolePluginService.class); } /** *

This handler returns a * Map<String id, List<URL>> containing all * the matches of the requested resource. Each List in * the Map is associated with a GUI Plugin, and the key * to the Map is the plugin id.

* * @param handlerCtx The HandlerContext. */ @Handler(id="getPluginResources", input={ @HandlerInput(name="name", type=String.class, required=true)}, output={ @HandlerOutput(name="resources", type=Map.class)}) public static void getPluginResources(HandlerContext handlerCtx) { String name = (String) handlerCtx.getInputValue("name"); ConsolePluginService cps = getPluginService( handlerCtx.getFacesContext()); handlerCtx.setOutputValue("resources", cps.getResources(name)); } /** *

This handler provides access to {@link IntegrationPoint}s for the * requested key.

* * @param handlerCtx The HandlerContext. */ @Handler(id="getIntegrationPoints", input={ @HandlerInput(name="type", type=String.class, required=true)}, output={ @HandlerOutput(name="points", type=List.class)}) public static void getIntegrationPoints(HandlerContext handlerCtx) { String type = (String) handlerCtx.getInputValue("type"); List value = getIntegrationPoints(handlerCtx.getFacesContext(), type); handlerCtx.setOutputValue("points", value); } /** * */ public static List getIntegrationPoints(FacesContext context, String type) { return getPluginService(context).getIntegrationPoints(type); } /** *

This handler adds {@link IntegrationPoint}s of a given type to a * UIComponent tree. It looks for * {@link IntegrationPoint}s using the given type. It * then sorts the results (if any) by parentId, and then * by priority. It next interates over each one looking for a * UIComponent with an id which matches the * its own parentId value. It then uses the content of * the {@link IntegrationPoint} to attempt to include the .jsf page * it refers to under the identified parent component.

*/ @Handler(id="includeIntegrations", input={ @HandlerInput(name="type", type=String.class, required=true), @HandlerInput(name="root", type=UIComponent.class, required=false)}) public static void includeIntegrations(HandlerContext handlerCtx) { // Get the input String type = (String) handlerCtx.getInputValue("type"); UIComponent root = (UIComponent) handlerCtx.getInputValue("root"); try{ // Get the IntegrationPoints FacesContext ctx = handlerCtx.getFacesContext(); List points = getIntegrationPoints(ctx, type); // Include them includeIntegrationPoints(ctx, root, getSortedIntegrationPoints(points)); }catch(Exception ex){ GuiUtil.getLogger().severe("Error in includeIntegrations ; \ntype = " + type + "; root=" + root.toString()); if (GuiUtil.getLogger().isLoggable(Level.FINE)){ ex.printStackTrace(); } } } /** * Includes the first IP based on priority for the given type. It adds * the content to the given UIComponent root. If the IP content looks * like a URL (contains ://), a StaticText component will be added with * the value of the content from the URL. */ @Handler(id="includeFirstIntegrationPoint", input={ @HandlerInput(name="type", type=String.class, required=true), @HandlerInput(name="root", type=UIComponent.class, required=false)}) public static void includeFirstIntegrationPoint(HandlerContext handlerCtx) throws java.io.IOException { // Get the input String type = (String) handlerCtx.getInputValue("type"); UIComponent root = (UIComponent) handlerCtx.getInputValue("root"); // Get the IntegrationPoints FacesContext ctx = handlerCtx.getFacesContext(); Set points = getSortedIntegrationPoints(getIntegrationPoints(ctx, type)); if (points != null) { Iterator it = points.iterator(); if (it.hasNext()) { // Get the first one... IntegrationPoint point = it.next(); root = getIntegrationPointParent(ctx, root, point); // Check to see if IP points to an external URL... if (point.getContent().lastIndexOf("://", 15) != -1) { // Treat content as a url... URL contentURL = FileUtil.searchForFile( point.getContent(), null); if (contentURL == null) { throw new IOException("Unable to locate file: " + point.getContent()); } // Read the content... String content = new String(FileUtil.readFromURL(contentURL)); // Create a StaticText component and add it under the // "root" component. LayoutComponent stDesc = new LayoutComponent(null, "externalContent", new ComponentType("tmpTextCT", "com.sun.jsftemplating.component.factory.basic.StaticTextFactory")); stDesc.addOption("value", content); ComponentUtil.getInstance(ctx).createChildComponent(ctx, stDesc, root); } else { // Include the first one... includeIntegrationPoint(ctx, root, point); } } } } /** * Finds the integration point of the specified type. Returns the contents of this IP type as a list. * The content can be a comma separated String. * This is useful for the case such as dropdown or list box to allow additional options in the component. */ @Handler(id="getContentOfIntegrationPoints", input={ @HandlerInput(name="type", type=String.class, required=true)}, output={ @HandlerOutput(name="labels", type=List.class), @HandlerOutput(name="values", type=List.class)}) public static void getContentOfIntegrationPoints(HandlerContext handlerCtx) throws java.io.IOException { // Get the input String type = (String) handlerCtx.getInputValue("type"); // Get the IntegrationPoints FacesContext ctx = handlerCtx.getFacesContext(); Set points = getSortedIntegrationPoints(getIntegrationPoints(ctx, type)); List labels = new ArrayList(); List values = new ArrayList(); if (points != null) { for(IntegrationPoint it : points){ String content = it.getContent(); if (GuiUtil.isEmpty(content)){ GuiUtil.getLogger().warning("No Content specified for Integration Point: " + type + " id : " + it.getId()); continue; } List labelsAndValues = GuiUtil.parseStringList(content, "|"); values.add(labelsAndValues.get(0)); labels.add(GuiUtil.getMessage(labelsAndValues.get(1), labelsAndValues.get(2))); } } handlerCtx.setOutputValue("labels", labels); handlerCtx.setOutputValue("values", values); } @Handler(id="getAppEditIntegrationPoint", input={ @HandlerInput(name="type", type=String.class, required=true)}, output={ @HandlerOutput(name="appEditPageMap", type=Map.class)}) public static void getAppEditIntegrationPoint(HandlerContext handlerCtx) throws java.io.IOException { // Get the input String type = (String) handlerCtx.getInputValue("type"); // Get the IntegrationPoints FacesContext ctx = handlerCtx.getFacesContext(); Set points = getSortedIntegrationPoints(getIntegrationPoints(ctx, type)); Map result = new HashMap(); if (points != null) { for(IntegrationPoint it : points){ String content = it.getContent(); if (GuiUtil.isEmpty(content)){ GuiUtil.getLogger().warning("No Content specified for Integration Point: " + type + " id : " + it.getId()); continue; } List vv = GuiUtil.parseStringList(content, ":"); if (vv.size()!=2){ GuiUtil.getLogger().warning("Invalid content specified for Integration Point: " + type + " id : " + it.getId()); continue; } result.put(vv.get(0), vv.get(1)); } } handlerCtx.setOutputValue("appEditPageMap", result); } /** *

This method sorts the given {@link IntegrationPoint}'s by parentId * and then by priority. It returns a SortedSet of the * results with the ABC order parentId. When parentId's match, the * highest piority will appear first.

*/ public static Set getSortedIntegrationPoints(List points) { // Make sure we have something... if (points == null) { return null; } // Use a TreeSet to sort automatically Set sortedSet = new TreeSet( IntegrationPointComparator.getInstance()); // FIXME: Check for duplicates! Modify "id" if there is a duplicate? sortedSet.addAll(points); return sortedSet; } /** * * @param points This parameter should be the {@link IntegrationPoint}s * to include in the order in which you want to include * them if that matters (i.e. use SortedSet). */ public static void includeIntegrationPoints(FacesContext ctx, UIComponent root, Set points) { if (points == null) { // Do nothing... return; } if (root == null) { // No root is specified, search whole page root = ctx.getViewRoot(); } // Iterate IntegrationPoint point; Iterator it = null; int lastSize = 0; int currSize = points.size(); String parentId = null; String lastParentId = null; while (currSize != lastSize) { // Stop loop by comparing previous size lastSize = currSize; it = points.iterator(); lastParentId = ""; UIComponent parent = root; // Iterate through the IntegrationPoints while (it.hasNext()) { point = it.next(); // Optimize for multiple plugins for the same parent parentId = point.getParentId(); // Resolve any EL that may be used in identifying the parent ID parentId = (String) ComponentUtil.getInstance(ctx).resolveValue(ctx, null, root, parentId); if ((parentId == null) || !parentId.equals(lastParentId)) { // New parent (or root -- null) parent = getIntegrationPointParent(ctx, root, point); } if (parent == null) { // Didn't find the one specified! // FIXME: log FINE! Note this may not be a problem, keep iterating to see if we find it later. //System.out.println("The specified parentId (" + parentId + ") was not found!"); lastParentId = null; continue; } lastParentId = parent.getId(); // Add the content includeIntegrationPoint(ctx, parent, point); // We found the parent, remove from our list of IPs to add it.remove(); } // Get the set size to see if we have any left to process currSize = points.size(); } } /** *

This method returns the parent for the content of the given * {@link IntegrationPoint}.

* * @param root The UIComponent in which to search for * the parent. * @param point The {@link IntegrationPoint} which is looking for its * parent UIComponent. */ public static UIComponent getIntegrationPointParent(FacesContext ctx, UIComponent root, IntegrationPoint point) { UIComponent parent = null; String parentId = point.getParentId(); parentId = (String) ComponentUtil.getInstance(ctx).resolveValue(ctx, null, root, parentId); if (parentId == null) { // If not specified, just stick it @ the root //parentId = root.getId(); parent = root; } else { parent = findComponentById(root, parentId); } // Return the IntegrationPoint parent return parent; } /** *

This method includes a single {@link IntegrationPoint} under the * given parent UIComponent.

* * @param ctx The FacesContext. * @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 method search for the requested simple id in the given * UIComponent. If the id matches the UIComponent, it * is returned, otherwise, it will search the children and facets * recursively.

* * @param base The UIComponent to search. * @param id The id we're looking for. * * @return The UIComponent, or null. */ private static UIComponent findComponentById(UIComponent base, String id) { // Check if this is the one we're looking for if (id.equals(base.getId())) { return base; } // Not this one, check its kids Iterator it = base.getFacetsAndChildren(); UIComponent comp = null; while (it.hasNext()) { // Recurse comp = findComponentById(it.next(), id); if (comp != null) { // Found! return comp; } } // Not found return null; } /** *

This handler is used for the navigation nodes that request content * from an external URL. This handler pulls the "real url" from from * the component specified by the compId parameter (this * necessarily depends on the presence of the navigation container in * the view for the component look up to work). Once the component * has been found, the url is retrieved from the attribute map, and * its contents retrieved. If processPage is true, the * URL contents are interpretted and the resulting component(s) are * added to the component tree (This feature is not currently * supported).. Otherwise, the contents are returned in the output * parameter pluginPage to be output as-is on the * page.

* * @param handlerCtx The HandlerContext. */ @Handler(id = "retrievePluginPageContents", input = {@HandlerInput(name = "compId", type = String.class, required = true)}, output = {@HandlerOutput(name = "pluginPage", type = String.class)}) public static void retrievePluginPageContents(HandlerContext handlerCtx) { String id = (String) handlerCtx.getInputValue("compId"); UIComponent comp = handlerCtx.getFacesContext().getViewRoot().findComponent(id); String urlContents = ""; if (comp != null) { String url = (String) comp.getAttributes().get(NavigationNodeFactory.REAL_URL); try { // Read from the URL... URL contentUrl = FileUtil.searchForFile(url, null); if (contentUrl == null) { throw new IOException("Unable to locate file: " + url); } urlContents = new String(FileUtil.readFromURL(contentUrl)); // FIXME: Implement processPage support /* if (processPage) { // probably do something like what includeIntegrations does ... } */ } catch (IOException ex) { GuiUtil.getLogger().log(Level.SEVERE, "Unable to read url: " + url, ex); } } // Set the content to output... handlerCtx.setOutputValue("pluginPage", urlContents); } @Handler(id="getPluginIdFromViewId", input={@HandlerInput(name="viewId",type=String.class,required=true)}, output={@HandlerOutput(name="pluginId",type=String.class)} ) public static void getPluginIdFromViewId(HandlerContext handlerCtx) { String viewId = (String) handlerCtx.getInputValue("viewId"); if (viewId == null) { return; } ConsolePluginService cps = getPluginService(handlerCtx.getFacesContext()); String pluginId = "common"; int next = viewId.indexOf("/", 1); if (next > -1) { pluginId = viewId.substring(0, next); String resource = viewId.substring(next); if (pluginId.startsWith("/")) { pluginId = pluginId.substring(1); } ClassLoader cl = cps.getModuleClassLoader(pluginId); URL url = null; if (cl != null) { url = cl.getResource(resource); } if (url == null) { pluginId = "common"; } } handlerCtx.setOutputValue("pluginId", pluginId); } @Handler(id="calculateHelpUrl", input={ @HandlerInput(name="pluginId",type=String.class,required=true), @HandlerInput(name="helpKey",type=String.class,required=true) }, output={ @HandlerOutput(name="url",type=String.class) } ) public static void calculateHelpUrl(HandlerContext handlerCtx) { String pluginId = (String) handlerCtx.getInputValue("pluginId"); String helpKey = (String)handlerCtx.getInputValue("helpKey"); ConsolePluginService cps = getPluginService(handlerCtx.getFacesContext()); ClassLoader cl = cps.getModuleClassLoader(pluginId); // // Try the viewRoot locale first // String path = getHelpPathForResource(helpKey, handlerCtx.getFacesContext().getViewRoot().getLocale(), cl); // if (path == null) { // // Try the default locale // path = getHelpPathForResource(helpKey, Locale.getDefault(), cl); // // // Default to en // if (path == null) { // path = "/en/help/" + helpKey; // } // } String path = ""; handlerCtx.setOutputValue("url", path); } /** *

This function attempts to calculate a help path with the * given locale and classloader. It only succeeds if it is able to * confirm a file exists at the generated path as determined by * ClassLoader.getResource(path). The paths checked are * the following in this order:

* *
  • /locale.toString()/help/<resource>
  • *
  • /locale.getLanguage()_locale.getCountry()/help/<resource>
  • *
  • /locale.getLanguage()/help/<resource>
* *

If all of those fail to yield a file in the classpath, then * null will be returned.

*/ public static String getHelpPathForResource(String resource, Locale locale, ClassLoader cl) { String path = "/" + locale.toString() + "/help/" + resource; // Try with full locale boolean found = (cl.getResource(path) != null); // Try with language_COUNTRY if (!found) { String language = locale.getLanguage(); String country = locale.getCountry(); path = "/" + language + "_" + country + "/help/" + resource; found = (cl.getResource(path) != null); // Try with just language if (!found) { path = "/" + language + "/help/" + resource; found = (cl.getResource(path) != null); if (!found) { // Still not found, so return null path = null; } } } return path; } /* private static String getPluginIdFromViewId(ConsolePluginService cps, String viewId) { String pluginId = ""; int next = viewId.indexOf("/", 1); if (next > -1) { pluginId = viewId.substring(0, next); String resource = viewId.substring(next); if (pluginId.startsWith("/")) { pluginId = pluginId.substring(1); } ClassLoader cl = cps.getModuleClassLoader(pluginId); if (cl != null) { if (cl.getResource(resource) == null) { pluginId = ""; } } } return pluginId; } */ }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy