001    /*
002     * Copyright (C) 2010 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    /**
035     * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
036     * @version $Revision$
037     */
038    public class WebPluginLifeCycle extends PluginLifeCycle implements ServletContextListener {
039    
040      /** . */
041      private static final Object lock = new Object();
042    
043      /** . */
044      private static final Map<String, PluginContext> contextMap = new HashMap<String, PluginContext>();
045    
046      /** . */
047      private boolean registered = false;
048    
049      /**
050       * Returns a plugin context associated with the servlet context or null if such context does not exist.
051       *
052       * @param sc the servlet context
053       * @return the associated plugin context
054       * @throws NullPointerException if the servlet context argument is null
055       */
056      public static PluginContext getPluginContext(ServletContext sc) throws NullPointerException {
057        String contextPath = sc.getContextPath();
058        synchronized (lock) {
059          return contextMap.get(contextPath);
060        }
061      }
062    
063      public void contextInitialized(ServletContextEvent sce) {
064        ServletContext sc = sce.getServletContext();
065        String contextPath = sc.getContextPath();
066    
067        // Use JVM properties as external config
068        setConfig(System.getProperties());
069    
070        //
071        synchronized (lock) {
072          if (!contextMap.containsKey(contextPath)) {
073    
074            //
075            FS cmdFS = new FS().mount(new ServletContextDriver(sc), "/WEB-INF/crash/commands/");
076            FS confFS = new FS().mount(new ServletContextDriver(sc), "/WEB-INF/crash/");
077            ClassLoader webAppLoader = Thread.currentThread().getContextClassLoader();
078    
079            //
080            PluginContext context = new PluginContext(
081              new ServiceLoaderDiscovery(webAppLoader),
082              new ServletContextMap(sc),
083              cmdFS,
084              confFS,
085              webAppLoader);
086    
087            //
088            contextMap.put(contextPath, context);
089            registered = true;
090    
091            //
092            start(context);
093          }
094        }
095      }
096    
097      public void contextDestroyed(ServletContextEvent sce) {
098        if (registered) {
099    
100          //
101          ServletContext sc = sce.getServletContext();
102          String contextPath = sc.getContextPath();
103    
104          //
105          synchronized (lock) {
106    
107            //
108            contextMap.remove(contextPath);
109            registered = false;
110    
111            //
112            stop();
113          }
114        }
115      }
116    }