org.glassfish.admingui.plugin.ConsolePluginService Maven / Gradle / Ivy
Show all versions of payara-micro Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 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.plugin;
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;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.enterprise.module.ModulesRegistry;
import com.sun.enterprise.module.Module;
import org.glassfish.admingui.connector.TOC;
import org.glassfish.admingui.connector.TOCItem;
import org.glassfish.admingui.connector.Index;
import org.glassfish.admingui.connector.IndexItem;
import org.glassfish.admingui.connector.IntegrationPoint;
import org.glassfish.admingui.connector.ConsoleConfig;
import javax.inject.Inject;
/**
* 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;
/*
@Inject ModulesRegistry modulesRegistry;
for(Module m : modulesRegistry.getModules()) {
url = m.getClassLoader().getResource(ConsoleProvider.DEFAULT_CONFIG_FILENAME);
if(url!=null)
; // TODO: parse url
}
*/
/**
* 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);
URL url = null;
String id = null;
// Loop through the configs and add them all
for (ConsoleProvider provider : providers) {
// Read the contents from the URL
url = provider.getConfiguration();
if (url == null) {
url = provider.getClass().getClassLoader().getResource(
ConsoleProvider.DEFAULT_CONFIG_FILENAME);
}
if (url == null) {
if (logger.isLoggable(Level.INFO)) {
logger.info("Unable to find "
+ ConsoleProvider.DEFAULT_CONFIG_FILENAME
+ " file for provider '"
+ provider.getClass().getName() + "'");
}
continue;
}
//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, provider.getClass().getClassLoader());
classLoaderModuleMap.put(provider.getClass().getClassLoader(), id);
// Add the new IntegrationPoints
addIntegrationPoints(config.getIntegrationPoints(), id);
}
}
//System.out.println("IP Map: " + pointsByType.toString());
// Log some trace messages
if (logger.isLoggable(Level.FINE)) {
logger.fine("Console Plugin Service has been Initialized!");
if (logger.isLoggable(Level.FINEST)) {
logger.finest(pointsByType.toString());
}
}
}
/**
* 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 mergedTOC = helpSetMap.get(locale);
if (mergedTOC != null) {
// Already calculated...
return mergedTOC;
}
// TOC
Map> mapUrls = getResources(locale + "/help/toc.xml");
// Get our parser...
ConfigParser parser = new ConfigParser(habitat);
// Setup a new "merged" TOC...
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...
}
Index mergedIndex = helpSetIndexMap.get(locale);
if (mergedIndex != null) {
// Already calculated...
return mergedIndex;
}
// TOC
Map> mapUrls = getResources(locale + "/help/index.xml");
// Get our parser...
ConfigParser parser = new ConfigParser(habitat);
// Setup a new "merged" TOC...
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) {
if (logger.isLoggable(Level.INFO)) {
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
System.out.println(
"ConsolePluginService: URL Copy Failed!");
}
}
// 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();
/**
*
*/
private Map helpSetMap = new HashMap();
private Map helpSetIndexMap = new HashMap();
}