1 11 12 package org.jivesoftware.messenger.container; 13 14 import org.apache.jasper.JasperException; 15 import org.apache.jasper.JspC; 16 import org.dom4j.Document; 17 import org.dom4j.Element; 18 import org.dom4j.io.SAXReader; 19 import org.jivesoftware.util.JiveGlobals; 20 import org.jivesoftware.util.Log; 21 import org.jivesoftware.util.StringUtils; 22 import org.xml.sax.SAXException ; 23 24 import javax.servlet.ServletConfig ; 25 import javax.servlet.ServletException ; 26 import javax.servlet.ServletOutputStream ; 27 import javax.servlet.http.HttpServlet ; 28 import javax.servlet.http.HttpServletRequest ; 29 import javax.servlet.http.HttpServletResponse ; 30 import java.io.*; 31 import java.util.HashMap ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.concurrent.ConcurrentHashMap ; 35 36 55 public class PluginServlet extends HttpServlet { 56 57 private static Map <String , HttpServlet > servlets; 58 private static PluginManager pluginManager; 59 private static ServletConfig servletConfig; 60 61 static { 62 servlets = new ConcurrentHashMap <String , HttpServlet >(); 63 } 64 65 public void init(ServletConfig config) throws ServletException { 66 super.init(config); 67 servletConfig = config; 68 } 69 70 public void service(HttpServletRequest request, HttpServletResponse response) 71 throws ServletException , IOException 72 { 73 String pathInfo = request.getPathInfo(); 74 if (pathInfo == null) { 75 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 76 return; 77 } 78 else { 79 try { 80 if (pathInfo.endsWith(".jsp")) { 82 if (handleDevJSP(pathInfo, request, response)) { 83 return; 84 } 85 handleJSP(pathInfo, request, response); 86 return; 87 } 88 else if (pathInfo.endsWith(".gif") || pathInfo.endsWith(".png")) { 90 handleImage(pathInfo, response); 91 return; 92 } 93 else if (getServlet(pathInfo) != null) { 95 handleServlet(pathInfo, request, response); 96 } 97 else { 99 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 100 return; 101 } 102 } 103 catch (Exception e) { 104 Log.error(e); 105 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 106 return; 107 } 108 } 109 } 110 111 119 public static void registerServlets(PluginManager manager, Plugin plugin, File webXML) { 120 pluginManager = manager; 121 if (!webXML.exists()) { 122 Log.error("Could not register plugin servlets, file " + webXML.getAbsolutePath() + 123 " does not exist."); 124 return; 125 } 126 String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName(); 129 try { 130 SAXReader saxReader = new SAXReader(false); 133 try { 134 saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", 135 false); 136 } 137 catch (SAXException e) { 138 Log.warn("Error setting SAXReader feature", e); 139 } 140 Document doc = saxReader.read(webXML); 141 List classes = doc.selectNodes("//servlet"); 143 Map <String , Class > classMap = new HashMap <String , Class >(); 144 for (int i = 0; i < classes.size(); i++) { 145 Element servletElement = (Element)classes.get(i); 146 String name = servletElement.element("servlet-name").getTextTrim(); 147 String className = servletElement.element("servlet-class").getTextTrim(); 148 classMap.put(name, manager.loadClass(plugin, className)); 149 } 150 List names = doc.selectNodes("//servlet-mapping"); 152 for (int i = 0; i < names.size(); i++) { 153 Element nameElement = (Element)names.get(i); 154 String name = nameElement.element("servlet-name").getTextTrim(); 155 String url = nameElement.element("url-pattern").getTextTrim(); 156 Class servletClass = classMap.get(name); 158 Object instance = servletClass.newInstance(); 159 if (instance instanceof HttpServlet ) { 160 ((HttpServlet )instance).init(servletConfig); 162 servlets.put(pluginName + url, (HttpServlet )instance); 163 } 164 else { 165 Log.warn("Could not load " + (pluginName + url) + ": not a servlet."); 166 } 167 } 168 } 169 catch (Throwable e) { 170 Log.error(e); 171 } 172 } 173 174 180 public static void unregisterServlets(File webXML) { 181 if (!webXML.exists()) { 182 Log.error("Could not unregister plugin servlets, file " + webXML.getAbsolutePath() + 183 " does not exist."); 184 return; 185 } 186 String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName(); 189 try { 190 SAXReader saxReader = new SAXReader(false); 191 saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", 192 false); 193 Document doc = saxReader.read(webXML); 194 List names = doc.selectNodes("//servlet-mapping"); 196 for (int i = 0; i < names.size(); i++) { 197 Element nameElement = (Element)names.get(i); 198 String url = nameElement.element("url-pattern").getTextTrim(); 199 HttpServlet servlet = servlets.get(pluginName + url); 201 servlet.destroy(); 202 servlets.remove(pluginName + url); 203 servlet = null; 204 } 205 } 206 catch (Throwable e) { 207 Log.error(e); 208 } 209 } 210 211 222 private void handleJSP(String pathInfo, HttpServletRequest request, 223 HttpServletResponse response) throws ServletException , IOException 224 { 225 String jspURL = pathInfo.substring(1); 227 228 229 HttpServlet servlet = servlets.get(jspURL); 230 if (servlet != null) { 231 servlet.service(request, response); 232 return; 233 } 234 else { 235 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 236 return; 237 } 238 } 239 240 250 private void handleServlet(String pathInfo, HttpServletRequest request, 251 HttpServletResponse response) throws ServletException , IOException { 252 HttpServlet servlet = getServlet(pathInfo); 254 if (servlet != null) { 255 servlet.service(request, response); 256 return; 257 } 258 else { 259 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 260 return; 261 } 262 } 263 264 270 private HttpServlet getServlet(String pathInfo) { 271 pathInfo = pathInfo.substring(1).toLowerCase(); 272 273 HttpServlet servlet = servlets.get(pathInfo); 274 if (servlet == null) { 275 for (String key : servlets.keySet()) { 276 int index = key.indexOf("/*"); 277 String searchkey = key; 278 if (index != -1) { 279 searchkey = key.substring(0, index); 280 } 281 if (searchkey.startsWith(pathInfo) || pathInfo.startsWith(searchkey)) { 282 servlet = servlets.get(key); 283 break; 284 } 285 } 286 } 287 return servlet; 288 } 289 290 297 private void handleImage(String pathInfo, HttpServletResponse response) throws IOException { 298 String [] parts = pathInfo.split("/"); 299 if (parts.length != 4) { 301 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 302 return; 303 } 304 File pluginDirectory = new File(JiveGlobals.getHomeDirectory(), "plugins"); 305 File image = new File(pluginDirectory, parts[1] + File.separator + "web" + 306 File.separator + "images" + File.separator + parts[3]); 307 if (!image.exists()) { 308 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 309 return; 310 } 311 else { 312 String contentType = "image/gif"; 314 if (pathInfo.endsWith(".png")) { 315 contentType = "image/png"; 316 } 317 response.setHeader("Content-disposition", "filename=\"" + image + "\";"); 318 response.setContentType(contentType); 319 InputStream in = null; 321 ServletOutputStream out = null; 322 try { 323 in = new BufferedInputStream(new FileInputStream(image)); 324 out = response.getOutputStream(); 325 326 response.setContentLength((int)image.length()); 328 329 byte[] buf = new byte[1024]; 331 int len; 332 while ((len = in.read(buf)) != -1) { 333 out.write(buf, 0, len); 334 } 335 } 336 finally { 337 try { 338 in.close(); 339 } 340 catch (Exception ignored) { 341 } 342 try { 343 out.close(); 344 } 345 catch (Exception ignored) { 346 } 347 } 348 } 349 } 350 351 362 private boolean handleDevJSP(String pathInfo, HttpServletRequest request, 363 HttpServletResponse response) 364 { 365 String jspURL = pathInfo.substring(1); 366 367 int fileSeperator = jspURL.indexOf("/"); 369 if (fileSeperator != -1) { 370 String pluginName = jspURL.substring(0, fileSeperator); 371 Plugin plugin = pluginManager.getPlugin(pluginName); 372 373 PluginDevEnvironment environment = pluginManager.getDevEnvironment(plugin); 374 if (environment == null) { 376 return false; 377 } 378 File webDir = environment.getWebRoot(); 379 if (webDir == null || !webDir.exists()) { 380 return false; 381 } 382 383 File pluginDirectory = pluginManager.getPluginDirectory(plugin); 384 385 File compilationDir = new File(pluginDirectory, "classes"); 386 compilationDir.mkdirs(); 387 388 String jsp = jspURL.substring(fileSeperator + 1); 389 390 int indexOfLastSlash = jsp.lastIndexOf("/"); 391 String relativeDir = ""; 392 if (indexOfLastSlash != -1) { 393 relativeDir = jsp.substring(0, indexOfLastSlash); 394 relativeDir = relativeDir.replaceAll("//", ".") + '.'; 395 } 396 397 File jspFile = new File(webDir, jsp); 398 String filename = jspFile.getName(); 399 int indexOfPeriod = filename.indexOf("."); 400 if (indexOfPeriod != -1) { 401 filename = "dev" + StringUtils.randomString(4); 402 } 403 404 JspC jspc = new JspC(); 405 if (!jspFile.exists()) { 406 return false; 407 } 408 try { 409 jspc.setJspFiles(jspFile.getCanonicalPath()); 410 } 411 catch (IOException e) { 412 Log.error(e); 413 } 414 jspc.setOutputDir(compilationDir.getAbsolutePath()); 415 jspc.setClassName(filename); 416 jspc.setCompile(true); 417 418 jspc.setClassPath(getClasspathForPlugin(plugin)); 419 try { 420 jspc.execute(); 421 422 try { 423 Object servletInstance = pluginManager.loadClass(plugin, "org.apache.jsp." + 424 relativeDir + filename).newInstance(); 425 HttpServlet servlet = (HttpServlet )servletInstance; 426 servlet.init(servletConfig); 427 servlet.service(request, response); 428 return true; 429 } 430 catch (Exception e) { 431 Log.error(e); 432 } 433 434 } 435 catch (JasperException e) { 436 Log.error(e); 437 } 438 } 439 return false; 440 } 441 442 448 private static String getClasspathForPlugin(Plugin plugin) { 449 StringBuilder builder = new StringBuilder (); 450 451 File pluginDirectory = pluginManager.getPluginDirectory(plugin); 452 453 PluginDevEnvironment env = pluginManager.getDevEnvironment(plugin); 454 455 File libDirectory = new File(pluginDirectory, "lib"); 457 File[] libs = libDirectory.listFiles(); 458 for (int i = 0; i < libs.length; i++) { 459 File libFile = libs[i]; 460 builder.append(libFile.getAbsolutePath() + ';'); 461 } 462 463 File messengerRoot = pluginDirectory.getParentFile().getParentFile().getParentFile(); 464 File messengerLib = new File(messengerRoot, "target//lib"); 465 466 builder.append(messengerLib.getAbsolutePath() + "//servlet.jar;"); 467 builder.append(messengerLib.getAbsolutePath() + "//messenger.jar;"); 468 builder.append(messengerLib.getAbsolutePath() + "//jasper-compiler.jar;"); 469 builder.append(messengerLib.getAbsolutePath() + "//jasper-runtime.jar;"); 470 builder.append(env.getClassesDir().getAbsolutePath() + ";"); 471 472 return builder.toString(); 473 } 474 } | Popular Tags |