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 }