[embjopr-commits] EMBJOPR SVN: r314 - in trunk/core/src/main: webapp/WEB-INF and 1 other directory.

embjopr-commits at lists.jboss.org embjopr-commits at lists.jboss.org
Mon Apr 20 19:25:08 EDT 2009


Author: ips
Date: 2009-04-20 19:25:07 -0400 (Mon, 20 Apr 2009)
New Revision: 314

Added:
   trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupFilter.java
   trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupListener.java
Modified:
   trunk/core/src/main/webapp/WEB-INF/web.xml
Log:
configure listener/filter that will init Seam lazily (upon first request to the webapp), rather than than at webapp init (during server startup) (https://jira.jboss.org/jira/browse/EMBJOPR-85)




Added: trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupFilter.java
===================================================================
--- trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupFilter.java	                        (rev 0)
+++ trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupFilter.java	2009-04-20 23:25:07 UTC (rev 314)
@@ -0,0 +1,119 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.jboss.on.embedded;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A filter which lazily initializes another filter.
+ *
+ * <p>The filter requires an initalization parameter with the name
+ * {@link org.jboss.on.embedded.LazyStartupFilter}
+ *
+ * <p>The value is the name of the filter to lazily load. All other
+ * parameters are passed to the lazily loaded filter.
+ *
+ * <pre><code>
+ *  &lt;filter>
+ *      &lt;filter-name>Seam Filter&lt;/filter-name&gt;
+ *      &lt;!-- Lazily start up the Seam Filter --&gt;
+ *      &lt;filter-class&gt;org.jboss.on.embedded.LazyStartupFilter&lt;/filter-class&gt;
+ *
+ *      &lt;init-param&gt;
+ *       &lt;param-name&gt;org.jboss.on.embedded.LazyStartupFilter&lt;/param-name&gt;
+ *       &lt;param-value&gt;org.jboss.seam.servlet.SeamFilter&lt;/param-value&gt;
+ *      &lt;/init-param&gt;
+ *  &lt;/filter&gt;
+ *  &lt;filter-mapping&gt;
+ *      &lt;filter-name&gt;Seam Filter&lt;/filter-name&gt;
+ *      &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+ *  &lt;/filter-mapping&gt;
+ *  </code></pre>
+ *
+ * @author Jason T. Greene
+ */
+public class LazyStartupFilter implements Filter
+{
+   private final Log log = LogFactory.getLog(getClass());
+
+   private volatile Filter filter;
+   private volatile boolean initialized = false;
+   private volatile FilterConfig config;
+
+   public void destroy()
+   {
+      try
+      {
+         init();
+      }
+      catch (ServletException e)
+      {
+      }
+
+      filter.destroy();
+   }
+
+   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
+   {
+      init();
+
+      filter.doFilter(request, response, chain);
+   }
+
+   private void init() throws ServletException
+   {
+      if (!initialized)
+      {
+         String parameter = getClass().getName();
+         String filterName = config.getInitParameter(parameter);
+         if (filterName == null)
+            throw new IllegalArgumentException("Filter was not specified using the " + parameter + " parameter");
+
+         log.debug("Loading filter" + filterName);
+         try
+         {
+            filter = (Filter) Class.forName(filterName).newInstance();
+         }
+         catch (Exception e)
+         {
+            throw new IllegalArgumentException("Could not instantiated filter: " + filterName, e);
+         }
+
+         filter.init(config);
+         log.debug("Filter activated: " + filter);
+         initialized = true;
+      }
+   }
+
+   public void init(FilterConfig config) throws ServletException
+   {
+      this.config = config;
+   }
+
+}


Property changes on: trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupFilter.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Author Id Revision HeadURL
Name: svn:eol-style
   + LF

Added: trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupListener.java
===================================================================
--- trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupListener.java	                        (rev 0)
+++ trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupListener.java	2009-04-20 23:25:07 UTC (rev 314)
@@ -0,0 +1,413 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.jboss.on.embedded;
+
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextAttributeEvent;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * LazyStartupListener is a special listener that can lazily start any number
+ * of hard-coded Servlet listeners.
+ *
+ * <p>This works by delaying instantiation and context initialization events until
+ * any post-init event occurs (session creation, servlet request, etc).
+ *
+ * <p>This filter expects a context parameter with the name:
+ * {@link org.jboss.on.embedded.LazyStartupListener}
+ *
+ * <p>The value is a comma separated list of listeners to lazily load:
+ *
+ * <pre><code>
+ *  &lt;!-- Seam (lazy loaded)--&gt;
+ *  &lt;context-param&gt;
+ *      <param-name>org.jboss.on.embedded.LazyStartupListener&lt;/param-name&gt;
+ *      <param-value>org.jboss.seam.servlet.SeamListener&lt;/param-value&gt;
+ *  &lt;/context-param&gt;
+ *  &lt;listener&gt;
+ *      &lt;listener-class>org.jboss.on.embedded.LazyStartupListener&lt;/listener-class&gt;
+ *  &lt;/listener&gt;
+ * </code></pre>
+ *
+ * @author Jason T. Greene
+ *
+ */
+public class LazyStartupListener implements HttpSessionListener, ServletRequestListener, ServletContextListener, HttpSessionAttributeListener,
+      ServletRequestAttributeListener, ServletContextAttributeListener
+{
+   private final Log log = LogFactory.getLog(getClass());
+   private final ConcurrentLinkedQueue<ContextEvent> contextEvents = new ConcurrentLinkedQueue<ContextEvent>();
+
+   /*
+    * Technically the array list fields don't need to be volatile, since initialized
+    * is read before they are read and written after they are read.
+    */
+   private volatile ArrayList<HttpSessionListener> sessionListeners;
+   private volatile ArrayList<HttpSessionAttributeListener> sessionAttributeListeners;
+   private volatile ArrayList<ServletRequestListener> requestListeners;
+   private volatile ArrayList<ServletRequestAttributeListener> requestAttributeListeners;
+   private volatile ArrayList<ServletContextListener> contextListeners;
+   private volatile ArrayList<ServletContextAttributeListener> contextAttributeListeners;
+
+   private volatile boolean initialized = false;
+   private volatile ServletContext context;
+   private volatile String[] names;
+
+
+   /**
+    *  This lock guards event replay. Any thread which adds to the context event queue
+    *  MUST obtain a read lock. The thread which replays the queue MUST obtain a write
+    *  lock.
+    */
+   private final ReentrantReadWriteLock replayLock = new ReentrantReadWriteLock();
+
+   private enum ContextEventType
+   {
+      ADD, REMOVE, REPLACE, INIT
+   };
+
+   private final class ContextEvent
+   {
+      final ContextEventType type;
+      final ServletContextEvent event;
+
+      private ContextEvent(ContextEventType type, ServletContextEvent event)
+      {
+         this.type = type;
+         this.event = event;
+      }
+   }
+
+   private void setupListeners()
+   {
+      final ArrayList<HttpSessionListener> sessionListeners = new ArrayList<HttpSessionListener>();
+      final ArrayList<HttpSessionAttributeListener> sessionAttributeListeners = new ArrayList<HttpSessionAttributeListener>();
+      final ArrayList<ServletRequestListener> requestListeners = new ArrayList<ServletRequestListener>();
+      final ArrayList<ServletRequestAttributeListener> requestAttributeListeners = new ArrayList<ServletRequestAttributeListener>();
+      final ArrayList<ServletContextListener> contextListeners = new ArrayList<ServletContextListener>();
+      final ArrayList<ServletContextAttributeListener> contextAttributeListeners = new ArrayList<ServletContextAttributeListener>();
+
+      Object[] objs = new Object[names.length];
+      for (int i = 0; i < names.length; i++)
+      {
+         try
+         {
+            objs[i] = Class.forName(names[i]).newInstance();
+         }
+         catch (InstantiationException e)
+         {
+         }
+         catch (IllegalAccessException e)
+         {
+         }
+         catch (ClassNotFoundException e)
+         {
+         }
+      }
+
+      for (Object obj : objs)
+      {
+         if (obj instanceof HttpSessionListener)
+            sessionListeners.add((HttpSessionListener)obj);
+         if (obj instanceof HttpSessionAttributeListener)
+            sessionAttributeListeners.add((HttpSessionAttributeListener)obj);
+         if (obj instanceof ServletRequestListener)
+            requestListeners.add((ServletRequestListener)obj);
+         if (obj instanceof ServletRequestAttributeListener)
+            requestAttributeListeners.add((ServletRequestAttributeListener)obj);
+         if (obj instanceof ServletContextListener)
+            contextListeners.add((ServletContextListener)obj);
+         if (obj instanceof ServletContextAttributeListener)
+            contextAttributeListeners.add((ServletContextAttributeListener)obj);
+
+         log.debug("Activated listener: "+ obj);
+      }
+
+      this.sessionListeners = sessionListeners;
+      this.sessionAttributeListeners = sessionAttributeListeners;
+      this.requestListeners = requestListeners;
+      this.requestAttributeListeners = requestAttributeListeners;
+      this.contextListeners = contextListeners;
+      this.contextAttributeListeners = contextAttributeListeners;
+   }
+
+   private void initialize()
+   {
+      if (initialized)
+         return;
+
+      log.debug("Activating listeners");
+      setupListeners();
+
+      try
+      {
+         replayLock.writeLock().lock();
+
+         ConcurrentLinkedQueue<ContextEvent> events = contextEvents;
+         ContextEvent event = events.poll();
+         while (event != null)
+         {
+            switch (event.type)
+            {
+               case INIT:
+                  for (ServletContextListener listener : contextListeners)
+                     listener.contextInitialized(event.event);
+                  break;
+               case ADD:
+                  for (ServletContextAttributeListener listener : contextAttributeListeners)
+                     listener.attributeAdded((ServletContextAttributeEvent)event.event);
+                  break;
+               case REMOVE:
+                  for (ServletContextAttributeListener listener : contextAttributeListeners)
+                     listener.attributeRemoved((ServletContextAttributeEvent)event.event);
+                  break;
+               case REPLACE:
+                  for (ServletContextAttributeListener listener : contextAttributeListeners)
+                     listener.attributeReplaced((ServletContextAttributeEvent)event.event);
+                  break;
+            }
+
+            event = events.poll();
+         }
+
+         initialized = true;
+      }
+      finally
+      {
+         replayLock.writeLock().unlock();
+      }
+
+   }
+
+   public void sessionCreated(HttpSessionEvent event)
+   {
+      initialize();
+
+      ArrayList<HttpSessionListener> listeners = sessionListeners;
+      for (HttpSessionListener listener : listeners)
+         listener.sessionCreated(event);
+   }
+
+   public void sessionDestroyed(HttpSessionEvent event)
+   {
+      initialize();
+
+      ArrayList<HttpSessionListener> listeners = sessionListeners;
+      for (HttpSessionListener listener : listeners)
+         listener.sessionDestroyed(event);
+   }
+
+   public void requestDestroyed(ServletRequestEvent event)
+   {
+      initialize();
+
+      ArrayList<ServletRequestListener> listeners = requestListeners;
+      for (ServletRequestListener listener : listeners)
+         listener.requestDestroyed(event);
+
+   }
+
+   public void requestInitialized(ServletRequestEvent event)
+   {
+      initialize();
+
+      ArrayList<ServletRequestListener> listeners = requestListeners;
+      for (ServletRequestListener listener : listeners)
+         listener.requestInitialized(event);
+   }
+
+   public void contextDestroyed(ServletContextEvent event)
+   {
+      initialize();
+
+      ArrayList<ServletContextListener> listeners = contextListeners;
+      for (ServletContextListener listener : listeners)
+         listener.contextDestroyed(event);
+   }
+
+   public void contextInitialized(ServletContextEvent event)
+   {
+      this.context = event.getServletContext();
+
+      // Comma separated list of listeners
+      String param = context.getInitParameter(getClass().getName());
+      log.debug("Listeners configured for lazy loading: " + param);
+      this.names = param == null ? new String[0] : param.split(",");
+
+      try
+      {
+         replayLock.readLock().lock();
+
+         if (!initialized)
+         {
+            contextEvents.add(new ContextEvent(ContextEventType.INIT, event));
+            return;
+         }
+
+         ArrayList<ServletContextListener> listeners = contextListeners;
+         for (ServletContextListener listener : listeners)
+            listener.contextInitialized(event);
+      }
+      finally
+      {
+         replayLock.readLock().unlock();
+      }
+   }
+
+   public void attributeAdded(HttpSessionBindingEvent event)
+   {
+      initialize();
+
+      ArrayList<HttpSessionAttributeListener> listeners = sessionAttributeListeners;
+      for (HttpSessionAttributeListener listener : listeners)
+         listener.attributeAdded(event);
+   }
+
+   public void attributeRemoved(HttpSessionBindingEvent event)
+   {
+      initialize();
+
+      ArrayList<HttpSessionAttributeListener> listeners = sessionAttributeListeners;
+      for (HttpSessionAttributeListener listener : listeners)
+         listener.attributeRemoved(event);
+   }
+
+   public void attributeReplaced(HttpSessionBindingEvent event)
+   {
+      initialize();
+
+      ArrayList<HttpSessionAttributeListener> listeners = sessionAttributeListeners;
+      for (HttpSessionAttributeListener listener : listeners)
+         listener.attributeReplaced(event);
+   }
+
+   public void attributeAdded(ServletRequestAttributeEvent event)
+   {
+      initialize();
+
+      ArrayList<ServletRequestAttributeListener> listeners = requestAttributeListeners;
+      for (ServletRequestAttributeListener listener : listeners)
+         listener.attributeAdded(event);
+   }
+
+   public void attributeRemoved(ServletRequestAttributeEvent event)
+   {
+      initialize();
+
+      ArrayList<ServletRequestAttributeListener> listeners = requestAttributeListeners;
+      for (ServletRequestAttributeListener listener : listeners)
+         listener.attributeRemoved(event);
+   }
+
+   public void attributeReplaced(ServletRequestAttributeEvent event)
+   {
+      initialize();
+
+      ArrayList<ServletRequestAttributeListener> listeners = requestAttributeListeners;
+      for (ServletRequestAttributeListener listener : listeners)
+         listener.attributeReplaced(event);
+
+   }
+
+   public void attributeAdded(ServletContextAttributeEvent event)
+   {
+      try
+      {
+         replayLock.readLock().lock();
+
+         if (!initialized)
+         {
+            contextEvents.add(new ContextEvent(ContextEventType.ADD, event));
+            return;
+         }
+
+         ArrayList<ServletContextAttributeListener> listeners = contextAttributeListeners;
+         for (ServletContextAttributeListener listener : listeners)
+            listener.attributeAdded(event);
+      }
+      finally
+      {
+         replayLock.readLock().unlock();
+      }
+
+   }
+
+   public void attributeRemoved(ServletContextAttributeEvent event)
+   {
+
+      try
+      {
+         replayLock.readLock().lock();
+
+         if (!initialized)
+         {
+            contextEvents.add(new ContextEvent(ContextEventType.REMOVE, event));
+            return;
+         }
+
+         ArrayList<ServletContextAttributeListener> listeners = contextAttributeListeners;
+         for (ServletContextAttributeListener listener : listeners)
+            listener.attributeRemoved(event);
+      }
+      finally
+      {
+         replayLock.readLock().unlock();
+      }
+   }
+
+   public void attributeReplaced(ServletContextAttributeEvent event)
+   {
+
+      try
+      {
+         replayLock.readLock().lock();
+
+         if (!initialized)
+         {
+            contextEvents.add(new ContextEvent(ContextEventType.REPLACE, event));
+            return;
+         }
+
+         ArrayList<ServletContextAttributeListener> listeners = contextAttributeListeners;
+         for (ServletContextAttributeListener listener : listeners)
+            listener.attributeRemoved(event);
+      }
+      finally
+      {
+         replayLock.readLock().unlock();
+      }
+   }
+}


Property changes on: trunk/core/src/main/java/org/jboss/on/embedded/LazyStartupListener.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Author Id Revision HeadURL
Name: svn:eol-style
   + LF

Modified: trunk/core/src/main/webapp/WEB-INF/web.xml
===================================================================
--- trunk/core/src/main/webapp/WEB-INF/web.xml	2009-04-20 21:50:03 UTC (rev 313)
+++ trunk/core/src/main/webapp/WEB-INF/web.xml	2009-04-20 23:25:07 UTC (rev 314)
@@ -36,40 +36,47 @@
         <param-value>jboss-console</param-value>
     </context-param>
 
-    <!-- Seam -->
-
+    <!-- Seam (lazy loaded)-->
+    <context-param>
+        <param-name>org.jboss.on.embedded.LazyStartupListener</param-name>
+        <param-value>org.jboss.seam.servlet.SeamListener</param-value>
+    </context-param>
     <listener>
-        <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
+        <listener-class>org.jboss.on.embedded.LazyStartupListener</listener-class>
     </listener>
 
     <!-- From Seam docs: The Seam master filter must be the first filter specified
          in web.xml. This ensures it is run first. -->
     <filter>
         <filter-name>Seam Filter</filter-name>
-        <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
+        <!-- Lazily start up the Seam Filter -->
+        <filter-class>org.jboss.on.embedded.LazyStartupFilter</filter-class>
+        <init-param>
+        	<param-name>org.jboss.on.embedded.LazyStartupFilter</param-name>
+        	<param-value>org.jboss.seam.servlet.SeamFilter</param-value>
+        </init-param>
     </filter>
     <filter-mapping>
         <filter-name>Seam Filter</filter-name>
         <url-pattern>/*</url-pattern>
-    </filter-mapping>    
-    
+    </filter-mapping>
+
     <!-- JSF -->
-    
+
     <servlet>
         <servlet-name>Faces Servlet</servlet-name>
         <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
-        <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
         <servlet-name>Faces Servlet</servlet-name>
         <url-pattern>*.seam</url-pattern>
-    </servlet-mapping>        
+    </servlet-mapping>
 
     <context-param>
         <param-name>javax.faces.CONFIG_FILES</param-name>
         <param-value>/WEB-INF/navigation.xml</param-value>
     </context-param>
-    
+
     <context-param>
         <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
         <param-value>client</param-value>
@@ -81,11 +88,10 @@
     </context-param>
 
     <!-- JSF RI -->
-    
     <listener>
         <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
     </listener>
-    
+
     <!-- Facelets -->
 
     <!-- load our Facelets taglibs (value must be semicolon-delimited) -->




More information about the embjopr-commits mailing list