/** * 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 static String getClasspathForPlugin(Plugin plugin) { final StringBuilder classpath = new StringBuilder(); File pluginDirectory = pluginManager.getPluginDirectory(plugin); PluginDevEnvironment pluginEnv = pluginManager.getDevEnvironment(plugin); PluginClassLoader pluginClassloader = pluginManager.getPluginClassloader(plugin); for (URL url : pluginClassloader.getURLs()) { File file = new File(url.getFile()); classpath.append(file.getAbsolutePath()).append(";"); } // Load all jars from lib File libDirectory = new File(pluginDirectory, "lib"); File[] libs = libDirectory.listFiles(); final int no = libs != null ? libs.length : 0; for (int i = 0; i < no; i++) { File libFile = libs[i]; classpath.append(libFile.getAbsolutePath()).append(';'); } File openfireRoot = pluginDirectory.getParentFile().getParentFile().getParentFile(); File openfireLib = new File(openfireRoot, "target//lib"); classpath.append(openfireLib.getAbsolutePath()).append("//servlet.jar;"); classpath.append(openfireLib.getAbsolutePath()).append("//openfire.jar;"); classpath.append(openfireLib.getAbsolutePath()).append("//jasper-compiler.jar;"); classpath.append(openfireLib.getAbsolutePath()).append("//jasper-runtime.jar;"); if (pluginEnv.getClassesDir() != null) { classpath.append(pluginEnv.getClassesDir().getAbsolutePath()).append(";"); } return classpath.toString(); }
/** * Handles a request for a JSP page in development mode. If development mode is not enabled, this * method returns false so that normal JSP handling can be performed. If development mode is * enabled, this method tries to locate the JSP, compile it using JSPC, and then return the * output. * * @param pathInfo the extra path info. * @param request the request object. * @param response the response object. * @return true if this page request was handled; false if the request was not handled. */ private boolean handleDevJSP( 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); PluginDevEnvironment environment = pluginManager.getDevEnvironment(plugin); // If development mode not turned on for plugin, return false. if (environment == null) { return false; } File webDir = environment.getWebRoot(); if (webDir == null || !webDir.exists()) { return false; } File pluginDirectory = pluginManager.getPluginDirectory(plugin); File compilationDir = new File(pluginDirectory, "classes"); compilationDir.mkdirs(); String jsp = jspURL.substring(fileSeperator + 1); int indexOfLastSlash = jsp.lastIndexOf("/"); String relativeDir = ""; if (indexOfLastSlash != -1) { relativeDir = jsp.substring(0, indexOfLastSlash); relativeDir = relativeDir.replaceAll("//", ".") + '.'; } File jspFile = new File(webDir, jsp); String filename = jspFile.getName(); int indexOfPeriod = filename.indexOf("."); if (indexOfPeriod != -1) { filename = "dev" + StringUtils.randomString(4); } JspC jspc = new JspC(); if (!jspFile.exists()) { return false; } try { jspc.setJspFiles(jspFile.getCanonicalPath()); } catch (IOException e) { Log.error(e.getMessage(), e); } jspc.setOutputDir(compilationDir.getAbsolutePath()); jspc.setClassName(filename); jspc.setCompile(true); jspc.setClassPath(getClasspathForPlugin(plugin)); try { jspc.execute(); try { Object servletInstance = pluginManager .loadClass(plugin, "org.apache.jsp." + relativeDir + filename) .newInstance(); HttpServlet servlet = (HttpServlet) servletInstance; servlet.init(servletConfig); servlet.service(request, response); return true; } catch (Exception e) { Log.error(e.getMessage(), e); } } catch (JasperException e) { Log.error(e.getMessage(), e); } } return false; }
/** * Handles a request for other web items (images, flash, applets, etc.) * * @param pathInfo the extra path info. * @param response the response object. * @throws IOException if an IOException occurs while handling the request. */ private void handleOtherRequest(String pathInfo, HttpServletResponse response) throws IOException { String[] parts = pathInfo.split("/"); // Image request must be in correct format. if (parts.length < 3) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); return; } String contextPath = ""; int index = pathInfo.indexOf(parts[1]); if (index != -1) { contextPath = pathInfo.substring(index + parts[1].length()); } File pluginDirectory = new File(JiveGlobals.getHomeDirectory(), "plugins"); File file = new File(pluginDirectory, parts[1] + File.separator + "web" + contextPath); // When using dev environment, the images dir may be under something other that web. Plugin plugin = pluginManager.getPlugin(parts[1]); PluginDevEnvironment environment = pluginManager.getDevEnvironment(plugin); if (environment != null) { file = new File(environment.getWebRoot(), contextPath); } if (!file.exists()) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); return; } else { // Content type will be GIF or PNG. String contentType = "image/gif"; if (pathInfo.endsWith(".png")) { contentType = "image/png"; } else if (pathInfo.endsWith(".swf")) { contentType = "application/x-shockwave-flash"; } else if (pathInfo.endsWith(".css")) { contentType = "text/css"; } else if (pathInfo.endsWith(".js")) { contentType = "text/javascript"; } else if (pathInfo.endsWith(".html") || pathInfo.endsWith(".htm")) { contentType = "text/html"; } // setting the content-disposition header breaks IE when downloading CSS // response.setHeader("Content-disposition", "filename=\"" + file + "\";"); response.setContentType(contentType); // Write out the resource to the user. InputStream in = null; ServletOutputStream out = null; try { in = new BufferedInputStream(new FileInputStream(file)); out = response.getOutputStream(); // Set the size of the file. response.setContentLength((int) file.length()); // Use a 1K buffer. byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } } finally { try { in.close(); } catch (Exception ignored) { // Ignore. } try { out.close(); } catch (Exception ignored) { // Ignore. } } } }