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

org.glassfish.admingui.plugin.ConsolePluginService Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
 * 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.plugin;

import jakarta.inject.Inject;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.glassfish.admingui.connector.ConsoleConfig;
import org.glassfish.admingui.connector.Index;
import org.glassfish.admingui.connector.IndexItem;
import org.glassfish.admingui.connector.IntegrationPoint;
import org.glassfish.admingui.connector.TOC;
import org.glassfish.admingui.connector.TOCItem;
import org.glassfish.api.admingui.ConsoleProvider;
import org.glassfish.hk2.api.IterableProvider;
import org.glassfish.hk2.api.ServiceLocator;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.component.MultiMap;
import org.jvnet.hk2.config.ConfigParser;
import org.jvnet.hk2.config.DomDocument;

/**
 * 

* This class provides access to {@link IntegrationPoint}s. *

* * @author Ken Paulsen ([email protected]) */ @Service public class ConsolePluginService { @Inject Logger logger; @Inject ServiceLocator habitat; @Inject IterableProvider providers; /** * Default constructor. */ public ConsolePluginService() { } /** * Initialize the available {@link IntegrationPoint}s. */ protected synchronized void init() { if (initialized) { return; } initialized = true; // First find the parser if ((providers != null) && (providers.iterator().hasNext())) { // Get our parser... ConfigParser parser = new ConfigParser(habitat); String id = null; Map configUrls = new HashMap<>(); // Loop through the configs and add them all for (ConsoleProvider provider : providers) { // Read the contents from the URL URL url = provider.getConfiguration(); Iterator urlsIterator; if (url != null) { urlsIterator = List.of(url).iterator(); } else { try { urlsIterator = provider.getClass().getClassLoader().getResources( ConsoleProvider.DEFAULT_CONFIG_FILENAME).asIterator(); } catch (IOException ex) { throw new RuntimeException(ex); } if (!urlsIterator.hasNext()) { logger.log(Level.INFO, "Unable to find " + ConsoleProvider.DEFAULT_CONFIG_FILENAME + " file for provider '" + provider.getClass().getName() + "'"); continue; } } while (urlsIterator.hasNext()) { configUrls.put(urlsIterator.next(), provider.getClass().getClassLoader()); } } for (Map.Entry entry : configUrls.entrySet()) { URL url = entry.getKey(); ClassLoader classLoader = entry.getValue(); //System.out.println("Provider *"+provider+"* : url=*"+url+"*"); DomDocument doc = parser.parse(url); // Get the New IntegrationPoints ConsoleConfig config = (ConsoleConfig) doc.getRoot().get(); // Save the ClassLoader for later //System.out.println("Storing: " + config.getId() + " : " + provider.getClass().getClassLoader()); id = config.getId(); moduleClassLoaderMap.put(id, classLoader); classLoaderModuleMap.put(classLoader, id); // Add the new IntegrationPoints addIntegrationPoints(config.getIntegrationPoints(), id); } } //System.out.println("IP Map: " + pointsByType.toString()); // Log some trace messages logger.log(Level.CONFIG, "Console Plugin Service has been initialized. Integration points by type: \n{0}", pointsByType); } /** * This method returns a merged Table Of Contents for all found help sets for the given locale. */ public synchronized TOC getHelpTOC(String locale) { if (locale == null) { locale = "en"; // Use this as the default... } // TOC Map> mapUrls = getResources(locale + "/help/toc.xml"); // Get our parser... ConfigParser parser = new ConfigParser(habitat); // Setup a new "merged" TOC... var mergedTOC = new TOC(); mergedTOC.setTOCItems(new ArrayList()); mergedTOC.setVersion("2.0"); // Loop through the urls and add them all String id = null; // module id String prefix = "/" + locale + "/help/"; // prefix (minus module id) List urls = null; // URLs to TOC files w/i each plugin module for (Map.Entry> entry : mapUrls.entrySet()) { id = entry.getKey(); urls = entry.getValue(); for (URL url : urls) { DomDocument doc = parser.parse(url); // Merge all the TOC's... TOC toc = (TOC) doc.getRoot().get(); for (TOCItem item : toc.getTOCItems()) { insertTOCItem(mergedTOC.getTOCItems(), item, id + prefix); } } } // FIXME: Sort? return mergedTOC; } /** * This method inserts the given item into the dest list. */ private void insertTOCItem(List dest, TOCItem item, String prefix) { int idx = dest.indexOf(item); if (idx == -1) { // Fix target path... fixTargetPath(item, prefix); // Not there yet, just add it... dest.add(item); } else { // Already there, insert children of item... TOCItem parent = dest.get(idx); for (TOCItem child : item.getTOCItems()) { insertTOCItem(parent.getTOCItems(), child, prefix); } } } /** * This method returns a merged Table Of Contents for all found help sets for the given locale. */ public synchronized Index getHelpIndex(String locale) { if (locale == null) { locale = "en"; // Use this as the default... } // TOC Map> mapUrls = getResources(locale + "/help/index.xml"); // Get our parser... ConfigParser parser = new ConfigParser(habitat); // Setup a new "merged" TOC... var mergedIndex = new Index(); mergedIndex.setIndexItems(new ArrayList()); mergedIndex.setVersion("2.0"); // Loop through the urls and add them all String id = null; // module id String prefix = "/" + locale + "/help/"; // prefix (minus module id) List urls = null; // URLs to TOC files w/i each plugin module for (Map.Entry> entry : mapUrls.entrySet()) { id = entry.getKey(); urls = entry.getValue(); for (URL url : urls) { DomDocument doc = parser.parse(url); // Merge all the TOC's... Index index = (Index) doc.getRoot().get(); for (IndexItem item : index.getIndexItems()) { insertIndexItem(mergedIndex.getIndexItems(), item, id + prefix); } } } // FIXME: Sort? return mergedIndex; } /** * This method inserts the given item into the dest list. */ private void insertIndexItem(List dest, IndexItem item, String prefix) { int idx = dest.indexOf(item); if (idx == -1) { // Fix target path... fixHtmlFileForIndexItem(item, prefix); // Not there yet, just add it... dest.add(item); } else { // Already there, insert children of item... IndexItem parent = dest.get(idx); for (IndexItem child : item.getIndexItems()) { insertIndexItem(parent.getIndexItems(), child, prefix); } } } /** * */ private void fixTargetPath(TOCItem parent, String prefix) { parent.setTargetPath(prefix + parent.getTarget() + ".html"); for (TOCItem item : parent.getTOCItems()) { fixTargetPath(item, prefix); } } /** * */ private void fixHtmlFileForIndexItem(IndexItem parent, String prefix) { String target = null; if (null != (target = parent.getTarget())) { parent.setHtmlFileForTarget(prefix + target + ".html"); } for (IndexItem item : parent.getIndexItems()) { fixHtmlFileForIndexItem(item, prefix); } } /** *

* This method searches the classpath of all plugins for the requested resource and returns all instances of it (if * any). This method will NOT return null, but may return an empty List. *

*/ public Map> getResources(String name) { Map> result = new HashMap>(); if ((providers != null) && (providers.iterator().hasNext())) { // Get our parser... Enumeration urls = null; URL url = null; // Loop through the configs and add them all for (ConsoleProvider provider : providers) { // Read the contents from the URL ClassLoader loader = provider.getClass().getClassLoader(); try { urls = loader.getResources(name); } catch (IOException ex) { logger.log(Level.INFO, "Error getting resource '" + name + "' from provider: '" + provider.getClass().getName() + "'. Skipping...", ex); continue; } List providerURLs = new ArrayList(); while (urls.hasMoreElements()) { // Found one... add it. url = urls.nextElement(); try { providerURLs.add(new URL(url, "")); } catch (Exception ex) { // Ignore b/c this should not ever happen, we're not // changing the URL logger.log(Level.SEVERE, "ConsolePluginService: URL Copy Failed!", ex); } } // Put the URLs into the Map by module id... if (providerURLs.size() > 0) { result.put(classLoaderModuleMap.get(loader), providerURLs); } } } return result; } /*********************************************************** public static byte[] readFromURL(URL url) throws IOException { byte buffer[] = new byte[10000]; byte result[] = new byte[0]; int count = 0; int offset = 0; java.io.InputStream in = url.openStream(); // Attempt to read up to 10K bytes. count = in.read(buffer); while (count != -1) { // Make room for new content... //result = Arrays.copyOf(result, offset + count); Java 6 only... // When I can depend on Java 6... replace the following 3 lines // with the line above. byte oldResult[] = result; result = new byte[offset + count]; System.arraycopy(oldResult, 0, result, 0, offset); // Copy in new content... System.arraycopy(buffer, 0, result, offset, count); // Increment the offset offset += count; // Attempt to read up to 10K more bytes... count = in.read(buffer); } return result; } ***********************************************************/ /** * This method allows new {@link IntegrationPoint}s to be added to the known {@link IntegrationPoint}s. */ public void addIntegrationPoints(List points, String id) { // Add them all... for (IntegrationPoint point : points) { addIntegrationPoint(point, id); } } /** * This method allows a new {@link IntegrationPoint} to be added to the known {@link IntegrationPoint}s. */ public void addIntegrationPoint(IntegrationPoint point, String id) { // Associate the Provider with this IntegrationPoint so we // have a way to get the correct classloader point.setConsoleConfigId(id); // Add it pointsByType.add(point.getType(), point); } /** *

* This method returns the {@link IntegrationPoint}s associated with the given type. *

* * @param type The type of {@link IntegrationPoint}s to retrieve. */ public List getIntegrationPoints(String type) { init(); // Ensure it is initialized. return pointsByType.get(type); } /** *

* This method returns the ClassLoader associated with the requested module. If the requested module does * not exist, has not been initialized, or does not contain any admin console extensions, this method will return * null. *

* * @param moduleName The name of the module. * * @return null, or the module's ClassLoader. */ public ClassLoader getModuleClassLoader(String moduleName) { return moduleClassLoaderMap.get(moduleName); } /** * Flag indicating intialization has already occured. */ private boolean initialized = false; /** * This Map contains the {@link IntegrationPoint}s keyed by the type of integration. */ private MultiMap pointsByType = new MultiMap(); /** *

* This Map keeps track of the ClassLoader for each module that provides GUI * {@link IntegrationPoint}s. It is keyed by the id specified in the console-config.xml file from the * module. *

*/ private Map moduleClassLoaderMap = new HashMap(); /** *

* This Map keeps track of the module id for each ClassLoader that provides * {@link IntegrationPoint}s. It is keyed by the classloader and returns the module id as specified in the module's * console-config.xml file. *

*/ private Map classLoaderModuleMap = new HashMap(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy