📄 pluginmanager.java
字号:
running = true;
}
try {
running = true;
// Look for extra plugin directories specified as a system property.
String pluginDirs = System.getProperty("pluginDirs");
if (pluginDirs != null) {
StringTokenizer st = new StringTokenizer(pluginDirs, ", ");
while (st.hasMoreTokens()) {
String dir = st.nextToken();
if (!devPlugins.contains(dir)) {
loadPlugin(new File(dir));
devPlugins.add(dir);
}
}
}
File[] jars = pluginDirectory.listFiles(new FileFilter() {
public boolean accept(File pathname) {
String fileName = pathname.getName().toLowerCase();
return (fileName.endsWith(".jar") || fileName.endsWith(".war"));
}
});
if (jars == null) {
return;
}
for (File jarFile : jars) {
String pluginName = jarFile.getName().substring(0,
jarFile.getName().length() - 4).toLowerCase();
// See if the JAR has already been exploded.
File dir = new File(pluginDirectory, pluginName);
// Store the JAR/WAR file that created the plugin folder
pluginFiles.put(pluginName, jarFile);
// If the JAR hasn't been exploded, do so.
if (!dir.exists()) {
unzipPlugin(pluginName, jarFile, dir);
}
// See if the JAR is newer than the directory. If so, the plugin
// needs to be unloaded and then reloaded.
else if (jarFile.lastModified() > dir.lastModified()) {
// If this is the first time that the monitor process is running, then
// plugins won't be loaded yet. Therefore, just delete the directory.
if (firstRun) {
int count = 0;
// Attempt to delete the folder for up to 5 seconds.
while (!deleteDir(dir) && count < 5) {
Thread.sleep(1000);
}
}
else {
unloadPlugin(pluginName);
}
// If the delete operation was a success, unzip the plugin.
if (!dir.exists()) {
unzipPlugin(pluginName, jarFile, dir);
}
}
}
File[] dirs = pluginDirectory.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
// Sort the list of directories so that the "admin" plugin is always
// first in the list.
Arrays.sort(dirs, new Comparator<File>() {
public int compare(File file1, File file2) {
if (file1.getName().equals("admin")) {
return -1;
}
else if (file2.getName().equals("admin")) {
return 1;
}
else {
return file1.compareTo(file2);
}
}
});
// Turn the list of JAR/WAR files into a set so that we can do lookups.
Set<String> jarSet = new HashSet<String>();
for (File file : jars) {
jarSet.add(file.getName().toLowerCase());
}
// See if any currently running plugins need to be unloaded
// due to the JAR file being deleted (ignore admin plugin).
// Build a list of plugins to delete first so that the plugins
// keyset isn't modified as we're iterating through it.
List<String> toDelete = new ArrayList<String>();
for (File pluginDir : dirs) {
String pluginName = pluginDir.getName();
if (pluginName.equals("admin")) {
continue;
}
if (!jarSet.contains(pluginName + ".jar")) {
if (!jarSet.contains(pluginName + ".war")) {
toDelete.add(pluginName);
}
}
}
for (String pluginName : toDelete) {
unloadPlugin(pluginName);
}
// Load all plugins that need to be loaded.
for (File dirFile : dirs) {
// If the plugin hasn't already been started, start it.
if (dirFile.exists() && !plugins.containsKey(dirFile.getName())) {
loadPlugin(dirFile);
}
}
// Set that at least one iteration was done. That means that "all available" plugins
// have been loaded by now.
if (!XMPPServer.getInstance().isSetupMode()) {
executed = true;
}
// Trigger event that plugins have been monitored
firePluginsMonitored();
}
catch (Throwable e) {
Log.error(e);
}
// Finished running task.
synchronized (this) {
running = false;
}
// Process finished, so set firstRun to false (setting it multiple times doesn't hurt).
firstRun = false;
}
/**
* Unzips a plugin from a JAR file into a directory. If the JAR file
* isn't a plugin, this method will do nothing.
*
* @param pluginName the name of the plugin.
* @param file the JAR file
* @param dir the directory to extract the plugin to.
*/
private void unzipPlugin(String pluginName, File file, File dir) {
try {
ZipFile zipFile = new JarFile(file);
// Ensure that this JAR is a plugin.
if (zipFile.getEntry("plugin.xml") == null) {
return;
}
dir.mkdir();
// Set the date of the JAR file to the newly created folder
dir.setLastModified(file.lastModified());
Log.debug("PluginManager: Extracting plugin: " + pluginName);
for (Enumeration e = zipFile.entries(); e.hasMoreElements();) {
JarEntry entry = (JarEntry)e.nextElement();
File entryFile = new File(dir, entry.getName());
// Ignore any manifest.mf entries.
if (entry.getName().toLowerCase().endsWith("manifest.mf")) {
continue;
}
if (!entry.isDirectory()) {
entryFile.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(entryFile);
InputStream zin = zipFile.getInputStream(entry);
byte[] b = new byte[512];
int len;
while ((len = zin.read(b)) != -1) {
out.write(b, 0, len);
}
out.flush();
out.close();
zin.close();
}
}
zipFile.close();
// The lib directory of the plugin may contain Pack200 versions of the JAR
// file. If so, unpack them.
unpackArchives(new File(dir, "lib"));
}
catch (Exception e) {
Log.error(e);
}
}
/**
* Converts any pack files in a directory into standard JAR files. Each
* pack file will be deleted after being converted to a JAR. If no
* pack files are found, this method does nothing.
*
* @param libDir the directory containing pack files.
*/
private void unpackArchives(File libDir) {
// Get a list of all packed files in the lib directory.
File [] packedFiles = libDir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".pack");
}
});
if (packedFiles == null) {
// Do nothing since no .pack files were found
return;
}
// Unpack each.
for (File packedFile : packedFiles) {
try {
String jarName = packedFile.getName().substring(0,
packedFile.getName().length() - ".pack".length());
// Delete JAR file with same name if it exists (could be due to upgrade
// from old Openfire release).
File jarFile = new File(libDir, jarName);
if (jarFile.exists()) {
jarFile.delete();
}
InputStream in = new BufferedInputStream(new FileInputStream(packedFile));
JarOutputStream out = new JarOutputStream(new BufferedOutputStream(
new FileOutputStream(new File(libDir, jarName))));
Pack200.Unpacker unpacker = Pack200.newUnpacker();
// Call the unpacker
unpacker.unpack(in, out);
in.close();
out.close();
packedFile.delete();
}
catch (Exception e) {
Log.error(e);
}
}
}
}
/**
* Deletes a directory.
*
* @param dir the directory to delete.
* @return true if the directory was deleted.
*/
private boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] childDirs = dir.list();
// Always try to delete JAR files first since that's what will
// be under contention. We do this by always sorting the lib directory
// first.
List<String> children = new ArrayList<String>(Arrays.asList(childDirs));
Collections.sort(children, new Comparator<String>() {
public int compare(String o1, String o2) {
if (o1.equals("lib")) {
return -1;
}
if (o2.equals("lib")) {
return 1;
}
else {
return o1.compareTo(o2);
}
}
});
for (String file : children) {
boolean success = deleteDir(new File(dir, file));
if (!success) {
Log.debug("PluginManager: Plugin removal: could not delete: " + new File(dir, file));
return false;
}
}
}
boolean deleted = dir.delete();
if (deleted) {
// Remove the JAR/WAR file that created the plugin folder
pluginFiles.remove(dir.getName());
}
return deleted;
}
public void addPluginListener(PluginListener listener) {
pluginListeners.add(listener);
}
public void removePluginListener(PluginListener listener) {
pluginListeners.remove(listener);
}
public void addPluginManagerListener(PluginManagerListener listener) {
pluginManagerListeners.add(listener);
if (isExecuted()) {
firePluginsMonitored();
}
}
public void removePluginManagerListener(PluginManagerListener listener) {
pluginManagerListeners.remove(listener);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -