001 /* 002 * Copyright (C) 2012 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 020 package org.crsh.plugin; 021 022 import org.crsh.util.ServletContextMap; 023 import org.crsh.vfs.FS; 024 import org.crsh.vfs.spi.servlet.ServletContextDriver; 025 026 import javax.servlet.ServletContext; 027 import javax.servlet.ServletContextEvent; 028 import javax.servlet.ServletContextListener; 029 import java.util.HashMap; 030 import java.util.Map; 031 032 public class WebPluginLifeCycle extends PluginLifeCycle implements ServletContextListener { 033 034 /** . */ 035 private static final Object lock = new Object(); 036 037 /** . */ 038 private static final Map<String, PluginContext> contextMap = new HashMap<String, PluginContext>(); 039 040 /** . */ 041 private boolean registered = false; 042 043 /** 044 * Returns a plugin context associated with the servlet context or null if such context does not exist. 045 * 046 * @param sc the servlet context 047 * @return the associated plugin context 048 * @throws NullPointerException if the servlet context argument is null 049 */ 050 public static PluginContext getPluginContext(ServletContext sc) throws NullPointerException { 051 String contextPath = sc.getContextPath(); 052 synchronized (lock) { 053 return contextMap.get(contextPath); 054 } 055 } 056 057 /** 058 * Create the service loader discovery, this can be subclassed to provide an implementation, the current 059 * implementation returns a {@link ServiceLoaderDiscovery} instance. 060 * 061 * @param context the servlet context 062 * @param classLoader the class loader 063 * @return the plugin discovery 064 */ 065 protected PluginDiscovery createDiscovery(ServletContext context, ClassLoader classLoader) { 066 return new ServiceLoaderDiscovery(classLoader); 067 } 068 069 public void contextInitialized(ServletContextEvent sce) { 070 ServletContext context = sce.getServletContext(); 071 String contextPath = context.getContextPath(); 072 073 // Use JVM properties as external config 074 setConfig(System.getProperties()); 075 076 // 077 synchronized (lock) { 078 if (!contextMap.containsKey(contextPath)) { 079 080 // 081 FS cmdFS = createCommandFS(context); 082 FS confFS = createConfFS(context); 083 ClassLoader webAppLoader = Thread.currentThread().getContextClassLoader(); 084 085 // 086 PluginContext pluginContext = new PluginContext( 087 createDiscovery(context, webAppLoader), 088 new ServletContextMap(context), 089 cmdFS, 090 confFS, 091 webAppLoader); 092 093 // 094 contextMap.put(contextPath, pluginContext); 095 registered = true; 096 097 // 098 start(pluginContext); 099 } 100 } 101 } 102 103 /** 104 * Create the command file system, this method binds the <code>/WEB-INF/crash/commands/</code> path of the 105 * servlet context. 106 * 107 * @param context the servlet context 108 * @return the command file system 109 */ 110 protected FS createCommandFS(ServletContext context) { 111 return new FS().mount(new ServletContextDriver(context, "/WEB-INF/crash/commands/")); 112 } 113 114 /** 115 * Create the conf file system, this method binds the <code>/WEB-INF/crash/</code> path of the 116 * servlet context. 117 * 118 * @param context the servlet context 119 * @return the conf file system 120 */ 121 protected FS createConfFS(ServletContext context) { 122 return new FS().mount(new ServletContextDriver(context, "/WEB-INF/crash/")); 123 } 124 125 public void contextDestroyed(ServletContextEvent sce) { 126 if (registered) { 127 128 // 129 ServletContext sc = sce.getServletContext(); 130 String contextPath = sc.getContextPath(); 131 132 // 133 synchronized (lock) { 134 135 // 136 contextMap.remove(contextPath); 137 registered = false; 138 139 // 140 stop(); 141 } 142 } 143 } 144 }