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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 9b628088307bab42a06c78f30641a140d954b376
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Thu Dec 30 13:14:59 2021 -0500

    Log4j 1.2 bridge interface org.apache.log4j.spi.RendererSupport was in
    the wrong package and incomplete.
    
    Log4j 1.2 bridge interfaces missing from package org.apache.log4j.spi:
    ThrowableRenderer, ThrowableRendererSupport, TriggeringEventEvaluator.
    
    Log4j 1.2 bridge missing class RendererMap.
---
 .../src/main/java/org/apache/log4j/Category.java   |  49 ++++--
 .../src/main/java/org/apache/log4j/LogManager.java |  12 +-
 .../java/org/apache/log4j/or/DefaultRenderer.java  |  40 +++++
 .../main/java/org/apache/log4j/or/RendererMap.java | 179 +++++++++++++++++++++
 .../apache/log4j/{or => spi}/RendererSupport.java  |  29 ++--
 .../org/apache/log4j/spi/ThrowableRenderer.java    |  34 ++++
 .../apache/log4j/spi/ThrowableRendererSupport.java |  38 +++++
 .../apache/log4j/spi/TriggeringEventEvaluator.java |  40 +++++
 8 files changed, 396 insertions(+), 25 deletions(-)

diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java 
b/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java
index ef913ae..8438243 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java
@@ -26,22 +26,22 @@ import java.util.concurrent.ConcurrentMap;
 import org.apache.log4j.helpers.NullEnumeration;
 import org.apache.log4j.legacy.core.CategoryUtil;
 import org.apache.log4j.or.ObjectRenderer;
-import org.apache.log4j.or.RendererSupport;
+import org.apache.log4j.or.RendererMap;
 import org.apache.log4j.spi.AppenderAttachable;
 import org.apache.log4j.spi.LoggerFactory;
 import org.apache.log4j.spi.LoggerRepository;
 import org.apache.log4j.spi.LoggingEvent;
-import org.apache.logging.log4j.message.MapMessage;
-import org.apache.logging.log4j.message.SimpleMessage;
-import org.apache.logging.log4j.spi.ExtendedLogger;
-import org.apache.logging.log4j.spi.LoggerContext;
+import org.apache.log4j.spi.RendererSupport;
 import org.apache.logging.log4j.message.LocalizedMessage;
+import org.apache.logging.log4j.message.MapMessage;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ObjectMessage;
+import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.spi.AbstractLoggerAdapter;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.util.Strings;
 
-
 /**
  * Implementation of the Category class for compatibility, despite it having 
been deprecated a long, long time ago.
  */
@@ -56,7 +56,7 @@ public class Category implements AppenderAttachable {
 
     private static final boolean isCoreAvailable;
 
-    private final Map<Class<?>, ObjectRenderer> rendererMap;
+    private final RendererMap rendererMap;
 
     static {
         boolean available;
@@ -76,14 +76,18 @@ public class Category implements AppenderAttachable {
 
     private final org.apache.logging.log4j.Logger logger;
 
+    /** Categories need to know what Hierarchy they are in. */
+    protected LoggerRepository repository;
+
     /**
      * Constructor used by Logger to specify a LoggerContext.
      * @param context The LoggerContext.
      * @param name The name of the Logger.
      */
     protected Category(final LoggerContext context, final String name) {
-        this.logger = context.getLogger(name);
-        rendererMap = ((RendererSupport) 
LogManager.getLoggerRepository()).getRendererMap();
+        logger = context.getLogger(name);
+        repository = LogManager.getLoggerRepository();
+        rendererMap = ((RendererSupport) repository).getRendererMap();
     }
 
     /**
@@ -228,6 +232,26 @@ public class Category implements AppenderAttachable {
         }
     }
 
+    /**
+     * Gets the the {@link LoggerRepository} where this <code>Category</code> 
instance is attached.
+     * 
+     * @deprecated Please use {@link #getLoggerRepository()} instead.
+     * @since 1.1
+     */
+    @Deprecated
+    public LoggerRepository getHierarchy() {
+        return repository;
+    }
+
+    /**
+     * Gets the the {@link LoggerRepository} where this <code>Category</code> 
is attached.
+     * 
+     * @since 1.2
+     */
+    public LoggerRepository getLoggerRepository() {
+        return repository;
+    }
+
     public final Priority getChainedPriority() {
         return getEffectiveLevel();
     }
@@ -444,6 +468,13 @@ public class Category implements AppenderAttachable {
         }
     }
 
+    /**
+     * Only the Hiearchy class can set the hiearchy of a category. Default 
package access is MANDATORY here.
+     */
+    final void setHierarchy(LoggerRepository repository) {
+        this.repository = repository;
+    }
+
     public void setResourceBundle(final ResourceBundle bundle) {
         this.bundle = bundle;
     }
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java 
b/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java
index d7d4018..5ef657e 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java
@@ -23,10 +23,11 @@ import java.util.Map;
 import org.apache.log4j.helpers.NullEnumeration;
 import org.apache.log4j.legacy.core.ContextUtil;
 import org.apache.log4j.or.ObjectRenderer;
-import org.apache.log4j.or.RendererSupport;
+import org.apache.log4j.or.RendererMap;
 import org.apache.log4j.spi.HierarchyEventListener;
 import org.apache.log4j.spi.LoggerFactory;
 import org.apache.log4j.spi.LoggerRepository;
+import org.apache.log4j.spi.RendererSupport;
 import org.apache.log4j.spi.RepositorySelector;
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.util.Strings;
@@ -149,10 +150,10 @@ public final class LogManager {
      */
     private static class Repository implements LoggerRepository, 
RendererSupport {
 
-        private final Map<Class<?>, ObjectRenderer> rendererMap = new 
HashMap<>();
+        private final RendererMap rendererMap = new RendererMap();
 
         @Override
-        public Map<Class<?>, ObjectRenderer> getRendererMap() {
+        public RendererMap getRendererMap() {
             return rendererMap;
         }
 
@@ -229,6 +230,11 @@ public final class LogManager {
         @Override
         public void resetConfiguration() {
         }
+
+        @Override
+        public void setRenderer(Class renderedClass, ObjectRenderer renderer) {
+            rendererMap.put(renderedClass, renderer);
+        }
     }
 
     /**
diff --git 
a/log4j-1.2-api/src/main/java/org/apache/log4j/or/DefaultRenderer.java 
b/log4j-1.2-api/src/main/java/org/apache/log4j/or/DefaultRenderer.java
new file mode 100644
index 0000000..e8f6321
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/or/DefaultRenderer.java
@@ -0,0 +1,40 @@
+/*
+ * 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.log4j.or;
+
+/**
+ * The default ObjectRenderer renders objects by calling their {@code 
toString()} method.
+ * 
+ * @since 1.0
+ */
+class DefaultRenderer implements ObjectRenderer {
+
+    DefaultRenderer() {
+    }
+
+    /**
+     * Render the object passed as parameter by calling its {@code toString()} 
method.
+     */
+    public String doRender(final Object o) {
+        try {
+            return o.toString();
+        } catch (Exception ex) {
+            return ex.toString();
+        }
+    }
+}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/or/RendererMap.java 
b/log4j-1.2-api/src/main/java/org/apache/log4j/or/RendererMap.java
new file mode 100644
index 0000000..b70b1a5
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/or/RendererMap.java
@@ -0,0 +1,179 @@
+/*
+ * 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.log4j.or;
+
+import java.util.Hashtable;
+
+import org.apache.log4j.helpers.OptionConverter;
+import org.apache.log4j.spi.RendererSupport;
+import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * Map class objects to an {@link ObjectRenderer}.
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+ * @since version 1.0
+ */
+public class RendererMap {
+
+    Hashtable map;
+
+    static ObjectRenderer defaultRenderer = new DefaultRenderer();
+
+    public RendererMap() {
+        map = new Hashtable();
+    }
+
+    /**
+     * Add a renderer to a hierarchy passed as parameter.
+     */
+    static public void addRenderer(RendererSupport repository, String 
renderedClassName, String renderingClassName) {
+        StatusLogger.getLogger().debug("Rendering class: [" + 
renderingClassName + "], Rendered class: [" + renderedClassName + "].");
+        ObjectRenderer renderer = (ObjectRenderer) 
OptionConverter.instantiateByClassName(renderingClassName, 
ObjectRenderer.class, null);
+        if (renderer == null) {
+            StatusLogger.getLogger().error("Could not instantiate renderer [" 
+ renderingClassName + "].");
+            return;
+        }
+        try {
+            Class renderedClass = Loader.loadClass(renderedClassName);
+            repository.setRenderer(renderedClass, renderer);
+        } catch (ClassNotFoundException e) {
+            StatusLogger.getLogger().error("Could not find class [" + 
renderedClassName + "].", e);
+        }
+    }
+
+    /**
+     * Find the appropriate renderer for the class type of the <code>o</code> 
parameter. This is accomplished by calling the
+     * {@link #get(Class)} method. Once a renderer is found, it is applied on 
the object <code>o</code> and the result is
+     * returned as a {@link String}.
+     */
+    public String findAndRender(Object o) {
+        if (o == null)
+            return null;
+        else
+            return get(o.getClass()).doRender(o);
+    }
+
+    /**
+     * Syntactic sugar method that calls {@link #get(Class)} with the class of 
the object parameter.
+     */
+    public ObjectRenderer get(Object o) {
+        if (o == null)
+            return null;
+        else
+            return get(o.getClass());
+    }
+
+    /**
+     * Search the parents of <code>clazz</code> for a renderer. The renderer 
closest in the hierarchy will be returned. If
+     * no renderers could be found, then the default renderer is returned.
+     * 
+     * <p>
+     * The search first looks for a renderer configured for 
<code>clazz</code>. If a renderer could not be found, then the
+     * search continues by looking at all the interfaces implemented by 
<code>clazz</code> including the super-interfaces of
+     * each interface. If a renderer cannot be found, then the search looks 
for a renderer defined for the parent
+     * (superclass) of <code>clazz</code>. If that fails, then all the 
interfaces implemented by the parent of
+     * <code>clazz</code> are searched and so on.
+     * 
+     * <p>
+     * For example, if A0, A1, A2 are classes and X0, X1, X2, Y0, Y1 are 
interfaces where A2 extends A1 which in turn
+     * extends A0 and similarly X2 extends X1 which extends X0 and Y1 extends 
Y0. Let us also assume that A1 implements the
+     * Y0 interface and that A2 implements the X2 interface.
+     * 
+     * <p>
+     * The table below shows the results returned by the 
<code>get(A2.class)</code> method depending on the renderers added
+     * to the map.
+     * 
+     * <p>
+     * <table border="1">
+     * <tr>
+     * <th>Added renderers</th>
+     * <th>Value returned by <code>get(A2.class)</code></th>
+     * 
+     * <tr>
+     * <td><code>A0Renderer</code>
+     * <td align="center"><code>A0Renderer</code>
+     * 
+     * <tr>
+     * <td><code>A0Renderer, A1Renderer</code>
+     * <td align="center"><code>A1Renderer</code>
+     * 
+     * <tr>
+     * <td><code>X0Renderer</code>
+     * <td align="center"><code>X0Renderer</code>
+     * 
+     * <tr>
+     * <td><code>A1Renderer, X0Renderer</code>
+     * <td align="center"><code>X0Renderer</code>
+     * 
+     * </table>
+     * 
+     * <p>
+     * This search algorithm is not the most natural, although it is 
particularly easy to implement. Future log4j versions
+     * <em>may</em> implement a more intuitive search algorithm. However, the 
present algorithm should be acceptable in the
+     * vast majority of circumstances.
+     * 
+     */
+    public ObjectRenderer get(Class clazz) {
+        // System.out.println("\nget: "+clazz);
+        ObjectRenderer r = null;
+        for (Class c = clazz; c != null; c = c.getSuperclass()) {
+            // System.out.println("Searching for class: "+c);
+            r = (ObjectRenderer) map.get(c);
+            if (r != null) {
+                return r;
+            }
+            r = searchInterfaces(c);
+            if (r != null)
+                return r;
+        }
+        return defaultRenderer;
+    }
+
+    ObjectRenderer searchInterfaces(Class c) {
+        // System.out.println("Searching interfaces of class: "+c);
+
+        ObjectRenderer r = (ObjectRenderer) map.get(c);
+        if (r != null) {
+            return r;
+        }
+        Class[] ia = c.getInterfaces();
+        for (int i = 0; i < ia.length; i++) {
+            r = searchInterfaces(ia[i]);
+            if (r != null)
+                return r;
+        }
+        return null;
+    }
+
+    public ObjectRenderer getDefaultRenderer() {
+        return defaultRenderer;
+    }
+
+    public void clear() {
+        map.clear();
+    }
+
+    /**
+     * Register an {@link ObjectRenderer} for <code>clazz</code>.
+     */
+    public void put(Class clazz, ObjectRenderer or) {
+        map.put(clazz, or);
+    }
+}
diff --git 
a/log4j-1.2-api/src/main/java/org/apache/log4j/or/RendererSupport.java 
b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/RendererSupport.java
similarity index 50%
rename from log4j-1.2-api/src/main/java/org/apache/log4j/or/RendererSupport.java
rename to log4j-1.2-api/src/main/java/org/apache/log4j/spi/RendererSupport.java
index 9b8728d..0a0b740 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/or/RendererSupport.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/RendererSupport.java
@@ -1,26 +1,29 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
+ * 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 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
- *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-package org.apache.log4j.or;
 
-import java.util.Map;
+package org.apache.log4j.spi;
+
+import org.apache.log4j.or.ObjectRenderer;
+import org.apache.log4j.or.RendererMap;
 
-/**
- * Interface that indicates the Renderer Map is available. This interface 
differs
- */
 public interface RendererSupport {
-    Map<Class<?>, ObjectRenderer> getRendererMap();
+
+    public RendererMap getRendererMap();
+
+    public void setRenderer(Class renderedClass, ObjectRenderer renderer);
+
 }
diff --git 
a/log4j-1.2-api/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java 
b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java
new file mode 100644
index 0000000..e2e87a1
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java
@@ -0,0 +1,34 @@
+/*
+ * 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.log4j.spi;
+
+/**
+ * Implemented by classes that render instances of java.lang.Throwable 
(exceptions and errors) into a string
+ * representation.
+ *
+ * @since 1.2.16
+ */
+public interface ThrowableRenderer {
+
+    /**
+     * Render Throwable.
+     * 
+     * @param t throwable, may not be null.
+     * @return String representation.
+     */
+    public String[] doRender(Throwable t);
+}
diff --git 
a/log4j-1.2-api/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
 
b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
new file mode 100644
index 0000000..37b17e0
--- /dev/null
+++ 
b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
@@ -0,0 +1,38 @@
+/*
+ * 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.log4j.spi;
+
+/**
+ * Implemented by logger repositories that support configurable rendering of 
Throwables.
+ *
+ * @since 1.2.16
+ */
+public interface ThrowableRendererSupport {
+    /**
+     * Get throwable renderer.
+     * 
+     * @return throwable renderer, may be null.
+     */
+    ThrowableRenderer getThrowableRenderer();
+
+    /**
+     * Set throwable renderer.
+     * 
+     * @param renderer renderer, may be null.
+     */
+    void setThrowableRenderer(ThrowableRenderer renderer);
+}
diff --git 
a/log4j-1.2-api/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java
 
b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java
new file mode 100644
index 0000000..96e86af
--- /dev/null
+++ 
b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.log4j.spi;
+
+/**
+ * Implementors decide when to perform an appender specific action.
+ * 
+ * <p>
+ * For example, the {@code org.apache.log4j.net.SMTPAppender} sends an email 
when the
+ * {@link #isTriggeringEvent(LoggingEvent)} method returns {@code true} and 
adds the event to an internal buffer when
+ * the returned result is {@code false}.
+ * </p>
+ * 
+ * @since version 1.0
+ */
+public interface TriggeringEventEvaluator {
+
+    /**
+     * Tests if this the triggering event.
+     * 
+     * @param event The vent to test.
+     * @return Whether this the triggering event.
+     */
+    public boolean isTriggeringEvent(LoggingEvent event);
+}

Reply via email to