This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/master by this push:
     new c5fbb15  Add utility Server listener
c5fbb15 is described below

commit c5fbb158f7e91306a010dd95f4f13996991dd8fd
Author: remm <r...@apache.org>
AuthorDate: Tue May 28 16:40:30 2019 +0200

    Add utility Server listener
    
    Its purpose is to replicate adding a Listener in context.xml. Also add
    new container events to notify container add and remove before start and
    after stop (respectively) so that containers can actually be configured
    before a possible lifecycle change.
---
 java/org/apache/catalina/Container.java            |  14 +++
 java/org/apache/catalina/core/ContainerBase.java   |   4 +
 .../apache/catalina/core/FrameworkListener.java    | 114 +++++++++++++++++++++
 webapps/docs/changelog.xml                         |  10 ++
 4 files changed, 142 insertions(+)

diff --git a/java/org/apache/catalina/Container.java 
b/java/org/apache/catalina/Container.java
index 177b2d2..0b30247 100644
--- a/java/org/apache/catalina/Container.java
+++ b/java/org/apache/catalina/Container.java
@@ -84,6 +84,13 @@ public interface Container extends Lifecycle {
 
     /**
      * The ContainerEvent event type sent when a child container is added
+     * by <code>addChild()</code>, but before it is started.
+     */
+    public static final String ADD_CHILD_BEFORE_START_EVENT = 
"addChildBeforeStart";
+
+
+    /**
+     * The ContainerEvent event type sent when a child container is added
      * by <code>addChild()</code>.
      */
     public static final String ADD_CHILD_EVENT = "addChild";
@@ -98,6 +105,13 @@ public interface Container extends Lifecycle {
 
     /**
      * The ContainerEvent event type sent when a child container is removed
+     * by <code>removeChild()</code>, but before it is stopped.
+     */
+    public static final String REMOVE_CHILD_BEFORE_STOP_EVENT = 
"removeChildBeforeStop";
+
+
+    /**
+     * The ContainerEvent event type sent when a child container is removed
      * by <code>removeChild()</code>.
      */
     public static final String REMOVE_CHILD_EVENT = "removeChild";
diff --git a/java/org/apache/catalina/core/ContainerBase.java 
b/java/org/apache/catalina/core/ContainerBase.java
index cee5e42..f3a3011 100644
--- a/java/org/apache/catalina/core/ContainerBase.java
+++ b/java/org/apache/catalina/core/ContainerBase.java
@@ -703,6 +703,8 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase
             children.put(child.getName(), child);
         }
 
+        fireContainerEvent(ADD_CHILD_BEFORE_START_EVENT, child);
+
         // Start child
         // Don't do this inside sync block - start can be a slow process and
         // locking the children object can cause problems elsewhere
@@ -798,6 +800,8 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase
             return;
         }
 
+        fireContainerEvent(REMOVE_CHILD_BEFORE_STOP_EVENT, child);
+
         try {
             if (child.getState().isAvailable()) {
                 child.stop();
diff --git a/java/org/apache/catalina/core/FrameworkListener.java 
b/java/org/apache/catalina/core/FrameworkListener.java
new file mode 100644
index 0000000..4927e49
--- /dev/null
+++ b/java/org/apache/catalina/core/FrameworkListener.java
@@ -0,0 +1,114 @@
+/*
+ * 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.catalina.core;
+
+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.LifecycleListener;
+import org.apache.catalina.Server;
+import org.apache.catalina.Service;
+
+/**
+ * This listener must be declared in server.xml as a Server listener, possibly 
optional.
+ * It will register a lifecycle listener on all contexts. This is an 
alternative to
+ * adding a Listener in context.xml with more flexibility.
+ */
+public abstract class FrameworkListener implements LifecycleListener, 
ContainerListener {
+
+    /**
+     * Create a lifecycle listener which will then be added to the specified 
context.
+     * @param context the associated Context
+     * @return the lifecycle listener
+     */
+    protected abstract LifecycleListener createLifecycleListener(Context 
context);
+
+    @Override
+    public void lifecycleEvent(LifecycleEvent event) {
+        Lifecycle lifecycle = event.getLifecycle();
+        if (Lifecycle.BEFORE_START_EVENT.equals(event.getType()) &&
+                lifecycle instanceof Server) {
+            Server server = (Server) lifecycle;
+            registerListenersForServer(server);
+        }
+    }
+
+    @Override
+    public void containerEvent(ContainerEvent event) {
+        String type = event.getType();
+        if (Container.ADD_CHILD_BEFORE_START_EVENT.equals(type)) {
+            processContainerAddChild(event.getContainer(),
+                    (Container) event.getData());
+        } else if (Container.REMOVE_CHILD_BEFORE_STOP_EVENT.equals(type)) {
+            processContainerRemoveChild(event.getContainer(),
+                    (Container) event.getData());
+        }
+    }
+
+    private void registerListenersForServer(Server server) {
+        for (Service service : server.findServices()) {
+            Engine engine = service.getContainer();
+            if (engine != null) {
+                engine.addContainerListener(this);
+                registerListenersForEngine(engine);
+            }
+        }
+
+    }
+
+    private void registerListenersForEngine(Engine engine) {
+        for (Container hostContainer : engine.findChildren()) {
+            Host host = (Host) hostContainer;
+            host.addContainerListener(this);
+            registerListenersForHost(host);
+        }
+    }
+
+    private void registerListenersForHost(Host host) {
+        for (Container contextContainer : host.findChildren()) {
+            Context context = (Context) contextContainer;
+            registerContextListener(context);
+        }
+    }
+
+    private void registerContextListener(Context context) {
+        context.addLifecycleListener(createLifecycleListener(context));
+    }
+
+    private void processContainerAddChild(Container parent, Container child) {
+        if (child instanceof Context) {
+            registerContextListener((Context) child);
+        } else if (child instanceof Engine) {
+            registerListenersForEngine((Engine) child);
+        } else if (child instanceof Host) {
+            registerListenersForHost((Host) child);
+        }
+    }
+
+    private void processContainerRemoveChild(Container parent, Container 
child) {
+        if (child instanceof Host || child instanceof Engine) {
+            child.removeContainerListener(this);
+        }
+    }
+
+}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 5032643..0e40e52 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -80,6 +80,16 @@
         Add <code>Context.createInstanceManager()</code> for easier framework
         integration. (remm)
       </scode>
+      <scode>
+        Add utility <code>org.apache.catalina.core.FrameworkListener</code> to
+        allow replicating adding a Listener to context.xml in a programmatic
+        way. (remm)
+      </scode>
+      <scode>
+        Add <code>Container.ADD_CHILD_BEFORE_START_EVENT</code> and
+        <code>Container.REMOVE_CHILD_BEFORE_STOP_EVENT</code> to allow
+        configuration of containers before a possible lifecycle event. (remm)
+      </scode>
     </changelog>
   </subsection>
   <subsection name="Coyote">


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

Reply via email to