Author: markt
Date: Fri Jan  7 18:26:09 2011
New Revision: 1056442

URL: http://svn.apache.org/viewvc?rev=1056442&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50201
Handle ROOT webapp redeployment, host start/stop etc for default access log

Modified:
    tomcat/tc6.0.x/trunk/STATUS.txt
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngine.java
    tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml

Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1056442&r1=1056441&r2=1056442&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Fri Jan  7 18:26:09 2011
@@ -127,12 +127,6 @@ PATCHES PROPOSED TO BACKPORT:
   -0: markt - Patch doesn't apply cleanly to tc6.0.x/trunk
   -1:
 
-* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50201
-  Handle ROOT webapp redeployment, host start/stop etc for default access log
-  http://people.apache.org/~kkolinko/patches/2010-12-07_tc6_bug50201.patch
-  +1: kkolinko, markt, fhanik
-  -1:
-
 * Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=48973
   Avoid creating file SESSIONS.ser if there's no session.
   The patch provided by Marc Guillemot works for tc 6 & 7

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngine.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngine.java?rev=1056442&r1=1056441&r2=1056442&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngine.java 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngine.java Fri 
Jan  7 18:26:09 2011
@@ -19,8 +19,11 @@
 package org.apache.catalina.core;
 
 
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
@@ -28,10 +31,15 @@ import javax.management.ObjectName;
 
 import org.apache.catalina.AccessLog;
 import org.apache.catalina.Container;
+import org.apache.catalina.ContainerEvent;
+import org.apache.catalina.ContainerListener;
 import org.apache.catalina.Context;
 import org.apache.catalina.Engine;
 import org.apache.catalina.Host;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
 import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
 import org.apache.catalina.Realm;
 import org.apache.catalina.Service;
 import org.apache.catalina.connector.Request;
@@ -132,7 +140,8 @@ public class StandardEngine
      * Default access log to use for request/response pairs where we can't ID
      * the intended host and context.
      */
-    private volatile AccessLog defaultAccessLog;
+    private final AtomicReference<AccessLog> defaultAccessLog =
+        new AtomicReference<AccessLog>();
 
     // ------------------------------------------------------------- Properties
 
@@ -496,28 +505,59 @@ public class StandardEngine
         }
 
         if (!logged && useDefault) {
-            if (defaultAccessLog == null) {
+            AccessLog newDefaultAccessLog = defaultAccessLog.get();
+            if (newDefaultAccessLog == null) {
                 // If we reached this point, this Engine can't have an 
AccessLog
                 // Look in the defaultHost
                 Host host = (Host) findChild(getDefaultHost());
-                if (host != null) {
-                    defaultAccessLog = host.getAccessLog();
+                Context context = null;
+                boolean checkHost = (host != null);
+                if (checkHost && host instanceof ContainerBase) {
+                    checkHost = ((ContainerBase) host).started;
+                }
+                if (checkHost) {
+                    newDefaultAccessLog = host.getAccessLog();
 
-                    if (defaultAccessLog == null) {
+                    if (newDefaultAccessLog != null) {
+                        if (defaultAccessLog.compareAndSet(null,
+                                newDefaultAccessLog)) {
+                            AccessLogListener l = new AccessLogListener(this,
+                                    host, null);
+                            l.install();
+                        }
+                    } else {
                         // Try the ROOT context of default host
-                        Context context = (Context) host.findChild("");
-                        if (context != null) {
-                            defaultAccessLog = context.getAccessLog();
+                        context = (Context) host.findChild("");
+                        boolean checkContext = (context != null);
+                        if (checkContext && context instanceof ContainerBase) {
+                            checkContext = ((ContainerBase) context).started;
+                        }
+                        if (checkContext) {
+                            newDefaultAccessLog = context.getAccessLog();
+                            if (newDefaultAccessLog != null) {
+                                if (defaultAccessLog.compareAndSet(null,
+                                        newDefaultAccessLog)) {
+                                    AccessLogListener l = new 
AccessLogListener(
+                                            this, null, context);
+                                    l.install();
+                                }
+                            }
                         }
                     }
                 }
 
-                if (defaultAccessLog == null) {
-                    defaultAccessLog = new NoopAccessLog();
+                if (newDefaultAccessLog == null) {
+                    newDefaultAccessLog = new NoopAccessLog();
+                    if (defaultAccessLog.compareAndSet(null,
+                            newDefaultAccessLog)) {
+                        AccessLogListener l = new AccessLogListener(this, host,
+                                context);
+                        l.install();
+                    }
                 }
             }
 
-            defaultAccessLog.log(request, response, time);
+            newDefaultAccessLog.log(request, response, time);
         }
     }
 
@@ -584,5 +624,88 @@ public class StandardEngine
     public void setDomain(String domain) {
         this.domain = domain;
     }
-    
+ 
+    protected static final class AccessLogListener
+            implements PropertyChangeListener, LifecycleListener,
+            ContainerListener {
+
+        private StandardEngine engine;
+        private Host host;
+        private Context context;
+        private volatile boolean disabled = false;
+
+        public AccessLogListener(StandardEngine engine, Host host,
+                Context context) {
+            this.engine = engine;
+            this.host = host;
+            this.context = context;
+        }
+
+        public void install() {
+            engine.addPropertyChangeListener(this);
+            if (host != null) {
+                host.addContainerListener(this);
+                if (host instanceof Lifecycle) {
+                    ((Lifecycle) host).addLifecycleListener(this);
+                }
+            }
+            if (context instanceof Lifecycle) {
+                ((Lifecycle) context).addLifecycleListener(this);
+            }
+        }
+
+        private void uninstall() {
+            disabled = true;
+            if (context instanceof Lifecycle) {
+                ((Lifecycle) context).removeLifecycleListener(this);
+            }
+            if (host != null) {
+                if (host instanceof Lifecycle) {
+                    ((Lifecycle) host).removeLifecycleListener(this);
+                }
+                host.removeContainerListener(this);
+            }
+            engine.removePropertyChangeListener(this);
+        }
+
+        public void lifecycleEvent(LifecycleEvent event) {
+            if (disabled) return;
+
+            String type = event.getType();
+            if (Lifecycle.AFTER_START_EVENT.equals(type) ||
+                    Lifecycle.BEFORE_STOP_EVENT.equals(type) ||
+                    Lifecycle.DESTROY_EVENT.equals(type)) {
+                // Container is being started/stopped/removed
+                // Force re-calculation and disable listener since it won't
+                // be re-used
+                engine.defaultAccessLog.set(null);
+                uninstall();
+            }
+        }
+
+        public void propertyChange(PropertyChangeEvent evt) {
+            if (disabled) return;
+            if ("defaultHost".equals(evt.getPropertyName())) {
+                // Force re-calculation and disable listener since it won't
+                // be re-used
+                engine.defaultAccessLog.set(null);
+                uninstall();
+            }
+        }
+
+        public void containerEvent(ContainerEvent event) {
+            // Only useful for hosts
+            if (disabled) return;
+            if (Container.ADD_CHILD_EVENT.equals(event.getType())) {
+                Context context = (Context) event.getData();
+                if ("".equals(context.getPath())) {
+                    // New ROOT context in default host
+                    // Force re-calculation and disable listener since it won't
+                    // be re-used
+                    engine.defaultAccessLog.set(null);
+                    uninstall();
+                }
+            }
+        }
+    }
 }

Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1056442&r1=1056441&r2=1056442&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Fri Jan  7 18:26:09 2011
@@ -67,8 +67,9 @@
         access. (markt)
       </fix>
       <fix>
-        <bug>49909</bug>: Provide a mechanism to log requests rejected before
-        they reach the AccessLogValve to appear in the access log. (markt)
+        <bug>49909</bug>, <bug>50201</bug>: Provide a mechanism to log requests
+        rejected before they reach the AccessLogValve to appear in the access
+        log. (markt/kkolinko)
       </fix>
     </changelog>
   </subsection>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to