Repository: tomee
Updated Branches:
  refs/heads/develop fea2a0243 -> e17c854b1


TOMEE-1491 LazyValve


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/e17c854b
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/e17c854b
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/e17c854b

Branch: refs/heads/develop
Commit: e17c854b1a612904da1f2582177dd6e86e064986
Parents: fea2a02
Author: Romain Manni-Bucau <[email protected]>
Authored: Fri Jan 9 12:35:37 2015 +0100
Committer: Romain Manni-Bucau <[email protected]>
Committed: Fri Jan 9 12:35:37 2015 +0100

----------------------------------------------------------------------
 .../apache/tomee/catalina/valve/LazyValve.java  | 238 +++++++++++++++++++
 1 file changed, 238 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/e17c854b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/valve/LazyValve.java
----------------------------------------------------------------------
diff --git 
a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/valve/LazyValve.java
 
b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/valve/LazyValve.java
new file mode 100644
index 0000000..afc4411
--- /dev/null
+++ 
b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/valve/LazyValve.java
@@ -0,0 +1,238 @@
+/*
+ * 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.tomee.catalina.valve;
+
+import org.apache.catalina.Contained;
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.LifecycleState;
+import org.apache.catalina.Valve;
+import org.apache.catalina.comet.CometEvent;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.util.LifecycleSupport;
+import org.apache.openejb.config.sys.PropertiesAdapter;
+import org.apache.openejb.core.ParentClassLoaderFinder;
+import org.apache.tomee.catalina.TomEERuntimeException;
+import org.apache.xbean.recipe.ObjectRecipe;
+import org.apache.xbean.recipe.Option;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+import java.util.Properties;
+
+public class LazyValve implements Valve, Lifecycle, Contained {
+    private String delegateClassName;
+    private String properties;
+    private Container container;
+    private Valve next;
+
+    private volatile Valve delegate;
+    private volatile boolean init;
+    private volatile boolean start;
+    private volatile LifecycleState state;
+    private final LifecycleSupport lifecycleSupport = new 
LifecycleSupport(this);
+
+    public void setDelegateClassName(String delegateClassName) {
+        this.delegateClassName = delegateClassName;
+    }
+
+    public void setProperties(final String properties) {
+        this.properties = properties;
+    }
+
+    private Valve instance() {
+        if (delegate == null) {
+            synchronized (this) {
+                if (delegate == null) {
+                    final Object instance;
+
+                    ClassLoader cl = loader();
+                    if (cl == null) {
+                        return null;
+                    }
+
+                    final Class<?> clazz;
+                    try {
+                        clazz = cl.loadClass(delegateClassName);
+                    } catch (final ClassNotFoundException e) {
+                        throw new TomEERuntimeException(e);
+                    }
+
+                    try {
+                        final ObjectRecipe recipe = new ObjectRecipe(clazz);
+                        recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
+                        recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
+                        recipe.allow(Option.FIELD_INJECTION);
+                        recipe.allow(Option.PRIVATE_PROPERTIES);
+                        if (properties != null) {
+                            final Properties props = new PropertiesAdapter()
+                                    
.unmarshal(properties.trim().replaceAll("\\p{Space}*(\\p{Alnum}*)=", "\n$1="));
+                            recipe.setAllProperties(props);
+                        }
+                        instance = recipe.create();
+                    } catch (final Exception e) {
+                        throw new TomEERuntimeException(e);
+                    }
+
+                    delegate = Valve.class.cast(instance);
+                    delegate.setNext(next);
+                    if (Contained.class.isInstance(delegate)) {
+                        Contained.class.cast(delegate).setContainer(container);
+                    }
+                    if (Lifecycle.class.isInstance(delegate)) {
+                        if (init) {
+                            try {
+                                final Lifecycle lifecycle = 
Lifecycle.class.cast(delegate);
+                                for (final LifecycleListener listener : 
lifecycleSupport.findLifecycleListeners()) {
+                                    lifecycle.addLifecycleListener(listener);
+                                }
+                                lifecycle.init();
+                                if (start) {
+                                    lifecycle.start();
+                                }
+                            } catch (final LifecycleException e) {
+                                // no-op
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return delegate;
+    }
+
+    private ClassLoader loader() {
+        if (container == null || !Context.class.isInstance(container)) {
+            return ParentClassLoaderFinder.Helper.get();
+        }
+        final Context ctx = Context.class.cast(container);
+        return ctx.getLoader() != null && ctx.getLoader().getClassLoader() != 
null ? ctx.getLoader().getClassLoader() : null;
+    }
+
+    @Override
+    public Valve getNext() {
+        return next;
+    }
+
+    @Override
+    public void setNext(final Valve valve) {
+        this.next = valve;
+        if (delegate != null) {
+            delegate.setNext(next);
+        }
+    }
+
+    @Override
+    public void backgroundProcess() {
+        if (delegate != null) {
+            delegate.backgroundProcess();
+        }
+    }
+
+    @Override
+    public void invoke(final Request request, final Response response) throws 
IOException, ServletException {
+        instance().invoke(request, response);
+    }
+
+    @Override
+    public void event(final Request request, final Response response, final 
CometEvent event) throws IOException, ServletException {
+        instance().event(request, response, event);
+    }
+
+    @Override
+    public boolean isAsyncSupported() {
+        return instance().isAsyncSupported();
+    }
+
+    @Override
+    public void addLifecycleListener(final LifecycleListener listener) {
+        lifecycleSupport.addLifecycleListener(listener);
+    }
+
+    @Override
+    public LifecycleListener[] findLifecycleListeners() {
+        return lifecycleSupport.findLifecycleListeners();
+    }
+
+    @Override
+    public void removeLifecycleListener(final LifecycleListener listener) {
+        lifecycleSupport.removeLifecycleListener(listener);
+    }
+
+    @Override
+    public void init() throws LifecycleException {
+        if (instance() != null && Lifecycle.class.isInstance(delegate)) {
+            Lifecycle.class.cast(delegate).init();
+        } else {
+            init = true;
+        }
+        state = LifecycleState.INITIALIZED;
+    }
+
+    @Override
+    public void start() throws LifecycleException {
+        if (instance() != null && Lifecycle.class.isInstance(delegate)) {
+            Lifecycle.class.cast(delegate).start();
+        } else {
+            start = true;
+        }
+        state = LifecycleState.STARTED;
+    }
+
+    @Override
+    public void stop() throws LifecycleException {
+        if (instance() != null && Lifecycle.class.isInstance(delegate)) {
+            Lifecycle.class.cast(delegate).stop();
+        }
+        state = LifecycleState.STOPPED;
+    }
+
+    @Override
+    public void destroy() throws LifecycleException {
+        if (instance() != null && Lifecycle.class.isInstance(delegate)) {
+            Lifecycle.class.cast(delegate).destroy();
+        }
+        state = LifecycleState.DESTROYED;
+    }
+
+    @Override
+    public LifecycleState getState() {
+        return state;
+    }
+
+    @Override
+    public String getStateName() {
+        return state.name();
+    }
+
+    @Override
+    public Container getContainer() {
+        return container;
+    }
+
+    @Override
+    public void setContainer(final Container container) {
+        this.container = container;
+        if (delegate != null && Contained.class.isInstance(delegate)) {
+            Contained.class.cast(delegate).setContainer(container);
+        }
+    }
+}

Reply via email to