Commit 2eb3e8f6 authored by Derek DeMoro's avatar Derek DeMoro Committed by derek

1)Adding first pieces of page compilation.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1457 b35dd754-fafc-0310-a699-88a17e54d16e
parent 71b25e50
...@@ -16,6 +16,9 @@ import org.dom4j.Element; ...@@ -16,6 +16,9 @@ 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.apache.jasper.JasperException;
import org.apache.jasper.JspC;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
...@@ -53,13 +56,14 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -53,13 +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 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 {
...@@ -67,8 +71,8 @@ public class PluginServlet extends HttpServlet { ...@@ -67,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);
...@@ -78,17 +82,17 @@ public class PluginServlet extends HttpServlet { ...@@ -78,17 +82,17 @@ public class PluginServlet extends HttpServlet {
try { try {
// Handle JSP requests. // Handle JSP requests.
if (pathInfo.endsWith(".jsp")) { if (pathInfo.endsWith(".jsp")) {
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 {
...@@ -112,10 +116,11 @@ public class PluginServlet extends HttpServlet { ...@@ -112,10 +116,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;
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
...@@ -125,22 +130,22 @@ public class PluginServlet extends HttpServlet { ...@@ -125,22 +130,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.
...@@ -148,8 +153,8 @@ public class PluginServlet extends HttpServlet { ...@@ -148,8 +153,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.");
...@@ -170,7 +175,7 @@ public class PluginServlet extends HttpServlet { ...@@ -170,7 +175,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
...@@ -178,13 +183,13 @@ public class PluginServlet extends HttpServlet { ...@@ -178,13 +183,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);
...@@ -210,13 +215,15 @@ public class PluginServlet extends HttpServlet { ...@@ -210,13 +215,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 {
...@@ -235,12 +242,12 @@ public class PluginServlet extends HttpServlet { ...@@ -235,12 +242,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 {
...@@ -257,14 +264,14 @@ public class PluginServlet extends HttpServlet { ...@@ -257,14 +264,14 @@ public class PluginServlet extends HttpServlet {
*/ */
private HttpServlet getServlet(String pathInfo) { private HttpServlet getServlet(String pathInfo) {
pathInfo = pathInfo.substring(1).toLowerCase(); pathInfo = pathInfo.substring(1).toLowerCase();
HttpServlet servlet = servlets.get(pathInfo); HttpServlet servlet = servlets.get(pathInfo);
if (servlet == null) { if (servlet == null) {
for (String key : servlets.keySet()) { for (String key : servlets.keySet()) {
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);
...@@ -282,15 +289,15 @@ public class PluginServlet extends HttpServlet { ...@@ -282,15 +289,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;
...@@ -301,7 +308,7 @@ public class PluginServlet extends HttpServlet { ...@@ -301,7 +308,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;
...@@ -311,13 +318,13 @@ public class PluginServlet extends HttpServlet { ...@@ -311,13 +318,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 {
...@@ -334,4 +341,99 @@ public class PluginServlet extends HttpServlet { ...@@ -334,4 +341,99 @@ public class PluginServlet extends HttpServlet {
} }
} }
} }
/**
* 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
* jsp page is found, we return false to allow for other handlers.
*
* @param pathInfo the extra path info.
* @param request the request object.
* @param response the response object.
*/
private boolean handleJspDocument(String pathInfo , HttpServletRequest request ,
HttpServletResponse response) {
String jspURL = pathInfo.substring(1);
// Handle pre-existing pages and fail over to pre-compiled pages.
int fileSeperator = jspURL.indexOf("/");
if (fileSeperator != -1) {
String pluginName = jspURL.substring(0 , fileSeperator);
Plugin plugin = pluginManager.getPlugin(pluginName);
File pluginDirectory = pluginManager.getPluginDirectory(plugin);
File compiledServletsDirectory = new File(pluginDirectory , "classes");
compiledServletsDirectory.mkdirs();
String jsp = jspURL.substring(fileSeperator + 1);
File jspFile = new File(pluginDirectory + "/web" , jsp);
String filename = jspFile.getName();
int indexOfPeriod = filename.indexOf(".");
if (indexOfPeriod != -1) {
filename = StringUtils.randomString(10);
}
JspC jspc = new JspC();
if (!jspFile.exists()) {
return false;
}
jspc.setJspFiles(jspFile.getAbsolutePath());
jspc.setOutputDir(compiledServletsDirectory.getAbsolutePath());
jspc.setClassName(filename);
jspc.setCompile(true);
jspc.setClassPath(getClasspathForPlugin(plugin));
try {
jspc.execute();
try {
Object servletInstance = pluginManager.loadClass("org.apache.jsp." + filename , plugin).newInstance();
HttpServlet servlet = (HttpServlet) servletInstance;
servlet.init(servletConfig);
servlet.service(request , response);
return true;
}
catch (Exception e) {
e.printStackTrace();
}
}
catch (JasperException e) {
e.printStackTrace();
}
}
return false;
}
/**
* Returns the classpath to use for the JSPC Compiler.
*
* @param plugin the plugin the jspc will handle.
* @return the classpath needed to compile a single jsp in a plugin.
*/
private String getClasspathForPlugin(Plugin plugin) {
StringBuilder builder = new StringBuilder();
File pluginDirectory = pluginManager.getPluginDirectory(plugin);
// Load all jars from lib
File libDirectory = new File(pluginDirectory , "lib");
File[] libs = libDirectory.listFiles();
for (int i = 0;i < libs.length;i++) {
File libFile = libs[i];
builder.append(libFile.getAbsolutePath() + ";");
}
File messengerRoot = pluginDirectory.getParentFile().getParentFile().getParentFile();
File messengerLib = new File(messengerRoot , "target//lib");
builder.append(messengerLib.getAbsolutePath() + "//servlet.jar;");
builder.append(messengerLib.getAbsolutePath() + "//messenger.jar;");
builder.append(messengerLib.getAbsolutePath() + "//jasper-compiler.jar;");
builder.append(messengerLib.getAbsolutePath() + "//jasper-runtime.jar;");
return builder.toString();
}
} }
\ No newline at end of file
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