3 解析pf4j
3.1 定义事件
package ro.fortsoft.pf4j;
import java.util.EventObject;
/**
* @author Decebal Suiu
*/
public class PluginStateEvent extends EventObject {
private PluginWrapper plugin;
private PluginState oldState;
public PluginStateEvent(PluginManager source, PluginWrapper plugin, PluginState oldState) {
super(source);
this.plugin = plugin;
this.oldState = oldState;
}
@Override
public PluginManager getSource() {
return (PluginManager) super.getSource();
}
public PluginWrapper getPlugin() {
return plugin;
}
public PluginState getPluginState() {
return plugin.getPluginState();
}
public PluginState getOldState() {
return oldState;
}
@Override
public String toString() {
return "PluginStateEvent [plugin=" + plugin.getPluginId() +
", newState=" + getPluginState() +
", oldState=" + oldState +
']';
}
}
3.2 定义监听器
package ro.fortsoft.pf4j;
import java.util.EventListener;
/**
* PluginStateListener defines the interface for an object that listens to plugin state changes.
*
* @author Decebal Suiu
*/
public interface PluginStateListener extends EventListener {
/**
* Invoked when a plugin's state (for example DISABLED, STARTED) is changed.
*/
public void pluginStateChanged(PluginStateEvent event);
}
3.3 监听器实现
package ro.fortsoft.pf4j;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The default implementation for ExtensionFinder.
* All extensions declared in a plugin are indexed in a file "META-INF/extensions.idx".
* This class lookup extensions in all extensions index files "META-INF/extensions.idx".
*
* @author Decebal Suiu
*/
public class DefaultExtensionFinder implements ExtensionFinder, PluginStateListener {
private
PluginManager
pluginManager
;
private
ExtensionFactory
extensionFactory
;
private
volatile
Map>
entries
;
// cache by pluginId
。。。。。
@Override
public
void
pluginStateChanged(PluginStateEvent event) {
//
TODO
optimize (do only for some transitions)
// clear cache
entries
=
null
;
}
}
3.4 触发监听器
public
class
DefaultPluginManager
implements
PluginManager {
。。。。
@Override
public
boolean
enablePlugin(String pluginId) {
if
(!
plugins
.containsKey(pluginId)) {
throw
new
IllegalArgumentException(String.format(
"Unknown pluginId %s"
, pluginId));
}
PluginWrapper pluginWrapper = getPlugin(pluginId);
if
(!isPluginValid(pluginWrapper)) {
log
.warn(
"Plugin '{}:{}' can not be enabled"
, pluginWrapper.getPluginId(),
pluginWrapper.getDescriptor().getVersion());
return
false
;
}
PluginDescriptor pluginDescriptor = pluginWrapper.getDescriptor();
PluginState pluginState = pluginWrapper.getPluginState();
if
(PluginState.
DISABLED
!= pluginState) {
log
.debug(
"Plugin '{}:{}' is not disabled"
, pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
return
true
;
}
try
{
if
(
disabledPlugins
.remove(pluginId)) {
FileUtils. writeLines(
disabledPlugins
,
new
File(
pluginsDirectory
,
"disabled.txt"
));
}
}
catch
(IOException e) {
log
.error(
"Failed to enable plugin {}"
, pluginId, e);
return
false
;
}
pluginWrapper.setPluginState(PluginState.
CREATED
);
firePluginStateEvent(
new
PluginStateEvent(
this
, pluginWrapper, pluginState));
log
.info(
"Enabled plugin '{}:{}'"
, pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
return
true
;
}
/**
* Add the possibility to override the ExtensionFinder.
*/
protected
ExtensionFinder createExtensionFinder() {
DefaultExtensionFinder extensionFinder =
new
DefaultExtensionFinder(
this
,
extensionFactory
);
addPluginStateListener(extensionFinder);
return
extensionFinder;
}
@Override
public
synchronized
void
addPluginStateListener(PluginStateListener listener) {
pluginStateListeners
.add(listener);
}
@Override
public
synchronized
void
removePluginStateListener(PluginStateListener listener) {
pluginStateListeners
.remove(listener);
}
。。。。
private
synchronized
void
firePluginStateEvent(PluginStateEvent event) {
for
(PluginStateListener listener :
pluginStateListeners
) {
log
.debug(
"Fire '{}' to '{}'"
, event, listener);
listener.pluginStateChanged(event);
}
}
}