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.Collection;
030    import java.util.Collections;
031    import java.util.HashMap;
032    import java.util.Map;
033    
034    public class WebPluginLifeCycle extends PluginLifeCycle implements ServletContextListener {
035    
036      /** . */
037      private static final Object lock = new Object();
038    
039      /** . */
040      private static final Map<String, PluginContext> contextMap = new HashMap<String, PluginContext>();
041    
042      /** . */
043      private boolean registered = false;
044    
045      /**
046       * Returns a plugin context associated with the servlet context or null if such context does not exist.
047       *
048       * @param sc the servlet context
049       * @return the associated plugin context
050       * @throws NullPointerException if the servlet context argument is null
051       */
052      public static PluginContext getPluginContext(ServletContext sc) throws NullPointerException {
053        String contextPath = sc.getContextPath();
054        synchronized (lock) {
055          return contextMap.get(contextPath);
056        }
057      }
058    
059      public void contextInitialized(ServletContextEvent sce) {
060        ServletContext context = sce.getServletContext();
061        String contextPath = context.getContextPath();
062    
063        // Use JVM properties as external config
064        setConfig(System.getProperties());
065    
066        //
067        synchronized (lock) {
068          if (!contextMap.containsKey(contextPath)) {
069    
070            //
071            FS cmdFS = createCommandFS(context);
072            FS confFS = createConfFS(context);
073            ClassLoader webAppLoader = Thread.currentThread().getContextClassLoader();
074    
075            //
076            PluginContext pluginContext = new PluginContext(
077              new ServiceLoaderDiscovery(webAppLoader),
078              new ServletContextMap(context),
079              cmdFS,
080              confFS,
081              webAppLoader);
082    
083            //
084            contextMap.put(contextPath, pluginContext);
085            registered = true;
086    
087            //
088            start(pluginContext);
089          }
090        }
091      }
092    
093      /**
094       * Create the command file system, this method binds the <code>/WEB-INF/crash/commands/</code> path of the
095       * servlet context.
096       *
097       * @param context the servlet context
098       * @return the command file system
099       */
100      protected FS createCommandFS(ServletContext context) {
101        return new FS().mount(new ServletContextDriver(context, "/WEB-INF/crash/commands/"));
102      }
103    
104      /**
105       * Create the conf file system, this method binds the <code>/WEB-INF/crash/</code> path of the
106       * servlet context.
107       *
108       * @param context the servlet context
109       * @return the conf file system
110       */
111      protected FS createConfFS(ServletContext context) {
112        return new FS().mount(new ServletContextDriver(context, "/WEB-INF/crash/"));
113      }
114    
115      public void contextDestroyed(ServletContextEvent sce) {
116        if (registered) {
117    
118          //
119          ServletContext sc = sce.getServletContext();
120          String contextPath = sc.getContextPath();
121    
122          //
123          synchronized (lock) {
124    
125            //
126            contextMap.remove(contextPath);
127            registered = false;
128    
129            //
130            stop();
131          }
132        }
133      }
134    }