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 2022/02/20 16:31:09 UTC
[logging-log4j2] 02/02: Fill basic support in DOMConfigurator except for DOM-based APIs.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 087a6fcf434e047844cc6bede1795ff8d7fb6abc
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Feb 20 11:31:04 2022 -0500
Fill basic support in DOMConfigurator except for DOM-based APIs.
Some internals mustn't be quite right, see @Disabled failing tests in
DOMTestCase.
---
log4j-1.2-api/pom.xml | 7 +
.../java/org/apache/log4j/xml/DOMConfigurator.java | 113 ++++-
.../java/org/apache/log4j/xml/XMLWatchdog.java | 37 ++
.../org/apache/log4j/xml/XmlConfiguration.java | 6 +-
.../log4j/util/AbsoluteDateAndTimeFilter.java | 36 ++
.../org/apache/log4j/util/AbsoluteTimeFilter.java | 35 ++
.../java/org/apache/log4j/util/ControlFilter.java | 47 ++
.../log4j/util/EnhancedJunitTestRunnerFilter.java | 58 +++
.../log4j/util/EnhancedLineNumberFilter.java | 42 ++
.../test/java/org/apache/log4j/util/Filter.java | 35 ++
.../java/org/apache/log4j/util/ISO8601Filter.java | 35 ++
.../apache/log4j/util/JunitTestRunnerFilter.java | 54 +++
.../org/apache/log4j/util/LineNumberFilter.java | 36 ++
.../org/apache/log4j/util/RelativeTimeFilter.java | 36 ++
.../apache/log4j/util/SerializationTestHelper.java | 112 +++--
.../org/apache/log4j/util/SunReflectFilter.java | 43 ++
.../java/org/apache/log4j/util/Transformer.java | 59 +++
.../log4j/util/UnexpectedFormatException.java | 27 ++
.../apache/log4j/util/XMLLineAttributeFilter.java | 36 ++
.../org/apache/log4j/util/XMLTimestampFilter.java | 33 ++
.../java/org/apache/log4j/xml/DOMTestCase.java | 473 +++++++++++++++++++++
.../log4j1-1.2.17/input/xml/DOMTestCase1.xml | 4 +-
22 files changed, 1280 insertions(+), 84 deletions(-)
diff --git a/log4j-1.2-api/pom.xml b/log4j-1.2-api/pom.xml
index 804fb92..f970643 100644
--- a/log4j-1.2-api/pom.xml
+++ b/log4j-1.2-api/pom.xml
@@ -104,6 +104,13 @@
<artifactId>jackson-dataformat-xml</artifactId>
<scope>test</scope>
</dependency>
+ <!-- 1.2 tests -->
+ <dependency>
+ <groupId>oro</groupId>
+ <artifactId>oro</artifactId>
+ <version>2.0.8</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
index 494208e..e751653 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
@@ -16,64 +16,141 @@
*/
package org.apache.log4j.xml;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.io.StringWriter;
import java.net.URL;
+import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Properties;
import javax.xml.parsers.FactoryConfigurationError;
+import org.apache.log4j.LogManager;
import org.apache.log4j.config.PropertySetter;
+import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggerRepository;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.util.IOUtils;
import org.w3c.dom.Element;
/**
+ * Use this class to initialize the log4j environment using a DOM tree.
*
+ * <p>
+ * The DTD is specified in <a href="doc-files/log4j.dtd"><b>log4j.dtd</b></a>.
+ *
+ * <p>
+ * Sometimes it is useful to see how log4j is reading configuration files. You can enable log4j internal logging by
+ * defining the <b>log4j.debug</b> variable on the java command line. Alternatively, set the <code>debug</code>
+ * attribute in the <code>log4j:configuration</code> element. As in
+ *
+ * <pre>
+<log4j:configuration <b>debug="true"</b> xmlns:log4j="http://jakarta.apache.org/log4j/">
+...
+</log4j:configuration>
+ * </pre>
+ *
+ * <p>
+ * There are sample XML files included in the package.
+ *
+ * @since 0.8.3
*/
public class DOMConfigurator {
- public void doConfigure(final String filename, final LoggerRepository repository) {
+ public static void configure(final Element element) {
}
- public void doConfigure(final URL url, final LoggerRepository repository) {
+ public static void configure(final String fileName) throws FactoryConfigurationError {
+ final Path path = Paths.get(fileName);
+ try (final InputStream inputStream = Files.newInputStream(path)) {
+ final ConfigurationSource source = new ConfigurationSource(inputStream, path);
+ final LoggerContext context = (LoggerContext) org.apache.logging.log4j.LogManager.getContext(false);
+ Configuration configuration;
+ configuration = new XmlConfigurationFactory().getConfiguration(context, source);
+ LogManager.getRootLogger().removeAllAppenders();
+ Configurator.reconfigure(configuration);
+ } catch (final IOException e) {
+ throw new FactoryConfigurationError(e);
+ }
}
- public void doConfigure(final InputStream inputStream, final LoggerRepository repository)
- throws FactoryConfigurationError {
+ public static void configure(final URL url) throws FactoryConfigurationError {
+ new DOMConfigurator().doConfigure(url, LogManager.getLoggerRepository());
}
- public void doConfigure(final Reader reader, final LoggerRepository repository)
- throws FactoryConfigurationError {
+ public static void configureAndWatch(final String fileName) {
+ // TODO Watch
+ configure(fileName);
}
- public void doConfigure(final Element element, final LoggerRepository repository) {
+ public static void configureAndWatch(final String fileName, final long delay) {
+ XMLWatchdog xdog = new XMLWatchdog(fileName);
+ xdog.setDelay(delay);
+ xdog.start();
}
- public static void configure(final Element element) {
+ public static Object parseElement(final Element element, final Properties props, @SuppressWarnings("rawtypes") final Class expectedClass) {
+ return null;
}
- public static void configureAndWatch(final String configFilename) {
+ public static void setParameter(final Element elem, final PropertySetter propSetter, final Properties props) {
+
}
- public static void configureAndWatch(final String configFilename, final long delay) {
+ public static String subst(final String value, final Properties props) {
+ return OptionConverter.substVars(value, props);
}
- public static void configure(final String filename) throws FactoryConfigurationError {
+ private void doConfigure(final ConfigurationSource source) {
+ final LoggerContext context = (LoggerContext) org.apache.logging.log4j.LogManager.getContext(false);
+ Configuration configuration;
+ configuration = new XmlConfigurationFactory().getConfiguration(context, source);
+ Configurator.reconfigure(configuration);
}
- public static void configure(final URL url) throws FactoryConfigurationError {
+ public void doConfigure(final Element element, final LoggerRepository repository) {
}
- public static String subst(final String value, final Properties props) {
- return value;
+ public void doConfigure(final InputStream inputStream, final LoggerRepository repository) throws FactoryConfigurationError {
+ try {
+ doConfigure(new ConfigurationSource(inputStream));
+ } catch (final IOException e) {
+ throw new FactoryConfigurationError(e);
+ }
}
- public static void setParameter(final Element elem, final PropertySetter propSetter, final Properties props) {
+ public void doConfigure(final Reader reader, final LoggerRepository repository) throws FactoryConfigurationError {
+ try {
+ final StringWriter sw = new StringWriter();
+ IOUtils.copy(reader, sw);
+ doConfigure(new ConfigurationSource(new ByteArrayInputStream(sw.toString().getBytes(StandardCharsets.UTF_8))));
+ } catch (final IOException e) {
+ throw new FactoryConfigurationError(e);
+ }
+ }
+ public void doConfigure(final String fileName, final LoggerRepository repository) {
+ configure(fileName);
}
- public static Object parseElement(final Element element, final Properties props,
- @SuppressWarnings("rawtypes") final Class expectedClass) {
- return null;
+ public void doConfigure(final URL url, final LoggerRepository repository) {
+ try {
+ final URLConnection connection = url.openConnection();
+ connection.setUseCaches(false); // Otherwise, a "jar:" URL file remains open after the stream is closed.
+ try (InputStream inputStream = connection.getInputStream()) {
+ doConfigure(new ConfigurationSource(inputStream, url));
+ }
+ } catch (final IOException e) {
+ throw new FactoryConfigurationError(e);
+ }
}
}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XMLWatchdog.java b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XMLWatchdog.java
new file mode 100644
index 0000000..753bd8b
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XMLWatchdog.java
@@ -0,0 +1,37 @@
+/*
+ * 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.xml;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.helpers.FileWatchdog;
+import org.apache.log4j.spi.LoggerRepository;
+
+class XMLWatchdog extends FileWatchdog {
+
+ XMLWatchdog(final String filename) {
+ super(filename);
+ }
+
+ /**
+ * Calls {@link DOMConfigurator#doConfigure(String, LoggerRepository)} with the <code>filename</code> to reconfigure Log4j.
+ */
+ @Override
+ public void doOnChange() {
+ new DOMConfigurator().doConfigure(filename, LogManager.getLoggerRepository());
+ }
+}
\ No newline at end of file
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java
index 3fe95d4..d604310 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java
@@ -751,14 +751,14 @@ public class XmlConfiguration extends Log4j1Configuration {
parseRoot(currentElement);
break;
case RENDERER_TAG:
- LOGGER.warn("Renderers are not supported by Log4j 2 and will be ignored.");
+ LOGGER.warn("Log4j 1 renderers are not supported by Log4j 2 and will be ignored.");
break;
case THROWABLE_RENDERER_TAG:
- LOGGER.warn("Throwable Renderers are not supported by Log4j 2 and will be ignored.");
+ LOGGER.warn("Log4j 1 throwable renderers are not supported by Log4j 2 and will be ignored.");
break;
case CATEGORY_FACTORY_TAG:
case LOGGER_FACTORY_TAG:
- LOGGER.warn("Log4j 1 Logger factories are not supported by Log4j 2 and will be ignored.");
+ LOGGER.warn("Log4j 1 logger factories are not supported by Log4j 2 and will be ignored.");
break;
case APPENDER_TAG:
Appender appender = parseAppender(currentElement);
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java
new file mode 100644
index 0000000..73f3c2b
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class AbsoluteDateAndTimeFilter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ final String pat = "/" + Filter.ABSOLUTE_DATE_AND_TIME_PAT + "/";
+
+ if (util.match(pat, in)) {
+ return util.substitute("s/" + Filter.ABSOLUTE_DATE_AND_TIME_PAT + "//", in);
+ } else {
+ return in;
+ }
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/AbsoluteTimeFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/AbsoluteTimeFilter.java
new file mode 100644
index 0000000..4528e8a
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/AbsoluteTimeFilter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class AbsoluteTimeFilter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ final String pat = "/" + Filter.ABSOLUTE_TIME_PAT + "/";
+
+ if (util.match(pat, in)) {
+ return util.substitute("s/" + Filter.ABSOLUTE_TIME_PAT + "//", in);
+ }
+ return in;
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/ControlFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/ControlFilter.java
new file mode 100644
index 0000000..325d460
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/ControlFilter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.util;
+
+import java.util.Arrays;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class ControlFilter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ String[] allowedPatterns;
+
+ public ControlFilter(final String[] allowedPatterns) {
+ this.allowedPatterns = allowedPatterns;
+ }
+
+ @Override
+ public String filter(final String in) throws UnexpectedFormatException {
+ final int len = allowedPatterns.length;
+ for (int i = 0; i < len; i++) {
+ // System.out.println("["+allowedPatterns[i]+"]");
+ if (util.match("/" + allowedPatterns[i] + "/", in)) {
+ // System.out.println("["+in+"] matched ["+allowedPatterns[i]);
+ return in;
+ }
+ }
+
+ throw new UnexpectedFormatException("[" + in + "] allowedPatterns = " + Arrays.toString(allowedPatterns));
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java
new file mode 100644
index 0000000..172d317
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java
@@ -0,0 +1,58 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class EnhancedJunitTestRunnerFilter implements Filter {
+ private static final String[] PATTERNS = {"at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner", "at org.apache.tools.ant",
+ "at junit.textui.TestRunner", "at com.intellij.rt.execution.junit", "at java.lang.reflect.Method.invoke", "at org.apache.maven.", "at org.codehaus.",
+ "at org.junit.internal.runners.", "at junit.framework.JUnit4TestAdapter"};
+
+ private final Perl5Util util = new Perl5Util();
+
+ public EnhancedJunitTestRunnerFilter() {
+ }
+
+ /**
+ * Filter out stack trace lines coming from the various JUnit TestRunners.
+ */
+ @Override
+ public String filter(final String in) {
+ if (in == null) {
+ return null;
+ }
+
+ //
+ // restore the one instance of Method.invoke that we actually want
+ //
+ if (in.indexOf("at junit.framework.TestCase.runTest") != -1) {
+ return "\tat java.lang.reflect.Method.invoke(X)\n\t" + in.trim();
+ }
+
+ for (final String element : PATTERNS) {
+ if (in.indexOf(element) != -1) {
+ return null;
+ }
+ }
+ if (util.match("/\\sat /", in)) {
+ return "\t" + in.trim();
+ }
+ return in;
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/EnhancedLineNumberFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/EnhancedLineNumberFilter.java
new file mode 100644
index 0000000..b112a03
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/EnhancedLineNumberFilter.java
@@ -0,0 +1,42 @@
+/*
+ * 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.util;
+
+import java.util.regex.Pattern;
+
+public class EnhancedLineNumberFilter implements Filter {
+ private final Pattern linePattern;
+ private final Pattern nativePattern;
+
+ public EnhancedLineNumberFilter() {
+ linePattern = Pattern.compile("\\(.*:\\d{1,4}\\)");
+ nativePattern = Pattern.compile("\\(Native Method\\)");
+ }
+
+ @Override
+ public String filter(final String in) {
+
+ if (linePattern.matcher(in).find()) {
+ return linePattern.matcher(in).replaceAll("(X)");
+ } else if (nativePattern.matcher(in).find()) {
+ return nativePattern.matcher(in).replaceAll("(X)");
+ } else {
+ return in;
+ }
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/Filter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/Filter.java
new file mode 100644
index 0000000..16bb43d
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/Filter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+public interface Filter {
+
+ final String BASIC_PAT = "\\[main\\] (FATAL|ERROR|WARN|INFO|DEBUG)";
+ final String ISO8601_PAT = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}";
+
+ // 06 avr. 2002 18:36:32,036
+ // 18 fevr. 2002 20:05:36,222
+ static public final String ABSOLUTE_DATE_AND_TIME_PAT = "^\\d{1,2} .{2,6}\\.? 2\\d{3} \\d{2}:\\d{2}:\\d{2},\\d{3}";
+
+ // 18:54:19,201
+ static public final String ABSOLUTE_TIME_PAT = "^\\d{2}:\\d{2}:\\d{2},\\d{3}";
+
+ static public final String RELATIVE_TIME_PAT = "^\\d{1,10}";
+
+ String filter(String in) throws UnexpectedFormatException;
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/ISO8601Filter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/ISO8601Filter.java
new file mode 100644
index 0000000..47232ad
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/ISO8601Filter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class ISO8601Filter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ final String pat = "/" + ISO8601_PAT + "/";
+
+ if (util.match(pat, in)) {
+ return util.substitute("s/" + ISO8601_PAT + "//", in);
+ }
+ return in;
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/JunitTestRunnerFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/JunitTestRunnerFilter.java
new file mode 100644
index 0000000..175224a
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/JunitTestRunnerFilter.java
@@ -0,0 +1,54 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class JunitTestRunnerFilter implements Filter {
+ Perl5Util util = new Perl5Util();
+
+ /**
+ * Filter out stack trace lines coming from the various JUnit TestRunners.
+ */
+ @Override
+ public String filter(final String in) {
+ if (in == null) {
+ return null;
+ }
+
+ if (util.match("/at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner/", in)) {
+ return null;
+ } else if (util.match("/at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner/", in)) {
+ return null;
+ } else if (util.match("/at com.intellij/", in)) {
+ return null;
+ } else if (in.indexOf("at junit.") >= 0 && in.indexOf("ui.TestRunner") >= 0) {
+ return null;
+ } else if (in.indexOf("org.apache.maven") >= 0) {
+ return null;
+ } else if (in.indexOf("junit.internal") >= 0) {
+ return null;
+ } else if (in.indexOf("JUnit4TestAdapter") >= 0) {
+ return null;
+ } else if (util.match("/\\sat /", in)) {
+ return "\t" + in.trim();
+ } else {
+ return in;
+ }
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/LineNumberFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/LineNumberFilter.java
new file mode 100644
index 0000000..45c6578
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/LineNumberFilter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class LineNumberFilter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ if (util.match("/\\(.*:\\d{1,4}\\)/", in)) {
+ return util.substitute("s/:\\d{1,4}\\)/:XXX)/", in);
+ }
+ if (in.indexOf(", Compiled Code") >= 0) {
+ return util.substitute("s/, Compiled Code/:XXX/", in);
+ }
+ return in;
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/RelativeTimeFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/RelativeTimeFilter.java
new file mode 100644
index 0000000..a15ffb1
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/RelativeTimeFilter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class RelativeTimeFilter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ final String pat = "/" + Filter.RELATIVE_TIME_PAT + "/";
+
+ if (util.match(pat, in)) {
+ // System.out.println("Removing relative time from line ["+in+"]");
+ return util.substitute("s/" + Filter.RELATIVE_TIME_PAT + "//", in);
+ }
+ return in;
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
index 882a37a..a3584c2 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
@@ -30,65 +30,20 @@ import java.io.ObjectOutputStream;
import org.apache.commons.io.FileUtils;
-
/**
* Utiities for serialization tests.
*/
public class SerializationTestHelper {
/**
- * Private constructor.
- */
- private SerializationTestHelper() {
- }
-
- /**
- * Creates a clone by serializing object and
- * deserializing byte stream.
- *
- * @param obj object to serialize and deserialize.
- * @return clone
- * @throws IOException on IO error.
- * @throws ClassNotFoundException if class not found.
- */
- public static Object serializeClone(final Object obj)
- throws IOException, ClassNotFoundException {
- final ByteArrayOutputStream memOut = new ByteArrayOutputStream();
- try (final ObjectOutputStream objOut = new ObjectOutputStream(memOut)) {
- objOut.writeObject(obj);
- }
-
- final ByteArrayInputStream src = new ByteArrayInputStream(memOut.toByteArray());
- final ObjectInputStream objIs = new ObjectInputStream(src);
-
- return objIs.readObject();
- }
-
- /**
- * Deserializes a specified file.
- *
- * @param witness serialization file, may not be null.
- * @return deserialized object.
- * @throws Exception thrown on IO or deserialization exception.
- */
- public static Object deserializeStream(final String witness) throws Exception {
- try (final ObjectInputStream objIs = new ObjectInputStream(new FileInputStream(witness))) {
- return objIs.readObject();
- }
- }
-
- /**
- * Checks the serialization of an object against an file
- * containing the expected serialization.
+ * Checks the serialization of an object against an file containing the expected serialization.
*
- * @param witness name of file containing expected serialization.
- * @param obj object to be serialized.
- * @param skip positions in serialized stream that should not be compared.
+ * @param witness name of file containing expected serialization.
+ * @param obj object to be serialized.
+ * @param skip positions in serialized stream that should not be compared.
* @param endCompare position to stop comparison.
* @throws Exception thrown on IO or serialization exception.
*/
- public static void assertSerializationEquals(
- final String witness, final Object obj, final int[] skip,
- final int endCompare) throws Exception {
+ public static void assertSerializationEquals(final String witness, final Object obj, final int[] skip, final int endCompare) throws Exception {
final ByteArrayOutputStream memOut = new ByteArrayOutputStream();
try (final ObjectOutputStream objOut = new ObjectOutputStream(memOut)) {
objOut.writeObject(obj);
@@ -100,15 +55,13 @@ public class SerializationTestHelper {
/**
* Asserts the serialized form of an object.
*
- * @param witness file name of expected serialization.
- * @param actual byte array of actual serialization.
- * @param skip positions to skip comparison.
+ * @param witness file name of expected serialization.
+ * @param actual byte array of actual serialization.
+ * @param skip positions to skip comparison.
* @param endCompare position to stop comparison.
* @throws IOException thrown on IO or serialization exception.
*/
- public static void assertStreamEquals(
- final String witness, final byte[] actual, final int[] skip,
- final int endCompare) throws IOException {
+ public static void assertStreamEquals(final String witness, final byte[] actual, final int[] skip, final int endCompare) throws IOException {
final File witnessFile = new File(witness);
if (witnessFile.exists()) {
@@ -130,17 +83,54 @@ public class SerializationTestHelper {
if ((skipIndex < skip.length) && (skip[skipIndex] == i)) {
skipIndex++;
} else if (expected[i] != actual[i]) {
- assertEquals(
- "Difference at offset " + i, expected[i], actual[i]);
+ assertEquals("Difference at offset " + i, expected[i], actual[i]);
}
}
} else {
//
- // if the file doesn't exist then
- // assume that we are setting up and need to write it
+ // if the file doesn't exist then
+ // assume that we are setting up and need to write it
FileUtils.writeByteArrayToFile(witnessFile, actual);
fail("Writing witness file " + witness);
}
}
-}
+ /**
+ * Deserializes a specified file.
+ *
+ * @param witness serialization file, may not be null.
+ * @return deserialized object.
+ * @throws Exception thrown on IO or deserialization exception.
+ */
+ public static Object deserializeStream(final String witness) throws Exception {
+ try (final ObjectInputStream objIs = new ObjectInputStream(new FileInputStream(witness))) {
+ return objIs.readObject();
+ }
+ }
+
+ /**
+ * Creates a clone by serializing object and deserializing byte stream.
+ *
+ * @param obj object to serialize and deserialize.
+ * @return clone
+ * @throws IOException on IO error.
+ * @throws ClassNotFoundException if class not found.
+ */
+ public static Object serializeClone(final Object obj) throws IOException, ClassNotFoundException {
+ final ByteArrayOutputStream memOut = new ByteArrayOutputStream();
+ try (final ObjectOutputStream objOut = new ObjectOutputStream(memOut)) {
+ objOut.writeObject(obj);
+ }
+
+ final ByteArrayInputStream src = new ByteArrayInputStream(memOut.toByteArray());
+ final ObjectInputStream objIs = new ObjectInputStream(src);
+
+ return objIs.readObject();
+ }
+
+ /**
+ * Private constructor.
+ */
+ private SerializationTestHelper() {
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/SunReflectFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/SunReflectFilter.java
new file mode 100644
index 0000000..14c8e00
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/SunReflectFilter.java
@@ -0,0 +1,43 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+/**
+ * The sun.reflect.* and java.lang.reflect.* lines are not present in all JDKs.
+ */
+public class SunReflectFilter implements Filter {
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ if ((in == null) || util.match("/at sun.reflect/", in) || (in.indexOf("at java.lang.reflect.") >= 0)) {
+ return null;
+ }
+ if (in.indexOf("Compiled Code") >= 0) {
+ if (in.indexOf("junit.framework.TestSuite") >= 0) {
+ return util.substitute("s/Compiled Code/TestSuite.java:XXX/", in);
+ }
+ }
+ if (util.match("/\\(Method.java:.*\\)/", in)) {
+ return util.substitute("s/\\(Method.java:.*\\)/(Native Method)/", in);
+ }
+ return in;
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/Transformer.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/Transformer.java
new file mode 100644
index 0000000..79d659e
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/Transformer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.util;
+
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+
+public class Transformer {
+
+ public static void transform(final String in, final String out, final Filter filter) throws IOException, UnexpectedFormatException {
+
+ String line;
+ final BufferedReader input = new BufferedReader(new FileReader(in));
+ final PrintStream output = new PrintStream(new FileOutputStream(out));
+
+ // Initialization of input and output omitted
+ while ((line = input.readLine()) != null) {
+ line = filter.filter(line);
+ output.println(line);
+ }
+ }
+
+ public static void transform(final String in, final String out, final Filter[] filters) throws IOException, UnexpectedFormatException {
+
+ String line;
+ final BufferedReader input = new BufferedReader(new FileReader(in));
+ final PrintStream output = new PrintStream(new FileOutputStream(out, false));
+
+ // Initialization of input and output omitted
+ while ((line = input.readLine()) != null) {
+ // apply all filters
+ for (final Filter filter : filters) {
+ line = filter.filter(line);
+ }
+ if (line != null) {
+ output.println(line);
+ }
+ }
+ }
+
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/UnexpectedFormatException.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/UnexpectedFormatException.java
new file mode 100644
index 0000000..ed25a35
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/UnexpectedFormatException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.util;
+
+public class UnexpectedFormatException extends Exception {
+
+ private static final long serialVersionUID = 1787725660780924147L;
+
+ public UnexpectedFormatException(final String msg) {
+ super(msg);
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/XMLLineAttributeFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/XMLLineAttributeFilter.java
new file mode 100644
index 0000000..9fcd070
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/XMLLineAttributeFilter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class XMLLineAttributeFilter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ if (util.match("/line=\"\\d{1,3}\"/", in)) {
+ return util.substitute("s/line=\"\\d{1,3}\"/line=\"X\"/", in);
+ } else if (util.match("/line=\"?\"/", in)) {
+ return util.substitute("s/line=\"?\"/line=\"X\"/", in);
+ } else {
+ return in;
+ }
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/XMLTimestampFilter.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/XMLTimestampFilter.java
new file mode 100644
index 0000000..5012831
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/XMLTimestampFilter.java
@@ -0,0 +1,33 @@
+/*
+ * 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.util;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+public class XMLTimestampFilter implements Filter {
+
+ Perl5Util util = new Perl5Util();
+
+ @Override
+ public String filter(final String in) {
+ if (util.match("/timestamp=\"\\d{10,13}\"/", in)) {
+ return util.substitute("s/timestamp=\"\\d{10,13}\"/timestamp=\"XXX\"/", in);
+ }
+ return in;
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/xml/DOMTestCase.java b/log4j-1.2-api/src/test/java/org/apache/log4j/xml/DOMTestCase.java
new file mode 100644
index 0000000..a01aa88
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/xml/DOMTestCase.java
@@ -0,0 +1,473 @@
+/*
+ * 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.xml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.VectorAppender;
+import org.apache.log4j.bridge.AppenderWrapper;
+import org.apache.log4j.spi.ErrorHandler;
+import org.apache.log4j.spi.LoggerFactory;
+import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.spi.OptionHandler;
+import org.apache.log4j.spi.ThrowableRenderer;
+import org.apache.log4j.spi.ThrowableRendererSupport;
+import org.apache.log4j.util.Compare;
+import org.apache.log4j.util.ControlFilter;
+import org.apache.log4j.util.Filter;
+import org.apache.log4j.util.ISO8601Filter;
+import org.apache.log4j.util.JunitTestRunnerFilter;
+import org.apache.log4j.util.LineNumberFilter;
+import org.apache.log4j.util.SunReflectFilter;
+import org.apache.log4j.util.Transformer;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+public class DOMTestCase {
+
+ /**
+ * CustomErrorHandler for testCategoryFactory2.
+ */
+ public static class CustomErrorHandler implements ErrorHandler {
+ public CustomErrorHandler() {
+ }
+
+ public void activateOptions() {
+ }
+
+ @Override
+ public void error(final String message) {
+ }
+
+ @Override
+ public void error(final String message, final Exception e, final int errorCode) {
+ }
+
+ @Override
+ public void error(final String message, final Exception e, final int errorCode, final LoggingEvent event) {
+ }
+
+ @Override
+ public void setAppender(final Appender appender) {
+ }
+
+ @Override
+ public void setBackupAppender(final Appender appender) {
+ }
+
+ @Override
+ public void setLogger(final Logger logger) {
+ }
+ }
+
+ /**
+ * CustomLogger implementation for testCategoryFactory1 and 2.
+ */
+ private static class CustomLogger extends Logger {
+ /**
+ * Creates new instance.
+ *
+ * @param name logger name.
+ */
+ public CustomLogger(final String name) {
+ super(name);
+ }
+ }
+
+ /**
+ * Creates new instances of CustomLogger.
+ */
+ public static class CustomLoggerFactory implements LoggerFactory {
+
+ /**
+ * Additivity, expected to be set false in configuration file.
+ */
+ private boolean additivity;
+
+ /**
+ * Create new instance of factory.
+ */
+ public CustomLoggerFactory() {
+ additivity = true;
+ }
+
+ /**
+ * Create new logger.
+ *
+ * @param name logger name.
+ * @return new logger.
+ */
+ @Override
+ public Logger makeNewLoggerInstance(final String name) {
+ final Logger logger = new CustomLogger(name);
+ assertFalse(additivity);
+ return logger;
+ }
+
+ /**
+ * Set additivity.
+ *
+ * @param newVal new value of additivity.
+ */
+ public void setAdditivity(final boolean newVal) {
+ additivity = newVal;
+ }
+ }
+
+ /**
+ * Mock ThrowableRenderer for testThrowableRenderer. See bug 45721.
+ */
+ public static class MockThrowableRenderer implements ThrowableRenderer, OptionHandler {
+ private boolean activated = false;
+ private boolean showVersion = true;
+
+ public MockThrowableRenderer() {
+ }
+
+ @Override
+ public void activateOptions() {
+ activated = true;
+ }
+
+ @Override
+ public String[] doRender(final Throwable t) {
+ return new String[0];
+ }
+
+ public boolean getShowVersion() {
+ return showVersion;
+ }
+
+ public boolean isActivated() {
+ return activated;
+ }
+
+ public void setShowVersion(final boolean v) {
+ showVersion = v;
+ }
+ }
+
+ static String TEMP_A1 = "target/output/temp.A1";
+ static String TEMP_A2 = "target/output/temp.A2";
+ static String FILTERED_A1 = "target/output/filtered.A1";
+ static String FILTERED_A2 = "target/output/filtered.A2";
+ static String EXCEPTION1 = "java.lang.Exception: Just testing";
+ static String EXCEPTION2 = "\\s*at .*\\(.*\\)";
+ static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)";
+ static String EXCEPTION4 = "\\s*at .*\\(.*Compiled Code\\)";
+ static String EXCEPTION5 = "\\s*at .*\\(.*libgcj.*\\)";
+ static String TEST1_1A_PAT = "(TRACE|DEBUG|INFO |WARN |ERROR|FATAL) \\w*\\.\\w* - Message \\d";
+ static String TEST1_1B_PAT = "(TRACE|DEBUG|INFO |WARN |ERROR|FATAL) root - Message \\d";
+ static String TEST1_2_PAT = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3} " + "\\[main]\\ (TRACE|DEBUG|INFO|WARN|ERROR|FATAL) .* - Message \\d";
+
+ private static final boolean Log4j1ActualAppender = false;
+
+ private static final boolean AssumeThrowableRendererSupport = false;
+
+ Logger root;
+
+ Logger logger;
+
+ void common() {
+ final String oldThreadName = Thread.currentThread().getName();
+ Thread.currentThread().setName("main");
+
+ int i = -1;
+
+ logger.trace("Message " + ++i);
+ root.trace("Message " + i);
+
+ logger.debug("Message " + ++i);
+ root.debug("Message " + i);
+
+ logger.info("Message " + ++i);
+ root.info("Message " + i);
+
+ logger.warn("Message " + ++i);
+ root.warn("Message " + i);
+
+ logger.error("Message " + ++i);
+ root.error("Message " + i);
+
+ logger.log(Level.FATAL, "Message " + ++i);
+ root.log(Level.FATAL, "Message " + i);
+
+ final Exception e = new Exception("Just testing");
+ logger.debug("Message " + ++i, e);
+ root.debug("Message " + i, e);
+
+ logger.error("Message " + ++i, e);
+ root.error("Message " + i, e);
+
+ Thread.currentThread().setName(oldThreadName);
+ }
+
+ @BeforeEach
+ public void setUp() {
+ root = Logger.getRootLogger();
+ logger = Logger.getLogger(DOMTestCase.class);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ root.getLoggerRepository().resetConfiguration();
+ }
+
+ @Test
+ @Disabled
+ public void test1() throws Exception {
+ DOMConfigurator.configure("src/test/resources/log4j1-1.2.17/input/xml/DOMTestCase1.xml");
+ common();
+
+ final ControlFilter cf1 = new ControlFilter(new String[] {TEST1_1A_PAT, TEST1_1B_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
+
+ final ControlFilter cf2 = new ControlFilter(new String[] {TEST1_2_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
+
+ Transformer.transform(TEMP_A1, FILTERED_A1, new Filter[] {cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter()});
+
+ Transformer.transform(TEMP_A2, FILTERED_A2,
+ new Filter[] {cf2, new LineNumberFilter(), new ISO8601Filter(), new SunReflectFilter(), new JunitTestRunnerFilter()});
+
+ assertTrue(Compare.compare(FILTERED_A1, "witness/dom.A1.1"));
+ assertTrue(Compare.compare(FILTERED_A2, "witness/dom.A2.1"));
+ }
+
+ /**
+ * Tests processing of external entities in XML file.
+ */
+ @Test
+ @Disabled
+ public void test4() throws Exception {
+ DOMConfigurator.configure("src/test/resources/log4j1-1.2.17/input/xml/DOMTest4.xml");
+ common();
+
+ final ControlFilter cf1 = new ControlFilter(new String[] {TEST1_1A_PAT, TEST1_1B_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
+
+ final ControlFilter cf2 = new ControlFilter(new String[] {TEST1_2_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
+
+ Transformer.transform(TEMP_A1 + ".4", FILTERED_A1 + ".4",
+ new Filter[] {cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter()});
+
+ Transformer.transform(TEMP_A2 + ".4", FILTERED_A2 + ".4",
+ new Filter[] {cf2, new LineNumberFilter(), new ISO8601Filter(), new SunReflectFilter(), new JunitTestRunnerFilter()});
+
+ assertTrue(Compare.compare(FILTERED_A1 + ".4", "witness/dom.A1.4"));
+ assertTrue(Compare.compare(FILTERED_A2 + ".4", "witness/dom.A2.4"));
+ }
+
+ /**
+ * Tests that loggers mentioned in logger elements use the specified categoryFactory. See bug 33708.
+ */
+ @Test
+ @Disabled
+ public void testCategoryFactory1() {
+ DOMConfigurator.configure("src/test/resources/log4j1-1.2.17/input/xml/categoryfactory1.xml");
+ //
+ // logger not explicitly mentioned in configuration,
+ // should use default factory
+ final Logger logger2 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory1.2");
+ assertFalse(logger2.toString(), logger2 instanceof CustomLogger);
+ //
+ // logger explicitly mentioned in configuration,
+ // should be a CustomLogger
+ final Logger logger1 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory1.1");
+ assertTrue(logger1.toString(), logger1 instanceof CustomLogger);
+ //
+ // logger not explicitly mentioned in configuration,
+ // should use default factory
+ final Logger logger2Bis = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory1.2");
+ assertFalse(logger2Bis.toString(), logger2Bis instanceof CustomLogger);
+ }
+
+ /**
+ * Tests that loggers mentioned in logger-ref elements use the specified categoryFactory. See bug 33708.
+ */
+ @Test
+ @Disabled
+ public void testCategoryFactory2() {
+ DOMConfigurator.configure("src/test/resources/log4j1-1.2.17/input/xml/categoryfactory2.xml");
+ //
+ // logger not explicitly mentioned in configuration,
+ // should use default factory
+ final Logger logger2 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory2.2");
+ assertFalse(logger2.toString(), logger2 instanceof CustomLogger);
+ //
+ // logger explicitly mentioned in configuration,
+ // should be a CustomLogger
+ final Logger logger1 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory2.1");
+ assertTrue(logger1.toString(), logger1 instanceof CustomLogger);
+ //
+ // logger not explicitly mentioned in configuration,
+ // should use default factory
+ final Logger logger2Bis = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory2.2");
+ assertFalse(logger2Bis.toString(), logger2Bis instanceof CustomLogger);
+ }
+
+ /**
+ * Test checks that configureAndWatch does initial configuration, see bug 33502.
+ *
+ * @throws Exception if IO error.
+ */
+ @Test
+ public void testConfigureAndWatch() throws Exception {
+ DOMConfigurator.configureAndWatch("src/test/resources/log4j1-1.2.17/input/xml/DOMTestCase1.xml");
+ assertNotNull(Logger.getRootLogger().getAppender("A1"));
+ }
+
+ /**
+ * Test for bug 47465. configure(URL) did not close opened JarURLConnection.
+ *
+ * @throws IOException if IOException creating properties jar.
+ */
+ @Test
+ public void testJarURL() throws IOException {
+ final File input = new File("src/test/resources/log4j1-1.2.17/input/xml/defaultInit.xml");
+ System.out.println(input.getAbsolutePath());
+ final File configJar = new File("target/output/xml.jar");
+ final File dir = new File("target/output");
+ dir.mkdirs();
+ try (final InputStream inputStream = new FileInputStream(input);
+ final FileOutputStream out = new FileOutputStream(configJar);
+ final ZipOutputStream zos = new ZipOutputStream(out)) {
+ zos.putNextEntry(new ZipEntry("log4j.xml"));
+ int len;
+ final byte[] buf = new byte[1024];
+ while ((len = inputStream.read(buf)) > 0) {
+ zos.write(buf, 0, len);
+ }
+ zos.closeEntry();
+ }
+ final URL urlInJar = new URL("jar:" + configJar.toURL() + "!/log4j.xml");
+ DOMConfigurator.configure(urlInJar);
+ assertTrue(configJar.delete());
+ assertFalse(configJar.exists());
+ }
+
+ /**
+ * Tests that loggers mentioned in logger elements use the specified loggerFactory. See bug 33708.
+ */
+ @Test
+ @Disabled("TODO")
+ public void testLoggerFactory1() {
+ DOMConfigurator.configure("src/test/resources/log4j1-1.2.17/input/xml/loggerfactory1.xml");
+ //
+ // logger not explicitly mentioned in configuration,
+ // should use default factory
+ final Logger logger2 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testLoggerFactory1.2");
+ assertNotNull(logger2);
+ assertFalse(logger2.toString(), logger2 instanceof CustomLogger);
+ //
+ // logger explicitly mentioned in configuration,
+ // should be a CustomLogger
+ final Logger logger1 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testLoggerFactory1.1");
+ assertNotNull(logger1);
+ assertTrue(logger1.toString(), logger1 instanceof CustomLogger);
+ //
+ // logger not explicitly mentioned in configuration,
+ // should use default factory
+ final Logger logger2Bis = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testLoggerFactory1.2");
+ assertNotNull(logger2Bis);
+ assertFalse(logger2Bis.toString(), logger2Bis instanceof CustomLogger);
+ }
+
+ /**
+ * This test checks that the subst method of an extending class is checked when evaluating parameters. See bug 43325.
+ *
+ */
+ @Test
+ public void testOverrideSubst() {
+ final DOMConfigurator configurator = new DOMConfigurator() {
+ protected String subst(final String value) {
+ if ("target/output/temp.A1".equals(value)) {
+ return "target/output/subst-test.A1";
+ }
+ return value;
+ }
+ };
+ configurator.doConfigure("src/test/resources/log4j1-1.2.17/input/xml/DOMTestCase1.xml", LogManager.getLoggerRepository());
+ final String name = "A1";
+ final Appender appender = Logger.getRootLogger().getAppender(name);
+ assertNotNull(name, appender);
+ if (Log4j1ActualAppender) {
+ final FileAppender a1 = (FileAppender) appender;
+ assertNotNull(name, a1);
+ final String file = a1.getFile();
+ assertEquals("target/output/subst-test.A1", file);
+ } else {
+ final AppenderWrapper wrapper = (AppenderWrapper) appender;
+ assertNotNull(name, wrapper);
+ final org.apache.logging.log4j.core.appender.FileAppender a1 = (org.apache.logging.log4j.core.appender.FileAppender) wrapper.getAppender();
+ assertNotNull(wrapper.toString(), a1);
+ final String file = a1.getFileName();
+ assertNotNull(a1.toString(), file);
+ // TODO Support this or not?
+ // assertEquals("target/output/subst-test.A1", file);
+ }
+ }
+
+ /**
+ * Tests that reset="true" on log4j:configuration element resets repository before configuration.
+ *
+ * @throws Exception thrown on error.
+ */
+ @Test
+ public void testReset() throws Exception {
+ final VectorAppender appender = new VectorAppender();
+ appender.setName("V1");
+ Logger.getRootLogger().addAppender(appender);
+ DOMConfigurator.configure("src/test/resources/log4j1-1.2.17/input/xml/testReset.xml");
+ assertNull(Logger.getRootLogger().getAppender("V1"));
+ }
+
+ /**
+ * Test of log4j.throwableRenderer support. See bug 45721.
+ */
+ @Test
+ public void testThrowableRenderer1() {
+ DOMConfigurator.configure("src/test/resources/log4j1-1.2.17/input/xml/throwableRenderer1.xml");
+ final ThrowableRendererSupport repo = (ThrowableRendererSupport) LogManager.getLoggerRepository();
+ final MockThrowableRenderer renderer = (MockThrowableRenderer) repo.getThrowableRenderer();
+ LogManager.resetConfiguration();
+ if (AssumeThrowableRendererSupport) {
+ assertNotNull(renderer);
+ assertEquals(true, renderer.isActivated());
+ assertEquals(false, renderer.getShowVersion());
+ }
+ }
+
+}
diff --git a/log4j-1.2-api/src/test/resources/log4j1-1.2.17/input/xml/DOMTestCase1.xml b/log4j-1.2-api/src/test/resources/log4j1-1.2.17/input/xml/DOMTestCase1.xml
index fcd1a7c..90917d1 100644
--- a/log4j-1.2-api/src/test/resources/log4j1-1.2.17/input/xml/DOMTestCase1.xml
+++ b/log4j-1.2-api/src/test/resources/log4j1-1.2.17/input/xml/DOMTestCase1.xml
@@ -20,7 +20,7 @@
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.FileAppender">
- <param name="File" value="output/temp.A1" />
+ <param name="File" value="target/output/temp.A1" />
<param name="Append" value="false" />
<layout class="org.apache.log4j.PatternLayout">
@@ -29,7 +29,7 @@
</appender>
<appender name="A2" class="org.apache.log4j.FileAppender">
- <param name="File" value="output/temp.A2" />
+ <param name="File" value="target/output/temp.A2" />
<param name="Append" value="false" />
<layout class="org.apache.log4j.TTCCLayout">
<param name="DateFormat" value="ISO8601" />