You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ma...@apache.org on 2008/11/12 11:09:28 UTC

svn commit: r713341 - in /myfaces/trinidad/branches/1.2.8.1-branch: trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/ trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/ trinidad-api/src/main/java/org/apache/myfaces/trinidad...

Author: matzew
Date: Wed Nov 12 02:09:19 2008
New Revision: 713341

URL: http://svn.apache.org/viewvc?rev=713341&view=rev
Log:
backport of different issues to this branch

Added:
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ThreadLocalUtils.java
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ThreadLocalResetter.java
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/resources/META-INF/services/org.apache.myfaces.trinidad.util.ThreadLocalUtils.ThreadLocalLifecycle.REQUEST
Modified:
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RenderingContext.java
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/table/TableRenderingContext.java
    myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java

Modified: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java?rev=713341&r1=713340&r2=713341&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java (original)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java Wed Nov 12 02:09:19 2008
@@ -56,6 +56,7 @@
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.render.ExtendedRenderer;
 import org.apache.myfaces.trinidad.render.LifecycleRenderer;
+import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
 
 
 /**
@@ -1457,8 +1458,7 @@
 
 
   static private final ThreadLocal<StringBuilder> _STRING_BUILDER =
-                                                        new ThreadLocal<StringBuilder>();
-
+                                                          ThreadLocalUtils.newRequestThreadLocal();
   static private FacesBean.Type _createType()
   {
     try

Modified: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RenderingContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RenderingContext.java?rev=713341&r1=713340&r2=713341&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RenderingContext.java (original)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RenderingContext.java Wed Nov 12 02:09:19 2008
@@ -25,6 +25,7 @@
 
 import org.apache.myfaces.trinidad.skin.Skin;
 import org.apache.myfaces.trinidad.skin.Icon;
+import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
 
 /**
  */
@@ -150,7 +151,7 @@
 
 
   static private final ThreadLocal<RenderingContext> _CURRENT_CONTEXT = 
-    new ThreadLocal<RenderingContext>();
+                                                         ThreadLocalUtils.newRequestThreadLocal();
   
   static private final TrinidadLogger _LOG =
     TrinidadLogger.createTrinidadLogger(RenderingContext.class);

Added: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ThreadLocalUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ThreadLocalUtils.java?rev=713341&view=auto
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ThreadLocalUtils.java (added)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ThreadLocalUtils.java Wed Nov 12 02:09:19 2008
@@ -0,0 +1,224 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.trinidad.util;
+
+import java.lang.ref.WeakReference;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Utility functions related to ThreadLocals.
+ * This class provides utilities for managing the lifecycles of ThreadLocals.
+ * In particular, many application servers do not clean up the ThreadLocals
+ * added to the request thread before returning the request thread to
+ * its thread pool.  This may have several severe side-effects, including
+ * <ol>
+ *   <li>Leakage of objects referenced by the thread local</li>
+ *   <li>Possible security holes if the ThreadLocals contents are reused
+ *       on a request for a different user.</li>
+ *   <li>Leakage of the entire class loader in live patching scenarios</li>
+ *   <li>ClassCastExceptions in live patching scenarios</li>
+ * </ol>
+ * To avoid these problems, this class provides utilities for creating
+ * and registering ThreadLocals that will be removed from the thread
+ * automatically at the end of the current request.
+ * @see #newRequestThreadLocal
+ * @see #registerRequestThreadLocal
+ */
+public final class ThreadLocalUtils
+{
+  /**
+   * Integration interface implemented by object holding onto ThreadLocals
+   * with a specified lifetime
+   * @see ThreadLocalLifecycle
+   */
+  public static abstract class ThreadLocalManager
+  {
+    /**
+     * Called by the ThreadLocalLifeCycle when the ThreadLocals managed by
+     * this ThreadLocalManager need to be cleaned up by removing their
+     * instances from the current Thread.
+     */
+    public abstract void removeThreadLocals();
+  }
+  
+  /**
+   * Integration interface implemented by an object that cleans up the
+   * ThreadLocals in a ThreadLocalManager with the specified lifetime.
+   * The ThreadLocalLifecycle cleans up the ThreadLocals by calling
+   * <code>removeThreadLocals</code> on the ThreadLocalManager passed
+   * to it in <code>init</code> at the appropriate time.
+   * @see ThreadLocalManager
+   * @see #init
+   */
+  public static abstract class ThreadLocalLifecycle
+  {
+    /**
+     * Called after instantiating the ThreadLocalLifecycle so that the
+     * ThreadLocalLifecycle can clean up the ThreadLocalManager at the
+     * appropriate moment.
+     * @param manager Manager of ThreadLocals that will be cleaned up by
+     * this ThreadLocalLifecycle.
+     * @see ThreadLocalManager#removeThreadLocals
+     */
+    public abstract void init(ThreadLocalManager manager);
+  }
+  
+  // don't allow instantiation 
+  private ThreadLocalUtils()
+  {
+  }
+
+  /**
+   * Creates and returns a new ThreadLocal that will be automatically removed from
+   * the each request thread when the request finishes.
+   * @return The ThreadLocal
+   * @see #registerRequestThreadLocal
+   */
+  public static <T> ThreadLocal<T> newRequestThreadLocal()
+  {
+    return registerRequestThreadLocal(new ThreadLocal<T>());
+  }
+
+  /**
+   * Registers and returns the ThreadLocal to be automatically removed from
+   * the each request thread when the request finishes.
+   * @param threadLocal ThreadLocal to register for automatic removal
+   * @return The reigistered ThreadLocal
+   * @see #newRequestThreadLocal
+   */
+  public static <T> ThreadLocal<T> registerRequestThreadLocal(ThreadLocal<T> threadLocal)
+  {
+    return _getThreadLocalManager(_REQUEST_SERVICE).registerThreadLocal(threadLocal);
+  }
+  
+  /**
+   * Returns the ResettableThreadLocalManager for the specified threadLocalGroup name.  If no
+   * ResettableThreadLocalManager is currently registered for the threadLocalGroup, one will
+   * be instantiated, its related ThreadLocalLifecycle instantiated and the ThreadLocalManager
+   * registered with the ThreadLocalLifecycle
+   * @param threadLocalGroup Identifier for this group
+   * @return the ResettableThreadLocalManager for this threadLocalGroup name
+   */
+  private static ResettableThreadLocalManager _getThreadLocalManager(String threadLocalGroup)
+  {
+    // see if we already have a ResettableThreadLocalManager registered
+    ResettableThreadLocalManager threadLocalManager = _threadLocalManagers.get(threadLocalGroup);
+    
+    // if we don't, create one
+    if (threadLocalManager == null)
+    {
+      threadLocalManager = new ResettableThreadLocalManager();
+      
+      // handle simultaneous registration
+      ResettableThreadLocalManager oldThreadLocalManager =
+                            _threadLocalManagers.putIfAbsent(threadLocalGroup, threadLocalManager);
+      
+      if (oldThreadLocalManager != null)
+      {
+        // simultaneous registration, use the one that was registered first
+        threadLocalManager = oldThreadLocalManager;
+      }
+      else
+      {
+        // find the ThreadLocalLifecycle for this threadLocalGroup by looking in
+        // META-INF/Services, instantiate it and register ourselves with it so that we
+        // can be cleaned up
+        List<ThreadLocalLifecycle> lifecycles = ClassLoaderUtils.getServices(threadLocalGroup);
+        
+        if (!lifecycles.isEmpty())
+        {
+          lifecycles.get(0).init(threadLocalManager);
+        }
+      }
+    }
+    
+    return threadLocalManager;
+  }
+  
+  /**
+   * ThreadLocalManager implementation class
+   */
+  private static class ResettableThreadLocalManager extends ThreadLocalManager
+  {
+    public ResettableThreadLocalManager()
+    {
+      // create the list of resettable ThreadLocals for this group
+      _threadLocals = new ConcurrentLinkedQueue<WeakReference<ThreadLocal<?>>>();
+    }
+    
+    /**
+     * Registers the ThreadLocal for cleanup when this ThreadLocalManager is cleaned up
+     * @param threadLocal ThreadLocal to register for clean up
+     * @return The registered ThreadLocal
+     */
+    public <T> ThreadLocal<T> registerThreadLocal(ThreadLocal<T> threadLocal)
+    {
+      if (threadLocal == null)
+        throw new NullPointerException();
+      
+      // WeakReference might be overkill here, but make sure we don't pin ThreadLocals
+      _threadLocals.add(new WeakReference<ThreadLocal<?>>(threadLocal));
+      
+      return threadLocal;
+    }
+    
+    /**
+     * Called by the ThreadLocalLifecycle to clean up all of the ThreadLocals registered
+     * with this ThreadLocalManager
+     */
+    public void removeThreadLocals()
+    {
+      Iterator<WeakReference<ThreadLocal<?>>> iterator = _threadLocals.iterator();
+      
+      while (iterator.hasNext())
+      {
+        ThreadLocal<?> threadLocal = iterator.next().get();
+        
+        if (threadLocal != null)
+        {
+          // reset the threadlocal for this thread
+          threadLocal.remove();
+        }
+        else
+        {
+          // The threadLocal is null, that means it has been released and we would really
+          // like to reclaim the entry
+          iterator.remove();
+        }
+      }
+    }
+    
+    private final Collection<WeakReference<ThreadLocal<?>>> _threadLocals;
+  }
+
+  // Name used for the request-scoped ThreadLocalManager
+  private static final String _REQUEST_SERVICE = ThreadLocalUtils.class.getName() + 
+                                                                    ".ThreadLocalLifecycle.REQUEST";
+  
+  // threadLocalGroup -> ThreadLocalManager Map
+  private static final ConcurrentMap<String, ResettableThreadLocalManager>_threadLocalManagers
+                     = new ConcurrentHashMap<String, ResettableThreadLocalManager>();
+}

Modified: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java?rev=713341&r1=713340&r2=713341&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java (original)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java Wed Nov 12 02:09:19 2008
@@ -23,6 +23,8 @@
 import java.util.List;
 import java.util.Map;
 
+import java.util.concurrent.atomic.AtomicReference;
+
 import javax.faces.context.ExternalContext;
 
 import javax.servlet.ServletRequest;
@@ -239,20 +241,28 @@
   {
     if (_initialized)
     {
-      for (final Configurator config : _services)
+      try
       {
-        try
+        for (final Configurator config : _services)
         {
-          config.destroy();
-        }
-        catch (final Throwable t)
-        {
-          // we always want to continue to destroy things, so log errors and continue
-          _LOG.severe(t);
+          try
+          {
+            config.destroy();
+          }
+          catch (final Throwable t)
+          {
+            // we always want to continue to destroy things, so log errors and continue
+            _LOG.severe(t);
+          }
         }
+        _services = null;
+        _initialized = false;
+      }
+      finally
+      {
+        //release any managed threadlocals that may have been used durring destroy
+        _releaseManagedThreadLocals();
       }
-      _services = null;
-      _initialized = false;
     }
   }
 
@@ -270,15 +280,21 @@
     {
       if (!_isDisabled(externalContext))
       {
-        final RequestType type = RequestType.getType(externalContext);
-
-        // Do not end services at the end of a portal action request
-        if (type != RequestType.PORTAL_ACTION)
+        try
+        {
+          final RequestType type = RequestType.getType(externalContext);
+  
+          // Do not end services at the end of a portal action request
+          if (type != RequestType.PORTAL_ACTION)
+          {
+            _endConfiguratorServiceRequest(externalContext);
+          }
+        }
+        finally
         {
-          _endConfiguratorServiceRequest(externalContext);
+          _releaseRequestContext(externalContext);
+          _releaseManagedThreadLocals();
         }
-
-        _releaseRequestContext(externalContext);
       }
       RequestType.clearType(externalContext);
     }
@@ -346,35 +362,44 @@
 
     if (!_initialized)
     {
-      _services = ClassLoaderUtils.getServices(Configurator.class.getName());
-
-      // Create a new RequestContextFactory is needed
-      if (RequestContextFactory.getFactory() == null)
-      {
-        RequestContextFactory.setFactory(new RequestContextFactoryImpl());
-      }
-
-      // Create a new SkinFactory if needed.
-      if (SkinFactory.getFactory() == null)
-      {
-        SkinFactory.setFactory(new SkinFactoryImpl());
-      }
-
-      // register the base skins
-      SkinUtils.registerBaseSkins();
-
-      for (final Configurator config : _services)
+      try
       {
-        config.init(externalContext);
+        _services = ClassLoaderUtils.getServices(Configurator.class.getName());
+  
+        // Create a new RequestContextFactory is needed
+        if (RequestContextFactory.getFactory() == null)
+        {
+          RequestContextFactory.setFactory(new RequestContextFactoryImpl());
+        }
+  
+        // Create a new SkinFactory if needed.
+        if (SkinFactory.getFactory() == null)
+        {
+          SkinFactory.setFactory(new SkinFactoryImpl());
+        }
+  
+        // register the base skins
+        SkinUtils.registerBaseSkins();
+  
+        for (final Configurator config : _services)
+        {
+          config.init(externalContext);
+        }
+  
+        // after the 'services' filters are initialized, then register
+        // the skin extensions found in trinidad-skins.xml. This
+        // gives a chance to the 'services' filters to create more base
+        // skins that the skins in trinidad-skins.xml can extend.
+        SkinUtils.registerSkinExtensions(externalContext);
+        _initialized = true;
+      }
+      finally
+      {
+        
+        //Do cleanup of anything which may have use the thread local manager durring
+        //init.
+        _releaseManagedThreadLocals();
       }
-
-      // after the 'services' filters are initialized, then register
-      // the skin extensions found in trinidad-skins.xml. This
-      // gives a chance to the 'services' filters to create more base
-      // skins that the skins in trinidad-skins.xml can extend.
-      SkinUtils.registerSkinExtensions(externalContext);
-
-      _initialized = true;
     }
     else
     {
@@ -383,6 +408,19 @@
   }
 
   /**
+   * Hackily called by the ThreadLocalResetter to register itself so that the
+   * GlobalConfiguratorImpl can tell the ThreadLocalResetter to clean up the
+   * ThreadLocals at the appropriate time.
+   */
+  void __setThreadLocalResetter(ThreadLocalResetter resetter)
+  {
+    if (resetter == null)
+      throw new NullPointerException();
+    
+    _threadResetter.set(resetter);
+  }
+    
+  /**
    * @param externalContext
    * @return
    */
@@ -401,8 +439,9 @@
         _LOG.warning("REQUESTCONTEXT_NOT_PROPERLY_RELEASED");
       }
       context.release();
+      _releaseManagedThreadLocals();
     }
-
+    
     // See if we've got a cached RequestContext instance; if so,
     // reattach it
     final Object cachedRequestContext = externalContext.getRequestMap().get(
@@ -440,17 +479,31 @@
     {
       context.release();
       assert RequestContext.getCurrentInstance() == null;
+
     }
   }
 
+  private void _releaseManagedThreadLocals() 
+  {
+    ThreadLocalResetter resetter = _threadResetter.get();
+    
+    if (resetter != null)
+    {
+      resetter.__removeThreadLocals();
+    }
+  }
+  
   private void _endConfiguratorServiceRequest(final ExternalContext ec)
   {
     // Physical request has now ended
     // Clear the in-request flag
     ec.getRequestMap().remove(_IN_REQUEST);
-    for (final Configurator config : _services)
+    if(_services != null)
     {
-      config.endRequest(ec);
+      for (final Configurator config : _services)
+      {
+        config.endRequest(ec);
+      }
     }
   }
 
@@ -716,6 +769,10 @@
       ".TEST_PARAM";
   }
 
+  // hacky reference to the ThreadLocalResetter used to clean up request-scoped
+  // ThreadLocals
+  private AtomicReference<ThreadLocalResetter> _threadResetter = 
+                                                        new AtomicReference<ThreadLocalResetter>();
 
   static private final TrinidadLogger _LOG =
     TrinidadLogger.createTrinidadLogger(GlobalConfiguratorImpl.class);

Added: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ThreadLocalResetter.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ThreadLocalResetter.java?rev=713341&view=auto
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ThreadLocalResetter.java (added)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ThreadLocalResetter.java Wed Nov 12 02:09:19 2008
@@ -0,0 +1,76 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.trinidadinternal.config;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.myfaces.trinidad.util.ThreadLocalUtils.ThreadLocalLifecycle;
+import org.apache.myfaces.trinidad.util.ThreadLocalUtils.ThreadLocalManager;
+
+/**
+ * Implementation of ThreadLocalLifecycle for request-scoped ThreadLocals, registered
+ * through META-INF/SERVICES.  This class cooperates with GlobalConfiguratorImpl in order
+ * to ensure that the request-scoped ThreadLocals are cleaned up at the end of each
+ * request.
+ */
+public class ThreadLocalResetter extends ThreadLocalLifecycle
+{
+  /**
+   * All class to be instatiated through reflection
+   */
+  public ThreadLocalResetter()
+  {
+  }
+  
+  /**
+   * Called by ThreadLocalUtils after instantiating the ThreadLocalResetter in order to
+   * pass the ThreadLocalManager to use to clean up the request-scoped ThreadLocals.
+   */
+  public void init(ThreadLocalManager manager)
+  {
+    if (manager == null)
+      throw new NullPointerException();
+    
+    // save the ThreadLocalManager to use to clean up the request-scoped ThreadLocals 
+    _threadLocalManager.set(manager);
+    
+    // slam a reference to our instance on the GlobalConfiguratorImpl so that it can
+    // call __removeRequestThreadLocals when the request is finished 
+    GlobalConfiguratorImpl.getInstance().__setThreadLocalResetter(this);
+  }
+  
+  /**
+   * Called by the GlobalConfiguratorImpl when the request is finished so that the
+   * ThreadLocalResetter can ask the ThreadLocalManager to clean itself up
+   */
+  void __removeThreadLocals()
+  {
+    ThreadLocalManager threadLocalManager = _threadLocalManager.get();
+    
+    if (threadLocalManager != null)
+    {
+      // clean up all of the request-scoped ThreadLocals
+      threadLocalManager.removeThreadLocals();
+    }
+  }
+
+  // ThreadLocalManager to clean up
+  private AtomicReference<ThreadLocalManager> _threadLocalManager = new 
+                                                   AtomicReference<ThreadLocalManager>();
+}

Modified: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java?rev=713341&r1=713340&r2=713341&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java (original)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java Wed Nov 12 02:09:19 2008
@@ -33,11 +33,12 @@
 import javax.faces.webapp.UIComponentTag;
 
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
 
 /**
  * Menu Utilities used by the Menu Model internal code.
  * All classes are package private.
- * 
+ *
  */
 class MenuUtils
 {
@@ -299,7 +300,7 @@
   @SuppressWarnings("unchecked")
   static void loadBundle(String resBundleName, String resBundleKey)
   {
-    ThreadLocal<String> bundleKey = new ThreadLocal<String>();
+    ThreadLocal<String> bundleKey = ThreadLocalUtils.newRequestThreadLocal();;
     
     bundleKey.set(resBundleKey);    
     loadBundle(resBundleName, bundleKey);

Modified: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/table/TableRenderingContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/table/TableRenderingContext.java?rev=713341&r1=713340&r2=713341&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/table/TableRenderingContext.java (original)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/table/TableRenderingContext.java Wed Nov 12 02:09:19 2008
@@ -32,6 +32,7 @@
 import org.apache.myfaces.trinidad.model.RowKeySet;
 import org.apache.myfaces.trinidad.context.RenderingContext;
 import org.apache.myfaces.trinidad.render.CoreRenderer;
+import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
 import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SkinSelectors;
 import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlRenderer;
 import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlUtils;
@@ -597,5 +598,5 @@
 
 
   static private final ThreadLocal<TableRenderingContext> _CURRENT_CONTEXT = 
-    new ThreadLocal<TableRenderingContext>();
+                                                          ThreadLocalUtils.newRequestThreadLocal();
 }

Modified: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java?rev=713341&r1=713340&r2=713341&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java (original)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java Wed Nov 12 02:09:19 2008
@@ -36,6 +36,7 @@
 
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
 import org.apache.myfaces.trinidadinternal.config.GlobalConfiguratorImpl;
 import org.apache.myfaces.trinidadinternal.config.dispatch.DispatchResponseConfiguratorImpl;
 import org.apache.myfaces.trinidadinternal.config.dispatch.DispatchServletResponse;
@@ -288,11 +289,7 @@
     "org.apache.myfaces.trinidadinternal.webapp.AdfacesFilterImpl.EXECUTED";
 
   private static ThreadLocal<PseudoFacesContext> _PSEUDO_FACES_CONTEXT = 
-    new ThreadLocal<PseudoFacesContext>()
-  {
-    @Override
-    protected PseudoFacesContext initialValue() { return null; }
-  };
+                                                           ThreadLocalUtils.newRequestThreadLocal();
 
   private static final TrinidadLogger _LOG =
     TrinidadLogger.createTrinidadLogger(TrinidadFilterImpl.class);

Added: myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/resources/META-INF/services/org.apache.myfaces.trinidad.util.ThreadLocalUtils.ThreadLocalLifecycle.REQUEST
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/resources/META-INF/services/org.apache.myfaces.trinidad.util.ThreadLocalUtils.ThreadLocalLifecycle.REQUEST?rev=713341&view=auto
==============================================================================
--- myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/resources/META-INF/services/org.apache.myfaces.trinidad.util.ThreadLocalUtils.ThreadLocalLifecycle.REQUEST (added)
+++ myfaces/trinidad/branches/1.2.8.1-branch/trinidad-impl/src/main/resources/META-INF/services/org.apache.myfaces.trinidad.util.ThreadLocalUtils.ThreadLocalLifecycle.REQUEST Wed Nov 12 02:09:19 2008
@@ -0,0 +1 @@
+org.apache.myfaces.trinidadinternal.config.ThreadLocalResetter