logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgo...@apache.org
Subject svn commit: r1147720 [2/2] - in /logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers: ./ log4j12-api/ log4j12-api/src/main/java/org/apache/log4j/ log4j12-api/src/test/java/org/apache/log4j/ log4j2-api/ log4j2-api/src/main/java/org/apache/logging/log4...
Date Mon, 18 Jul 2011 00:49:14 GMT
Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/javaee/JNDIContextFilter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/javaee/JNDIContextFilter.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/javaee/JNDIContextFilter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/javaee/JNDIContextFilter.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,102 @@
+/*
+ * 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.logging.log4j.core.javaee;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.core.Log4jContextFactory;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.selector.NamedContextSelector;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.UnavailableException;
+import java.io.IOException;
+
+/**
+ *
+ */
+public class JNDIContextFilter implements Filter {
+
+    public static final String CONTEXT_NAME = "context-name";
+    public static final String CONFIG_LOCATION = "config-location";
+    private static final String CONTEXT_CLASS = "org.apache.logging.log4j.core.LoggerContext";
+    private ServletContext context;
+    private boolean created = false;
+    private String name;
+    private NamedContextSelector selector = null;
+
+    public void init(FilterConfig filterConfig) throws ServletException {
+        context = filterConfig.getServletContext();
+        name = filterConfig.getInitParameter(CONTEXT_NAME);
+        String configLocn = filterConfig.getInitParameter(CONFIG_LOCATION);
+        if (name == null) {
+            throw new UnavailableException("A context-name attribute is required");
+        }
+        if (context.getAttribute(ContextListener.LOG4J_CONTEXT_ATTRIBUTE) == null) {
+            LoggerContext ctx;
+            LoggerContextFactory factory = LogManager.getFactory();
+            if (factory instanceof Log4jContextFactory) {
+                ContextSelector sel = ((Log4jContextFactory) factory).getSelector();
+                if (sel instanceof NamedContextSelector) {
+                    selector = (NamedContextSelector) sel;
+                    ctx = selector.locateContext(name, configLocn);
+                } else {
+                    return;
+                }
+            } else {
+                return;
+            }
+            context.setAttribute(ContextListener.LOG4J_CONTEXT_ATTRIBUTE, ctx);
+            created = true;
+            context.log("Created context for " + name + " using " + ctx.getClass().getClassLoader());
+        }
+    }
+
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+        throws IOException, ServletException {
+        LoggerContext ctx = (LoggerContext) context.getAttribute(ContextListener.LOG4J_CONTEXT_ATTRIBUTE);
+        if (ctx != null) {
+            ContextAnchor.threadContext.set(ctx);
+            try {
+                filterChain.doFilter(servletRequest, servletResponse);
+            } finally {
+                ContextAnchor.threadContext.remove();
+            }
+        } else {
+            filterChain.doFilter(servletRequest, servletResponse);
+        }
+    }
+
+    public void destroy() {
+        LoggerContext ctx = (LoggerContext) context.getAttribute(ContextListener.LOG4J_CONTEXT_ATTRIBUTE);
+        if (ctx != null && created) {
+            context.log("Removing context for " + name);
+            context.removeAttribute(ContextListener.LOG4J_CONTEXT_ATTRIBUTE);
+            if (selector != null) {
+                selector.removeContext(name);
+            }
+            ctx.shutdown();
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManager.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManager.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManager.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,44 @@
+/*
+ * 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.logging.log4j.core.jmx;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Log4jContextFactory;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.internal.StatusData;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.util.List;
+
+/**
+ * Preliminary implementation for testing with JBoss.
+ */
+public class Log4jManager {
+
+    public StatusLogger logger = StatusLogger.getLogger();
+
+    public List<LoggerContext> getLoggerContexts() {
+        Log4jContextFactory factory = (Log4jContextFactory) LogManager.getFactory();
+        ContextSelector selector = factory.getSelector();
+        return selector.getLoggerContexts();
+    }
+
+    public List<StatusData> getStatusData() {
+        return logger.getStatusData();
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManagerMBean.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManagerMBean.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManagerMBean.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManagerMBean.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,16 @@
+package org.apache.logging.log4j.core.jmx;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.internal.StatusData;
+
+import java.util.List;
+
+/**
+ *
+ */
+public interface Log4jManagerMBean {
+
+    public List<LoggerContext> getLoggerContexts();
+
+    public List<StatusData> getStatusData();
+}

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/SocketServer.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/SocketServer.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/SocketServer.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/SocketServer.java Mon Jul 18 00:49:07 2011
@@ -28,6 +28,7 @@ import org.xml.sax.InputSource;
 
 import java.io.BufferedReader;
 import java.io.EOFException;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -37,6 +38,7 @@ import java.io.OptionalDataException;
 import java.net.MalformedURLException;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.URI;
 import java.net.URL;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -190,11 +192,13 @@ public class SocketServer extends Abstra
         }
 
         @Override
-        public Configuration getConfiguration() {
+        public Configuration getConfiguration(String name, URI configLocation) {
             if (path != null && path.length() > 0) {
+                File file = null;
                 InputSource source = null;
                 try {
-                    FileInputStream is = new FileInputStream(path);
+                    file = new File(path);
+                    FileInputStream is = new FileInputStream(file);
                     source = new InputSource(is);
                     source.setSystemId(path);
                 } catch (FileNotFoundException ex) {
@@ -214,14 +218,14 @@ public class SocketServer extends Abstra
 
                 try {
                     if (source != null) {
-                        return new XMLConfiguration(source);
+                        return new XMLConfiguration(source, file);
                     }
                 } catch (Exception ex) {
                     // Ignore this error.
                 }
                 System.err.println("Unable to process configuration at " + path + ", using default.");
             }
-            return super.getConfiguration();
+            return super.getConfiguration(name, configLocation);
         }
     }
 }

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,56 @@
+/*
+ * 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.logging.log4j.core.selector;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.javaee.ContextAnchor;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ */
+public class BasicContextSelector implements ContextSelector {
+
+    private static LoggerContext context = new LoggerContext("Default");
+
+    private static StatusLogger logger = StatusLogger.getLogger();
+
+    public LoggerContext getContext(String FQCN, boolean currentContext) {
+
+        LoggerContext ctx = ContextAnchor.threadContext.get();
+        return ctx != null ? ctx : context;
+    }
+
+    public LoggerContext locateContext(String name, String configLocation) {
+        return context;
+    }
+
+    public void removeContext(LoggerContext context) {
+
+    }
+
+    public List<LoggerContext> getLoggerContexts() {
+        List<LoggerContext> list = new ArrayList<LoggerContext>();
+        list.add(context);
+        return Collections.unmodifiableList(list);
+    }
+
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,229 @@
+/*
+ * 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.logging.log4j.core.selector;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.helpers.Loader;
+import org.apache.logging.log4j.core.javaee.ContextAnchor;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * This ContextSelector chooses a LoggerContext based upon the ClassLoader of the caller. This allows Loggers
+ * assigned to static variables to be released along with the classes that own then. Other ContextSelectors
+ * will generally cause Loggers associated with classes loaded from different ClassLoaders to be co-mingled.
+ * This is a problem if, for example, a web application is undeployed as some of the Loggers being released may be
+ * associated with a Class in a parent ClassLoader, which will generally have negative consequences.
+ *
+ * The main downside to this ContextSelector is that Configuration is more challenging.
+ *
+ * This ContextSelector should not be used with a Servlet Filter such as the JNDIContextFilter.
+ */
+public class ClassLoaderContextSelector implements ContextSelector {
+
+    private static AtomicReference<LoggerContext> context = new AtomicReference<LoggerContext>();
+
+    private static PrivateSecurityManager securityManager;
+
+    private static Method getCallerClass;
+
+    private static StatusLogger logger = StatusLogger.getLogger();
+
+    private static ConcurrentMap<String, AtomicReference<WeakReference<LoggerContext>>> contextMap =
+        new ConcurrentHashMap<String, AtomicReference<WeakReference<LoggerContext>>>();
+
+
+    static {
+        setupCallerCheck();
+    }
+
+    public LoggerContext getContext(String fqcn, boolean currentContext) {
+
+        if (currentContext) {
+            LoggerContext ctx = ContextAnchor.threadContext.get();
+            if (ctx != null) {
+                return ctx;
+            }
+            return getDefault();
+        } else {
+            if (getCallerClass != null) {
+                try {
+                    Class clazz = Class.class;
+                    boolean next = false;
+                    for (int index = 2; clazz != null; ++index) {
+                        Object[] params = new Object[] {index};
+                        clazz = (Class) getCallerClass.invoke(null, params);
+                        if (clazz == null) {
+                            break;
+                        }
+                        if (clazz.getName().equals(fqcn)) {
+                            next = true;
+                            continue;
+                        }
+                        if (next) {
+                            break;
+                        }
+                    }
+                    if (clazz != null) {
+                        return locateContext(clazz.getClassLoader(), null);
+                    }
+                } catch (Exception ex) {
+                    // logger.debug("Unable to determine caller class via Sun Reflection", ex);
+                }
+            }
+
+            if (securityManager != null) {
+                Class clazz = securityManager.getCaller();
+                return locateContext(clazz.getClassLoader(), null);
+            }
+
+            Throwable t = new Throwable();
+            boolean next = false;
+            String name = null;
+            for (StackTraceElement element : t.getStackTrace()) {
+                if (element.getClassName().equals(fqcn)) {
+                    next = true;
+                    continue;
+                }
+                if (next) {
+                    name = element.getClassName();
+                    break;
+                }
+            }
+            if (name != null) {
+                try {
+                    return locateContext(Loader.loadClass(name).getClassLoader(), null);
+                } catch (ClassNotFoundException ex) {
+                    //System.out.println("Could not load class " + name);
+                }
+            }
+            LoggerContext lc = ContextAnchor.threadContext.get();
+            if (lc != null) {
+                return lc;
+            }
+            return getDefault();
+        }
+    }
+
+    public void removeContext(LoggerContext context) {
+
+        for (Map.Entry<String, AtomicReference<WeakReference<LoggerContext>>> entry : contextMap.entrySet()) {
+            LoggerContext ctx = entry.getValue().get().get();
+            if (ctx == context) {
+                contextMap.remove(entry.getKey());
+            }
+        }
+    }
+
+    public List<LoggerContext> getLoggerContexts() {
+        List<LoggerContext> list = new ArrayList<LoggerContext>();
+        Collection<AtomicReference<WeakReference<LoggerContext>>> coll = contextMap.values();
+        for (AtomicReference<WeakReference<LoggerContext>> ref : coll) {
+            LoggerContext ctx = ref.get().get();
+            if (ctx != null) {
+                list.add(ctx);
+            }
+        }
+        return Collections.unmodifiableList(list);
+    }
+
+    private LoggerContext locateContext(ClassLoader loader, String configLocation) {
+        String name = loader.toString();
+        AtomicReference<WeakReference<LoggerContext>> ref = contextMap.get(name);
+        if (ref == null) {
+            LoggerContext ctx = new LoggerContext(name, null, configLocation);
+            AtomicReference<WeakReference<LoggerContext>> r =
+                new AtomicReference<WeakReference<LoggerContext>>();
+            r.set(new WeakReference<LoggerContext>(ctx));
+            contextMap.putIfAbsent(loader.toString(), r);
+            ctx = contextMap.get(name).get().get();
+            return ctx;
+        } else {
+            WeakReference<LoggerContext> r = ref.get();
+            LoggerContext ctx = r.get();
+            if (ctx != null) {
+                return ctx;
+            }
+            ctx = new LoggerContext(name, null, configLocation);
+            ref.compareAndSet(r, new WeakReference<LoggerContext>(ctx));
+            return ctx;
+        }
+    }
+
+    private static void setupCallerCheck() {
+        try {
+            ClassLoader loader = Loader.getClassLoader();
+            Class clazz = loader.loadClass("sun.reflect.Reflection");
+            Method[] methods = clazz.getMethods();
+            for (Method method : methods) {
+                int modifier = method.getModifiers();
+                if (method.getName().equals("getCallerClass") && Modifier.isStatic(modifier)) {
+                    getCallerClass = method;
+                    break;
+                }
+            }
+        } catch (ClassNotFoundException cnfe) {
+            logger.debug("sun.reflect.Reflection is not installed");
+        }
+        try {
+            securityManager = new PrivateSecurityManager();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            logger.debug("Unable to install security manager", ex);
+        }
+    }
+
+    private LoggerContext getDefault() {
+        LoggerContext ctx = context.get();
+        if (ctx != null) {
+            return ctx;
+        }
+        context.compareAndSet(null, new LoggerContext("Default"));
+        return context.get();
+    }
+
+    private static class PrivateSecurityManager extends SecurityManager {
+
+        public Class getCaller() {
+            Class[] classes = getClassContext();
+            boolean next = false;
+            for (Class clazz : classes) {
+                if (clazz.getName().equals(LogManager.class.getName())) {
+                    next = true;
+                    continue;
+                }
+                if (next) {
+                    return clazz;
+                }
+            }
+            return null;
+        }
+    }
+
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,22 @@
+package org.apache.logging.log4j.core.selector;
+
+import org.apache.logging.log4j.core.LoggerContext;
+
+import java.util.List;
+
+/**
+ *
+ */
+public interface ContextSelector {
+
+    /**
+     * Return the LoggerContext.
+     * @param FQCN The fully qualified class name of the caller.
+     * @param currentContext If true returns the current Context, if false returns the Context appropriate
+     * for the caller if a more appropriate Context can be determined.
+     * @return The LoggerContext.
+     */
+    LoggerContext getContext(String FQCN, boolean currentContext);
+
+    List<LoggerContext> getLoggerContexts();
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/JNDIContextSelector.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/JNDIContextSelector.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/JNDIContextSelector.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/JNDIContextSelector.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,157 @@
+/*
+ * 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.logging.log4j.core.selector;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.helpers.Constants;
+import org.apache.logging.log4j.core.javaee.ContextAnchor;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * This class can be used to define a
+ * custom logger repository.  It makes use of the fact that in J2EE
+ * environments, each web-application is guaranteed to have its own JNDI
+ * context relative to the <code>java:comp/env</code> context. In EJBs, each
+ * enterprise bean (albeit not each application) has its own context relative
+ * to the <code>java:comp/env</code> context.  An <code>env-entry</code> in a
+ * deployment descriptor provides the information to the JNDI context.  Once the
+ * <code>env-entry</code> is set, a repository selector can query the JNDI
+ * application context to look up the value of the entry. The logging context of
+ * the web-application will depend on the value the env-entry.  The JNDI context
+ *  which is looked up by this class is
+ * <code>java:comp/env/log4j/context-name</code>.
+ *
+ * <p>Here is an example of an <code>env-entry<code>:
+ * <blockquote>
+ * <pre>
+ * &lt;env-entry&gt;
+ *   &lt;description&gt;JNDI logging context name for this app&lt;/description&gt;
+ *   &lt;env-entry-name&gt;log4j/context-name&lt;/env-entry-name&gt;
+ *   &lt;env-entry-value&gt;aDistinctiveLoggingContextName&lt;/env-entry-value&gt;
+ *   &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
+ * &lt;/env-entry&gt;
+ * </pre>
+ * </blockquote>
+ * </p>
+ *
+ * <p><em>If multiple applications use the same logging context name, then they
+ * will share the same logging context.</em>
+ * </p>
+ *
+ *<p>You can also specify the URL for this context's configuration resource.
+ * This repository selector (ContextJNDISelector) will use this resource
+ * to automatically configure the log4j repository.
+ *</p>
+ ** <blockquote>
+ * <pre>
+ * &lt;env-entry&gt;
+ *   &lt;description&gt;URL for configuring log4j context&lt;/description&gt;
+ *   &lt;env-entry-name&gt;log4j/configuration-resource&lt;/env-entry-name&gt;
+ *   &lt;env-entry-value&gt;urlOfConfigrationResource&lt;/env-entry-value&gt;
+ *   &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
+ * &lt;/env-entry&gt;
+ * </pre>
+ * </blockquote>
+ *
+ * <p>It usually good practice for configuration resources of distinct
+ * applications to have distinct names. However, if this is not possible
+ * Naming
+ * </p>
+ *
+ */
+public class JNDIContextSelector implements NamedContextSelector {
+
+    private static LoggerContext context = new LoggerContext("Default");
+
+    private static ConcurrentMap<String, LoggerContext> contextMap =
+        new ConcurrentHashMap<String, LoggerContext>();
+
+    private static StatusLogger logger = StatusLogger.getLogger();
+
+    public LoggerContext getContext(String FQCN, boolean currentContext) {
+
+        LoggerContext lc = ContextAnchor.threadContext.get();
+        if (lc != null) {
+            return lc;
+        }
+
+        String loggingContextName = null;
+
+        try {
+            Context ctx = new InitialContext();
+            loggingContextName = (String) lookup(ctx, Constants.JNDI_CONTEXT_NAME);
+        } catch (NamingException ne) {
+            logger.error("Unable to lookup " + Constants.JNDI_CONTEXT_NAME, ne);
+        }
+
+        return loggingContextName == null ? context : locateContext(loggingContextName, null);
+    }
+
+    public LoggerContext locateContext(String name, String configLocation) {
+        if (name == null) {
+            logger.error("A context name is required to locate a LoggerContext");
+            return null;
+        }
+        if (!contextMap.containsKey(name)) {
+            LoggerContext ctx = new LoggerContext(name, null, configLocation);
+            contextMap.putIfAbsent(name, ctx);
+        }
+        return contextMap.get(name);
+    }
+
+    public void removeContext(LoggerContext context) {
+
+        for (Map.Entry<String, LoggerContext> entry : contextMap.entrySet()) {
+            if (entry.getValue().equals(context)) {
+                contextMap.remove(entry.getKey());
+            }
+        }
+    }
+
+    public LoggerContext removeContext(String name) {
+        return contextMap.remove(name);
+    }
+
+    public List<LoggerContext> getLoggerContexts() {
+        List<LoggerContext> list = new ArrayList<LoggerContext>(contextMap.values());
+        return Collections.unmodifiableList(list);
+    }
+
+
+    protected static Object lookup(Context ctx, String name) throws NamingException {
+        if (ctx == null) {
+            return null;
+        }
+        try {
+            return ctx.lookup(name);
+        } catch(NameNotFoundException e) {
+            logger.error("Could not find name [" + name + "].");
+            throw e;
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/NamedContextSelector.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/NamedContextSelector.java?rev=1147720&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/NamedContextSelector.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/selector/NamedContextSelector.java Mon Jul 18 00:49:07 2011
@@ -0,0 +1,13 @@
+package org.apache.logging.log4j.core.selector;
+
+import org.apache.logging.log4j.core.LoggerContext;
+
+/**
+ *
+ */
+public interface NamedContextSelector extends ContextSelector {
+
+    LoggerContext locateContext(String name, String configLocation);
+
+    LoggerContext removeContext(String name);
+}

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/resources/META-INF/log4j-provider.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/resources/META-INF/log4j-provider.xml?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/resources/META-INF/log4j-provider.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/resources/META-INF/log4j-provider.xml Mon Jul 18 00:49:07 2011
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
 <properties>
-    <entry key="LoggerContextClass">org.apache.logging.log4j.core.LoggerContext</entry>
+    <entry key="LoggerContextFactory">org.apache.logging.log4j.core.Log4jContextFactory</entry>
     <entry key="Log4jAPIVersion">1.99.0</entry>
 </properties>
\ No newline at end of file

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/BasicConfigurationFactory.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/BasicConfigurationFactory.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/BasicConfigurationFactory.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/BasicConfigurationFactory.java Mon Jul 18 00:49:07 2011
@@ -22,12 +22,14 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 
+import java.net.URI;
+
 /**
  *
  */
 public class BasicConfigurationFactory extends ConfigurationFactory {
 
-    public Configuration getConfiguration() {
+    public Configuration getConfiguration(String name, URI configLocation) {
         return new BasicConfiguration();
     }
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java Mon Jul 18 00:49:07 2011
@@ -43,11 +43,12 @@ public class LoggerTest {
     private static final String CONFIG = "log4j-test2.xml";
     private static Configuration config;
     private static ListAppender app;
+    private static LoggerContext ctx;
 
     @BeforeClass
     public static void setupClass() {
         System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
-        LoggerContext ctx = (LoggerContext) LogManager.getContext();
+        ctx = (LoggerContext) LogManager.getContext(false);
         config = ctx.getConfiguration();
         for (Map.Entry<String, Appender> entry : config.getAppenders().entrySet()) {
             if (entry.getKey().equals("List")) {
@@ -60,7 +61,6 @@ public class LoggerTest {
     @AfterClass
     public static void cleanupClass() {
         System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-        LoggerContext ctx = (LoggerContext) LogManager.getContext();
         ctx.reconfigure();
         StatusLogger.getLogger().reset();
     }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/StrictXMLConfigTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/StrictXMLConfigTest.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/StrictXMLConfigTest.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/StrictXMLConfigTest.java Mon Jul 18 00:49:07 2011
@@ -44,11 +44,12 @@ public class StrictXMLConfigTest {
     private static final String CONFIG = "log4j-strict1.xml";
     private static Configuration config;
     private static ListAppender app;
+    private static LoggerContext ctx;
 
     @BeforeClass
     public static void setupClass() {
         System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
-        LoggerContext ctx = (LoggerContext) LogManager.getContext();
+        ctx = (LoggerContext) LogManager.getContext(false);
         config = ctx.getConfiguration();
         for (Map.Entry<String, Appender> entry : config.getAppenders().entrySet()) {
             if (entry.getKey().equals("List")) {
@@ -61,7 +62,6 @@ public class StrictXMLConfigTest {
     @AfterClass
     public static void cleanupClass() {
         System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-        LoggerContext ctx = (LoggerContext) LogManager.getContext();
         ctx.reconfigure();
         StatusLogger.getLogger().reset();
     }

Propchange: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Jul 18 00:49:07 2011
@@ -0,0 +1,3 @@
+*.iml
+.idea
+target

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/main/java/org/apache/logging/log4j/jcl/LogFactoryImpl.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/main/java/org/apache/logging/log4j/jcl/LogFactoryImpl.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/main/java/org/apache/logging/log4j/jcl/LogFactoryImpl.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/main/java/org/apache/logging/log4j/jcl/LogFactoryImpl.java Mon Jul 18 00:49:07 2011
@@ -23,6 +23,9 @@ import org.apache.logging.log4j.LogManag
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
 
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -31,21 +34,18 @@ import java.util.concurrent.ConcurrentMa
  */
 public class LogFactoryImpl extends LogFactory {
 
-    private static LoggerContext context = LogManager.getContext();
-
-    private ConcurrentMap<String, Log> loggers = new ConcurrentHashMap<String, Log>();
+    private final Map<LoggerContext, ConcurrentMap<String, Log>> contextMap =
+        Collections.synchronizedMap(new WeakHashMap<LoggerContext, ConcurrentMap<String, Log>>());
 
     private ConcurrentMap<String, Object> attributes = new ConcurrentHashMap<String, Object>();
 
-    public static LoggerContext getContext() {
-        return context;
-    }
-
     public Log getInstance(String name) throws LogConfigurationException {
+        LoggerContext context = PrivateManager.getContext();
+        ConcurrentMap<String, Log> loggers = getLoggersMap();
         if (loggers.containsKey(name)) {
             return loggers.get(name);
         }
-        org.apache.logging.log4j.Logger logger = context.getLogger(name);
+        org.apache.logging.log4j.Logger logger = PrivateManager.getLogger(name);
         if (logger instanceof AbstractLogger) {
             loggers.putIfAbsent(name, new Log4JLog((AbstractLogger) logger, name));
             return loggers.get(name);
@@ -53,6 +53,18 @@ public class LogFactoryImpl extends LogF
         throw new LogConfigurationException("SLF4J Adapter requires base logging system to extend Log4J AbstractLogger");
     }
 
+    private ConcurrentMap<String, Log> getLoggersMap() {
+        LoggerContext context = PrivateManager.getContext();
+        synchronized (contextMap) {
+            ConcurrentMap<String, Log> map = contextMap.get(context);
+            if (map == null) {
+                map = new ConcurrentHashMap<String, Log>();
+                contextMap.put(context, map);
+            }
+            return map;
+        }
+    }
+
     @Override
     public Object getAttribute(String name) {
         return attributes.get(name);
@@ -74,7 +86,7 @@ public class LogFactoryImpl extends LogF
      */
     @Override
     public void release() {
-        loggers.clear();
+        getLoggersMap().clear();
     }
 
     @Override
@@ -87,6 +99,16 @@ public class LogFactoryImpl extends LogF
         attributes.put(name, value);
     }
 
+    private static class PrivateManager extends LogManager {
+        private static final String FQCN = LogFactory.class.getName();
+
+        public static LoggerContext getContext() {
+            return getContext(FQCN, false);
+        }
 
+        public static org.apache.logging.log4j.Logger getLogger(String name) {
+            return getLogger(FQCN, name);
+        }
+    }
 
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java Mon Jul 18 00:49:07 2011
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.jcl;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.ListAppender;
@@ -45,14 +46,14 @@ public class LoggerTest {
     @BeforeClass
     public static void setupClass() {
         System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
-        LoggerContext ctx = (LoggerContext) LogFactoryImpl.getContext();
+        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
         Configuration config = ctx.getConfiguration();
     }
 
     @AfterClass
     public static void cleanupClass() {
         System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-        LoggerContext ctx = (LoggerContext) LogFactoryImpl.getContext();
+        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
         ctx.reconfigure();
         StatusLogger.getLogger().reset();
     }
@@ -70,7 +71,7 @@ public class LoggerTest {
     }
 
     private void verify(String name, String expected) {
-        LoggerContext ctx = (LoggerContext) LogFactoryImpl.getContext();
+        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
         Map<String, Appender> list = ctx.getConfiguration().getAppenders();
         Appender listApp = list.get(name);
         assertNotNull("Missing Appender", listApp);

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/pom.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/pom.xml?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/pom.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/pom.xml Mon Jul 18 00:49:07 2011
@@ -116,13 +116,29 @@
         <artifactId>log4j2-core</artifactId>
         <version>${project.version}</version>
       </dependency>
-       <dependency>
+      <dependency>
         <groupId>org.apache.logging</groupId>
         <artifactId>log4j2-core</artifactId>
         <version>${project.version}</version>
         <type>test-jar</type>
       </dependency>
       <dependency>
+        <groupId>org.apache.logging</groupId>
+        <artifactId>slf4j-impl</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging</groupId>
+        <artifactId>log4j2-jcl</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+ 	    <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>servlet-api</artifactId>
+        <version>2.4</version>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.3.1</version>

Propchange: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Jul 18 00:49:07 2011
@@ -0,0 +1,3 @@
+*.iml
+.idea
+target

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/main/java/org/slf4j/helpers/Log4JLoggerFactory.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/main/java/org/slf4j/helpers/Log4JLoggerFactory.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/main/java/org/slf4j/helpers/Log4JLoggerFactory.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/main/java/org/slf4j/helpers/Log4JLoggerFactory.java Mon Jul 18 00:49:07 2011
@@ -22,8 +22,12 @@ import org.apache.logging.log4j.spi.Logg
 import org.apache.logging.slf4j.SLF4JLoggingException;
 import org.slf4j.ILoggerFactory;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.slf4j.impl.SLF4JLogger;
 
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -31,16 +35,15 @@ import java.util.concurrent.ConcurrentMa
  *
  */
 public class Log4JLoggerFactory implements ILoggerFactory {
+    private final Map<LoggerContext, ConcurrentMap<String, Logger>> contextMap =
+        Collections.synchronizedMap(new WeakHashMap<LoggerContext, ConcurrentMap<String, Logger>>());
 
-    private static LoggerContext context = LogManager.getContext();
-
-    private ConcurrentMap<String, Logger> loggers = new ConcurrentHashMap<String, Logger>();
-
-    public static LoggerContext getContext() {
-        return context;
-    }
+    private static final String FQCN = Log4JLoggerFactory.class.getName();
+    private static final String PACKAGE = "org.slf4j";
 
     public Logger getLogger(String name) {
+        LoggerContext context = getContext();
+        ConcurrentMap<String, Logger> loggers = getLoggersMap(context);
         if (loggers.containsKey(name)) {
             return loggers.get(name);
         }
@@ -51,4 +54,53 @@ public class Log4JLoggerFactory implemen
         }
         throw new SLF4JLoggingException("SLF4J Adapter requires base logging system to extend Log4J AbstractLogger");
     }
+
+    private ConcurrentMap<String, Logger> getLoggersMap(LoggerContext context) {
+        synchronized (contextMap) {
+            ConcurrentMap<String, Logger> map = contextMap.get(context);
+            if (map == null) {
+                map = new ConcurrentHashMap<String, Logger>();
+                contextMap.put(context, map);
+            }
+            return map;
+        }
+    }
+    private LoggerContext getContext() {
+        Throwable t = new Throwable();
+        boolean next = false;
+        boolean pkg = false;
+        String fqcn = LoggerFactory.class.getName();
+        for (StackTraceElement element : t.getStackTrace()) {
+            if (FQCN.equals(element.getClassName())) {
+                next = true;
+                continue;
+            }
+            if (next && element.getClassName().startsWith(PACKAGE)) {
+                fqcn = element.getClassName();
+                pkg = true;
+                continue;
+            }
+            if (pkg) {
+                break;
+            }
+        }
+        return PrivateManager.getContext(fqcn);
+    }
+
+    private static class PrivateManager extends LogManager {
+        private static final String FQCN = LoggerFactory.class.getName();
+
+        public static LoggerContext getContext() {
+            return getContext(FQCN, false);
+        }
+
+        public static LoggerContext getContext(String fqcn) {
+            return getContext(fqcn, false);
+        }
+
+        public static org.apache.logging.log4j.Logger getLogger(String name) {
+            return getLogger(FQCN, name);
+        }
+    }
+
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java?rev=1147720&r1=1147719&r2=1147720&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java Mon Jul 18 00:49:07 2011
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.slf4j;
 
+import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.ListAppender;
 import org.apache.logging.log4j.core.config.Configuration;
@@ -50,18 +50,18 @@ import static org.junit.Assert.assertTru
 public class LoggerTest {
 
     private static final String CONFIG = "log4j-test1.xml";
+    private static LoggerContext ctx;
 
     @BeforeClass
     public static void setupClass() {
         System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
-        LoggerContext ctx = (LoggerContext) Log4JLoggerFactory.getContext();
+        ctx = (LoggerContext) LogManager.getContext(false);
         Configuration config = ctx.getConfiguration();
     }
 
     @AfterClass
     public static void cleanupClass() {
         System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-        LoggerContext ctx = (LoggerContext) Log4JLoggerFactory.getContext();
         ctx.reconfigure();
         StatusLogger.getLogger().reset();
     }
@@ -143,7 +143,7 @@ public class LoggerTest {
     }
 
     private void verify(String name, String expected) {
-        LoggerContext ctx = (LoggerContext) Log4JLoggerFactory.getContext();
+        //LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
         Map<String, Appender> list = ctx.getConfiguration().getAppenders();
         Appender listApp = list.get(name);
         assertNotNull("Missing Appender", listApp);



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Mime
View raw message