Commit 6598cb21 authored by Derek DeMoro's avatar Derek DeMoro Committed by derek

1)Updating build to allow for own development classpath.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1474 b35dd754-fafc-0310-a699-88a17e54d16e
parent 064dc050
...@@ -24,9 +24,9 @@ import java.util.List; ...@@ -24,9 +24,9 @@ import java.util.List;
* ClassLoader for plugins. It searches the plugin directory for classes * ClassLoader for plugins. It searches the plugin directory for classes
* and JAR files, then constructs a class loader for the resources found. * and JAR files, then constructs a class loader for the resources found.
* Resources are loaded as follows:<ul> * Resources are loaded as follows:<ul>
* * <p/>
* <li>Any JAR files in the <tt>lib</tt> will be added to the classpath. * <li>Any JAR files in the <tt>lib</tt> will be added to the classpath.
* <li>Any files in the classes directory will be added to the classpath. * <li>Any files in the classes directory will be added to the classpath.
* </ul> * </ul>
* *
* @author Derek DeMoro * @author Derek DeMoro
...@@ -34,18 +34,19 @@ import java.util.List; ...@@ -34,18 +34,19 @@ import java.util.List;
class PluginClassLoader { class PluginClassLoader {
private URLClassLoader classLoader; private URLClassLoader classLoader;
private final List list = new ArrayList();
/** /**
* Constructs a plugin loader for the given plugin directory. * Constructs a plugin loader for the given plugin directory.
* *
* @param pluginDir the plugin directory. * @param pluginDir the plugin directory.
* @throws java.lang.SecurityException if the created class loader violates * @throws java.lang.SecurityException if the created class loader violates
* existing security constraints. * existing security constraints.
* @throws java.net.MalformedURLException if a located resource name cannot be * @throws java.net.MalformedURLException if a located resource name cannot be
* properly converted to a URL. * properly converted to a URL.
*/ */
public PluginClassLoader(File pluginDir) throws MalformedURLException, SecurityException { public PluginClassLoader(File pluginDir) throws MalformedURLException, SecurityException {
final List list = new ArrayList();
File classesDir = new File(pluginDir, "classes"); File classesDir = new File(pluginDir, "classes");
if (classesDir.exists()) { if (classesDir.exists()) {
list.add(classesDir.toURL()); list.add(classesDir.toURL());
...@@ -63,6 +64,13 @@ class PluginClassLoader { ...@@ -63,6 +64,13 @@ class PluginClassLoader {
} }
} }
} }
}
public void addURL(URL url) {
list.add(url);
}
public void initialize(){
Iterator urls = list.iterator(); Iterator urls = list.iterator();
URL[] urlArray = new URL[list.size()]; URL[] urlArray = new URL[list.size()];
for (int i = 0; urls.hasNext(); i++) { for (int i = 0; urls.hasNext(); i++) {
...@@ -79,11 +87,10 @@ class PluginClassLoader { ...@@ -79,11 +87,10 @@ class PluginClassLoader {
* @throws ClassNotFoundException if the class could not be loaded by this class loader. * @throws ClassNotFoundException if the class could not be loaded by this class loader.
* @throws IllegalAccessException if the class constructor was private or protected. * @throws IllegalAccessException if the class constructor was private or protected.
* @throws InstantiationException if the class could not be instantiated (initialization error). * @throws InstantiationException if the class could not be instantiated (initialization error).
* @throws SecurityException if the custom class loader not allowed. * @throws SecurityException if the custom class loader not allowed.
*/ */
public Class loadClass(String name) throws ClassNotFoundException, IllegalAccessException, public Class loadClass(String name) throws ClassNotFoundException, IllegalAccessException,
InstantiationException, SecurityException InstantiationException, SecurityException {
{
return classLoader.loadClass(name); return classLoader.loadClass(name);
} }
......
...@@ -25,7 +25,15 @@ import java.io.File; ...@@ -25,7 +25,15 @@ import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -48,12 +56,12 @@ import java.util.zip.ZipFile; ...@@ -48,12 +56,12 @@ import java.util.zip.ZipFile;
public class PluginManager { public class PluginManager {
private File pluginDirectory; private File pluginDirectory;
private Map<String , Plugin> plugins; private Map<String, Plugin> plugins;
private Map<Plugin , PluginClassLoader> classloaders; private Map<Plugin, PluginClassLoader> classloaders;
private Map<Plugin , File> pluginDirs; private Map<Plugin, File> pluginDirs;
private boolean setupMode = !(Boolean.valueOf(JiveGlobals.getXMLProperty("setup")).booleanValue()); private boolean setupMode = !(Boolean.valueOf(JiveGlobals.getXMLProperty("setup")).booleanValue());
private ScheduledExecutorService executor = null; private ScheduledExecutorService executor = null;
private Map<Plugin , PluginDevEnvironment> pluginDevelopment; private Map<Plugin, PluginDevEnvironment> pluginDevelopment;
/** /**
* Constructs a new plugin manager. * Constructs a new plugin manager.
...@@ -62,10 +70,10 @@ public class PluginManager { ...@@ -62,10 +70,10 @@ public class PluginManager {
*/ */
public PluginManager(File pluginDir) { public PluginManager(File pluginDir) {
this.pluginDirectory = pluginDir; this.pluginDirectory = pluginDir;
plugins = new HashMap<String , Plugin>(); plugins = new HashMap<String, Plugin>();
pluginDirs = new HashMap<Plugin , File>(); pluginDirs = new HashMap<Plugin, File>();
classloaders = new HashMap<Plugin , PluginClassLoader>(); classloaders = new HashMap<Plugin, PluginClassLoader>();
pluginDevelopment = new HashMap<Plugin , PluginDevEnvironment>(); pluginDevelopment = new HashMap<Plugin, PluginDevEnvironment>();
} }
/** /**
...@@ -73,7 +81,7 @@ public class PluginManager { ...@@ -73,7 +81,7 @@ public class PluginManager {
*/ */
public void start() { public void start() {
executor = new ScheduledThreadPoolExecutor(1); executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleWithFixedDelay(new PluginMonitor() , 0 , 10 , TimeUnit.SECONDS); executor.scheduleWithFixedDelay(new PluginMonitor(), 0, 10, TimeUnit.SECONDS);
} }
/** /**
...@@ -145,54 +153,36 @@ public class PluginManager { ...@@ -145,54 +153,36 @@ public class PluginManager {
Log.debug("Loading plugin " + pluginDir.getName()); Log.debug("Loading plugin " + pluginDir.getName());
Plugin plugin = null; Plugin plugin = null;
try { try {
File pluginConfig = new File(pluginDir , "plugin.xml"); File pluginConfig = new File(pluginDir, "plugin.xml");
if (pluginConfig.exists()) { if (pluginConfig.exists()) {
SAXReader saxReader = new SAXReader(); SAXReader saxReader = new SAXReader();
Document pluginXML = saxReader.read(pluginConfig); Document pluginXML = saxReader.read(pluginConfig);
// See if the plugin specifies a version of Jive Messenger // See if the plugin specifies a version of Jive Messenger
// required to run. // required to run.
Element minServerVersion = (Element) pluginXML.selectSingleNode("/plugin/minServerVersion"); Element minServerVersion = (Element)pluginXML.selectSingleNode("/plugin/minServerVersion");
if (minServerVersion != null) { if (minServerVersion != null) {
String requiredVersion = minServerVersion.getTextTrim(); String requiredVersion = minServerVersion.getTextTrim();
Version version = XMPPServer.getInstance().getServerInfo().getVersion(); Version version = XMPPServer.getInstance().getServerInfo().getVersion();
String hasVersion = version.getMajor() + "." + version.getMinor() + "." + String hasVersion = version.getMajor() + "." + version.getMinor() + "." +
version.getMicro(); version.getMicro();
if (hasVersion.compareTo(requiredVersion) < 0) { if (hasVersion.compareTo(requiredVersion) < 0) {
String msg = "Ignoring plugin " + pluginDir.getName() + ": requires " + String msg = "Ignoring plugin " + pluginDir.getName() + ": requires " +
"server version " + requiredVersion; "server version " + requiredVersion;
Log.warn(msg); Log.warn(msg);
System.out.println(msg); System.out.println(msg);
return; return;
} }
} }
PluginClassLoader pluginLoader = new PluginClassLoader(pluginDir); PluginClassLoader pluginLoader = new PluginClassLoader(pluginDir);
String className = pluginXML.selectSingleNode("/plugin/class").getText(); Element developmentNode = (Element)pluginXML.selectSingleNode("/plugin/development");
plugin = (Plugin) pluginLoader.loadClass(className).newInstance(); PluginDevEnvironment dev = null;
plugin.initializePlugin(this , pluginDir);
plugins.put(pluginDir.getName() , plugin);
pluginDirs.put(plugin , pluginDir);
classloaders.put(plugin , pluginLoader);
// Load any JSP's defined by the plugin.
File webXML = new File(pluginDir , "web" + File.separator + "WEB-INF" +
File.separator + "web.xml");
if (webXML.exists()) {
PluginServlet.registerServlets(this , plugin , webXML);
}
// Load any custom-defined servlets.
File customWebXML = new File(pluginDir , "web" + File.separator + "WEB-INF" +
File.separator + "web-custom.xml");
if (customWebXML.exists()) {
PluginServlet.registerServlets(this , plugin , customWebXML);
}
Element developmentNode = (Element) pluginXML.selectSingleNode("/plugin/development");
if (developmentNode != null) { if (developmentNode != null) {
Element webRoot = (Element) developmentNode.selectSingleNode("/plugin/development/webRoot"); Element webRoot = (Element)developmentNode.selectSingleNode("/plugin/development/webRoot");
Element classesDir = (Element) developmentNode.selectSingleNode("/plugin/development/classesDir"); Element classesDir = (Element)developmentNode.selectSingleNode("/plugin/development/classesDir");
PluginDevEnvironment dev = new PluginDevEnvironment(); dev = new PluginDevEnvironment();
String wrd = webRoot.getTextTrim(); String wrd = webRoot.getTextTrim();
File webRootDir = new File(wrd); File webRootDir = new File(wrd);
...@@ -204,31 +194,55 @@ public class PluginManager { ...@@ -204,31 +194,55 @@ public class PluginManager {
File classes = new File(cd); File classes = new File(cd);
if (classes.exists()) { if (classes.exists()) {
dev.setClassesDir(classes); dev.setClassesDir(classes);
pluginLoader.addURL(classes.getAbsoluteFile().toURL());
} }
}
pluginLoader.initialize();
pluginDevelopment.put(plugin , dev); String className = pluginXML.selectSingleNode("/plugin/class").getText();
plugin = (Plugin)pluginLoader.loadClass(className).newInstance();
plugin.initializePlugin(this, pluginDir);
plugins.put(pluginDir.getName(), plugin);
pluginDirs.put(plugin, pluginDir);
classloaders.put(plugin, pluginLoader);
// Load any JSP's defined by the plugin.
File webXML = new File(pluginDir, "web" + File.separator + "WEB-INF" +
File.separator + "web.xml");
if (webXML.exists()) {
PluginServlet.registerServlets(this, plugin, webXML);
} }
// Load any custom-defined servlets.
File customWebXML = new File(pluginDir, "web" + File.separator + "WEB-INF" +
File.separator + "web-custom.xml");
if (customWebXML.exists()) {
PluginServlet.registerServlets(this, plugin, customWebXML);
}
if (dev != null) {
pluginDevelopment.put(plugin, dev);
}
// If there a <adminconsole> section defined, register it. // If there a <adminconsole> section defined, register it.
Element adminElement = (Element) pluginXML.selectSingleNode("/plugin/adminconsole"); Element adminElement = (Element)pluginXML.selectSingleNode("/plugin/adminconsole");
if (adminElement != null) { if (adminElement != null) {
// If global images are specified, override their URL. // If global images are specified, override their URL.
Element imageEl = (Element) adminElement.selectSingleNode("/plugin/adminconsole/global/logo-image"); Element imageEl = (Element)adminElement.selectSingleNode("/plugin/adminconsole/global/logo-image");
if (imageEl != null) { if (imageEl != null) {
imageEl.setText("plugins/" + pluginDir.getName() + "/" + imageEl.getText()); imageEl.setText("plugins/" + pluginDir.getName() + "/" + imageEl.getText());
} }
imageEl = (Element) adminElement.selectSingleNode("/plugin/adminconsole/global/login-image"); imageEl = (Element)adminElement.selectSingleNode("/plugin/adminconsole/global/login-image");
if (imageEl != null) { if (imageEl != null) {
imageEl.setText("plugins/" + pluginDir.getName() + "/" + imageEl.getText()); imageEl.setText("plugins/" + pluginDir.getName() + "/" + imageEl.getText());
} }
// Modify all the URL's in the XML so that they are passed through // Modify all the URL's in the XML so that they are passed through
// the plugin servlet correctly. // the plugin servlet correctly.
List urls = adminElement.selectNodes("//@url"); List urls = adminElement.selectNodes("//@url");
for (int i = 0;i < urls.size();i++) { for (int i = 0; i < urls.size(); i++) {
Attribute attr = (Attribute) urls.get(i); Attribute attr = (Attribute)urls.get(i);
attr.setValue("plugins/" + pluginDir.getName() + "/" + attr.getValue()); attr.setValue("plugins/" + pluginDir.getName() + "/" + attr.getValue());
} }
AdminConsole.addModel(pluginDir.getName() , adminElement); AdminConsole.addModel(pluginDir.getName(), adminElement);
} }
} }
else { else {
...@@ -236,7 +250,7 @@ public class PluginManager { ...@@ -236,7 +250,7 @@ public class PluginManager {
} }
} }
catch (Exception e) { catch (Exception e) {
Log.error("Error loading plugin" , e); Log.error("Error loading plugin", e);
} }
} }
...@@ -258,14 +272,14 @@ public class PluginManager { ...@@ -258,14 +272,14 @@ public class PluginManager {
if (plugin == null) { if (plugin == null) {
return; return;
} }
File webXML = new File(pluginDirectory , "web" + File.separator + "WEB-INF" + File webXML = new File(pluginDirectory, "web" + File.separator + "WEB-INF" +
File.separator + "web.xml"); File.separator + "web.xml");
if (webXML.exists()) { if (webXML.exists()) {
AdminConsole.removeModel(pluginName); AdminConsole.removeModel(pluginName);
PluginServlet.unregisterServlets(webXML); PluginServlet.unregisterServlets(webXML);
} }
File customWebXML = new File(pluginDirectory , "web" + File.separator + "WEB-INF" + File customWebXML = new File(pluginDirectory, "web" + File.separator + "WEB-INF" +
File.separator + "web-custom.xml"); File.separator + "web-custom.xml");
if (customWebXML.exists()) { if (customWebXML.exists()) {
PluginServlet.unregisterServlets(customWebXML); PluginServlet.unregisterServlets(customWebXML);
} }
...@@ -278,8 +292,8 @@ public class PluginManager { ...@@ -278,8 +292,8 @@ public class PluginManager {
classloaders.remove(plugin); classloaders.remove(plugin);
} }
public Class loadClass(String className , Plugin plugin) throws ClassNotFoundException , public Class loadClass(String className, Plugin plugin) throws ClassNotFoundException,
IllegalAccessException , InstantiationException { IllegalAccessException, InstantiationException {
PluginClassLoader loader = classloaders.get(plugin); PluginClassLoader loader = classloaders.get(plugin);
return loader.loadClass(className); return loader.loadClass(className);
} }
...@@ -293,7 +307,7 @@ public class PluginManager { ...@@ -293,7 +307,7 @@ public class PluginManager {
* @return the plugin's name. * @return the plugin's name.
*/ */
public String getName(Plugin plugin) { public String getName(Plugin plugin) {
String name = getElementValue(plugin , "/plugin/name"); String name = getElementValue(plugin, "/plugin/name");
if (name != null) { if (name != null) {
return name; return name;
} }
...@@ -310,7 +324,7 @@ public class PluginManager { ...@@ -310,7 +324,7 @@ public class PluginManager {
* @return the plugin's description. * @return the plugin's description.
*/ */
public String getDescription(Plugin plugin) { public String getDescription(Plugin plugin) {
return getElementValue(plugin , "/plugin/description"); return getElementValue(plugin, "/plugin/description");
} }
/** /**
...@@ -321,7 +335,7 @@ public class PluginManager { ...@@ -321,7 +335,7 @@ public class PluginManager {
* @return the plugin's author. * @return the plugin's author.
*/ */
public String getAuthor(Plugin plugin) { public String getAuthor(Plugin plugin) {
return getElementValue(plugin , "/plugin/author"); return getElementValue(plugin, "/plugin/author");
} }
/** /**
...@@ -332,7 +346,7 @@ public class PluginManager { ...@@ -332,7 +346,7 @@ public class PluginManager {
* @return the plugin's version. * @return the plugin's version.
*/ */
public String getVersion(Plugin plugin) { public String getVersion(Plugin plugin) {
return getElementValue(plugin , "/plugin/version"); return getElementValue(plugin, "/plugin/version");
} }
/** /**
...@@ -343,17 +357,17 @@ public class PluginManager { ...@@ -343,17 +357,17 @@ public class PluginManager {
* @param xpath the xpath expression. * @param xpath the xpath expression.
* @return the value of the element selected by the xpath expression. * @return the value of the element selected by the xpath expression.
*/ */
private String getElementValue(Plugin plugin , String xpath) { private String getElementValue(Plugin plugin, String xpath) {
File pluginDir = pluginDirs.get(plugin); File pluginDir = pluginDirs.get(plugin);
if (pluginDir == null) { if (pluginDir == null) {
return null; return null;
} }
try { try {
File pluginConfig = new File(pluginDir , "plugin.xml"); File pluginConfig = new File(pluginDir, "plugin.xml");
if (pluginConfig.exists()) { if (pluginConfig.exists()) {
SAXReader saxReader = new SAXReader(); SAXReader saxReader = new SAXReader();
Document pluginXML = saxReader.read(pluginConfig); Document pluginXML = saxReader.read(pluginConfig);
Element element = (Element) pluginXML.selectSingleNode(xpath); Element element = (Element)pluginXML.selectSingleNode(xpath);
if (element != null) { if (element != null) {
return element.getTextTrim(); return element.getTextTrim();
} }
...@@ -381,14 +395,14 @@ public class PluginManager { ...@@ -381,14 +395,14 @@ public class PluginManager {
} }
}); });
for (int i = 0;i < jars.length;i++) { for (int i = 0; i < jars.length; i++) {
File jarFile = jars[i]; File jarFile = jars[i];
String pluginName = jarFile.getName().substring(0 , jarFile.getName().length() - 4).toLowerCase(); String pluginName = jarFile.getName().substring(0, jarFile.getName().length() - 4).toLowerCase();
// See if the JAR has already been exploded. // See if the JAR has already been exploded.
File dir = new File(pluginDirectory , pluginName); File dir = new File(pluginDirectory, pluginName);
// If the JAR hasn't been exploded, do so. // If the JAR hasn't been exploded, do so.
if (!dir.exists()) { if (!dir.exists()) {
unzipPlugin(pluginName , jarFile , dir); unzipPlugin(pluginName, jarFile, dir);
} }
// See if the JAR is newer than the directory. If so, the plugin // See if the JAR is newer than the directory. If so, the plugin
// needs to be unloaded and then reloaded. // needs to be unloaded and then reloaded.
...@@ -398,11 +412,11 @@ public class PluginManager { ...@@ -398,11 +412,11 @@ public class PluginManager {
System.gc(); System.gc();
while (!deleteDir(dir)) { while (!deleteDir(dir)) {
Log.error("Error unloading plugin " + pluginName + ". " + Log.error("Error unloading plugin " + pluginName + ". " +
"Will attempt again momentarily."); "Will attempt again momentarily.");
Thread.sleep(5000); Thread.sleep(5000);
} }
// Now unzip the plugin. // Now unzip the plugin.
unzipPlugin(pluginName , jarFile , dir); unzipPlugin(pluginName, jarFile, dir);
} }
} }
...@@ -414,8 +428,8 @@ public class PluginManager { ...@@ -414,8 +428,8 @@ public class PluginManager {
// Sort the list of directories so that the "admin" plugin is always // Sort the list of directories so that the "admin" plugin is always
// first in the list. // first in the list.
Arrays.sort(dirs , new Comparator<File>() { Arrays.sort(dirs, new Comparator<File>() {
public int compare(File file1 , File file2) { public int compare(File file1, File file2) {
if (file1.getName().equals("admin")) { if (file1.getName().equals("admin")) {
return -1; return -1;
} }
...@@ -427,7 +441,7 @@ public class PluginManager { ...@@ -427,7 +441,7 @@ public class PluginManager {
} }
}); });
for (int i = 0;i < dirs.length;i++) { for (int i = 0; i < dirs.length; i++) {
File dirFile = dirs[i]; File dirFile = dirs[i];
// If the plugin hasn't already been started, start it. // If the plugin hasn't already been started, start it.
if (!plugins.containsKey(dirFile.getName())) { if (!plugins.containsKey(dirFile.getName())) {
...@@ -445,7 +459,7 @@ public class PluginManager { ...@@ -445,7 +459,7 @@ public class PluginManager {
if (pluginName.equals("admin")) { if (pluginName.equals("admin")) {
continue; continue;
} }
File file = new File(pluginDirectory , pluginName + ".jar"); File file = new File(pluginDirectory, pluginName + ".jar");
if (!file.exists()) { if (!file.exists()) {
toDelete.add(pluginName); toDelete.add(pluginName);
} }
...@@ -453,9 +467,9 @@ public class PluginManager { ...@@ -453,9 +467,9 @@ public class PluginManager {
for (String pluginName : toDelete) { for (String pluginName : toDelete) {
unloadPlugin(pluginName); unloadPlugin(pluginName);
System.gc(); System.gc();
while (!deleteDir(new File(pluginDirectory , pluginName))) { while (!deleteDir(new File(pluginDirectory, pluginName))) {
Log.error("Error unloading plugin " + pluginName + ". " + Log.error("Error unloading plugin " + pluginName + ". " +
"Will attempt again momentarily."); "Will attempt again momentarily.");
Thread.sleep(5000); Thread.sleep(5000);
} }
} }
...@@ -474,7 +488,7 @@ public class PluginManager { ...@@ -474,7 +488,7 @@ public class PluginManager {
* @param file the JAR file * @param file the JAR file
* @param dir the directory to extract the plugin to. * @param dir the directory to extract the plugin to.
*/ */
private void unzipPlugin(String pluginName , File file , File dir) { private void unzipPlugin(String pluginName, File file, File dir) {
try { try {
ZipFile zipFile = new JarFile(file); ZipFile zipFile = new JarFile(file);
// Ensure that this JAR is a plugin. // Ensure that this JAR is a plugin.
...@@ -483,9 +497,9 @@ public class PluginManager { ...@@ -483,9 +497,9 @@ public class PluginManager {
} }
dir.mkdir(); dir.mkdir();
Log.debug("Extracting plugin: " + pluginName); Log.debug("Extracting plugin: " + pluginName);
for (Enumeration e = zipFile.entries();e.hasMoreElements();) { for (Enumeration e = zipFile.entries(); e.hasMoreElements();) {
JarEntry entry = (JarEntry) e.nextElement(); JarEntry entry = (JarEntry)e.nextElement();
File entryFile = new File(dir , entry.getName()); File entryFile = new File(dir, entry.getName());
// Ignore any manifest.mf entries. // Ignore any manifest.mf entries.
if (entry.getName().toLowerCase().endsWith("manifest.mf")) { if (entry.getName().toLowerCase().endsWith("manifest.mf")) {
continue; continue;
...@@ -497,7 +511,7 @@ public class PluginManager { ...@@ -497,7 +511,7 @@ public class PluginManager {
byte[] b = new byte[512]; byte[] b = new byte[512];
int len = 0; int len = 0;
while ((len = zin.read(b)) != -1) { while ((len = zin.read(b)) != -1) {
out.write(b , 0 , len); out.write(b, 0, len);
} }
out.flush(); out.flush();
out.close(); out.close();
...@@ -518,8 +532,8 @@ public class PluginManager { ...@@ -518,8 +532,8 @@ public class PluginManager {
public boolean deleteDir(File dir) { public boolean deleteDir(File dir) {
if (dir.isDirectory()) { if (dir.isDirectory()) {
String[] children = dir.list(); String[] children = dir.list();
for (int i = 0;i < children.length;i++) { for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir , children[i])); boolean success = deleteDir(new File(dir, children[i]));
if (!success) { if (!success) {
return false; return false;
} }
......
...@@ -11,14 +11,14 @@ ...@@ -11,14 +11,14 @@
package org.jivesoftware.messenger.container; package org.jivesoftware.messenger.container;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspC;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspC;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
...@@ -56,14 +56,14 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -56,14 +56,14 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
public class PluginServlet extends HttpServlet { public class PluginServlet extends HttpServlet {
private static Map<String , HttpServlet> servlets; private static Map<String, HttpServlet> servlets;
private static File pluginDirectory; private static File pluginDirectory;
private static PluginManager pluginManager; private static PluginManager pluginManager;
private static ServletConfig servletConfig; private static ServletConfig servletConfig;
static { static {
servlets = new ConcurrentHashMap<String , HttpServlet>(); servlets = new ConcurrentHashMap<String, HttpServlet>();
pluginDirectory = new File(JiveGlobals.getHomeDirectory() , "plugins"); pluginDirectory = new File(JiveGlobals.getHomeDirectory(), "plugins");
} }
public void init(ServletConfig config) throws ServletException { public void init(ServletConfig config) throws ServletException {
...@@ -71,8 +71,8 @@ public class PluginServlet extends HttpServlet { ...@@ -71,8 +71,8 @@ public class PluginServlet extends HttpServlet {
servletConfig = config; servletConfig = config;
} }
public void service(HttpServletRequest request , HttpServletResponse response) public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException , IOException { throws ServletException, IOException {
String pathInfo = request.getPathInfo(); String pathInfo = request.getPathInfo();
if (pathInfo == null) { if (pathInfo == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setStatus(HttpServletResponse.SC_NOT_FOUND);
...@@ -82,20 +82,20 @@ public class PluginServlet extends HttpServlet { ...@@ -82,20 +82,20 @@ public class PluginServlet extends HttpServlet {
try { try {
// Handle JSP requests. // Handle JSP requests.
if (pathInfo.endsWith(".jsp")) { if (pathInfo.endsWith(".jsp")) {
if(handleJspDocument(pathInfo, request, response)){ if (handleJspDocument(pathInfo, request, response)) {
return; return;
} }
handleJSP(pathInfo , request , response); handleJSP(pathInfo, request, response);
return; return;
} }
// Handle image requests. // Handle image requests.
else if (pathInfo.endsWith(".gif") || pathInfo.endsWith(".png")) { else if (pathInfo.endsWith(".gif") || pathInfo.endsWith(".png")) {
handleImage(pathInfo , response); handleImage(pathInfo, response);
return; return;
} }
// Handle servlet requests. // Handle servlet requests.
else if (getServlet(pathInfo) != null) { else if (getServlet(pathInfo) != null) {
handleServlet(pathInfo , request , response); handleServlet(pathInfo, request, response);
} }
// Anything else results in a 404. // Anything else results in a 404.
else { else {
...@@ -119,11 +119,11 @@ public class PluginServlet extends HttpServlet { ...@@ -119,11 +119,11 @@ public class PluginServlet extends HttpServlet {
* @param webXML the web.xml file containing JSP page names to servlet class file * @param webXML the web.xml file containing JSP page names to servlet class file
* mappings. * mappings.
*/ */
public static void registerServlets(PluginManager manager , Plugin plugin , File webXML) { public static void registerServlets(PluginManager manager, Plugin plugin, File webXML) {
pluginManager = manager; pluginManager = manager;
if (!webXML.exists()) { if (!webXML.exists()) {
Log.error("Could not register plugin servlets, file " + webXML.getAbsolutePath() + Log.error("Could not register plugin servlets, file " + webXML.getAbsolutePath() +
" does not exist."); " does not exist.");
return; return;
} }
// Find the name of the plugin directory given that the webXML file // Find the name of the plugin directory given that the webXML file
...@@ -133,22 +133,22 @@ public class PluginServlet extends HttpServlet { ...@@ -133,22 +133,22 @@ public class PluginServlet extends HttpServlet {
// Make the reader non-validating so that it doesn't try to resolve external // Make the reader non-validating so that it doesn't try to resolve external
// DTD's. Trying to resolve external DTD's can break on some firewall configurations. // DTD's. Trying to resolve external DTD's can break on some firewall configurations.
SAXReader saxReader = new SAXReader(false); SAXReader saxReader = new SAXReader(false);
saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd" , saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",
false); false);
Document doc = saxReader.read(webXML); Document doc = saxReader.read(webXML);
// Find all <servlet> entries to discover name to class mapping. // Find all <servlet> entries to discover name to class mapping.
List classes = doc.selectNodes("//servlet"); List classes = doc.selectNodes("//servlet");
Map<String , Class> classMap = new HashMap<String , Class>(); Map<String, Class> classMap = new HashMap<String, Class>();
for (int i = 0;i < classes.size();i++) { for (int i = 0; i < classes.size(); i++) {
Element servletElement = (Element) classes.get(i); Element servletElement = (Element)classes.get(i);
String name = servletElement.element("servlet-name").getTextTrim(); String name = servletElement.element("servlet-name").getTextTrim();
String className = servletElement.element("servlet-class").getTextTrim(); String className = servletElement.element("servlet-class").getTextTrim();
classMap.put(name , manager.loadClass(className , plugin)); classMap.put(name, manager.loadClass(className, plugin));
} }
// Find all <servelt-mapping> entries to discover name to URL mapping. // Find all <servelt-mapping> entries to discover name to URL mapping.
List names = doc.selectNodes("//servlet-mapping"); List names = doc.selectNodes("//servlet-mapping");
for (int i = 0;i < names.size();i++) { for (int i = 0; i < names.size(); i++) {
Element nameElement = (Element) names.get(i); Element nameElement = (Element)names.get(i);
String name = nameElement.element("servlet-name").getTextTrim(); String name = nameElement.element("servlet-name").getTextTrim();
String url = nameElement.element("url-pattern").getTextTrim(); String url = nameElement.element("url-pattern").getTextTrim();
// Register the servlet for the URL. // Register the servlet for the URL.
...@@ -156,8 +156,8 @@ public class PluginServlet extends HttpServlet { ...@@ -156,8 +156,8 @@ public class PluginServlet extends HttpServlet {
Object instance = servletClass.newInstance(); Object instance = servletClass.newInstance();
if (instance instanceof HttpServlet) { if (instance instanceof HttpServlet) {
// Initialize the servlet then add it to the map.. // Initialize the servlet then add it to the map..
((HttpServlet) instance).init(servletConfig); ((HttpServlet)instance).init(servletConfig);
servlets.put(pluginName + url , (HttpServlet) instance); servlets.put(pluginName + url, (HttpServlet)instance);
} }
else { else {
Log.warn("Could not load " + (pluginName + url) + ": not a servlet."); Log.warn("Could not load " + (pluginName + url) + ": not a servlet.");
...@@ -178,7 +178,7 @@ public class PluginServlet extends HttpServlet { ...@@ -178,7 +178,7 @@ public class PluginServlet extends HttpServlet {
public static void unregisterServlets(File webXML) { public static void unregisterServlets(File webXML) {
if (!webXML.exists()) { if (!webXML.exists()) {
Log.error("Could not unregister plugin servlets, file " + webXML.getAbsolutePath() + Log.error("Could not unregister plugin servlets, file " + webXML.getAbsolutePath() +
" does not exist."); " does not exist.");
return; return;
} }
// Find the name of the plugin directory given that the webXML file // Find the name of the plugin directory given that the webXML file
...@@ -186,13 +186,13 @@ public class PluginServlet extends HttpServlet { ...@@ -186,13 +186,13 @@ public class PluginServlet extends HttpServlet {
String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName(); String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName();
try { try {
SAXReader saxReader = new SAXReader(false); SAXReader saxReader = new SAXReader(false);
saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd" , saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",
false); false);
Document doc = saxReader.read(webXML); Document doc = saxReader.read(webXML);
// Find all <servelt-mapping> entries to discover name to URL mapping. // Find all <servelt-mapping> entries to discover name to URL mapping.
List names = doc.selectNodes("//servlet-mapping"); List names = doc.selectNodes("//servlet-mapping");
for (int i = 0;i < names.size();i++) { for (int i = 0; i < names.size(); i++) {
Element nameElement = (Element) names.get(i); Element nameElement = (Element)names.get(i);
String url = nameElement.element("url-pattern").getTextTrim(); String url = nameElement.element("url-pattern").getTextTrim();
// Destroy the servlet than remove from servlets map. // Destroy the servlet than remove from servlets map.
HttpServlet servlet = servlets.get(pluginName + url); HttpServlet servlet = servlets.get(pluginName + url);
...@@ -218,15 +218,15 @@ public class PluginServlet extends HttpServlet { ...@@ -218,15 +218,15 @@ public class PluginServlet extends HttpServlet {
* request. * request.
* @throws IOException if an IOException occurs while handling the request. * @throws IOException if an IOException occurs while handling the request.
*/ */
private void handleJSP(String pathInfo , HttpServletRequest request , private void handleJSP(String pathInfo, HttpServletRequest request,
HttpServletResponse response) throws ServletException , IOException { HttpServletResponse response) throws ServletException, IOException {
// Strip the starting "/" from the path to find the JSP URL. // Strip the starting "/" from the path to find the JSP URL.
String jspURL = pathInfo.substring(1); String jspURL = pathInfo.substring(1);
HttpServlet servlet = servlets.get(jspURL); HttpServlet servlet = servlets.get(jspURL);
if (servlet != null) { if (servlet != null) {
servlet.service(request , response); servlet.service(request, response);
return; return;
} }
else { else {
...@@ -245,12 +245,12 @@ public class PluginServlet extends HttpServlet { ...@@ -245,12 +245,12 @@ public class PluginServlet extends HttpServlet {
* @throws ServletException if a servlet exception occurs while handling the request. * @throws ServletException if a servlet exception occurs while handling the request.
* @throws IOException if an IOException occurs while handling the request. * @throws IOException if an IOException occurs while handling the request.
*/ */
private void handleServlet(String pathInfo , HttpServletRequest request , private void handleServlet(String pathInfo, HttpServletRequest request,
HttpServletResponse response) throws ServletException , IOException { HttpServletResponse response) throws ServletException, IOException {
// Strip the starting "/" from the path to find the JSP URL. // Strip the starting "/" from the path to find the JSP URL.
HttpServlet servlet = getServlet(pathInfo); HttpServlet servlet = getServlet(pathInfo);
if (servlet != null) { if (servlet != null) {
servlet.service(request , response); servlet.service(request, response);
return; return;
} }
else { else {
...@@ -274,7 +274,7 @@ public class PluginServlet extends HttpServlet { ...@@ -274,7 +274,7 @@ public class PluginServlet extends HttpServlet {
int index = key.indexOf("/*"); int index = key.indexOf("/*");
String searchkey = key; String searchkey = key;
if (index != -1) { if (index != -1) {
searchkey = key.substring(0 , index); searchkey = key.substring(0, index);
} }
if (searchkey.startsWith(pathInfo) || pathInfo.startsWith(searchkey)) { if (searchkey.startsWith(pathInfo) || pathInfo.startsWith(searchkey)) {
servlet = servlets.get(key); servlet = servlets.get(key);
...@@ -292,15 +292,15 @@ public class PluginServlet extends HttpServlet { ...@@ -292,15 +292,15 @@ public class PluginServlet extends HttpServlet {
* @param response the response object. * @param response the response object.
* @throws IOException if an IOException occurs while handling the request. * @throws IOException if an IOException occurs while handling the request.
*/ */
private void handleImage(String pathInfo , HttpServletResponse response) throws IOException { private void handleImage(String pathInfo, HttpServletResponse response) throws IOException {
String[] parts = pathInfo.split("/"); String[] parts = pathInfo.split("/");
// Image request must be in correct format. // Image request must be in correct format.
if (parts.length != 4) { if (parts.length != 4) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return; return;
} }
File image = new File(pluginDirectory , parts[1] + File.separator + "web" + File image = new File(pluginDirectory, parts[1] + File.separator + "web" +
File.separator + "images" + File.separator + parts[3]); File.separator + "images" + File.separator + parts[3]);
if (!image.exists()) { if (!image.exists()) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return; return;
...@@ -311,7 +311,7 @@ public class PluginServlet extends HttpServlet { ...@@ -311,7 +311,7 @@ public class PluginServlet extends HttpServlet {
if (pathInfo.endsWith(".png")) { if (pathInfo.endsWith(".png")) {
contentType = "image/png"; contentType = "image/png";
} }
response.setHeader("Content-disposition" , "filename=\"" + image + "\";"); response.setHeader("Content-disposition", "filename=\"" + image + "\";");
response.setContentType(contentType); response.setContentType(contentType);
// Write out the image to the user. // Write out the image to the user.
InputStream in = null; InputStream in = null;
...@@ -321,13 +321,13 @@ public class PluginServlet extends HttpServlet { ...@@ -321,13 +321,13 @@ public class PluginServlet extends HttpServlet {
out = response.getOutputStream(); out = response.getOutputStream();
// Set the size of the file. // Set the size of the file.
response.setContentLength((int) image.length()); response.setContentLength((int)image.length());
// Use a 1K buffer. // Use a 1K buffer.
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int len; int len;
while ((len = in.read(buf)) != -1) { while ((len = in.read(buf)) != -1) {
out.write(buf , 0 , len); out.write(buf, 0, len);
} }
} }
finally { finally {
...@@ -345,7 +345,7 @@ public class PluginServlet extends HttpServlet { ...@@ -345,7 +345,7 @@ public class PluginServlet extends HttpServlet {
} }
} }
/** /**
* Handles a request for a JSP page. It checks to see if the jsp page exists in * Handles a request for a JSP page. It checks to see if the jsp page exists in
* the current plugin. If one is found, request handling is passed to it. If no * the current plugin. If one is found, request handling is passed to it. If no
* jsp page is found, we return false to allow for other handlers. * jsp page is found, we return false to allow for other handlers.
...@@ -355,7 +355,7 @@ public class PluginServlet extends HttpServlet { ...@@ -355,7 +355,7 @@ public class PluginServlet extends HttpServlet {
* @param response the response object. * @param response the response object.
* @return true if this page was handled successfully. * @return true if this page was handled successfully.
*/ */
private boolean handleJspDocument(String pathInfo , HttpServletRequest request , private boolean handleJspDocument(String pathInfo, HttpServletRequest request,
HttpServletResponse response) { HttpServletResponse response) {
String jspURL = pathInfo.substring(1); String jspURL = pathInfo.substring(1);
...@@ -363,26 +363,26 @@ public class PluginServlet extends HttpServlet { ...@@ -363,26 +363,26 @@ public class PluginServlet extends HttpServlet {
// Handle pre-existing pages and fail over to pre-compiled pages. // Handle pre-existing pages and fail over to pre-compiled pages.
int fileSeperator = jspURL.indexOf("/"); int fileSeperator = jspURL.indexOf("/");
if (fileSeperator != -1) { if (fileSeperator != -1) {
String pluginName = jspURL.substring(0 , fileSeperator); String pluginName = jspURL.substring(0, fileSeperator);
Plugin plugin = pluginManager.getPlugin(pluginName); Plugin plugin = pluginManager.getPlugin(pluginName);
PluginDevEnvironment environment = pluginManager.getDevEnvironment(plugin); PluginDevEnvironment environment = pluginManager.getDevEnvironment(plugin);
File webDir = environment.getWebRoot(); File webDir = environment.getWebRoot();
if(webDir == null || !webDir.exists()){ if (webDir == null || !webDir.exists()) {
return false; return false;
} }
File pluginDirectory = pluginManager.getPluginDirectory(plugin); File pluginDirectory = pluginManager.getPluginDirectory(plugin);
File compilationDir = new File(pluginDirectory , "classes"); File compilationDir = new File(pluginDirectory, "classes");
compilationDir.mkdirs(); compilationDir.mkdirs();
String jsp = jspURL.substring(fileSeperator + 1); String jsp = jspURL.substring(fileSeperator + 1);
int indexOfLastSlash = jsp.lastIndexOf("/"); int indexOfLastSlash = jsp.lastIndexOf("/");
String relativeDir = ""; String relativeDir = "";
if(indexOfLastSlash != -1){ if (indexOfLastSlash != -1) {
relativeDir = jsp.substring(0, indexOfLastSlash); relativeDir = jsp.substring(0, indexOfLastSlash);
relativeDir = relativeDir.replaceAll("//", ".") + '.'; relativeDir = relativeDir.replaceAll("//", ".") + '.';
} }
...@@ -390,7 +390,7 @@ public class PluginServlet extends HttpServlet { ...@@ -390,7 +390,7 @@ public class PluginServlet extends HttpServlet {
String filename = jspFile.getName(); String filename = jspFile.getName();
int indexOfPeriod = filename.indexOf("."); int indexOfPeriod = filename.indexOf(".");
if (indexOfPeriod != -1) { if (indexOfPeriod != -1) {
filename = "dev"+StringUtils.randomString(4); filename = "dev" + StringUtils.randomString(4);
} }
JspC jspc = new JspC(); JspC jspc = new JspC();
...@@ -412,10 +412,10 @@ public class PluginServlet extends HttpServlet { ...@@ -412,10 +412,10 @@ public class PluginServlet extends HttpServlet {
jspc.execute(); jspc.execute();
try { try {
Object servletInstance = pluginManager.loadClass("org.apache.jsp." + relativeDir + filename , plugin).newInstance(); Object servletInstance = pluginManager.loadClass("org.apache.jsp." + relativeDir + filename, plugin).newInstance();
HttpServlet servlet = (HttpServlet) servletInstance; HttpServlet servlet = (HttpServlet)servletInstance;
servlet.init(servletConfig); servlet.init(servletConfig);
servlet.service(request , response); servlet.service(request, response);
return true; return true;
} }
catch (Exception e) { catch (Exception e) {
...@@ -443,21 +443,24 @@ public class PluginServlet extends HttpServlet { ...@@ -443,21 +443,24 @@ public class PluginServlet extends HttpServlet {
File pluginDirectory = pluginManager.getPluginDirectory(plugin); File pluginDirectory = pluginManager.getPluginDirectory(plugin);
PluginDevEnvironment env = pluginManager.getDevEnvironment(plugin);
// Load all jars from lib // Load all jars from lib
File libDirectory = new File(pluginDirectory , "lib"); File libDirectory = new File(pluginDirectory, "lib");
File[] libs = libDirectory.listFiles(); File[] libs = libDirectory.listFiles();
for (int i = 0;i < libs.length;i++) { for (int i = 0; i < libs.length; i++) {
File libFile = libs[i]; File libFile = libs[i];
builder.append(libFile.getAbsolutePath() + ';'); builder.append(libFile.getAbsolutePath() + ';');
} }
File messengerRoot = pluginDirectory.getParentFile().getParentFile().getParentFile(); File messengerRoot = pluginDirectory.getParentFile().getParentFile().getParentFile();
File messengerLib = new File(messengerRoot , "target//lib"); File messengerLib = new File(messengerRoot, "target//lib");
builder.append(messengerLib.getAbsolutePath() + "//servlet.jar;"); builder.append(messengerLib.getAbsolutePath() + "//servlet.jar;");
builder.append(messengerLib.getAbsolutePath() + "//messenger.jar;"); builder.append(messengerLib.getAbsolutePath() + "//messenger.jar;");
builder.append(messengerLib.getAbsolutePath() + "//jasper-compiler.jar;"); builder.append(messengerLib.getAbsolutePath() + "//jasper-compiler.jar;");
builder.append(messengerLib.getAbsolutePath() + "//jasper-runtime.jar;"); builder.append(messengerLib.getAbsolutePath() + "//jasper-runtime.jar;");
builder.append(env.getClassesDir().getAbsolutePath() + ";");
return builder.toString(); return builder.toString();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment