You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2021/12/30 18:17:43 UTC
[logging-log4j2] 01/02: Log4j 1.2 bridge interface org.apache.log4j.spi.RendererSupport was in the wrong package and incomplete.
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 <ga...@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ülcü
+ * @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);
+}