org.crsh.plugin.PluginContext Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.crsh.plugin;
import org.crsh.util.Utils;
import org.crsh.vfs.FS;
import org.crsh.vfs.Resource;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public final class PluginContext {
/** . */
private static final Logger log = Logger.getLogger(PluginContext.class.getName());
/** . */
final PluginManager manager;
/** . */
private final ClassLoader loader;
/** . */
private final String version;
/** . */
private final ScheduledExecutorService scanner;
/** . */
private final Map attributes;
/** The shared executor. */
private final ExecutorService executor;
/** . */
private boolean started;
/** . */
private ScheduledFuture scannerFuture;
/** . */
private final ResourceManager resourceManager;
/** . */
private final PropertyManager propertyManager;
/**
* Create a new plugin context with preconfigured executor and scanner, this is equivalent to invoking:
*
* new PluginContext(
* Executors.newFixedThreadPool(20),
* new ScheduledThreadPoolExecutor(1),
* discovery,
* attributes,
* cmdFS,
* confFS,
* loader);
*
* @param discovery the plugin discovery
* @param cmdFS the command file system
* @param attributes the attributes
* @param confFS the conf file system
* @param loader the loader
* @throws NullPointerException if any parameter argument is null
*/
public PluginContext(
PluginDiscovery discovery,
Map attributes,
FS cmdFS,
FS confFS,
ClassLoader loader) throws NullPointerException {
this(
Executors.newFixedThreadPool(20),
new ScheduledThreadPoolExecutor(1),
discovery,
attributes,
cmdFS,
confFS,
loader);
}
/**
* Create a new plugin context.
*
* @param executor the executor for executing asynchronous jobs
* @param scanner the background scanner for scanning commands
* @param discovery the plugin discovery
* @param cmdFS the command file system
* @param attributes the attributes
* @param confFS the conf file system
* @param loader the loader
* @throws NullPointerException if any parameter argument is null
*/
public PluginContext(
ExecutorService executor,
ScheduledExecutorService scanner,
PluginDiscovery discovery,
Map attributes,
FS cmdFS,
FS confFS,
ClassLoader loader) throws NullPointerException {
if (executor == null) {
throw new NullPointerException("No null executor accepted");
}
if (scanner == null) {
throw new NullPointerException("No null scanner accepted");
}
if (discovery == null) {
throw new NullPointerException("No null plugin discovery accepted");
}
if (confFS == null) {
throw new NullPointerException("No null configuration file system accepted");
}
if (cmdFS == null) {
throw new NullPointerException("No null command file system accepted");
}
if (loader == null) {
throw new NullPointerException("No null loader accepted");
}
if (attributes == null) {
throw new NullPointerException("No null attributes accepted");
}
//
String version = null;
try {
Properties props = new Properties();
InputStream in = getClass().getClassLoader().getResourceAsStream("META-INF/maven/org.crashub/crash.shell/pom.properties");
if (in != null) {
props.load(in);
version = props.getProperty("version");
}
} catch (Exception e) {
log.log(Level.SEVERE, "Could not load maven properties", e);
}
//
if (version == null) {
log.log(Level.WARNING, "No version found will use unknown value instead");
version = "unknown";
}
//
this.loader = loader;
this.attributes = attributes;
this.version = version;
this.started = false;
this.manager = new PluginManager(this, discovery);
this.executor = executor;
this.scanner = scanner;
this.resourceManager = new ResourceManager(cmdFS, confFS);
this.propertyManager = new PropertyManager();
}
public String getVersion() {
return version;
}
public Map getAttributes() {
return attributes;
}
public ExecutorService getExecutor() {
return executor;
}
/**
* @return the property manager
*/
public PropertyManager getPropertyManager() {
return propertyManager;
}
/**
* Returns a context property or null if it cannot be found.
*
* @param desc the property descriptor
* @param the property parameter type
* @return the property value
* @throws NullPointerException if the descriptor argument is null
*/
public T getProperty(PropertyDescriptor desc) throws NullPointerException {
return propertyManager.getPropertyValue(desc);
}
/**
* Set a context property to a new value. If the provided value is null, then the property is removed.
*
* @param desc the property descriptor
* @param value the property value
* @param the property parameter type
* @throws NullPointerException if the descriptor argument is null
*/
public void setProperty(PropertyDescriptor desc, T value) throws NullPointerException {
propertyManager.setProperty(desc, value);
}
/**
* Set a context property to a new value. If the provided value is null, then the property is removed.
*
* @param desc the property descriptor
* @param value the property value
* @param the property parameter type
* @throws NullPointerException if the descriptor argument is null
* @throws IllegalArgumentException if the string value cannot be converted to the property type
*/
public void setProperty(PropertyDescriptor desc, String value) throws NullPointerException, IllegalArgumentException {
propertyManager.parseProperty(desc, value);
}
/**
* Load a resource from the context.
*
* @param resourceId the resource id
* @param resourceKind the resource kind
* @return the resource or null if it cannot be found
*/
public Resource loadResource(String resourceId, ResourceKind resourceKind) {
return Utils.first(resourceManager.loadResource(resourceId, resourceKind));
}
/**
* Load a resource from the context.
*
* @param resourceId the resource id
* @param resourceKind the resource kind
* @return the resource or null if it cannot be found
*/
public Iterable loadResources(String resourceId, ResourceKind resourceKind) {
return resourceManager.loadResource(resourceId, resourceKind);
}
/**
* List the resources id for a specific resource kind.
*
* @param kind the resource kind
* @return the resource ids
*/
public Iterable listResources(ResourceKind kind) {
return resourceManager.listResourceId(kind);
}
/**
* Returns the classloader associated with this context.
*
* @return the class loader
*/
public ClassLoader getLoader() {
return loader;
}
public Iterable> getPlugins() {
return manager.getPlugins();
}
/**
* Returns the plugins associated with this context.
*
* @param pluginType the plugin type
* @param the plugin generic type
* @return the plugins
*/
public Iterable getPlugins(Class pluginType) {
return manager.getPlugins(pluginType);
}
/**
* Returns the first plugin associated with this context implementing the specified type.
*
* @param pluginType the plugin type
* @param the plugin generic type
* @return the plugins
*/
public T getPlugin(Class pluginType) {
Iterator plugins = manager.getPlugins(pluginType).iterator();
return plugins.hasNext() ? plugins.next() : null;
}
/**
* Refresh the fs system view. This is normally triggered by the periodic job but it can be manually
* invoked to trigger explicit refreshes.
*/
public void refresh() {
resourceManager.refresh();
}
synchronized void start() {
if (!started) {
// Start refresh
Integer refreshRate = getProperty(PropertyDescriptor.VFS_REFRESH_PERIOD);
TimeUnit timeUnit = getProperty(PropertyDescriptor.VFS_REFRESH_UNIT);
if (refreshRate != null && refreshRate > 0) {
TimeUnit tu = timeUnit != null ? timeUnit : TimeUnit.SECONDS;
scannerFuture = scanner.scheduleWithFixedDelay(new Runnable() {
public void run() {
refresh();
}
}, 0, refreshRate, tu);
}
// Init plugins
manager.getPlugins(Object.class);
//
started = true;
} else {
log.log(Level.WARNING, "Attempt to double start");
}
}
synchronized void stop() {
//
if (started) {
// Shutdown manager
manager.shutdown();
// Shutdown scanner
if (scannerFuture != null) {
scannerFuture.cancel(true);
}
//
scanner.shutdownNow();
// Shutdown executor
executor.shutdownNow();
} else {
log.log(Level.WARNING, "Attempt to stop when stopped");
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy