diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000000..3f05d8ca44
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-parent
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-core
+ Apache Log4j-Core
+ Apache Log4j core library.
+ bundle
+
\ No newline at end of file
diff --git a/src/assembly/bin.xml b/core/src/assembly/bin.xml
similarity index 100%
rename from src/assembly/bin.xml
rename to core/src/assembly/bin.xml
diff --git a/src/changes/changes.xml b/core/src/changes/changes.xml
similarity index 100%
rename from src/changes/changes.xml
rename to core/src/changes/changes.xml
diff --git a/src/main/java/org/apache/log4j/Appender.java b/core/src/main/java/org/apache/log4j/Appender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Appender.java
rename to core/src/main/java/org/apache/log4j/Appender.java
diff --git a/src/main/java/org/apache/log4j/AppenderSkeleton.java b/core/src/main/java/org/apache/log4j/AppenderSkeleton.java
similarity index 100%
rename from src/main/java/org/apache/log4j/AppenderSkeleton.java
rename to core/src/main/java/org/apache/log4j/AppenderSkeleton.java
diff --git a/src/main/java/org/apache/log4j/AsyncAppender.java b/core/src/main/java/org/apache/log4j/AsyncAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/AsyncAppender.java
rename to core/src/main/java/org/apache/log4j/AsyncAppender.java
diff --git a/src/main/java/org/apache/log4j/BasicConfigurator.java b/core/src/main/java/org/apache/log4j/BasicConfigurator.java
similarity index 100%
rename from src/main/java/org/apache/log4j/BasicConfigurator.java
rename to core/src/main/java/org/apache/log4j/BasicConfigurator.java
diff --git a/src/main/java/org/apache/log4j/Category.java b/core/src/main/java/org/apache/log4j/Category.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Category.java
rename to core/src/main/java/org/apache/log4j/Category.java
diff --git a/src/main/java/org/apache/log4j/CategoryKey.java b/core/src/main/java/org/apache/log4j/CategoryKey.java
similarity index 100%
rename from src/main/java/org/apache/log4j/CategoryKey.java
rename to core/src/main/java/org/apache/log4j/CategoryKey.java
diff --git a/src/main/java/org/apache/log4j/ConsoleAppender.java b/core/src/main/java/org/apache/log4j/ConsoleAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/ConsoleAppender.java
rename to core/src/main/java/org/apache/log4j/ConsoleAppender.java
diff --git a/src/main/java/org/apache/log4j/DailyRollingFileAppender.java b/core/src/main/java/org/apache/log4j/DailyRollingFileAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/DailyRollingFileAppender.java
rename to core/src/main/java/org/apache/log4j/DailyRollingFileAppender.java
diff --git a/src/main/java/org/apache/log4j/DefaultCategoryFactory.java b/core/src/main/java/org/apache/log4j/DefaultCategoryFactory.java
similarity index 100%
rename from src/main/java/org/apache/log4j/DefaultCategoryFactory.java
rename to core/src/main/java/org/apache/log4j/DefaultCategoryFactory.java
diff --git a/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java b/core/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/DefaultThrowableRenderer.java
rename to core/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java
diff --git a/src/main/java/org/apache/log4j/Dispatcher.java b/core/src/main/java/org/apache/log4j/Dispatcher.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Dispatcher.java
rename to core/src/main/java/org/apache/log4j/Dispatcher.java
diff --git a/src/main/java/org/apache/log4j/EnhancedPatternLayout.java b/core/src/main/java/org/apache/log4j/EnhancedPatternLayout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/EnhancedPatternLayout.java
rename to core/src/main/java/org/apache/log4j/EnhancedPatternLayout.java
diff --git a/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java b/core/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java
rename to core/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java
diff --git a/src/main/java/org/apache/log4j/FileAppender.java b/core/src/main/java/org/apache/log4j/FileAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/FileAppender.java
rename to core/src/main/java/org/apache/log4j/FileAppender.java
diff --git a/src/main/java/org/apache/log4j/HTMLLayout.java b/core/src/main/java/org/apache/log4j/HTMLLayout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/HTMLLayout.java
rename to core/src/main/java/org/apache/log4j/HTMLLayout.java
diff --git a/src/main/java/org/apache/log4j/Hierarchy.java b/core/src/main/java/org/apache/log4j/Hierarchy.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Hierarchy.java
rename to core/src/main/java/org/apache/log4j/Hierarchy.java
diff --git a/src/main/java/org/apache/log4j/Layout.java b/core/src/main/java/org/apache/log4j/Layout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Layout.java
rename to core/src/main/java/org/apache/log4j/Layout.java
diff --git a/src/main/java/org/apache/log4j/Level.java b/core/src/main/java/org/apache/log4j/Level.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Level.java
rename to core/src/main/java/org/apache/log4j/Level.java
diff --git a/src/main/java/org/apache/log4j/LogMF.java b/core/src/main/java/org/apache/log4j/LogMF.java
similarity index 100%
rename from src/main/java/org/apache/log4j/LogMF.java
rename to core/src/main/java/org/apache/log4j/LogMF.java
diff --git a/src/main/java/org/apache/log4j/LogManager.java b/core/src/main/java/org/apache/log4j/LogManager.java
similarity index 100%
rename from src/main/java/org/apache/log4j/LogManager.java
rename to core/src/main/java/org/apache/log4j/LogManager.java
diff --git a/src/main/java/org/apache/log4j/LogSF.java b/core/src/main/java/org/apache/log4j/LogSF.java
similarity index 100%
rename from src/main/java/org/apache/log4j/LogSF.java
rename to core/src/main/java/org/apache/log4j/LogSF.java
diff --git a/src/main/java/org/apache/log4j/LogXF.java b/core/src/main/java/org/apache/log4j/LogXF.java
similarity index 100%
rename from src/main/java/org/apache/log4j/LogXF.java
rename to core/src/main/java/org/apache/log4j/LogXF.java
diff --git a/src/main/java/org/apache/log4j/Logger.java b/core/src/main/java/org/apache/log4j/Logger.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Logger.java
rename to core/src/main/java/org/apache/log4j/Logger.java
diff --git a/src/main/java/org/apache/log4j/MDC.java b/core/src/main/java/org/apache/log4j/MDC.java
similarity index 100%
rename from src/main/java/org/apache/log4j/MDC.java
rename to core/src/main/java/org/apache/log4j/MDC.java
diff --git a/src/main/java/org/apache/log4j/NDC.java b/core/src/main/java/org/apache/log4j/NDC.java
similarity index 100%
rename from src/main/java/org/apache/log4j/NDC.java
rename to core/src/main/java/org/apache/log4j/NDC.java
diff --git a/src/main/java/org/apache/log4j/PatternLayout.java b/core/src/main/java/org/apache/log4j/PatternLayout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/PatternLayout.java
rename to core/src/main/java/org/apache/log4j/PatternLayout.java
diff --git a/src/main/java/org/apache/log4j/Priority.java b/core/src/main/java/org/apache/log4j/Priority.java
similarity index 100%
rename from src/main/java/org/apache/log4j/Priority.java
rename to core/src/main/java/org/apache/log4j/Priority.java
diff --git a/src/main/java/org/apache/log4j/PropertyConfigurator.java b/core/src/main/java/org/apache/log4j/PropertyConfigurator.java
similarity index 100%
rename from src/main/java/org/apache/log4j/PropertyConfigurator.java
rename to core/src/main/java/org/apache/log4j/PropertyConfigurator.java
diff --git a/src/main/java/org/apache/log4j/ProvisionNode.java b/core/src/main/java/org/apache/log4j/ProvisionNode.java
similarity index 100%
rename from src/main/java/org/apache/log4j/ProvisionNode.java
rename to core/src/main/java/org/apache/log4j/ProvisionNode.java
diff --git a/src/main/java/org/apache/log4j/RollingFileAppender.java b/core/src/main/java/org/apache/log4j/RollingFileAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/RollingFileAppender.java
rename to core/src/main/java/org/apache/log4j/RollingFileAppender.java
diff --git a/src/main/java/org/apache/log4j/SimpleLayout.java b/core/src/main/java/org/apache/log4j/SimpleLayout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/SimpleLayout.java
rename to core/src/main/java/org/apache/log4j/SimpleLayout.java
diff --git a/src/main/java/org/apache/log4j/TTCCLayout.java b/core/src/main/java/org/apache/log4j/TTCCLayout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/TTCCLayout.java
rename to core/src/main/java/org/apache/log4j/TTCCLayout.java
diff --git a/src/main/java/org/apache/log4j/WriterAppender.java b/core/src/main/java/org/apache/log4j/WriterAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/WriterAppender.java
rename to core/src/main/java/org/apache/log4j/WriterAppender.java
diff --git a/src/main/java/org/apache/log4j/config/PropertyGetter.java b/core/src/main/java/org/apache/log4j/config/PropertyGetter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/config/PropertyGetter.java
rename to core/src/main/java/org/apache/log4j/config/PropertyGetter.java
diff --git a/src/main/java/org/apache/log4j/config/PropertyPrinter.java b/core/src/main/java/org/apache/log4j/config/PropertyPrinter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/config/PropertyPrinter.java
rename to core/src/main/java/org/apache/log4j/config/PropertyPrinter.java
diff --git a/src/main/java/org/apache/log4j/config/PropertySetter.java b/core/src/main/java/org/apache/log4j/config/PropertySetter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/config/PropertySetter.java
rename to core/src/main/java/org/apache/log4j/config/PropertySetter.java
diff --git a/src/main/java/org/apache/log4j/config/PropertySetterException.java b/core/src/main/java/org/apache/log4j/config/PropertySetterException.java
similarity index 100%
rename from src/main/java/org/apache/log4j/config/PropertySetterException.java
rename to core/src/main/java/org/apache/log4j/config/PropertySetterException.java
diff --git a/src/main/java/org/apache/log4j/config/package.html b/core/src/main/java/org/apache/log4j/config/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/config/package.html
rename to core/src/main/java/org/apache/log4j/config/package.html
diff --git a/src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java b/core/src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java
rename to core/src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java
diff --git a/src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java b/core/src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java
rename to core/src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java
diff --git a/src/main/java/org/apache/log4j/helpers/BoundedFIFO.java b/core/src/main/java/org/apache/log4j/helpers/BoundedFIFO.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/BoundedFIFO.java
rename to core/src/main/java/org/apache/log4j/helpers/BoundedFIFO.java
diff --git a/src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java b/core/src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java
rename to core/src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java
diff --git a/src/main/java/org/apache/log4j/helpers/CyclicBuffer.java b/core/src/main/java/org/apache/log4j/helpers/CyclicBuffer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/CyclicBuffer.java
rename to core/src/main/java/org/apache/log4j/helpers/CyclicBuffer.java
diff --git a/src/main/java/org/apache/log4j/helpers/DateLayout.java b/core/src/main/java/org/apache/log4j/helpers/DateLayout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/DateLayout.java
rename to core/src/main/java/org/apache/log4j/helpers/DateLayout.java
diff --git a/src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java b/core/src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java
rename to core/src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java
diff --git a/src/main/java/org/apache/log4j/helpers/FileWatchdog.java b/core/src/main/java/org/apache/log4j/helpers/FileWatchdog.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/FileWatchdog.java
rename to core/src/main/java/org/apache/log4j/helpers/FileWatchdog.java
diff --git a/src/main/java/org/apache/log4j/helpers/FormattingInfo.java b/core/src/main/java/org/apache/log4j/helpers/FormattingInfo.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/FormattingInfo.java
rename to core/src/main/java/org/apache/log4j/helpers/FormattingInfo.java
diff --git a/src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java b/core/src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java
rename to core/src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java
diff --git a/src/main/java/org/apache/log4j/helpers/Loader.java b/core/src/main/java/org/apache/log4j/helpers/Loader.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/Loader.java
rename to core/src/main/java/org/apache/log4j/helpers/Loader.java
diff --git a/src/main/java/org/apache/log4j/helpers/LogLog.java b/core/src/main/java/org/apache/log4j/helpers/LogLog.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/LogLog.java
rename to core/src/main/java/org/apache/log4j/helpers/LogLog.java
diff --git a/src/main/java/org/apache/log4j/helpers/MDCKeySetExtractor.java b/core/src/main/java/org/apache/log4j/helpers/MDCKeySetExtractor.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/MDCKeySetExtractor.java
rename to core/src/main/java/org/apache/log4j/helpers/MDCKeySetExtractor.java
diff --git a/src/main/java/org/apache/log4j/helpers/NullEnumeration.java b/core/src/main/java/org/apache/log4j/helpers/NullEnumeration.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/NullEnumeration.java
rename to core/src/main/java/org/apache/log4j/helpers/NullEnumeration.java
diff --git a/src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java b/core/src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java
rename to core/src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java
diff --git a/src/main/java/org/apache/log4j/helpers/OptionConverter.java b/core/src/main/java/org/apache/log4j/helpers/OptionConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/OptionConverter.java
rename to core/src/main/java/org/apache/log4j/helpers/OptionConverter.java
diff --git a/src/main/java/org/apache/log4j/helpers/PatternConverter.java b/core/src/main/java/org/apache/log4j/helpers/PatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/PatternConverter.java
rename to core/src/main/java/org/apache/log4j/helpers/PatternConverter.java
diff --git a/src/main/java/org/apache/log4j/helpers/PatternParser.java b/core/src/main/java/org/apache/log4j/helpers/PatternParser.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/PatternParser.java
rename to core/src/main/java/org/apache/log4j/helpers/PatternParser.java
diff --git a/src/main/java/org/apache/log4j/helpers/QuietWriter.java b/core/src/main/java/org/apache/log4j/helpers/QuietWriter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/QuietWriter.java
rename to core/src/main/java/org/apache/log4j/helpers/QuietWriter.java
diff --git a/src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java b/core/src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java
rename to core/src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java
diff --git a/src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java b/core/src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java
rename to core/src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java
diff --git a/src/main/java/org/apache/log4j/helpers/SyslogWriter.java b/core/src/main/java/org/apache/log4j/helpers/SyslogWriter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/SyslogWriter.java
rename to core/src/main/java/org/apache/log4j/helpers/SyslogWriter.java
diff --git a/src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java b/core/src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java
rename to core/src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java
diff --git a/src/main/java/org/apache/log4j/helpers/Transform.java b/core/src/main/java/org/apache/log4j/helpers/Transform.java
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/Transform.java
rename to core/src/main/java/org/apache/log4j/helpers/Transform.java
diff --git a/src/main/java/org/apache/log4j/helpers/package.html b/core/src/main/java/org/apache/log4j/helpers/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/helpers/package.html
rename to core/src/main/java/org/apache/log4j/helpers/package.html
diff --git a/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java b/core/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jdbc/JDBCAppender.java
rename to core/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java
diff --git a/src/main/java/org/apache/log4j/jdbc/package.html b/core/src/main/java/org/apache/log4j/jdbc/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/jdbc/package.html
rename to core/src/main/java/org/apache/log4j/jdbc/package.html
diff --git a/src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java b/core/src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java
rename to core/src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java
diff --git a/src/main/java/org/apache/log4j/jmx/Agent.java b/core/src/main/java/org/apache/log4j/jmx/Agent.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/Agent.java
rename to core/src/main/java/org/apache/log4j/jmx/Agent.java
diff --git a/src/main/java/org/apache/log4j/jmx/AppenderDynamicMBean.java b/core/src/main/java/org/apache/log4j/jmx/AppenderDynamicMBean.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/AppenderDynamicMBean.java
rename to core/src/main/java/org/apache/log4j/jmx/AppenderDynamicMBean.java
diff --git a/src/main/java/org/apache/log4j/jmx/HierarchyDynamicMBean.java b/core/src/main/java/org/apache/log4j/jmx/HierarchyDynamicMBean.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/HierarchyDynamicMBean.java
rename to core/src/main/java/org/apache/log4j/jmx/HierarchyDynamicMBean.java
diff --git a/src/main/java/org/apache/log4j/jmx/LayoutDynamicMBean.java b/core/src/main/java/org/apache/log4j/jmx/LayoutDynamicMBean.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/LayoutDynamicMBean.java
rename to core/src/main/java/org/apache/log4j/jmx/LayoutDynamicMBean.java
diff --git a/src/main/java/org/apache/log4j/jmx/LoggerDynamicMBean.java b/core/src/main/java/org/apache/log4j/jmx/LoggerDynamicMBean.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/LoggerDynamicMBean.java
rename to core/src/main/java/org/apache/log4j/jmx/LoggerDynamicMBean.java
diff --git a/src/main/java/org/apache/log4j/jmx/MethodUnion.java b/core/src/main/java/org/apache/log4j/jmx/MethodUnion.java
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/MethodUnion.java
rename to core/src/main/java/org/apache/log4j/jmx/MethodUnion.java
diff --git a/src/main/java/org/apache/log4j/jmx/package.html b/core/src/main/java/org/apache/log4j/jmx/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/jmx/package.html
rename to core/src/main/java/org/apache/log4j/jmx/package.html
diff --git a/src/main/java/org/apache/log4j/or/DefaultRenderer.java b/core/src/main/java/org/apache/log4j/or/DefaultRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/or/DefaultRenderer.java
rename to core/src/main/java/org/apache/log4j/or/DefaultRenderer.java
diff --git a/src/main/java/org/apache/log4j/or/ObjectRenderer.java b/core/src/main/java/org/apache/log4j/or/ObjectRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/or/ObjectRenderer.java
rename to core/src/main/java/org/apache/log4j/or/ObjectRenderer.java
diff --git a/src/main/java/org/apache/log4j/or/RendererMap.java b/core/src/main/java/org/apache/log4j/or/RendererMap.java
similarity index 100%
rename from src/main/java/org/apache/log4j/or/RendererMap.java
rename to core/src/main/java/org/apache/log4j/or/RendererMap.java
diff --git a/src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java b/core/src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java
rename to core/src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java
diff --git a/src/main/java/org/apache/log4j/or/jms/MessageRenderer.java b/core/src/main/java/org/apache/log4j/or/jms/MessageRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/or/jms/MessageRenderer.java
rename to core/src/main/java/org/apache/log4j/or/jms/MessageRenderer.java
diff --git a/src/main/java/org/apache/log4j/or/jms/package.html b/core/src/main/java/org/apache/log4j/or/jms/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/or/jms/package.html
rename to core/src/main/java/org/apache/log4j/or/jms/package.html
diff --git a/src/main/java/org/apache/log4j/or/package.html b/core/src/main/java/org/apache/log4j/or/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/or/package.html
rename to core/src/main/java/org/apache/log4j/or/package.html
diff --git a/src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java b/core/src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java
rename to core/src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java
diff --git a/src/main/java/org/apache/log4j/or/sax/package.html b/core/src/main/java/org/apache/log4j/or/sax/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/or/sax/package.html
rename to core/src/main/java/org/apache/log4j/or/sax/package.html
diff --git a/src/main/java/org/apache/log4j/package.html b/core/src/main/java/org/apache/log4j/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/package.html
rename to core/src/main/java/org/apache/log4j/package.html
diff --git a/src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/BridgePatternParser.java b/core/src/main/java/org/apache/log4j/pattern/BridgePatternParser.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/BridgePatternParser.java
rename to core/src/main/java/org/apache/log4j/pattern/BridgePatternParser.java
diff --git a/src/main/java/org/apache/log4j/pattern/CachedDateFormat.java b/core/src/main/java/org/apache/log4j/pattern/CachedDateFormat.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/CachedDateFormat.java
rename to core/src/main/java/org/apache/log4j/pattern/CachedDateFormat.java
diff --git a/src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/DatePatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/DatePatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/DatePatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/DatePatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/FormattingInfo.java b/core/src/main/java/org/apache/log4j/pattern/FormattingInfo.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/FormattingInfo.java
rename to core/src/main/java/org/apache/log4j/pattern/FormattingInfo.java
diff --git a/src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/LogEvent.java b/core/src/main/java/org/apache/log4j/pattern/LogEvent.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/LogEvent.java
rename to core/src/main/java/org/apache/log4j/pattern/LogEvent.java
diff --git a/src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/NameAbbreviator.java b/core/src/main/java/org/apache/log4j/pattern/NameAbbreviator.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/NameAbbreviator.java
rename to core/src/main/java/org/apache/log4j/pattern/NameAbbreviator.java
diff --git a/src/main/java/org/apache/log4j/pattern/NamePatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/NamePatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/NamePatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/NamePatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/PatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/PatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/PatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/PatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/PatternParser.java b/core/src/main/java/org/apache/log4j/pattern/PatternParser.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/PatternParser.java
rename to core/src/main/java/org/apache/log4j/pattern/PatternParser.java
diff --git a/src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java b/core/src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java
rename to core/src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java
diff --git a/src/main/java/org/apache/log4j/pattern/package.html b/core/src/main/java/org/apache/log4j/pattern/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/pattern/package.html
rename to core/src/main/java/org/apache/log4j/pattern/package.html
diff --git a/src/main/java/org/apache/log4j/spi/AppenderAttachable.java b/core/src/main/java/org/apache/log4j/spi/AppenderAttachable.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/AppenderAttachable.java
rename to core/src/main/java/org/apache/log4j/spi/AppenderAttachable.java
diff --git a/src/main/java/org/apache/log4j/spi/Configurator.java b/core/src/main/java/org/apache/log4j/spi/Configurator.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/Configurator.java
rename to core/src/main/java/org/apache/log4j/spi/Configurator.java
diff --git a/src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java b/core/src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java
rename to core/src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java
diff --git a/src/main/java/org/apache/log4j/spi/ErrorCode.java b/core/src/main/java/org/apache/log4j/spi/ErrorCode.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/ErrorCode.java
rename to core/src/main/java/org/apache/log4j/spi/ErrorCode.java
diff --git a/src/main/java/org/apache/log4j/spi/ErrorHandler.java b/core/src/main/java/org/apache/log4j/spi/ErrorHandler.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/ErrorHandler.java
rename to core/src/main/java/org/apache/log4j/spi/ErrorHandler.java
diff --git a/src/main/java/org/apache/log4j/spi/Filter.java b/core/src/main/java/org/apache/log4j/spi/Filter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/Filter.java
rename to core/src/main/java/org/apache/log4j/spi/Filter.java
diff --git a/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java b/core/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/HierarchyEventListener.java
rename to core/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java
diff --git a/src/main/java/org/apache/log4j/spi/LocationInfo.java b/core/src/main/java/org/apache/log4j/spi/LocationInfo.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/LocationInfo.java
rename to core/src/main/java/org/apache/log4j/spi/LocationInfo.java
diff --git a/src/main/java/org/apache/log4j/spi/LoggerFactory.java b/core/src/main/java/org/apache/log4j/spi/LoggerFactory.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/LoggerFactory.java
rename to core/src/main/java/org/apache/log4j/spi/LoggerFactory.java
diff --git a/src/main/java/org/apache/log4j/spi/LoggerRepository.java b/core/src/main/java/org/apache/log4j/spi/LoggerRepository.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/LoggerRepository.java
rename to core/src/main/java/org/apache/log4j/spi/LoggerRepository.java
diff --git a/src/main/java/org/apache/log4j/spi/LoggingEvent.java b/core/src/main/java/org/apache/log4j/spi/LoggingEvent.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/LoggingEvent.java
rename to core/src/main/java/org/apache/log4j/spi/LoggingEvent.java
diff --git a/src/main/java/org/apache/log4j/spi/NOPLogger.java b/core/src/main/java/org/apache/log4j/spi/NOPLogger.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/NOPLogger.java
rename to core/src/main/java/org/apache/log4j/spi/NOPLogger.java
diff --git a/src/main/java/org/apache/log4j/spi/NOPLoggerRepository.java b/core/src/main/java/org/apache/log4j/spi/NOPLoggerRepository.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/NOPLoggerRepository.java
rename to core/src/main/java/org/apache/log4j/spi/NOPLoggerRepository.java
diff --git a/src/main/java/org/apache/log4j/spi/NullWriter.java b/core/src/main/java/org/apache/log4j/spi/NullWriter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/NullWriter.java
rename to core/src/main/java/org/apache/log4j/spi/NullWriter.java
diff --git a/src/main/java/org/apache/log4j/spi/OptionHandler.java b/core/src/main/java/org/apache/log4j/spi/OptionHandler.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/OptionHandler.java
rename to core/src/main/java/org/apache/log4j/spi/OptionHandler.java
diff --git a/src/main/java/org/apache/log4j/spi/RendererSupport.java b/core/src/main/java/org/apache/log4j/spi/RendererSupport.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/RendererSupport.java
rename to core/src/main/java/org/apache/log4j/spi/RendererSupport.java
diff --git a/src/main/java/org/apache/log4j/spi/RepositorySelector.java b/core/src/main/java/org/apache/log4j/spi/RepositorySelector.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/RepositorySelector.java
rename to core/src/main/java/org/apache/log4j/spi/RepositorySelector.java
diff --git a/src/main/java/org/apache/log4j/spi/RootCategory.java b/core/src/main/java/org/apache/log4j/spi/RootCategory.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/RootCategory.java
rename to core/src/main/java/org/apache/log4j/spi/RootCategory.java
diff --git a/src/main/java/org/apache/log4j/spi/RootLogger.java b/core/src/main/java/org/apache/log4j/spi/RootLogger.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/RootLogger.java
rename to core/src/main/java/org/apache/log4j/spi/RootLogger.java
diff --git a/src/main/java/org/apache/log4j/spi/ThrowableInformation.java b/core/src/main/java/org/apache/log4j/spi/ThrowableInformation.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/ThrowableInformation.java
rename to core/src/main/java/org/apache/log4j/spi/ThrowableInformation.java
diff --git a/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java b/core/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/ThrowableRenderer.java
rename to core/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java
diff --git a/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java b/core/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
rename to core/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
diff --git a/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java b/core/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java
rename to core/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java
diff --git a/src/main/java/org/apache/log4j/spi/VectorWriter.java b/core/src/main/java/org/apache/log4j/spi/VectorWriter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/VectorWriter.java
rename to core/src/main/java/org/apache/log4j/spi/VectorWriter.java
diff --git a/src/main/java/org/apache/log4j/spi/package.html b/core/src/main/java/org/apache/log4j/spi/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/spi/package.html
rename to core/src/main/java/org/apache/log4j/spi/package.html
diff --git a/src/main/java/org/apache/log4j/varia/DenyAllFilter.java b/core/src/main/java/org/apache/log4j/varia/DenyAllFilter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/DenyAllFilter.java
rename to core/src/main/java/org/apache/log4j/varia/DenyAllFilter.java
diff --git a/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java b/core/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java
rename to core/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java
diff --git a/src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java b/core/src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java
rename to core/src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java
diff --git a/src/main/java/org/apache/log4j/varia/LevelMatchFilter.java b/core/src/main/java/org/apache/log4j/varia/LevelMatchFilter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/LevelMatchFilter.java
rename to core/src/main/java/org/apache/log4j/varia/LevelMatchFilter.java
diff --git a/src/main/java/org/apache/log4j/varia/LevelRangeFilter.java b/core/src/main/java/org/apache/log4j/varia/LevelRangeFilter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/LevelRangeFilter.java
rename to core/src/main/java/org/apache/log4j/varia/LevelRangeFilter.java
diff --git a/src/main/java/org/apache/log4j/varia/NullAppender.java b/core/src/main/java/org/apache/log4j/varia/NullAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/NullAppender.java
rename to core/src/main/java/org/apache/log4j/varia/NullAppender.java
diff --git a/src/main/java/org/apache/log4j/varia/ReloadingPropertyConfigurator.java b/core/src/main/java/org/apache/log4j/varia/ReloadingPropertyConfigurator.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/ReloadingPropertyConfigurator.java
rename to core/src/main/java/org/apache/log4j/varia/ReloadingPropertyConfigurator.java
diff --git a/src/main/java/org/apache/log4j/varia/Roller.java b/core/src/main/java/org/apache/log4j/varia/Roller.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/Roller.java
rename to core/src/main/java/org/apache/log4j/varia/Roller.java
diff --git a/src/main/java/org/apache/log4j/varia/StringMatchFilter.java b/core/src/main/java/org/apache/log4j/varia/StringMatchFilter.java
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/StringMatchFilter.java
rename to core/src/main/java/org/apache/log4j/varia/StringMatchFilter.java
diff --git a/src/main/java/org/apache/log4j/varia/package.html b/core/src/main/java/org/apache/log4j/varia/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/varia/package.html
rename to core/src/main/java/org/apache/log4j/varia/package.html
diff --git a/src/main/java/org/apache/log4j/xml/DOMConfigurator.java b/core/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
similarity index 100%
rename from src/main/java/org/apache/log4j/xml/DOMConfigurator.java
rename to core/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
diff --git a/src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java b/core/src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java
similarity index 100%
rename from src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java
rename to core/src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java
diff --git a/src/main/java/org/apache/log4j/xml/SAXErrorHandler.java b/core/src/main/java/org/apache/log4j/xml/SAXErrorHandler.java
similarity index 100%
rename from src/main/java/org/apache/log4j/xml/SAXErrorHandler.java
rename to core/src/main/java/org/apache/log4j/xml/SAXErrorHandler.java
diff --git a/src/main/java/org/apache/log4j/xml/UnrecognizedElementHandler.java b/core/src/main/java/org/apache/log4j/xml/UnrecognizedElementHandler.java
similarity index 100%
rename from src/main/java/org/apache/log4j/xml/UnrecognizedElementHandler.java
rename to core/src/main/java/org/apache/log4j/xml/UnrecognizedElementHandler.java
diff --git a/src/main/java/org/apache/log4j/xml/XMLLayout.java b/core/src/main/java/org/apache/log4j/xml/XMLLayout.java
similarity index 100%
rename from src/main/java/org/apache/log4j/xml/XMLLayout.java
rename to core/src/main/java/org/apache/log4j/xml/XMLLayout.java
diff --git a/src/main/java/org/apache/log4j/xml/package.html b/core/src/main/java/org/apache/log4j/xml/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/xml/package.html
rename to core/src/main/java/org/apache/log4j/xml/package.html
diff --git a/src/main/javadoc/org/apache/log4j/xml/doc-files/log4j.dtd b/core/src/main/javadoc/org/apache/log4j/xml/docFiles/log4j.dtd
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/doc-files/log4j.dtd
rename to core/src/main/javadoc/org/apache/log4j/xml/docFiles/log4j.dtd
diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/XMLSample.java b/core/src/main/javadoc/org/apache/log4j/xml/examples/XMLSample.java
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/examples/XMLSample.java
rename to core/src/main/javadoc/org/apache/log4j/xml/examples/XMLSample.java
diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/XMLSample.java b/core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/XMLSample.java
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/examples/doc-files/XMLSample.java
rename to core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/XMLSample.java
diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample1.xml b/core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample1.xml
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample1.xml
rename to core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample1.xml
diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample2.xml b/core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample2.xml
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample2.xml
rename to core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample2.xml
diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample3.xml b/core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample3.xml
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample3.xml
rename to core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample3.xml
diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample4.xml b/core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample4.xml
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample4.xml
rename to core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample4.xml
diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample5.xml b/core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample5.xml
similarity index 100%
rename from src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample5.xml
rename to core/src/main/javadoc/org/apache/log4j/xml/examples/docFiles/sample5.xml
diff --git a/src/main/resources/META-INF/LICENSE b/core/src/main/resources/META-INF/LICENSE
similarity index 100%
rename from src/main/resources/META-INF/LICENSE
rename to core/src/main/resources/META-INF/LICENSE
diff --git a/src/main/resources/META-INF/NOTICE b/core/src/main/resources/META-INF/NOTICE
similarity index 100%
rename from src/main/resources/META-INF/NOTICE
rename to core/src/main/resources/META-INF/NOTICE
diff --git a/src/main/resources/org/apache/log4j/xml/log4j.dtd b/core/src/main/resources/org/apache/log4j/xml/log4j.dtd
similarity index 100%
rename from src/main/resources/org/apache/log4j/xml/log4j.dtd
rename to core/src/main/resources/org/apache/log4j/xml/log4j.dtd
diff --git a/src/site/apt/download.apt b/core/src/site/apt/download.apt
similarity index 100%
rename from src/site/apt/download.apt
rename to core/src/site/apt/download.apt
diff --git a/src/site/apt/index.apt b/core/src/site/apt/index.apt
similarity index 100%
rename from src/site/apt/index.apt
rename to core/src/site/apt/index.apt
diff --git a/src/site/apt/publications.apt b/core/src/site/apt/publications.apt
similarity index 100%
rename from src/site/apt/publications.apt
rename to core/src/site/apt/publications.apt
diff --git a/src/site/apt/roadmap.apt b/core/src/site/apt/roadmap.apt
similarity index 100%
rename from src/site/apt/roadmap.apt
rename to core/src/site/apt/roadmap.apt
diff --git a/src/site/fml/faq.fml b/core/src/site/fml/faq.fml
similarity index 100%
rename from src/site/fml/faq.fml
rename to core/src/site/fml/faq.fml
diff --git a/src/site/resources/css/site.css b/core/src/site/resources/css/site.css
similarity index 100%
rename from src/site/resources/css/site.css
rename to core/src/site/resources/css/site.css
diff --git a/src/site/resources/images/logo.jpg b/core/src/site/resources/images/logo.jpg
similarity index 100%
rename from src/site/resources/images/logo.jpg
rename to core/src/site/resources/images/logo.jpg
diff --git a/src/site/resources/images/ls-logo.jpg b/core/src/site/resources/images/ls-logo.jpg
similarity index 100%
rename from src/site/resources/images/ls-logo.jpg
rename to core/src/site/resources/images/ls-logo.jpg
diff --git a/src/site/resources/images/od.gif b/core/src/site/resources/images/od.gif
similarity index 100%
rename from src/site/resources/images/od.gif
rename to core/src/site/resources/images/od.gif
diff --git a/src/site/site.xml b/core/src/site/site.xml
similarity index 100%
rename from src/site/site.xml
rename to core/src/site/site.xml
diff --git a/src/site/xdoc/manual.xml b/core/src/site/xdoc/manual.xml
similarity index 100%
rename from src/site/xdoc/manual.xml
rename to core/src/site/xdoc/manual.xml
diff --git a/tests/README b/core/src/test/README
similarity index 100%
rename from tests/README
rename to core/src/test/README
diff --git a/tests/build.properties.sample b/core/src/test/build.properties.sample
similarity index 100%
rename from tests/build.properties.sample
rename to core/src/test/build.properties.sample
diff --git a/tests/src/java/org/apache/log4j/AsyncAppenderTestCase.java b/core/src/test/java/org/apache/log4j/AsyncAppenderTestCase.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/AsyncAppenderTestCase.java
rename to core/src/test/java/org/apache/log4j/AsyncAppenderTestCase.java
diff --git a/tests/src/java/org/apache/log4j/CategoryTest.java b/core/src/test/java/org/apache/log4j/CategoryTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/CategoryTest.java
rename to core/src/test/java/org/apache/log4j/CategoryTest.java
diff --git a/tests/src/java/org/apache/log4j/CoreTestSuite.java b/core/src/test/java/org/apache/log4j/CoreTestSuite.java
similarity index 95%
rename from tests/src/java/org/apache/log4j/CoreTestSuite.java
rename to core/src/test/java/org/apache/log4j/CoreTestSuite.java
index 82ab97de4c..f72d9b575e 100644
--- a/tests/src/java/org/apache/log4j/CoreTestSuite.java
+++ b/core/src/test/java/org/apache/log4j/CoreTestSuite.java
@@ -49,8 +49,6 @@ public static Test suite() {
s.addTestSuite(org.apache.log4j.spi.ThrowableInformationTest.class);
s.addTestSuite(org.apache.log4j.spi.LocationInfoTest.class);
s.addTestSuite(org.apache.log4j.PropertyConfiguratorTest.class);
- s.addTestSuite(org.apache.log4j.net.SMTPAppenderTest.class);
- s.addTestSuite(org.apache.log4j.net.TelnetAppenderTest.class);
s.addTestSuite(org.apache.log4j.DefaultThrowableRendererTest.class);
s.addTestSuite(org.apache.log4j.EnhancedThrowableRendererTest.class);
s.addTestSuite(org.apache.log4j.TestLogXF.class);
diff --git a/tests/src/java/org/apache/log4j/DRFATestCase.java b/core/src/test/java/org/apache/log4j/DRFATestCase.java
similarity index 99%
rename from tests/src/java/org/apache/log4j/DRFATestCase.java
rename to core/src/test/java/org/apache/log4j/DRFATestCase.java
index 8d0417422f..68b72ac944 100644
--- a/tests/src/java/org/apache/log4j/DRFATestCase.java
+++ b/core/src/test/java/org/apache/log4j/DRFATestCase.java
@@ -494,7 +494,7 @@ public void testBlockedRollover() throws IOException, InterruptedException {
append(combined, new FileInputStream(filename), buf);
combined.close();
assertTrue(Compare.compare(combinedFilename,
- "witness/drfa_blockedRollover.log"));
+ "target/test-classes/witness/drfa_blockedRollover.log"));
}
/** Check that the computed rollover period for a pattern containing a week as the finest unit is set to be
diff --git a/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java b/core/src/test/java/org/apache/log4j/DefaultThrowableRendererTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java
rename to core/src/test/java/org/apache/log4j/DefaultThrowableRendererTest.java
diff --git a/tests/src/java/org/apache/log4j/EnhancedMyPatternLayout.java b/core/src/test/java/org/apache/log4j/EnhancedMyPatternLayout.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/EnhancedMyPatternLayout.java
rename to core/src/test/java/org/apache/log4j/EnhancedMyPatternLayout.java
diff --git a/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTest.java b/core/src/test/java/org/apache/log4j/EnhancedPatternLayoutTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/EnhancedPatternLayoutTest.java
rename to core/src/test/java/org/apache/log4j/EnhancedPatternLayoutTest.java
diff --git a/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java b/core/src/test/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java
similarity index 85%
rename from tests/src/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java
rename to core/src/test/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java
index e97c42f737..34d186f665 100644
--- a/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java
+++ b/core/src/test/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java
@@ -40,6 +40,8 @@
public class EnhancedPatternLayoutTestCase extends TestCase {
+ static final String FILE_PREFIX = "target/test-classes/";
+
static String TEMP = "output/temp";
static String FILTERED = "output/filtered";
static String EXCEPTION1 = "java.lang.Exception: Just testing";
@@ -111,7 +113,7 @@ private static boolean compare(final String actual,
}
public void test1() throws Exception {
- configure("input/pattern/enhancedPatternLayout1.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout1.properties");
common();
Transformer.transform(
TEMP, FILTERED,
@@ -119,11 +121,11 @@ public void test1() throws Exception {
new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.1"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.1"));
}
public void test2() throws Exception {
- configure("input/pattern/enhancedPatternLayout2.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout2.properties");
common();
ControlFilter cf1 =
@@ -135,11 +137,11 @@ public void test2() throws Exception {
cf1, new EnhancedLineNumberFilter(), new ISO8601Filter(),
new SunReflectFilter(), new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.2"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.2"));
}
public void test3() throws Exception {
- configure("input/pattern/enhancedPatternLayout3.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout3.properties");
common();
ControlFilter cf1 =
@@ -151,13 +153,13 @@ public void test3() throws Exception {
cf1, new EnhancedLineNumberFilter(), new ISO8601Filter(),
new SunReflectFilter(), new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.3"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.3"));
}
// Output format:
// 06 avr. 2002 18:30:58,937 [main] DEBUG atternLayoutTest - Message 0
public void test4() throws Exception {
- configure("input/pattern/enhancedPatternLayout4.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout4.properties");
common();
ControlFilter cf1 =
@@ -169,11 +171,11 @@ public void test4() throws Exception {
cf1, new EnhancedLineNumberFilter(), new AbsoluteDateAndTimeFilter(),
new SunReflectFilter(), new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.4"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.4"));
}
public void test5() throws Exception {
- configure("input/pattern/enhancedPatternLayout5.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout5.properties");
common();
ControlFilter cf1 =
@@ -185,12 +187,12 @@ public void test5() throws Exception {
cf1, new EnhancedLineNumberFilter(), new AbsoluteDateAndTimeFilter(),
new SunReflectFilter(), new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.5"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.5"));
}
// 18:54:19,201 [main] DEBUG atternLayoutTest - Message 0
public void test6() throws Exception {
- configure("input/pattern/enhancedPatternLayout6.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout6.properties");
common();
ControlFilter cf1 =
@@ -202,11 +204,11 @@ public void test6() throws Exception {
cf1, new EnhancedLineNumberFilter(), new AbsoluteTimeFilter(),
new SunReflectFilter(), new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.6"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.6"));
}
public void test7() throws Exception {
- configure("input/pattern/enhancedPatternLayout7.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout7.properties");
common();
ControlFilter cf1 =
@@ -218,11 +220,11 @@ public void test7() throws Exception {
cf1, new EnhancedLineNumberFilter(), new AbsoluteTimeFilter(),
new SunReflectFilter(), new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.7"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.7"));
}
public void test8() throws Exception {
- configure("input/pattern/enhancedPatternLayout8.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout8.properties");
common();
ControlFilter cf1 =
@@ -234,11 +236,11 @@ public void test8() throws Exception {
cf1, new EnhancedLineNumberFilter(), new RelativeTimeFilter(),
new SunReflectFilter(), new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.8"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.8"));
}
public void test9() throws Exception {
- configure("input/pattern/enhancedPatternLayout9.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout9.properties");
common();
ControlFilter cf1 =
@@ -250,11 +252,11 @@ public void test9() throws Exception {
cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.9"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.9"));
}
public void test10() throws Exception {
- configure("input/pattern/enhancedPatternLayout10.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout10.properties");
common();
ControlFilter cf1 =
@@ -266,11 +268,11 @@ public void test10() throws Exception {
cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.10"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.10"));
}
public void test11() throws Exception {
- configure("input/pattern/enhancedPatternLayout11.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout11.properties");
common();
ControlFilter cf1 =
@@ -282,11 +284,11 @@ public void test11() throws Exception {
cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.11"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.11"));
}
public void test12() throws Exception {
- configure("input/pattern/enhancedPatternLayout12.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout12.properties");
common();
ControlFilter cf1 =
@@ -298,11 +300,11 @@ public void test12() throws Exception {
cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.12"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.12"));
}
public void test13() throws Exception {
- configure("input/pattern/enhancedPatternLayout13.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout13.properties");
common();
ControlFilter cf1 =
@@ -314,7 +316,7 @@ public void test13() throws Exception {
cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.13"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.13"));
}
/**
@@ -323,7 +325,7 @@ cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
* @throws Exception
*/
public void test14() throws Exception {
- configure("input/pattern/enhancedPatternLayout14.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout14.properties");
common();
Transformer.transform(
@@ -332,7 +334,7 @@ public void test14() throws Exception {
new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.14"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.14"));
}
@@ -344,7 +346,7 @@ private static void clearMDC() throws Exception {
}
public void testMDC1() throws Exception {
- configure("input/pattern/enhancedPatternLayout.mdc.1.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout.mdc.1.properties");
clearMDC();
MDC.put("key1", "va11");
MDC.put("key2", "va12");
@@ -359,7 +361,7 @@ public void testMDC1() throws Exception {
new EnhancedJunitTestRunnerFilter(),
new MDCOrderFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.mdc.1"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.mdc.1"));
}
/**
* Tests log4j 1.2 style extension of EnhancedPatternLayout.
@@ -367,7 +369,7 @@ public void testMDC1() throws Exception {
* @throws Exception
*/
public void test15() throws Exception {
- configure("input/pattern/enhancedPatternLayout15.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout15.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT14, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4});
@@ -377,7 +379,7 @@ public void test15() throws Exception {
cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
new EnhancedJunitTestRunnerFilter()
});
- assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.15"));
+ assertTrue(compare(FILTERED, FILE_PREFIX + "witness/pattern/enhancedPatternLayout.15"));
}
/**
* Tests explicit UTC time zone in pattern.
@@ -385,7 +387,7 @@ cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(),
*/
public void test16() throws Exception {
final long start = new Date().getTime();
- configure("input/pattern/enhancedPatternLayout16.properties");
+ configure(FILE_PREFIX + "input/pattern/enhancedPatternLayout16.properties");
common();
final long end = new Date().getTime();
FileReader reader = new FileReader("output/patternLayout16.log");
@@ -435,7 +437,7 @@ void common() {
Test case for MDC conversion pattern. */
public void testMDC2() throws Exception {
String OUTPUT_FILE = "output/patternLayout.mdc.2";
- String WITNESS_FILE = "witness/pattern/enhancedPatternLayout.mdc.2";
+ String WITNESS_FILE = FILE_PREFIX + "witness/pattern/enhancedPatternLayout.mdc.2";
String mdcMsgPattern1 = "%m : %X%n";
String mdcMsgPattern2 = "%m : %X{key1}%n";
@@ -520,7 +522,7 @@ public void testMDC2() throws Exception {
Test case for throwable conversion pattern. */
public void testThrowable() throws Exception {
String OUTPUT_FILE = "output/patternLayout.throwable";
- String WITNESS_FILE = "witness/pattern/enhancedPatternLayout.throwable";
+ String WITNESS_FILE = FILE_PREFIX + "witness/pattern/enhancedPatternLayout.throwable";
// set up appender
diff --git a/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java b/core/src/test/java/org/apache/log4j/EnhancedThrowableRendererTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java
rename to core/src/test/java/org/apache/log4j/EnhancedThrowableRendererTest.java
diff --git a/tests/src/java/org/apache/log4j/FileAppenderTest.java b/core/src/test/java/org/apache/log4j/FileAppenderTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/FileAppenderTest.java
rename to core/src/test/java/org/apache/log4j/FileAppenderTest.java
diff --git a/tests/src/java/org/apache/log4j/HTMLLayoutTest.java b/core/src/test/java/org/apache/log4j/HTMLLayoutTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/HTMLLayoutTest.java
rename to core/src/test/java/org/apache/log4j/HTMLLayoutTest.java
diff --git a/tests/src/java/org/apache/log4j/HierarchyThresholdTestCase.java b/core/src/test/java/org/apache/log4j/HierarchyThresholdTestCase.java
similarity index 66%
rename from tests/src/java/org/apache/log4j/HierarchyThresholdTestCase.java
rename to core/src/test/java/org/apache/log4j/HierarchyThresholdTestCase.java
index 3e885bde4f..7ae45c3e2e 100644
--- a/tests/src/java/org/apache/log4j/HierarchyThresholdTestCase.java
+++ b/core/src/test/java/org/apache/log4j/HierarchyThresholdTestCase.java
@@ -30,6 +30,10 @@
@author Ceki Gülcü
*/
public class HierarchyThresholdTestCase extends TestCase {
+
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
static String TEMP = "output/temp";
static Logger logger = Logger.getLogger(HierarchyThresholdTestCase.class);
@@ -47,51 +51,51 @@ public void tearDown() {
}
public void test1() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold1.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold1.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.1"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.1"));
}
public void test2() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold2.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold2.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.2"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.2"));
}
public void test3() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold3.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold3.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.3"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.3"));
}
public void test4() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold4.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold4.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.4"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.4"));
}
public void test5() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold5.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold5.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.5"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.5"));
}
public void test6() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold6.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold6.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.6"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.6"));
}
public void test7() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold7.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold7.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.7"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.7"));
}
public void test8() throws Exception {
- PropertyConfigurator.configure("input/hierarchyThreshold8.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/hierarchyThreshold8.properties");
common();
- assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.8"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/hierarchyThreshold.8"));
}
diff --git a/tests/src/java/org/apache/log4j/Last.java b/core/src/test/java/org/apache/log4j/Last.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/Last.java
rename to core/src/test/java/org/apache/log4j/Last.java
diff --git a/tests/src/java/org/apache/log4j/LayoutTest.java b/core/src/test/java/org/apache/log4j/LayoutTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/LayoutTest.java
rename to core/src/test/java/org/apache/log4j/LayoutTest.java
diff --git a/tests/src/java/org/apache/log4j/LevelTest.java b/core/src/test/java/org/apache/log4j/LevelTest.java
similarity index 97%
rename from tests/src/java/org/apache/log4j/LevelTest.java
rename to core/src/test/java/org/apache/log4j/LevelTest.java
index 8ed550c17d..4374e5da96 100644
--- a/tests/src/java/org/apache/log4j/LevelTest.java
+++ b/core/src/test/java/org/apache/log4j/LevelTest.java
@@ -46,7 +46,7 @@ public LevelTest(final String name) {
public void testSerializeINFO() throws Exception {
int[] skip = new int[] { };
SerializationTestHelper.assertSerializationEquals(
- "witness/serialization/info.bin", Level.INFO, skip, Integer.MAX_VALUE);
+ "target/test-classes/witness/serialization/info.bin", Level.INFO, skip, Integer.MAX_VALUE);
}
/**
@@ -56,7 +56,7 @@ public void testSerializeINFO() throws Exception {
public void testDeserializeINFO() throws Exception {
Object obj =
SerializationTestHelper.deserializeStream(
- "witness/serialization/info.bin");
+ "target/test-classes/witness/serialization/info.bin");
assertTrue(obj instanceof Level);
Level info = (Level) obj;
assertEquals("INFO", info.toString());
diff --git a/tests/src/java/org/apache/log4j/LogCapture.java b/core/src/test/java/org/apache/log4j/LogCapture.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/LogCapture.java
rename to core/src/test/java/org/apache/log4j/LogCapture.java
diff --git a/tests/src/java/org/apache/log4j/LogManagerTest.java b/core/src/test/java/org/apache/log4j/LogManagerTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/LogManagerTest.java
rename to core/src/test/java/org/apache/log4j/LogManagerTest.java
diff --git a/tests/src/java/org/apache/log4j/LoggerTestCase.java b/core/src/test/java/org/apache/log4j/LoggerTestCase.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/LoggerTestCase.java
rename to core/src/test/java/org/apache/log4j/LoggerTestCase.java
diff --git a/tests/src/java/org/apache/log4j/MinimumTestCase.java b/core/src/test/java/org/apache/log4j/MinimumTestCase.java
similarity index 95%
rename from tests/src/java/org/apache/log4j/MinimumTestCase.java
rename to core/src/test/java/org/apache/log4j/MinimumTestCase.java
index 50d1503f7b..568b22a034 100644
--- a/tests/src/java/org/apache/log4j/MinimumTestCase.java
+++ b/core/src/test/java/org/apache/log4j/MinimumTestCase.java
@@ -29,6 +29,10 @@
*/
public class MinimumTestCase extends TestCase {
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
+
static String FILTERED = "output/filtered";
static String EXCEPTION1 = "java.lang.Exception: Just testing";
@@ -75,7 +79,7 @@ public void simple() throws Exception {
new Filter[] { new LineNumberFilter(),
new SunReflectFilter(),
new JunitTestRunnerFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/simple"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/simple"));
}
public void ttcc() throws Exception {
@@ -101,7 +105,7 @@ cf1, new LineNumberFilter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/ttcc"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/ttcc"));
}
diff --git a/tests/src/java/org/apache/log4j/MyPatternLayout.java b/core/src/test/java/org/apache/log4j/MyPatternLayout.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/MyPatternLayout.java
rename to core/src/test/java/org/apache/log4j/MyPatternLayout.java
diff --git a/tests/src/java/org/apache/log4j/MyPatternParser.java b/core/src/test/java/org/apache/log4j/MyPatternParser.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/MyPatternParser.java
rename to core/src/test/java/org/apache/log4j/MyPatternParser.java
diff --git a/tests/src/java/org/apache/log4j/PatternLayoutTest.java b/core/src/test/java/org/apache/log4j/PatternLayoutTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/PatternLayoutTest.java
rename to core/src/test/java/org/apache/log4j/PatternLayoutTest.java
diff --git a/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java b/core/src/test/java/org/apache/log4j/PatternLayoutTestCase.java
similarity index 79%
rename from tests/src/java/org/apache/log4j/PatternLayoutTestCase.java
rename to core/src/test/java/org/apache/log4j/PatternLayoutTestCase.java
index 9578523097..10ed06a000 100644
--- a/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java
+++ b/core/src/test/java/org/apache/log4j/PatternLayoutTestCase.java
@@ -32,6 +32,10 @@
public class PatternLayoutTestCase extends TestCase {
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
+
static String TEMP = "output/temp";
static String FILTERED = "output/filtered";
@@ -80,7 +84,7 @@ public void tearDown() {
}
public void test1() throws Exception {
- PropertyConfigurator.configure("input/patternLayout1.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout1.properties");
common();
Transformer.transform(
TEMP, FILTERED,
@@ -88,11 +92,11 @@ public void test1() throws Exception {
new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.1"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.1"));
}
public void test2() throws Exception {
- PropertyConfigurator.configure("input/patternLayout2.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout2.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT1, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -102,11 +106,11 @@ public void test2() throws Exception {
cf1, new LineNumberFilter(), new ISO8601Filter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.2"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.2"));
}
public void test3() throws Exception {
- PropertyConfigurator.configure("input/patternLayout3.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout3.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT1, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -116,13 +120,13 @@ public void test3() throws Exception {
cf1, new LineNumberFilter(), new ISO8601Filter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.3"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.3"));
}
// Output format:
// 06 avr. 2002 18:30:58,937 [main] DEBUG rnLayoutTestCase - Message 0
public void test4() throws Exception {
- PropertyConfigurator.configure("input/patternLayout4.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout4.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT2, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -132,11 +136,11 @@ public void test4() throws Exception {
cf1, new LineNumberFilter(), new AbsoluteDateAndTimeFilter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.4"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.4"));
}
public void test5() throws Exception {
- PropertyConfigurator.configure("input/patternLayout5.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout5.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT2, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -146,12 +150,12 @@ public void test5() throws Exception {
cf1, new LineNumberFilter(), new AbsoluteDateAndTimeFilter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.5"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.5"));
}
// 18:54:19,201 [main] DEBUG rnLayoutTestCase - Message 0
public void test6() throws Exception {
- PropertyConfigurator.configure("input/patternLayout6.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout6.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT3, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -161,12 +165,12 @@ public void test6() throws Exception {
cf1, new LineNumberFilter(), new AbsoluteTimeFilter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.6"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.6"));
}
public void test7() throws Exception {
- PropertyConfigurator.configure("input/patternLayout7.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout7.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT3, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -176,11 +180,11 @@ public void test7() throws Exception {
cf1, new LineNumberFilter(), new AbsoluteTimeFilter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.7"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.7"));
}
public void test8() throws Exception {
- PropertyConfigurator.configure("input/patternLayout8.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout8.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT4, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -190,11 +194,11 @@ public void test8() throws Exception {
cf1, new LineNumberFilter(), new RelativeTimeFilter(),
new SunReflectFilter(), new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.8"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.8"));
}
public void test9() throws Exception {
- PropertyConfigurator.configure("input/patternLayout9.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout9.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT5, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -204,11 +208,11 @@ public void test9() throws Exception {
cf1, new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.9"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.9"));
}
public void test10() throws Exception {
- PropertyConfigurator.configure("input/patternLayout10.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout10.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT6, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -218,11 +222,11 @@ public void test10() throws Exception {
cf1, new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.10"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.10"));
}
public void test11() throws Exception {
- PropertyConfigurator.configure("input/patternLayout11.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout11.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT11a, PAT11b, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -232,11 +236,11 @@ public void test11() throws Exception {
cf1, new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.11"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.11"));
}
public void test12() throws Exception {
- PropertyConfigurator.configure("input/patternLayout12.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout12.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT12, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -246,11 +250,11 @@ public void test12() throws Exception {
cf1, new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.12"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.12"));
}
public void test13() throws Exception {
- PropertyConfigurator.configure("input/patternLayout13.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout13.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT13, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -260,11 +264,11 @@ public void test13() throws Exception {
cf1, new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.13"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.13"));
}
public void test14() throws Exception {
- PropertyConfigurator.configure("input/patternLayout14.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout14.properties");
common();
ControlFilter cf1 = new ControlFilter(new String[]{PAT14, EXCEPTION1,
EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5});
@@ -274,29 +278,29 @@ public void test14() throws Exception {
cf1, new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/patternLayout.14"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/patternLayout.14"));
}
public void testMDC1() throws Exception {
- PropertyConfigurator.configure("input/patternLayout.mdc.1.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout.mdc.1.properties");
MDC.put("key1", "va11");
MDC.put("key2", "va12");
logger.debug("Hello World");
MDC.remove("key1");
MDC.remove("key2");
- assertTrue(Compare.compare(TEMP, "witness/patternLayout.mdc.1"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/patternLayout.mdc.1"));
}
public void testMDCClear() throws Exception {
- PropertyConfigurator.configure("input/patternLayout.mdc.1.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/patternLayout.mdc.1.properties");
MDC.put("key1", "va11");
MDC.put("key2", "va12");
logger.debug("Hello World");
MDC.clear();
logger.debug("Hello World");
- assertTrue(Compare.compare(TEMP, "witness/patternLayout.mdc.clear"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/patternLayout.mdc.clear"));
}
diff --git a/tests/src/java/org/apache/log4j/PriorityTest.java b/core/src/test/java/org/apache/log4j/PriorityTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/PriorityTest.java
rename to core/src/test/java/org/apache/log4j/PriorityTest.java
diff --git a/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java b/core/src/test/java/org/apache/log4j/PropertyConfiguratorTest.java
similarity index 88%
rename from tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java
rename to core/src/test/java/org/apache/log4j/PropertyConfiguratorTest.java
index 4b5e030197..c8b4eef7ab 100644
--- a/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java
+++ b/core/src/test/java/org/apache/log4j/PropertyConfiguratorTest.java
@@ -40,6 +40,11 @@
*
*/
public class PropertyConfiguratorTest extends TestCase {
+
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
+
public PropertyConfiguratorTest(final String testName) {
super(testName);
}
@@ -311,12 +316,20 @@ public void append(final LoggingEvent event) {
* Tests processing of nested objects, see bug 36384.
*/
public void testNested() {
- try {
- PropertyConfigurator.configure("input/filter1.properties");
- this.validateNested();
- } finally {
- LogManager.resetConfiguration();
- }
+ PropertyConfigurator.configure(INPUT_DIR + "/filter1.properties");
+ RollingFileAppender rfa = (RollingFileAppender)
+ Logger.getLogger("org.apache.log4j.PropertyConfiguratorTest")
+ .getAppender("ROLLING");
+ FixedWindowRollingPolicy rollingPolicy = (FixedWindowRollingPolicy) rfa.getRollingPolicy();
+ assertEquals("filterBase-test1.log", rollingPolicy.getActiveFileName());
+ assertEquals("filterBased-test1.%i", rollingPolicy.getFileNamePattern());
+ assertEquals(0, rollingPolicy.getMinIndex());
+ assertTrue(rollingPolicy.isActivated());
+ FilterBasedTriggeringPolicy triggeringPolicy =
+ (FilterBasedTriggeringPolicy) rfa.getTriggeringPolicy();
+ LevelRangeFilter filter = (LevelRangeFilter) triggeringPolicy.getFilter();
+ assertTrue(Level.INFO.equals(filter.getLevelMin()));
+ LogManager.resetConfiguration();
}
diff --git a/tests/src/java/org/apache/log4j/RFATestCase.java b/core/src/test/java/org/apache/log4j/RFATestCase.java
similarity index 96%
rename from tests/src/java/org/apache/log4j/RFATestCase.java
rename to core/src/test/java/org/apache/log4j/RFATestCase.java
index 0d11fc200d..d1537ab18a 100644
--- a/tests/src/java/org/apache/log4j/RFATestCase.java
+++ b/core/src/test/java/org/apache/log4j/RFATestCase.java
@@ -30,6 +30,10 @@
*/
public class RFATestCase extends TestCase {
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
+
public RFATestCase(String name) {
super(name);
}
@@ -43,7 +47,7 @@ public void tearDown() {
*/
public void test1() throws Exception {
Logger logger = Logger.getLogger(RFATestCase.class);
- PropertyConfigurator.configure("input/RFA1.properties");
+ PropertyConfigurator.configure(INPUT_DIR + "/RFA1.properties");
// Write exactly 10 bytes with each log
for (int i = 0; i < 25; i++) {
diff --git a/tests/src/java/org/apache/log4j/StressCategory.java b/core/src/test/java/org/apache/log4j/StressCategory.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/StressCategory.java
rename to core/src/test/java/org/apache/log4j/StressCategory.java
diff --git a/tests/src/java/org/apache/log4j/TTCCLayoutTest.java b/core/src/test/java/org/apache/log4j/TTCCLayoutTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/TTCCLayoutTest.java
rename to core/src/test/java/org/apache/log4j/TTCCLayoutTest.java
diff --git a/tests/src/java/org/apache/log4j/TestLogMF.java b/core/src/test/java/org/apache/log4j/TestLogMF.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/TestLogMF.java
rename to core/src/test/java/org/apache/log4j/TestLogMF.java
diff --git a/tests/src/java/org/apache/log4j/TestLogSF.java b/core/src/test/java/org/apache/log4j/TestLogSF.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/TestLogSF.java
rename to core/src/test/java/org/apache/log4j/TestLogSF.java
diff --git a/tests/src/java/org/apache/log4j/TestLogXF.java b/core/src/test/java/org/apache/log4j/TestLogXF.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/TestLogXF.java
rename to core/src/test/java/org/apache/log4j/TestLogXF.java
diff --git a/tests/src/java/org/apache/log4j/VectorAppender.java b/core/src/test/java/org/apache/log4j/VectorAppender.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/VectorAppender.java
rename to core/src/test/java/org/apache/log4j/VectorAppender.java
diff --git a/tests/src/java/org/apache/log4j/VectorErrorHandler.java b/core/src/test/java/org/apache/log4j/VectorErrorHandler.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/VectorErrorHandler.java
rename to core/src/test/java/org/apache/log4j/VectorErrorHandler.java
diff --git a/tests/src/java/org/apache/log4j/customLogger/XLogger.java b/core/src/test/java/org/apache/log4j/customLogger/XLogger.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/customLogger/XLogger.java
rename to core/src/test/java/org/apache/log4j/customLogger/XLogger.java
diff --git a/tests/src/java/org/apache/log4j/customLogger/XLoggerTestCase.java b/core/src/test/java/org/apache/log4j/customLogger/XLoggerTestCase.java
similarity index 92%
rename from tests/src/java/org/apache/log4j/customLogger/XLoggerTestCase.java
rename to core/src/test/java/org/apache/log4j/customLogger/XLoggerTestCase.java
index ac05b765ca..f30d356005 100644
--- a/tests/src/java/org/apache/log4j/customLogger/XLoggerTestCase.java
+++ b/core/src/test/java/org/apache/log4j/customLogger/XLoggerTestCase.java
@@ -46,7 +46,7 @@ public void tearDown() {
public void test2() throws Exception { common(2); }
void common(int number) throws Exception {
- DOMConfigurator.configure("input/xml/customLogger"+number+".xml");
+ DOMConfigurator.configure("target/test-classes/input/xml/customLogger"+number+".xml");
int i = -1;
@@ -64,7 +64,7 @@ void common(int number) throws Exception {
new LineNumberFilter(), new SunReflectFilter(),
new JunitTestRunnerFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/customLogger."+number));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/customLogger."+number));
}
diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase1.java b/core/src/test/java/org/apache/log4j/defaultInit/TestCase1.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/defaultInit/TestCase1.java
rename to core/src/test/java/org/apache/log4j/defaultInit/TestCase1.java
diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase2.java b/core/src/test/java/org/apache/log4j/defaultInit/TestCase2.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/defaultInit/TestCase2.java
rename to core/src/test/java/org/apache/log4j/defaultInit/TestCase2.java
diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase3.java b/core/src/test/java/org/apache/log4j/defaultInit/TestCase3.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/defaultInit/TestCase3.java
rename to core/src/test/java/org/apache/log4j/defaultInit/TestCase3.java
diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase4.java b/core/src/test/java/org/apache/log4j/defaultInit/TestCase4.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/defaultInit/TestCase4.java
rename to core/src/test/java/org/apache/log4j/defaultInit/TestCase4.java
diff --git a/tests/src/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java b/core/src/test/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java
rename to core/src/test/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java
diff --git a/tests/src/java/org/apache/log4j/helpers/CyclicBufferTestCase.java b/core/src/test/java/org/apache/log4j/helpers/CyclicBufferTestCase.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/helpers/CyclicBufferTestCase.java
rename to core/src/test/java/org/apache/log4j/helpers/CyclicBufferTestCase.java
diff --git a/tests/src/java/org/apache/log4j/helpers/DateLayoutTest.java b/core/src/test/java/org/apache/log4j/helpers/DateLayoutTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/helpers/DateLayoutTest.java
rename to core/src/test/java/org/apache/log4j/helpers/DateLayoutTest.java
diff --git a/tests/src/java/org/apache/log4j/helpers/LogLogTest.java b/core/src/test/java/org/apache/log4j/helpers/LogLogTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/helpers/LogLogTest.java
rename to core/src/test/java/org/apache/log4j/helpers/LogLogTest.java
diff --git a/tests/src/java/org/apache/log4j/helpers/OptionConverterTestCase.java b/core/src/test/java/org/apache/log4j/helpers/OptionConverterTestCase.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/helpers/OptionConverterTestCase.java
rename to core/src/test/java/org/apache/log4j/helpers/OptionConverterTestCase.java
diff --git a/tests/src/java/org/apache/log4j/helpers/PatternParserTestCase.java b/core/src/test/java/org/apache/log4j/helpers/PatternParserTestCase.java
similarity index 98%
rename from tests/src/java/org/apache/log4j/helpers/PatternParserTestCase.java
rename to core/src/test/java/org/apache/log4j/helpers/PatternParserTestCase.java
index 872e15faa0..f0d113be44 100644
--- a/tests/src/java/org/apache/log4j/helpers/PatternParserTestCase.java
+++ b/core/src/test/java/org/apache/log4j/helpers/PatternParserTestCase.java
@@ -39,7 +39,7 @@ class tests PatternParser via the PatternLayout class which
public class PatternParserTestCase extends TestCase {
static String OUTPUT_FILE = "output/PatternParser";
- static String WITNESS_FILE = "witness/PatternParser";
+ static String WITNESS_FILE = "target/test-classes/witness/PatternParser";
static String msgPattern = "%m%n";
diff --git a/tests/src/java/org/apache/log4j/or/ORTestCase.java b/core/src/test/java/org/apache/log4j/or/ORTestCase.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/or/ORTestCase.java
rename to core/src/test/java/org/apache/log4j/or/ORTestCase.java
diff --git a/tests/src/java/org/apache/log4j/pattern/CachedDateFormatTest.java b/core/src/test/java/org/apache/log4j/pattern/CachedDateFormatTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/pattern/CachedDateFormatTest.java
rename to core/src/test/java/org/apache/log4j/pattern/CachedDateFormatTest.java
diff --git a/tests/src/java/org/apache/log4j/pattern/FormattingInfoTest.java b/core/src/test/java/org/apache/log4j/pattern/FormattingInfoTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/pattern/FormattingInfoTest.java
rename to core/src/test/java/org/apache/log4j/pattern/FormattingInfoTest.java
diff --git a/tests/src/java/org/apache/log4j/pattern/NameAbbreviatorTest.java b/core/src/test/java/org/apache/log4j/pattern/NameAbbreviatorTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/pattern/NameAbbreviatorTest.java
rename to core/src/test/java/org/apache/log4j/pattern/NameAbbreviatorTest.java
diff --git a/tests/src/java/org/apache/log4j/pattern/Num343PatternConverter.java b/core/src/test/java/org/apache/log4j/pattern/Num343PatternConverter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/pattern/Num343PatternConverter.java
rename to core/src/test/java/org/apache/log4j/pattern/Num343PatternConverter.java
diff --git a/tests/src/java/org/apache/log4j/pattern/PatternParserTest.java b/core/src/test/java/org/apache/log4j/pattern/PatternParserTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/pattern/PatternParserTest.java
rename to core/src/test/java/org/apache/log4j/pattern/PatternParserTest.java
diff --git a/tests/src/java/org/apache/log4j/spi/LocationInfoTest.java b/core/src/test/java/org/apache/log4j/spi/LocationInfoTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/spi/LocationInfoTest.java
rename to core/src/test/java/org/apache/log4j/spi/LocationInfoTest.java
diff --git a/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java b/core/src/test/java/org/apache/log4j/spi/LoggingEventTest.java
similarity index 92%
rename from tests/src/java/org/apache/log4j/spi/LoggingEventTest.java
rename to core/src/test/java/org/apache/log4j/spi/LoggingEventTest.java
index 9dbec3a520..5b7e49a7ee 100644
--- a/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java
+++ b/core/src/test/java/org/apache/log4j/spi/LoggingEventTest.java
@@ -34,6 +34,11 @@
* @author Curt Arnold
*/
public class LoggingEventTest extends TestCase {
+
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
+
/**
* Create LoggingEventTest.
*
@@ -57,7 +62,7 @@ public void testSerializationSimple() throws Exception {
int[] skip = new int[] { 352, 353, 354, 355, 356 };
SerializationTestHelper.assertSerializationEquals(
- "witness/serialization/simple.bin", event, skip, 237);
+ WITNESS_DIR + "/serialization/simple.bin", event, skip, 237);
}
/**
@@ -76,7 +81,7 @@ public void testSerializationWithException() throws Exception {
int[] skip = new int[] { 352, 353, 354, 355, 356 };
SerializationTestHelper.assertSerializationEquals(
- "witness/serialization/exception.bin", event, skip, 237);
+ WITNESS_DIR + "/serialization/exception.bin", event, skip, 237);
}
/**
@@ -95,7 +100,7 @@ public void testSerializationWithLocation() throws Exception {
int[] skip = new int[] { 352, 353, 354, 355, 356 };
SerializationTestHelper.assertSerializationEquals(
- "witness/serialization/location.bin", event, skip, 237);
+ WITNESS_DIR + "/serialization/location.bin", event, skip, 237);
}
/**
@@ -114,7 +119,7 @@ public void testSerializationNDC() throws Exception {
int[] skip = new int[] { 352, 353, 354, 355, 356 };
SerializationTestHelper.assertSerializationEquals(
- "witness/serialization/ndc.bin", event, skip, 237);
+ WITNESS_DIR + "/serialization/ndc.bin", event, skip, 237);
}
/**
@@ -133,7 +138,7 @@ public void testSerializationMDC() throws Exception {
int[] skip = new int[] { 352, 353, 354, 355, 356 };
SerializationTestHelper.assertSerializationEquals(
- "witness/serialization/mdc.bin", event, skip, 237);
+ WITNESS_DIR + "/serialization/mdc.bin", event, skip, 237);
}
/**
@@ -144,7 +149,7 @@ public void testSerializationMDC() throws Exception {
public void testDeserializationSimple() throws Exception {
Object obj =
SerializationTestHelper.deserializeStream(
- "witness/serialization/simple.bin");
+ WITNESS_DIR + "/serialization/simple.bin");
assertTrue(obj instanceof LoggingEvent);
LoggingEvent event = (LoggingEvent) obj;
@@ -160,7 +165,7 @@ public void testDeserializationSimple() throws Exception {
public void testDeserializationWithException() throws Exception {
Object obj =
SerializationTestHelper.deserializeStream(
- "witness/serialization/exception.bin");
+ WITNESS_DIR + "/serialization/exception.bin");
assertTrue(obj instanceof LoggingEvent);
LoggingEvent event = (LoggingEvent) obj;
@@ -176,7 +181,7 @@ public void testDeserializationWithException() throws Exception {
public void testDeserializationWithLocation() throws Exception {
Object obj =
SerializationTestHelper.deserializeStream(
- "witness/serialization/location.bin");
+ WITNESS_DIR + "/serialization/location.bin");
assertTrue(obj instanceof LoggingEvent);
LoggingEvent event = (LoggingEvent) obj;
diff --git a/tests/src/java/org/apache/log4j/spi/ThrowableInformationTest.java b/core/src/test/java/org/apache/log4j/spi/ThrowableInformationTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/spi/ThrowableInformationTest.java
rename to core/src/test/java/org/apache/log4j/spi/ThrowableInformationTest.java
diff --git a/tests/src/java/org/apache/log4j/stressCategory b/core/src/test/java/org/apache/log4j/stressCategory
similarity index 100%
rename from tests/src/java/org/apache/log4j/stressCategory
rename to core/src/test/java/org/apache/log4j/stressCategory
diff --git a/tests/src/java/org/apache/log4j/stressCategory.pl b/core/src/test/java/org/apache/log4j/stressCategory.pl
similarity index 100%
rename from tests/src/java/org/apache/log4j/stressCategory.pl
rename to core/src/test/java/org/apache/log4j/stressCategory.pl
diff --git a/tests/src/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java b/core/src/test/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java
rename to core/src/test/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/AbsoluteTimeFilter.java b/core/src/test/java/org/apache/log4j/util/AbsoluteTimeFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/AbsoluteTimeFilter.java
rename to core/src/test/java/org/apache/log4j/util/AbsoluteTimeFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/Compare.java b/core/src/test/java/org/apache/log4j/util/Compare.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/Compare.java
rename to core/src/test/java/org/apache/log4j/util/Compare.java
diff --git a/tests/src/java/org/apache/log4j/util/ControlFilter.java b/core/src/test/java/org/apache/log4j/util/ControlFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/ControlFilter.java
rename to core/src/test/java/org/apache/log4j/util/ControlFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java b/core/src/test/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java
rename to core/src/test/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/EnhancedLineNumberFilter.java b/core/src/test/java/org/apache/log4j/util/EnhancedLineNumberFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/EnhancedLineNumberFilter.java
rename to core/src/test/java/org/apache/log4j/util/EnhancedLineNumberFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/Filter.java b/core/src/test/java/org/apache/log4j/util/Filter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/Filter.java
rename to core/src/test/java/org/apache/log4j/util/Filter.java
diff --git a/tests/src/java/org/apache/log4j/util/ISO8601Filter.java b/core/src/test/java/org/apache/log4j/util/ISO8601Filter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/ISO8601Filter.java
rename to core/src/test/java/org/apache/log4j/util/ISO8601Filter.java
diff --git a/tests/src/java/org/apache/log4j/util/JunitTestRunnerFilter.java b/core/src/test/java/org/apache/log4j/util/JunitTestRunnerFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/JunitTestRunnerFilter.java
rename to core/src/test/java/org/apache/log4j/util/JunitTestRunnerFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/LineNumberFilter.java b/core/src/test/java/org/apache/log4j/util/LineNumberFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/LineNumberFilter.java
rename to core/src/test/java/org/apache/log4j/util/LineNumberFilter.java
diff --git a/tests/src/java/org/apache/log4j/MDCOrderFilter.java b/core/src/test/java/org/apache/log4j/util/MDCOrderFilter.java
similarity index 98%
rename from tests/src/java/org/apache/log4j/MDCOrderFilter.java
rename to core/src/test/java/org/apache/log4j/util/MDCOrderFilter.java
index 06f85b28b9..c8a206c061 100644
--- a/tests/src/java/org/apache/log4j/MDCOrderFilter.java
+++ b/core/src/test/java/org/apache/log4j/util/MDCOrderFilter.java
@@ -19,6 +19,8 @@
import org.apache.log4j.util.Filter;
+import org.apache.log4j.util.Filter;
+
/**
* This class switches MDC values into the order
* (unreasonably) expected by the witness files.
diff --git a/tests/src/java/org/apache/log4j/util/RelativeTimeFilter.java b/core/src/test/java/org/apache/log4j/util/RelativeTimeFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/RelativeTimeFilter.java
rename to core/src/test/java/org/apache/log4j/util/RelativeTimeFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/SerializationTestHelper.java b/core/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/SerializationTestHelper.java
rename to core/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
diff --git a/tests/src/java/org/apache/log4j/util/SunReflectFilter.java b/core/src/test/java/org/apache/log4j/util/SunReflectFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/SunReflectFilter.java
rename to core/src/test/java/org/apache/log4j/util/SunReflectFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/Transformer.java b/core/src/test/java/org/apache/log4j/util/Transformer.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/Transformer.java
rename to core/src/test/java/org/apache/log4j/util/Transformer.java
diff --git a/tests/src/java/org/apache/log4j/util/UnexpectedFormatException.java b/core/src/test/java/org/apache/log4j/util/UnexpectedFormatException.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/UnexpectedFormatException.java
rename to core/src/test/java/org/apache/log4j/util/UnexpectedFormatException.java
diff --git a/tests/src/java/org/apache/log4j/util/XMLLineAttributeFilter.java b/core/src/test/java/org/apache/log4j/util/XMLLineAttributeFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/XMLLineAttributeFilter.java
rename to core/src/test/java/org/apache/log4j/util/XMLLineAttributeFilter.java
diff --git a/tests/src/java/org/apache/log4j/util/XMLTimestampFilter.java b/core/src/test/java/org/apache/log4j/util/XMLTimestampFilter.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/util/XMLTimestampFilter.java
rename to core/src/test/java/org/apache/log4j/util/XMLTimestampFilter.java
diff --git a/tests/src/java/org/apache/log4j/varia/ERFATestCase.java b/core/src/test/java/org/apache/log4j/varia/ERFATestCase.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/varia/ERFATestCase.java
rename to core/src/test/java/org/apache/log4j/varia/ERFATestCase.java
diff --git a/tests/src/java/org/apache/log4j/varia/ErrorHandlerTestCase.java b/core/src/test/java/org/apache/log4j/varia/ErrorHandlerTestCase.java
similarity index 92%
rename from tests/src/java/org/apache/log4j/varia/ErrorHandlerTestCase.java
rename to core/src/test/java/org/apache/log4j/varia/ErrorHandlerTestCase.java
index b0001f8730..e218a71f1a 100644
--- a/tests/src/java/org/apache/log4j/varia/ErrorHandlerTestCase.java
+++ b/core/src/test/java/org/apache/log4j/varia/ErrorHandlerTestCase.java
@@ -63,7 +63,7 @@ public void tearDown() {
}
public void test1() throws Exception {
- DOMConfigurator.configure("input/xml/fallback1.xml");
+ DOMConfigurator.configure("target/test-classes/input/xml/fallback1.xml");
Appender primary = root.getAppender("PRIMARY");
ErrorHandler eh = primary.getErrorHandler();
assertNotNull(eh);
@@ -79,11 +79,11 @@ public void test1() throws Exception {
new SunReflectFilter()});
- assertTrue(Compare.compare(FILTERED, "witness/fallback1"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/fallback1"));
}
public void test2() throws Exception {
- PropertyConfigurator.configure("input/fallback1.properties");
+ PropertyConfigurator.configure("target/test-classes/input/fallback1.properties");
Appender primary = root.getAppender("PRIMARY");
ErrorHandler eh = primary.getErrorHandler();
assertNotNull(eh);
@@ -99,7 +99,7 @@ public void test2() throws Exception {
new SunReflectFilter()});
- assertTrue(Compare.compare(FILTERED, "witness/fallback1"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/fallback1"));
}
void common() {
diff --git a/tests/src/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java b/core/src/test/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java
similarity index 96%
rename from tests/src/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java
rename to core/src/test/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java
index 1afc0d502c..fbf901bb5c 100644
--- a/tests/src/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java
+++ b/core/src/test/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java
@@ -41,11 +41,11 @@ public class LevelMatchFilterTestCase extends TestCase {
static String ACCEPT_FILE = "output/LevelMatchFilter_accept";
static String ACCEPT_FILTERED = "output/LevelMatchFilter_accept_filtered";
- static String ACCEPT_WITNESS = "witness/LevelMatchFilter_accept";
+ static String ACCEPT_WITNESS = "target/test-classes/witness/LevelMatchFilter_accept";
static String DENY_FILE = "output/LevelMatchFilter_deny";
static String DENY_FILTERED = "output/LevelMatchFilter_deny_filtered";
- static String DENY_WITNESS = "witness/LevelMatchFilter_deny";
+ static String DENY_WITNESS = "target/test-classes/witness/LevelMatchFilter_deny";
Logger root;
Logger logger;
diff --git a/tests/src/java/org/apache/log4j/xml/CustomLevelTestCase.java b/core/src/test/java/org/apache/log4j/xml/CustomLevelTestCase.java
similarity index 74%
rename from tests/src/java/org/apache/log4j/xml/CustomLevelTestCase.java
rename to core/src/test/java/org/apache/log4j/xml/CustomLevelTestCase.java
index 52c366ae94..825a40be6f 100644
--- a/tests/src/java/org/apache/log4j/xml/CustomLevelTestCase.java
+++ b/core/src/test/java/org/apache/log4j/xml/CustomLevelTestCase.java
@@ -25,6 +25,10 @@
public class CustomLevelTestCase extends TestCase {
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
+
static String TEMP = "output/temp";
Logger root;
@@ -44,27 +48,27 @@ public void tearDown() {
}
public void test1() throws Exception {
- DOMConfigurator.configure("input/xml/customLevel1.xml");
+ DOMConfigurator.configure(INPUT_DIR + "/xml/customLevel1.xml");
common();
- assertTrue(Compare.compare(TEMP, "witness/customLevel.1"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/customLevel.1"));
}
public void test2() throws Exception {
- DOMConfigurator.configure("input/xml/customLevel2.xml");
+ DOMConfigurator.configure(INPUT_DIR + "/xml/customLevel2.xml");
common();
- assertTrue(Compare.compare(TEMP, "witness/customLevel.2"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/customLevel.2"));
}
public void test3() throws Exception {
- DOMConfigurator.configure("input/xml/customLevel3.xml");
+ DOMConfigurator.configure(INPUT_DIR + "/xml/customLevel3.xml");
common();
- assertTrue(Compare.compare(TEMP, "witness/customLevel.3"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/customLevel.3"));
}
public void test4() throws Exception {
- DOMConfigurator.configure("input/xml/customLevel4.xml");
+ DOMConfigurator.configure(INPUT_DIR + "/xml/customLevel4.xml");
common();
- assertTrue(Compare.compare(TEMP, "witness/customLevel.4"));
+ assertTrue(Compare.compare(TEMP, WITNESS_DIR + "/customLevel.4"));
}
diff --git a/tests/src/java/org/apache/log4j/xml/DOMTestCase.java b/core/src/test/java/org/apache/log4j/xml/DOMTestCase.java
similarity index 91%
rename from tests/src/java/org/apache/log4j/xml/DOMTestCase.java
rename to core/src/test/java/org/apache/log4j/xml/DOMTestCase.java
index e664c43996..314e42d35a 100644
--- a/tests/src/java/org/apache/log4j/xml/DOMTestCase.java
+++ b/core/src/test/java/org/apache/log4j/xml/DOMTestCase.java
@@ -49,7 +49,8 @@
import java.util.zip.ZipOutputStream;
public class DOMTestCase extends TestCase {
-
+ static final String FILE_PREFIX = "target/test-classes/";
+
static String TEMP_A1 = "output/temp.A1";
static String TEMP_A2 = "output/temp.A2";
static String FILTERED_A1 = "output/filtered.A1";
@@ -90,7 +91,7 @@ public void tearDown() {
}
public void test1() throws Exception {
- DOMConfigurator.configure("input/xml/DOMTestCase1.xml");
+ DOMConfigurator.configure(FILE_PREFIX + "input/xml/DOMTestCase1.xml");
common();
ControlFilter cf1 = new ControlFilter(new String[]{TEST1_1A_PAT, TEST1_1B_PAT,
@@ -113,15 +114,15 @@ 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"));
+ assertTrue(Compare.compare(FILTERED_A1, FILE_PREFIX + "witness/dom.A1.1"));
+ assertTrue(Compare.compare(FILTERED_A2, FILE_PREFIX + "witness/dom.A2.1"));
}
/**
* Tests processing of external entities in XML file.
*/
public void test4() throws Exception {
- DOMConfigurator.configure("input/xml/DOMTest4.xml");
+ DOMConfigurator.configure(FILE_PREFIX + "input/xml/DOMTest4.xml");
common();
ControlFilter cf1 = new ControlFilter(new String[]{TEST1_1A_PAT, TEST1_1B_PAT,
@@ -144,8 +145,8 @@ 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"));
+ assertTrue(Compare.compare(FILTERED_A1 + ".4", FILE_PREFIX + "witness/dom.A1.4"));
+ assertTrue(Compare.compare(FILTERED_A2 + ".4", FILE_PREFIX + "witness/dom.A2.4"));
}
void common() {
@@ -251,7 +252,7 @@ public void setBackupAppender(Appender appender) {}
* use the specified categoryFactory. See bug 33708.
*/
public void testCategoryFactory1() {
- DOMConfigurator.configure("input/xml/categoryfactory1.xml");
+ DOMConfigurator.configure(FILE_PREFIX + "input/xml/categoryfactory1.xml");
//
// logger explicitly mentioned in configuration,
// should be a CustomLogger
@@ -269,7 +270,7 @@ public void testCategoryFactory1() {
* use the specified categoryFactory. See bug 33708.
*/
public void testCategoryFactory2() {
- DOMConfigurator.configure("input/xml/categoryfactory2.xml");
+ DOMConfigurator.configure(FILE_PREFIX + "input/xml/categoryfactory2.xml");
//
// logger explicitly mentioned in configuration,
// should be a CustomLogger
@@ -287,7 +288,7 @@ public void testCategoryFactory2() {
* use the specified loggerFactory. See bug 33708.
*/
public void testLoggerFactory1() {
- DOMConfigurator.configure("input/xml/loggerfactory1.xml");
+ DOMConfigurator.configure(FILE_PREFIX + "input/xml/loggerfactory1.xml");
//
// logger explicitly mentioned in configuration,
// should be a CustomLogger
@@ -309,7 +310,7 @@ public void testReset() throws Exception {
VectorAppender appender = new VectorAppender();
appender.setName("V1");
Logger.getRootLogger().addAppender(appender);
- DOMConfigurator.configure("input/xml/testReset.xml");
+ DOMConfigurator.configure(FILE_PREFIX + "input/xml/testReset.xml");
assertNull(Logger.getRootLogger().getAppender("V1"));
}
@@ -319,7 +320,7 @@ public void testReset() throws Exception {
* @throws Exception if IO error.
*/
public void testConfigureAndWatch() throws Exception {
- DOMConfigurator.configureAndWatch("input/xml/DOMTestCase1.xml");
+ DOMConfigurator.configureAndWatch(FILE_PREFIX + "input/xml/DOMTestCase1.xml");
assertNotNull(Logger.getRootLogger().getAppender("A1"));
}
@@ -338,7 +339,7 @@ protected String subst(final String value) {
return value;
}
};
- configurator.doConfigure("input/xml/DOMTestCase1.xml", LogManager.getLoggerRepository());
+ configurator.doConfigure(FILE_PREFIX + "input/xml/DOMTestCase1.xml", LogManager.getLoggerRepository());
FileAppender a1 = (FileAppender) Logger.getRootLogger().getAppender("A1");
String file = a1.getFile();
assertEquals("output/subst-test.A1", file);
@@ -379,7 +380,7 @@ public boolean getShowVersion() {
* Test of log4j.throwableRenderer support. See bug 45721.
*/
public void testThrowableRenderer1() {
- DOMConfigurator.configure("input/xml/throwableRenderer1.xml");
+ DOMConfigurator.configure(FILE_PREFIX + "input/xml/throwableRenderer1.xml");
ThrowableRendererSupport repo = (ThrowableRendererSupport) LogManager.getLoggerRepository();
MockThrowableRenderer renderer = (MockThrowableRenderer) repo.getThrowableRenderer();
LogManager.resetConfiguration();
@@ -394,7 +395,7 @@ public void testThrowableRenderer1() {
* @throws IOException if IOException creating properties jar.
*/
public void testJarURL() throws IOException {
- File input = new File("input/xml/defaultInit.xml");
+ File input = new File(FILE_PREFIX + "input/xml/defaultInit.xml");
System.out.println(input.getAbsolutePath());
InputStream is = new FileInputStream(input);
File dir = new File("output");
diff --git a/tests/src/java/org/apache/log4j/xml/XLevel.java b/core/src/test/java/org/apache/log4j/xml/XLevel.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/xml/XLevel.java
rename to core/src/test/java/org/apache/log4j/xml/XLevel.java
diff --git a/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java b/core/src/test/java/org/apache/log4j/xml/XMLLayoutTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java
rename to core/src/test/java/org/apache/log4j/xml/XMLLayoutTest.java
diff --git a/tests/src/java/org/apache/log4j/xml/XMLLayoutTestCase.java b/core/src/test/java/org/apache/log4j/xml/XMLLayoutTestCase.java
similarity index 91%
rename from tests/src/java/org/apache/log4j/xml/XMLLayoutTestCase.java
rename to core/src/test/java/org/apache/log4j/xml/XMLLayoutTestCase.java
index e76acd6b19..f45f788d1b 100644
--- a/tests/src/java/org/apache/log4j/xml/XMLLayoutTestCase.java
+++ b/core/src/test/java/org/apache/log4j/xml/XMLLayoutTestCase.java
@@ -37,6 +37,10 @@
public class XMLLayoutTestCase extends TestCase {
+ static final String FILE_PREFIX = "target/test-classes";
+ static final String INPUT_DIR = FILE_PREFIX + "/input";
+ static final String WITNESS_DIR = FILE_PREFIX + "/witness";
+
static String TEMP = "output/temp";
static String FILTERED = "output/filtered";
@@ -70,7 +74,7 @@ public void basic() throws Exception {
new JunitTestRunnerFilter(),
new SunReflectFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.1"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/xmlLayout.1"));
}
public void locationInfo() throws Exception {
@@ -87,7 +91,7 @@ public void locationInfo() throws Exception {
new JunitTestRunnerFilter(),
new SunReflectFilter()
});
- assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.2"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/xmlLayout.2"));
}
public void testCDATA() throws Exception {
@@ -116,7 +120,7 @@ public void testCDATA() throws Exception {
Transformer.transform(TEMP, FILTERED, new Filter[] {new LineNumberFilter(),
new XMLTimestampFilter(),
new XMLLineAttributeFilter()});
- assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.3"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/xmlLayout.3"));
}
public void testNull() throws Exception {
@@ -139,7 +143,7 @@ public void testNull() throws Exception {
new XMLTimestampFilter(),
new JunitTestRunnerFilter(),
new SunReflectFilter()});
- assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.null"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/xmlLayout.null"));
}
/**
@@ -165,7 +169,7 @@ public void testMDC() throws Exception {
new Filter[] { new LineNumberFilter(),
new JunitTestRunnerFilter(),
new XMLTimestampFilter()});
- assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.mdc.1"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/xmlLayout.mdc.1"));
}
public void testMDCEscaped() throws Exception {
@@ -186,7 +190,7 @@ public void testMDCEscaped() throws Exception {
new Filter[] { new LineNumberFilter(),
new JunitTestRunnerFilter(),
new XMLTimestampFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.mdc.2"));
+ assertTrue(Compare.compare(FILTERED, WITNESS_DIR + "/xmlLayout.mdc.2"));
}
diff --git a/tests/log4j-coding-convention.xml b/core/src/test/log4j-coding-convention.xml
similarity index 100%
rename from tests/log4j-coding-convention.xml
rename to core/src/test/log4j-coding-convention.xml
diff --git a/tests/resources/L7D_en_US.properties b/core/src/test/resources/L7D_en_US.properties
similarity index 100%
rename from tests/resources/L7D_en_US.properties
rename to core/src/test/resources/L7D_en_US.properties
diff --git a/tests/resources/L7D_fr.properties b/core/src/test/resources/L7D_fr.properties
similarity index 100%
rename from tests/resources/L7D_fr.properties
rename to core/src/test/resources/L7D_fr.properties
diff --git a/tests/resources/L7D_fr_CH.properties b/core/src/test/resources/L7D_fr_CH.properties
similarity index 100%
rename from tests/resources/L7D_fr_CH.properties
rename to core/src/test/resources/L7D_fr_CH.properties
diff --git a/tests/resources/TestLogSFPatterns.properties b/core/src/test/resources/TestLogSFPatterns.properties
similarity index 100%
rename from tests/resources/TestLogSFPatterns.properties
rename to core/src/test/resources/TestLogSFPatterns.properties
diff --git a/tests/input/RFA1.properties b/core/src/test/resources/input/RFA1.properties
similarity index 100%
rename from tests/input/RFA1.properties
rename to core/src/test/resources/input/RFA1.properties
diff --git a/tests/input/defaultInit3.properties b/core/src/test/resources/input/defaultInit3.properties
similarity index 100%
rename from tests/input/defaultInit3.properties
rename to core/src/test/resources/input/defaultInit3.properties
diff --git a/tests/input/fallback1.properties b/core/src/test/resources/input/fallback1.properties
similarity index 100%
rename from tests/input/fallback1.properties
rename to core/src/test/resources/input/fallback1.properties
diff --git a/tests/input/filter1.properties b/core/src/test/resources/input/filter1.properties
similarity index 100%
rename from tests/input/filter1.properties
rename to core/src/test/resources/input/filter1.properties
diff --git a/tests/input/hierarchyThreshold1.properties b/core/src/test/resources/input/hierarchyThreshold1.properties
similarity index 100%
rename from tests/input/hierarchyThreshold1.properties
rename to core/src/test/resources/input/hierarchyThreshold1.properties
diff --git a/tests/input/hierarchyThreshold2.properties b/core/src/test/resources/input/hierarchyThreshold2.properties
similarity index 100%
rename from tests/input/hierarchyThreshold2.properties
rename to core/src/test/resources/input/hierarchyThreshold2.properties
diff --git a/tests/input/hierarchyThreshold3.properties b/core/src/test/resources/input/hierarchyThreshold3.properties
similarity index 100%
rename from tests/input/hierarchyThreshold3.properties
rename to core/src/test/resources/input/hierarchyThreshold3.properties
diff --git a/tests/input/hierarchyThreshold4.properties b/core/src/test/resources/input/hierarchyThreshold4.properties
similarity index 100%
rename from tests/input/hierarchyThreshold4.properties
rename to core/src/test/resources/input/hierarchyThreshold4.properties
diff --git a/tests/input/hierarchyThreshold5.properties b/core/src/test/resources/input/hierarchyThreshold5.properties
similarity index 100%
rename from tests/input/hierarchyThreshold5.properties
rename to core/src/test/resources/input/hierarchyThreshold5.properties
diff --git a/tests/input/hierarchyThreshold6.properties b/core/src/test/resources/input/hierarchyThreshold6.properties
similarity index 100%
rename from tests/input/hierarchyThreshold6.properties
rename to core/src/test/resources/input/hierarchyThreshold6.properties
diff --git a/tests/input/hierarchyThreshold7.properties b/core/src/test/resources/input/hierarchyThreshold7.properties
similarity index 100%
rename from tests/input/hierarchyThreshold7.properties
rename to core/src/test/resources/input/hierarchyThreshold7.properties
diff --git a/tests/input/hierarchyThreshold8.properties b/core/src/test/resources/input/hierarchyThreshold8.properties
similarity index 100%
rename from tests/input/hierarchyThreshold8.properties
rename to core/src/test/resources/input/hierarchyThreshold8.properties
diff --git a/tests/input/pattern/enhancedPatternLayout.mdc.1.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout.mdc.1.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout.mdc.1.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout.mdc.1.properties
diff --git a/tests/input/pattern/enhancedPatternLayout1.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout1.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout1.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout1.properties
diff --git a/tests/input/pattern/enhancedPatternLayout10.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout10.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout10.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout10.properties
diff --git a/tests/input/pattern/enhancedPatternLayout11.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout11.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout11.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout11.properties
diff --git a/tests/input/pattern/enhancedPatternLayout12.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout12.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout12.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout12.properties
diff --git a/tests/input/pattern/enhancedPatternLayout13.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout13.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout13.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout13.properties
diff --git a/tests/input/pattern/enhancedPatternLayout14.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout14.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout14.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout14.properties
diff --git a/tests/input/pattern/enhancedPatternLayout15.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout15.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout15.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout15.properties
diff --git a/tests/input/pattern/enhancedPatternLayout16.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout16.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout16.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout16.properties
diff --git a/tests/input/pattern/enhancedPatternLayout2.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout2.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout2.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout2.properties
diff --git a/tests/input/pattern/enhancedPatternLayout3.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout3.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout3.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout3.properties
diff --git a/tests/input/pattern/enhancedPatternLayout4.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout4.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout4.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout4.properties
diff --git a/tests/input/pattern/enhancedPatternLayout5.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout5.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout5.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout5.properties
diff --git a/tests/input/pattern/enhancedPatternLayout6.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout6.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout6.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout6.properties
diff --git a/tests/input/pattern/enhancedPatternLayout7.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout7.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout7.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout7.properties
diff --git a/tests/input/pattern/enhancedPatternLayout8.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout8.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout8.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout8.properties
diff --git a/tests/input/pattern/enhancedPatternLayout9.properties b/core/src/test/resources/input/pattern/enhancedPatternLayout9.properties
similarity index 100%
rename from tests/input/pattern/enhancedPatternLayout9.properties
rename to core/src/test/resources/input/pattern/enhancedPatternLayout9.properties
diff --git a/tests/input/patternLayout.mdc.1.properties b/core/src/test/resources/input/patternLayout.mdc.1.properties
similarity index 100%
rename from tests/input/patternLayout.mdc.1.properties
rename to core/src/test/resources/input/patternLayout.mdc.1.properties
diff --git a/tests/input/patternLayout1.properties b/core/src/test/resources/input/patternLayout1.properties
similarity index 100%
rename from tests/input/patternLayout1.properties
rename to core/src/test/resources/input/patternLayout1.properties
diff --git a/tests/input/patternLayout10.properties b/core/src/test/resources/input/patternLayout10.properties
similarity index 100%
rename from tests/input/patternLayout10.properties
rename to core/src/test/resources/input/patternLayout10.properties
diff --git a/tests/input/patternLayout11.properties b/core/src/test/resources/input/patternLayout11.properties
similarity index 100%
rename from tests/input/patternLayout11.properties
rename to core/src/test/resources/input/patternLayout11.properties
diff --git a/tests/input/patternLayout12.properties b/core/src/test/resources/input/patternLayout12.properties
similarity index 100%
rename from tests/input/patternLayout12.properties
rename to core/src/test/resources/input/patternLayout12.properties
diff --git a/tests/input/patternLayout13.properties b/core/src/test/resources/input/patternLayout13.properties
similarity index 100%
rename from tests/input/patternLayout13.properties
rename to core/src/test/resources/input/patternLayout13.properties
diff --git a/tests/input/patternLayout14.properties b/core/src/test/resources/input/patternLayout14.properties
similarity index 100%
rename from tests/input/patternLayout14.properties
rename to core/src/test/resources/input/patternLayout14.properties
diff --git a/tests/input/patternLayout2.properties b/core/src/test/resources/input/patternLayout2.properties
similarity index 100%
rename from tests/input/patternLayout2.properties
rename to core/src/test/resources/input/patternLayout2.properties
diff --git a/tests/input/patternLayout3.properties b/core/src/test/resources/input/patternLayout3.properties
similarity index 100%
rename from tests/input/patternLayout3.properties
rename to core/src/test/resources/input/patternLayout3.properties
diff --git a/tests/input/patternLayout4.properties b/core/src/test/resources/input/patternLayout4.properties
similarity index 100%
rename from tests/input/patternLayout4.properties
rename to core/src/test/resources/input/patternLayout4.properties
diff --git a/tests/input/patternLayout5.properties b/core/src/test/resources/input/patternLayout5.properties
similarity index 100%
rename from tests/input/patternLayout5.properties
rename to core/src/test/resources/input/patternLayout5.properties
diff --git a/tests/input/patternLayout6.properties b/core/src/test/resources/input/patternLayout6.properties
similarity index 100%
rename from tests/input/patternLayout6.properties
rename to core/src/test/resources/input/patternLayout6.properties
diff --git a/tests/input/patternLayout7.properties b/core/src/test/resources/input/patternLayout7.properties
similarity index 100%
rename from tests/input/patternLayout7.properties
rename to core/src/test/resources/input/patternLayout7.properties
diff --git a/tests/input/patternLayout8.properties b/core/src/test/resources/input/patternLayout8.properties
similarity index 100%
rename from tests/input/patternLayout8.properties
rename to core/src/test/resources/input/patternLayout8.properties
diff --git a/tests/input/patternLayout9.properties b/core/src/test/resources/input/patternLayout9.properties
similarity index 100%
rename from tests/input/patternLayout9.properties
rename to core/src/test/resources/input/patternLayout9.properties
diff --git a/tests/input/xml/DOMTest4.xml b/core/src/test/resources/input/xml/DOMTest4.xml
similarity index 100%
rename from tests/input/xml/DOMTest4.xml
rename to core/src/test/resources/input/xml/DOMTest4.xml
diff --git a/tests/input/xml/DOMTest4_A1.xml b/core/src/test/resources/input/xml/DOMTest4_A1.xml
similarity index 100%
rename from tests/input/xml/DOMTest4_A1.xml
rename to core/src/test/resources/input/xml/DOMTest4_A1.xml
diff --git a/tests/input/xml/DOMTest4_A2.xml b/core/src/test/resources/input/xml/DOMTest4_A2.xml
similarity index 100%
rename from tests/input/xml/DOMTest4_A2.xml
rename to core/src/test/resources/input/xml/DOMTest4_A2.xml
diff --git a/tests/input/xml/DOMTestCase1.xml b/core/src/test/resources/input/xml/DOMTestCase1.xml
similarity index 100%
rename from tests/input/xml/DOMTestCase1.xml
rename to core/src/test/resources/input/xml/DOMTestCase1.xml
diff --git a/tests/input/xml/categoryfactory1.xml b/core/src/test/resources/input/xml/categoryfactory1.xml
similarity index 100%
rename from tests/input/xml/categoryfactory1.xml
rename to core/src/test/resources/input/xml/categoryfactory1.xml
diff --git a/tests/input/xml/categoryfactory2.xml b/core/src/test/resources/input/xml/categoryfactory2.xml
similarity index 100%
rename from tests/input/xml/categoryfactory2.xml
rename to core/src/test/resources/input/xml/categoryfactory2.xml
diff --git a/tests/input/xml/customLevel1.xml b/core/src/test/resources/input/xml/customLevel1.xml
similarity index 100%
rename from tests/input/xml/customLevel1.xml
rename to core/src/test/resources/input/xml/customLevel1.xml
diff --git a/tests/input/xml/customLevel2.xml b/core/src/test/resources/input/xml/customLevel2.xml
similarity index 100%
rename from tests/input/xml/customLevel2.xml
rename to core/src/test/resources/input/xml/customLevel2.xml
diff --git a/tests/input/xml/customLevel3.xml b/core/src/test/resources/input/xml/customLevel3.xml
similarity index 100%
rename from tests/input/xml/customLevel3.xml
rename to core/src/test/resources/input/xml/customLevel3.xml
diff --git a/tests/input/xml/customLevel4.xml b/core/src/test/resources/input/xml/customLevel4.xml
similarity index 100%
rename from tests/input/xml/customLevel4.xml
rename to core/src/test/resources/input/xml/customLevel4.xml
diff --git a/tests/input/xml/customLogger1.xml b/core/src/test/resources/input/xml/customLogger1.xml
similarity index 100%
rename from tests/input/xml/customLogger1.xml
rename to core/src/test/resources/input/xml/customLogger1.xml
diff --git a/tests/input/xml/customLogger2.xml b/core/src/test/resources/input/xml/customLogger2.xml
similarity index 100%
rename from tests/input/xml/customLogger2.xml
rename to core/src/test/resources/input/xml/customLogger2.xml
diff --git a/tests/input/xml/customLogger3.xml b/core/src/test/resources/input/xml/customLogger3.xml
similarity index 100%
rename from tests/input/xml/customLogger3.xml
rename to core/src/test/resources/input/xml/customLogger3.xml
diff --git a/tests/input/xml/defaultInit.xml b/core/src/test/resources/input/xml/defaultInit.xml
similarity index 100%
rename from tests/input/xml/defaultInit.xml
rename to core/src/test/resources/input/xml/defaultInit.xml
diff --git a/tests/input/xml/fallback1.xml b/core/src/test/resources/input/xml/fallback1.xml
similarity index 100%
rename from tests/input/xml/fallback1.xml
rename to core/src/test/resources/input/xml/fallback1.xml
diff --git a/tests/input/xml/loggerfactory1.xml b/core/src/test/resources/input/xml/loggerfactory1.xml
similarity index 100%
rename from tests/input/xml/loggerfactory1.xml
rename to core/src/test/resources/input/xml/loggerfactory1.xml
diff --git a/tests/input/xml/testReset.xml b/core/src/test/resources/input/xml/testReset.xml
similarity index 100%
rename from tests/input/xml/testReset.xml
rename to core/src/test/resources/input/xml/testReset.xml
diff --git a/tests/input/xml/throwableRenderer1.xml b/core/src/test/resources/input/xml/throwableRenderer1.xml
similarity index 100%
rename from tests/input/xml/throwableRenderer1.xml
rename to core/src/test/resources/input/xml/throwableRenderer1.xml
diff --git a/tests/resources/org/apache/log4j/TestLogMFPatterns.properties b/core/src/test/resources/org/apache/log4j/TestLogMFPatterns.properties
similarity index 100%
rename from tests/resources/org/apache/log4j/TestLogMFPatterns.properties
rename to core/src/test/resources/org/apache/log4j/TestLogMFPatterns.properties
diff --git a/tests/resources/org/apache/log4j/TestLogSFPatterns.properties b/core/src/test/resources/org/apache/log4j/TestLogSFPatterns.properties
similarity index 100%
rename from tests/resources/org/apache/log4j/TestLogSFPatterns.properties
rename to core/src/test/resources/org/apache/log4j/TestLogSFPatterns.properties
diff --git a/tests/witness/LevelMatchFilter_accept b/core/src/test/resources/witness/LevelMatchFilter_accept
similarity index 100%
rename from tests/witness/LevelMatchFilter_accept
rename to core/src/test/resources/witness/LevelMatchFilter_accept
diff --git a/tests/witness/LevelMatchFilter_deny b/core/src/test/resources/witness/LevelMatchFilter_deny
similarity index 100%
rename from tests/witness/LevelMatchFilter_deny
rename to core/src/test/resources/witness/LevelMatchFilter_deny
diff --git a/tests/witness/PatternParser_mdc b/core/src/test/resources/witness/PatternParser_mdc
similarity index 100%
rename from tests/witness/PatternParser_mdc
rename to core/src/test/resources/witness/PatternParser_mdc
diff --git a/tests/witness/customLevel.1 b/core/src/test/resources/witness/customLevel.1
similarity index 100%
rename from tests/witness/customLevel.1
rename to core/src/test/resources/witness/customLevel.1
diff --git a/tests/witness/customLevel.2 b/core/src/test/resources/witness/customLevel.2
similarity index 100%
rename from tests/witness/customLevel.2
rename to core/src/test/resources/witness/customLevel.2
diff --git a/tests/witness/customLevel.3 b/core/src/test/resources/witness/customLevel.3
similarity index 100%
rename from tests/witness/customLevel.3
rename to core/src/test/resources/witness/customLevel.3
diff --git a/tests/witness/customLevel.4 b/core/src/test/resources/witness/customLevel.4
similarity index 100%
rename from tests/witness/customLevel.4
rename to core/src/test/resources/witness/customLevel.4
diff --git a/tests/witness/customLogger.1 b/core/src/test/resources/witness/customLogger.1
similarity index 100%
rename from tests/witness/customLogger.1
rename to core/src/test/resources/witness/customLogger.1
diff --git a/tests/witness/customLogger.2 b/core/src/test/resources/witness/customLogger.2
similarity index 100%
rename from tests/witness/customLogger.2
rename to core/src/test/resources/witness/customLogger.2
diff --git a/tests/witness/dom.A1.1 b/core/src/test/resources/witness/dom.A1.1
similarity index 100%
rename from tests/witness/dom.A1.1
rename to core/src/test/resources/witness/dom.A1.1
diff --git a/tests/witness/dom.A1.4 b/core/src/test/resources/witness/dom.A1.4
similarity index 100%
rename from tests/witness/dom.A1.4
rename to core/src/test/resources/witness/dom.A1.4
diff --git a/tests/witness/dom.A2.1 b/core/src/test/resources/witness/dom.A2.1
similarity index 100%
rename from tests/witness/dom.A2.1
rename to core/src/test/resources/witness/dom.A2.1
diff --git a/tests/witness/dom.A2.4 b/core/src/test/resources/witness/dom.A2.4
similarity index 100%
rename from tests/witness/dom.A2.4
rename to core/src/test/resources/witness/dom.A2.4
diff --git a/tests/witness/drfa_blockedRollover.log b/core/src/test/resources/witness/drfa_blockedRollover.log
similarity index 100%
rename from tests/witness/drfa_blockedRollover.log
rename to core/src/test/resources/witness/drfa_blockedRollover.log
diff --git a/tests/witness/fallback1 b/core/src/test/resources/witness/fallback1
similarity index 100%
rename from tests/witness/fallback1
rename to core/src/test/resources/witness/fallback1
diff --git a/tests/witness/hierarchyThreshold.1 b/core/src/test/resources/witness/hierarchyThreshold.1
similarity index 100%
rename from tests/witness/hierarchyThreshold.1
rename to core/src/test/resources/witness/hierarchyThreshold.1
diff --git a/tests/witness/hierarchyThreshold.2 b/core/src/test/resources/witness/hierarchyThreshold.2
similarity index 100%
rename from tests/witness/hierarchyThreshold.2
rename to core/src/test/resources/witness/hierarchyThreshold.2
diff --git a/tests/witness/hierarchyThreshold.3 b/core/src/test/resources/witness/hierarchyThreshold.3
similarity index 100%
rename from tests/witness/hierarchyThreshold.3
rename to core/src/test/resources/witness/hierarchyThreshold.3
diff --git a/tests/witness/hierarchyThreshold.4 b/core/src/test/resources/witness/hierarchyThreshold.4
similarity index 100%
rename from tests/witness/hierarchyThreshold.4
rename to core/src/test/resources/witness/hierarchyThreshold.4
diff --git a/tests/witness/hierarchyThreshold.5 b/core/src/test/resources/witness/hierarchyThreshold.5
similarity index 100%
rename from tests/witness/hierarchyThreshold.5
rename to core/src/test/resources/witness/hierarchyThreshold.5
diff --git a/tests/witness/hierarchyThreshold.6 b/core/src/test/resources/witness/hierarchyThreshold.6
similarity index 100%
rename from tests/witness/hierarchyThreshold.6
rename to core/src/test/resources/witness/hierarchyThreshold.6
diff --git a/tests/witness/hierarchyThreshold.7 b/core/src/test/resources/witness/hierarchyThreshold.7
similarity index 100%
rename from tests/witness/hierarchyThreshold.7
rename to core/src/test/resources/witness/hierarchyThreshold.7
diff --git a/tests/witness/hierarchyThreshold.8 b/core/src/test/resources/witness/hierarchyThreshold.8
similarity index 100%
rename from tests/witness/hierarchyThreshold.8
rename to core/src/test/resources/witness/hierarchyThreshold.8
diff --git a/tests/witness/pattern/enhancedPatternLayout.1 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.1
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.1
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.1
diff --git a/tests/witness/pattern/enhancedPatternLayout.10 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.10
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.10
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.10
diff --git a/tests/witness/pattern/enhancedPatternLayout.11 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.11
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.11
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.11
diff --git a/tests/witness/pattern/enhancedPatternLayout.12 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.12
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.12
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.12
diff --git a/tests/witness/pattern/enhancedPatternLayout.13 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.13
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.13
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.13
diff --git a/tests/witness/pattern/enhancedPatternLayout.14 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.14
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.14
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.14
diff --git a/tests/witness/pattern/enhancedPatternLayout.15 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.15
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.15
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.15
diff --git a/tests/witness/pattern/enhancedPatternLayout.2 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.2
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.2
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.2
diff --git a/tests/witness/pattern/enhancedPatternLayout.3 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.3
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.3
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.3
diff --git a/tests/witness/pattern/enhancedPatternLayout.4 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.4
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.4
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.4
diff --git a/tests/witness/pattern/enhancedPatternLayout.5 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.5
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.5
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.5
diff --git a/tests/witness/pattern/enhancedPatternLayout.6 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.6
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.6
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.6
diff --git a/tests/witness/pattern/enhancedPatternLayout.7 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.7
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.7
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.7
diff --git a/tests/witness/pattern/enhancedPatternLayout.8 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.8
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.8
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.8
diff --git a/tests/witness/pattern/enhancedPatternLayout.9 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.9
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.9
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.9
diff --git a/tests/witness/pattern/enhancedPatternLayout.mdc.1 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.mdc.1
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.mdc.1
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.mdc.1
diff --git a/tests/witness/pattern/enhancedPatternLayout.mdc.2 b/core/src/test/resources/witness/pattern/enhancedPatternLayout.mdc.2
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.mdc.2
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.mdc.2
diff --git a/tests/witness/pattern/enhancedPatternLayout.throwable b/core/src/test/resources/witness/pattern/enhancedPatternLayout.throwable
similarity index 100%
rename from tests/witness/pattern/enhancedPatternLayout.throwable
rename to core/src/test/resources/witness/pattern/enhancedPatternLayout.throwable
diff --git a/tests/witness/patternLayout.1 b/core/src/test/resources/witness/patternLayout.1
similarity index 100%
rename from tests/witness/patternLayout.1
rename to core/src/test/resources/witness/patternLayout.1
diff --git a/tests/witness/patternLayout.10 b/core/src/test/resources/witness/patternLayout.10
similarity index 100%
rename from tests/witness/patternLayout.10
rename to core/src/test/resources/witness/patternLayout.10
diff --git a/tests/witness/patternLayout.11 b/core/src/test/resources/witness/patternLayout.11
similarity index 100%
rename from tests/witness/patternLayout.11
rename to core/src/test/resources/witness/patternLayout.11
diff --git a/tests/witness/patternLayout.12 b/core/src/test/resources/witness/patternLayout.12
similarity index 100%
rename from tests/witness/patternLayout.12
rename to core/src/test/resources/witness/patternLayout.12
diff --git a/tests/witness/patternLayout.13 b/core/src/test/resources/witness/patternLayout.13
similarity index 100%
rename from tests/witness/patternLayout.13
rename to core/src/test/resources/witness/patternLayout.13
diff --git a/tests/witness/patternLayout.14 b/core/src/test/resources/witness/patternLayout.14
similarity index 100%
rename from tests/witness/patternLayout.14
rename to core/src/test/resources/witness/patternLayout.14
diff --git a/tests/witness/patternLayout.2 b/core/src/test/resources/witness/patternLayout.2
similarity index 100%
rename from tests/witness/patternLayout.2
rename to core/src/test/resources/witness/patternLayout.2
diff --git a/tests/witness/patternLayout.3 b/core/src/test/resources/witness/patternLayout.3
similarity index 100%
rename from tests/witness/patternLayout.3
rename to core/src/test/resources/witness/patternLayout.3
diff --git a/tests/witness/patternLayout.4 b/core/src/test/resources/witness/patternLayout.4
similarity index 100%
rename from tests/witness/patternLayout.4
rename to core/src/test/resources/witness/patternLayout.4
diff --git a/tests/witness/patternLayout.5 b/core/src/test/resources/witness/patternLayout.5
similarity index 100%
rename from tests/witness/patternLayout.5
rename to core/src/test/resources/witness/patternLayout.5
diff --git a/tests/witness/patternLayout.6 b/core/src/test/resources/witness/patternLayout.6
similarity index 100%
rename from tests/witness/patternLayout.6
rename to core/src/test/resources/witness/patternLayout.6
diff --git a/tests/witness/patternLayout.7 b/core/src/test/resources/witness/patternLayout.7
similarity index 100%
rename from tests/witness/patternLayout.7
rename to core/src/test/resources/witness/patternLayout.7
diff --git a/tests/witness/patternLayout.8 b/core/src/test/resources/witness/patternLayout.8
similarity index 100%
rename from tests/witness/patternLayout.8
rename to core/src/test/resources/witness/patternLayout.8
diff --git a/tests/witness/patternLayout.9 b/core/src/test/resources/witness/patternLayout.9
similarity index 100%
rename from tests/witness/patternLayout.9
rename to core/src/test/resources/witness/patternLayout.9
diff --git a/tests/witness/patternLayout.mdc.1 b/core/src/test/resources/witness/patternLayout.mdc.1
similarity index 100%
rename from tests/witness/patternLayout.mdc.1
rename to core/src/test/resources/witness/patternLayout.mdc.1
diff --git a/tests/witness/patternLayout.mdc.clear b/core/src/test/resources/witness/patternLayout.mdc.clear
similarity index 100%
rename from tests/witness/patternLayout.mdc.clear
rename to core/src/test/resources/witness/patternLayout.mdc.clear
diff --git a/tests/witness/prudent b/core/src/test/resources/witness/prudent
similarity index 100%
rename from tests/witness/prudent
rename to core/src/test/resources/witness/prudent
diff --git a/tests/witness/serialization/exception.bin b/core/src/test/resources/witness/serialization/exception.bin
similarity index 100%
rename from tests/witness/serialization/exception.bin
rename to core/src/test/resources/witness/serialization/exception.bin
diff --git a/tests/witness/serialization/info.bin b/core/src/test/resources/witness/serialization/info.bin
similarity index 100%
rename from tests/witness/serialization/info.bin
rename to core/src/test/resources/witness/serialization/info.bin
diff --git a/tests/witness/serialization/location.bin b/core/src/test/resources/witness/serialization/location.bin
similarity index 100%
rename from tests/witness/serialization/location.bin
rename to core/src/test/resources/witness/serialization/location.bin
diff --git a/tests/witness/serialization/mdc.bin b/core/src/test/resources/witness/serialization/mdc.bin
similarity index 100%
rename from tests/witness/serialization/mdc.bin
rename to core/src/test/resources/witness/serialization/mdc.bin
diff --git a/tests/witness/serialization/ndc.bin b/core/src/test/resources/witness/serialization/ndc.bin
similarity index 100%
rename from tests/witness/serialization/ndc.bin
rename to core/src/test/resources/witness/serialization/ndc.bin
diff --git a/tests/witness/serialization/simple.bin b/core/src/test/resources/witness/serialization/simple.bin
similarity index 100%
rename from tests/witness/serialization/simple.bin
rename to core/src/test/resources/witness/serialization/simple.bin
diff --git a/tests/witness/simple b/core/src/test/resources/witness/simple
similarity index 100%
rename from tests/witness/simple
rename to core/src/test/resources/witness/simple
diff --git a/tests/witness/socketServer.1 b/core/src/test/resources/witness/socketServer.1
similarity index 100%
rename from tests/witness/socketServer.1
rename to core/src/test/resources/witness/socketServer.1
diff --git a/tests/witness/socketServer.2 b/core/src/test/resources/witness/socketServer.2
similarity index 100%
rename from tests/witness/socketServer.2
rename to core/src/test/resources/witness/socketServer.2
diff --git a/tests/witness/socketServer.3 b/core/src/test/resources/witness/socketServer.3
similarity index 100%
rename from tests/witness/socketServer.3
rename to core/src/test/resources/witness/socketServer.3
diff --git a/tests/witness/socketServer.4 b/core/src/test/resources/witness/socketServer.4
similarity index 100%
rename from tests/witness/socketServer.4
rename to core/src/test/resources/witness/socketServer.4
diff --git a/tests/witness/socketServer.5 b/core/src/test/resources/witness/socketServer.5
similarity index 100%
rename from tests/witness/socketServer.5
rename to core/src/test/resources/witness/socketServer.5
diff --git a/tests/witness/socketServer.6 b/core/src/test/resources/witness/socketServer.6
similarity index 100%
rename from tests/witness/socketServer.6
rename to core/src/test/resources/witness/socketServer.6
diff --git a/tests/witness/socketServer.7 b/core/src/test/resources/witness/socketServer.7
similarity index 100%
rename from tests/witness/socketServer.7
rename to core/src/test/resources/witness/socketServer.7
diff --git a/tests/witness/socketServer.8 b/core/src/test/resources/witness/socketServer.8
similarity index 100%
rename from tests/witness/socketServer.8
rename to core/src/test/resources/witness/socketServer.8
diff --git a/tests/witness/ttcc b/core/src/test/resources/witness/ttcc
similarity index 100%
rename from tests/witness/ttcc
rename to core/src/test/resources/witness/ttcc
diff --git a/tests/witness/xmlLayout.1 b/core/src/test/resources/witness/xmlLayout.1
similarity index 100%
rename from tests/witness/xmlLayout.1
rename to core/src/test/resources/witness/xmlLayout.1
diff --git a/tests/witness/xmlLayout.2 b/core/src/test/resources/witness/xmlLayout.2
similarity index 100%
rename from tests/witness/xmlLayout.2
rename to core/src/test/resources/witness/xmlLayout.2
diff --git a/tests/witness/xmlLayout.3 b/core/src/test/resources/witness/xmlLayout.3
similarity index 100%
rename from tests/witness/xmlLayout.3
rename to core/src/test/resources/witness/xmlLayout.3
diff --git a/tests/witness/xmlLayout.mdc.1 b/core/src/test/resources/witness/xmlLayout.mdc.1
similarity index 100%
rename from tests/witness/xmlLayout.mdc.1
rename to core/src/test/resources/witness/xmlLayout.mdc.1
diff --git a/tests/witness/xmlLayout.mdc.2 b/core/src/test/resources/witness/xmlLayout.mdc.2
similarity index 100%
rename from tests/witness/xmlLayout.mdc.2
rename to core/src/test/resources/witness/xmlLayout.mdc.2
diff --git a/tests/witness/xmlLayout.null b/core/src/test/resources/witness/xmlLayout.null
similarity index 100%
rename from tests/witness/xmlLayout.null
rename to core/src/test/resources/witness/xmlLayout.null
diff --git a/tests/run-tests.bat b/core/src/test/run-tests.bat
similarity index 100%
rename from tests/run-tests.bat
rename to core/src/test/run-tests.bat
diff --git a/tests/sun_checks.xml b/core/src/test/sun_checks.xml
similarity index 100%
rename from tests/sun_checks.xml
rename to core/src/test/sun_checks.xml
diff --git a/modules/chainsaw/pom.xml b/modules/chainsaw/pom.xml
new file mode 100644
index 0000000000..d4497eaab5
--- /dev/null
+++ b/modules/chainsaw/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-modules
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-chainsaw
+ Apache Log4j-Chainsaw V1
+ jar
+
+
+
+ org.apache.log4j
+ log4j-core
+ ${project.version}
+
+
+
+
\ No newline at end of file
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ControlPanel.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ControlPanel.java
new file mode 100644
index 0000000000..53b0b1b5fa
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ControlPanel.java
@@ -0,0 +1,222 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import org.apache.log4j.Logger;
+import org.apache.log4j.Priority;
+import org.apache.log4j.Level;
+
+/**
+ * Represents the controls for filtering, pausing, exiting, etc.
+ *
+ * @author Oliver Burn
+ */
+class ControlPanel extends JPanel {
+ /** use the log messages **/
+ private static final Logger LOG =
+ Logger.getLogger(ControlPanel.class);
+
+ /**
+ * Creates a new ControlPanel
instance.
+ *
+ * @param aModel the model to control
+ */
+ ControlPanel(final MyTableModel aModel) {
+ setBorder(BorderFactory.createTitledBorder("Controls: "));
+ final GridBagLayout gridbag = new GridBagLayout();
+ final GridBagConstraints c = new GridBagConstraints();
+ setLayout(gridbag);
+
+ // Pad everything
+ c.ipadx = 5;
+ c.ipady = 5;
+
+ // Add the 1st column of labels
+ c.gridx = 0;
+ c.anchor = GridBagConstraints.EAST;
+
+ c.gridy = 0;
+ JLabel label = new JLabel("Filter Level:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter Thread:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter Logger:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter NDC:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter Message:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ // Add the 2nd column of filters
+ c.weightx = 1;
+ //c.weighty = 1;
+ c.gridx = 1;
+ c.anchor = GridBagConstraints.WEST;
+
+ c.gridy = 0;
+ final Level[] allPriorities = new Level[] {Level.FATAL,
+ Level.ERROR,
+ Level.WARN,
+ Level.INFO,
+ Level.DEBUG,
+ Level.TRACE };
+
+ final JComboBox priorities = new JComboBox(allPriorities);
+ final Level lowest = allPriorities[allPriorities.length - 1];
+ priorities.setSelectedItem(lowest);
+ aModel.setPriorityFilter(lowest);
+ gridbag.setConstraints(priorities, c);
+ add(priorities);
+ priorities.setEditable(false);
+ priorities.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent aEvent) {
+ aModel.setPriorityFilter(
+ (Priority) priorities.getSelectedItem());
+ }
+ });
+
+
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridy++;
+ final JTextField threadField = new JTextField("");
+ threadField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setThreadFilter(threadField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvente) {
+ aModel.setThreadFilter(threadField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setThreadFilter(threadField.getText());
+ }
+ });
+ gridbag.setConstraints(threadField, c);
+ add(threadField);
+
+ c.gridy++;
+ final JTextField catField = new JTextField("");
+ catField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setCategoryFilter(catField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvent) {
+ aModel.setCategoryFilter(catField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setCategoryFilter(catField.getText());
+ }
+ });
+ gridbag.setConstraints(catField, c);
+ add(catField);
+
+ c.gridy++;
+ final JTextField ndcField = new JTextField("");
+ ndcField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setNDCFilter(ndcField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvent) {
+ aModel.setNDCFilter(ndcField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setNDCFilter(ndcField.getText());
+ }
+ });
+ gridbag.setConstraints(ndcField, c);
+ add(ndcField);
+
+ c.gridy++;
+ final JTextField msgField = new JTextField("");
+ msgField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setMessageFilter(msgField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvent) {
+ aModel.setMessageFilter(msgField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setMessageFilter(msgField.getText());
+ }
+ });
+
+
+ gridbag.setConstraints(msgField, c);
+ add(msgField);
+
+ // Add the 3rd column of buttons
+ c.weightx = 0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.EAST;
+ c.gridx = 2;
+
+ c.gridy = 0;
+ final JButton exitButton = new JButton("Exit");
+ exitButton.setMnemonic('x');
+ exitButton.addActionListener(ExitAction.INSTANCE);
+ gridbag.setConstraints(exitButton, c);
+ add(exitButton);
+
+ c.gridy++;
+ final JButton clearButton = new JButton("Clear");
+ clearButton.setMnemonic('c');
+ clearButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent aEvent) {
+ aModel.clear();
+ }
+ });
+ gridbag.setConstraints(clearButton, c);
+ add(clearButton);
+
+ c.gridy++;
+ final JButton toggleButton = new JButton("Pause");
+ toggleButton.setMnemonic('p');
+ toggleButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent aEvent) {
+ aModel.toggle();
+ toggleButton.setText(
+ aModel.isPaused() ? "Resume" : "Pause");
+ }
+ });
+ gridbag.setConstraints(toggleButton, c);
+ add(toggleButton);
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ControlPanel.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ControlPanel.java.orig
new file mode 100644
index 0000000000..53b0b1b5fa
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ControlPanel.java.orig
@@ -0,0 +1,222 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import org.apache.log4j.Logger;
+import org.apache.log4j.Priority;
+import org.apache.log4j.Level;
+
+/**
+ * Represents the controls for filtering, pausing, exiting, etc.
+ *
+ * @author Oliver Burn
+ */
+class ControlPanel extends JPanel {
+ /** use the log messages **/
+ private static final Logger LOG =
+ Logger.getLogger(ControlPanel.class);
+
+ /**
+ * Creates a new ControlPanel
instance.
+ *
+ * @param aModel the model to control
+ */
+ ControlPanel(final MyTableModel aModel) {
+ setBorder(BorderFactory.createTitledBorder("Controls: "));
+ final GridBagLayout gridbag = new GridBagLayout();
+ final GridBagConstraints c = new GridBagConstraints();
+ setLayout(gridbag);
+
+ // Pad everything
+ c.ipadx = 5;
+ c.ipady = 5;
+
+ // Add the 1st column of labels
+ c.gridx = 0;
+ c.anchor = GridBagConstraints.EAST;
+
+ c.gridy = 0;
+ JLabel label = new JLabel("Filter Level:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter Thread:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter Logger:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter NDC:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ c.gridy++;
+ label = new JLabel("Filter Message:");
+ gridbag.setConstraints(label, c);
+ add(label);
+
+ // Add the 2nd column of filters
+ c.weightx = 1;
+ //c.weighty = 1;
+ c.gridx = 1;
+ c.anchor = GridBagConstraints.WEST;
+
+ c.gridy = 0;
+ final Level[] allPriorities = new Level[] {Level.FATAL,
+ Level.ERROR,
+ Level.WARN,
+ Level.INFO,
+ Level.DEBUG,
+ Level.TRACE };
+
+ final JComboBox priorities = new JComboBox(allPriorities);
+ final Level lowest = allPriorities[allPriorities.length - 1];
+ priorities.setSelectedItem(lowest);
+ aModel.setPriorityFilter(lowest);
+ gridbag.setConstraints(priorities, c);
+ add(priorities);
+ priorities.setEditable(false);
+ priorities.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent aEvent) {
+ aModel.setPriorityFilter(
+ (Priority) priorities.getSelectedItem());
+ }
+ });
+
+
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridy++;
+ final JTextField threadField = new JTextField("");
+ threadField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setThreadFilter(threadField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvente) {
+ aModel.setThreadFilter(threadField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setThreadFilter(threadField.getText());
+ }
+ });
+ gridbag.setConstraints(threadField, c);
+ add(threadField);
+
+ c.gridy++;
+ final JTextField catField = new JTextField("");
+ catField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setCategoryFilter(catField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvent) {
+ aModel.setCategoryFilter(catField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setCategoryFilter(catField.getText());
+ }
+ });
+ gridbag.setConstraints(catField, c);
+ add(catField);
+
+ c.gridy++;
+ final JTextField ndcField = new JTextField("");
+ ndcField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setNDCFilter(ndcField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvent) {
+ aModel.setNDCFilter(ndcField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setNDCFilter(ndcField.getText());
+ }
+ });
+ gridbag.setConstraints(ndcField, c);
+ add(ndcField);
+
+ c.gridy++;
+ final JTextField msgField = new JTextField("");
+ msgField.getDocument().addDocumentListener(new DocumentListener () {
+ public void insertUpdate(DocumentEvent aEvent) {
+ aModel.setMessageFilter(msgField.getText());
+ }
+ public void removeUpdate(DocumentEvent aEvent) {
+ aModel.setMessageFilter(msgField.getText());
+ }
+ public void changedUpdate(DocumentEvent aEvent) {
+ aModel.setMessageFilter(msgField.getText());
+ }
+ });
+
+
+ gridbag.setConstraints(msgField, c);
+ add(msgField);
+
+ // Add the 3rd column of buttons
+ c.weightx = 0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.EAST;
+ c.gridx = 2;
+
+ c.gridy = 0;
+ final JButton exitButton = new JButton("Exit");
+ exitButton.setMnemonic('x');
+ exitButton.addActionListener(ExitAction.INSTANCE);
+ gridbag.setConstraints(exitButton, c);
+ add(exitButton);
+
+ c.gridy++;
+ final JButton clearButton = new JButton("Clear");
+ clearButton.setMnemonic('c');
+ clearButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent aEvent) {
+ aModel.clear();
+ }
+ });
+ gridbag.setConstraints(clearButton, c);
+ add(clearButton);
+
+ c.gridy++;
+ final JButton toggleButton = new JButton("Pause");
+ toggleButton.setMnemonic('p');
+ toggleButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent aEvent) {
+ aModel.toggle();
+ toggleButton.setText(
+ aModel.isPaused() ? "Resume" : "Pause");
+ }
+ });
+ gridbag.setConstraints(toggleButton, c);
+ add(toggleButton);
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/DetailPanel.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/DetailPanel.java
new file mode 100644
index 0000000000..1f5dfe2c83
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/DetailPanel.java
@@ -0,0 +1,170 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.BorderLayout;
+import java.text.MessageFormat;
+import java.util.Date;
+import javax.swing.BorderFactory;
+import javax.swing.JEditorPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import org.apache.log4j.Logger;
+
+/**
+ * A panel for showing a stack trace.
+ *
+ * @author Oliver Burn
+ */
+class DetailPanel
+ extends JPanel
+ implements ListSelectionListener
+{
+ /** used to log events **/
+ private static final Logger LOG =
+ Logger.getLogger(DetailPanel.class);
+
+ /** used to format the logging event **/
+ private static final MessageFormat FORMATTER = new MessageFormat(
+ "Time: {0,time,medium}
" +
+ " Priority: {1}
" +
+ " Thread: {2}
" +
+ " NDC: {3}
" +
+ "
Logger: {4}
" +
+ "
Location: {5}
" +
+ "
Message:" +
+ "
{6}
" +
+ "Throwable:" +
+ "{7}
");
+
+ /** the model for the data to render **/
+ private final MyTableModel mModel;
+ /** pane for rendering detail **/
+ private final JEditorPane mDetails;
+
+ /**
+ * Creates a new DetailPanel
instance.
+ *
+ * @param aTable the table to listen for selections on
+ * @param aModel the model backing the table
+ */
+ DetailPanel(JTable aTable, final MyTableModel aModel) {
+ mModel = aModel;
+ setLayout(new BorderLayout());
+ setBorder(BorderFactory.createTitledBorder("Details: "));
+
+ mDetails = new JEditorPane();
+ mDetails.setEditable(false);
+ mDetails.setContentType("text/html");
+ add(new JScrollPane(mDetails), BorderLayout.CENTER);
+
+ final ListSelectionModel rowSM = aTable.getSelectionModel();
+ rowSM.addListSelectionListener(this);
+ }
+
+ /** @see ListSelectionListener **/
+ public void valueChanged(ListSelectionEvent aEvent) {
+ //Ignore extra messages.
+ if (aEvent.getValueIsAdjusting()) {
+ return;
+ }
+
+ final ListSelectionModel lsm = (ListSelectionModel) aEvent.getSource();
+ if (lsm.isSelectionEmpty()) {
+ mDetails.setText("Nothing selected");
+ } else {
+ final int selectedRow = lsm.getMinSelectionIndex();
+ final EventDetails e = mModel.getEventDetails(selectedRow);
+ final Object[] args =
+ {
+ new Date(e.getTimeStamp()),
+ e.getPriority(),
+ escape(e.getThreadName()),
+ escape(e.getNDC()),
+ escape(e.getCategoryName()),
+ escape(e.getLocationDetails()),
+ escape(e.getMessage()),
+ escape(getThrowableStrRep(e))
+ };
+ mDetails.setText(FORMATTER.format(args));
+ mDetails.setCaretPosition(0);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Private methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Returns a string representation of a throwable.
+ *
+ * @param aEvent contains the throwable information
+ * @return a String
value
+ */
+ private static String getThrowableStrRep(EventDetails aEvent) {
+ final String[] strs = aEvent.getThrowableStrRep();
+ if (strs == null) {
+ return null;
+ }
+
+ final StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < strs.length; i++) {
+ sb.append(strs[i]).append("\n");
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Escape <, > & and " as their entities. It is very
+ * dumb about & handling.
+ * @param aStr the String to escape.
+ * @return the escaped String
+ */
+ private String escape(String aStr) {
+ if (aStr == null) {
+ return null;
+ }
+
+ final StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < aStr.length(); i++) {
+ char c = aStr.charAt(i);
+ switch (c) {
+ case '<':
+ buf.append("<");
+ break;
+ case '>':
+ buf.append(">");
+ break;
+ case '\"':
+ buf.append(""");
+ break;
+ case '&':
+ buf.append("&");
+ break;
+ default:
+ buf.append(c);
+ break;
+ }
+ }
+ return buf.toString();
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/DetailPanel.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/DetailPanel.java.orig
new file mode 100644
index 0000000000..1f5dfe2c83
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/DetailPanel.java.orig
@@ -0,0 +1,170 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.BorderLayout;
+import java.text.MessageFormat;
+import java.util.Date;
+import javax.swing.BorderFactory;
+import javax.swing.JEditorPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import org.apache.log4j.Logger;
+
+/**
+ * A panel for showing a stack trace.
+ *
+ * @author Oliver Burn
+ */
+class DetailPanel
+ extends JPanel
+ implements ListSelectionListener
+{
+ /** used to log events **/
+ private static final Logger LOG =
+ Logger.getLogger(DetailPanel.class);
+
+ /** used to format the logging event **/
+ private static final MessageFormat FORMATTER = new MessageFormat(
+ "Time: {0,time,medium}
" +
+ " Priority: {1}
" +
+ " Thread: {2}
" +
+ " NDC: {3}
" +
+ "
Logger: {4}
" +
+ "
Location: {5}
" +
+ "
Message:" +
+ "{6}
" +
+ "Throwable:" +
+ "{7}
");
+
+ /** the model for the data to render **/
+ private final MyTableModel mModel;
+ /** pane for rendering detail **/
+ private final JEditorPane mDetails;
+
+ /**
+ * Creates a new DetailPanel
instance.
+ *
+ * @param aTable the table to listen for selections on
+ * @param aModel the model backing the table
+ */
+ DetailPanel(JTable aTable, final MyTableModel aModel) {
+ mModel = aModel;
+ setLayout(new BorderLayout());
+ setBorder(BorderFactory.createTitledBorder("Details: "));
+
+ mDetails = new JEditorPane();
+ mDetails.setEditable(false);
+ mDetails.setContentType("text/html");
+ add(new JScrollPane(mDetails), BorderLayout.CENTER);
+
+ final ListSelectionModel rowSM = aTable.getSelectionModel();
+ rowSM.addListSelectionListener(this);
+ }
+
+ /** @see ListSelectionListener **/
+ public void valueChanged(ListSelectionEvent aEvent) {
+ //Ignore extra messages.
+ if (aEvent.getValueIsAdjusting()) {
+ return;
+ }
+
+ final ListSelectionModel lsm = (ListSelectionModel) aEvent.getSource();
+ if (lsm.isSelectionEmpty()) {
+ mDetails.setText("Nothing selected");
+ } else {
+ final int selectedRow = lsm.getMinSelectionIndex();
+ final EventDetails e = mModel.getEventDetails(selectedRow);
+ final Object[] args =
+ {
+ new Date(e.getTimeStamp()),
+ e.getPriority(),
+ escape(e.getThreadName()),
+ escape(e.getNDC()),
+ escape(e.getCategoryName()),
+ escape(e.getLocationDetails()),
+ escape(e.getMessage()),
+ escape(getThrowableStrRep(e))
+ };
+ mDetails.setText(FORMATTER.format(args));
+ mDetails.setCaretPosition(0);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Private methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Returns a string representation of a throwable.
+ *
+ * @param aEvent contains the throwable information
+ * @return a String
value
+ */
+ private static String getThrowableStrRep(EventDetails aEvent) {
+ final String[] strs = aEvent.getThrowableStrRep();
+ if (strs == null) {
+ return null;
+ }
+
+ final StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < strs.length; i++) {
+ sb.append(strs[i]).append("\n");
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Escape <, > & and " as their entities. It is very
+ * dumb about & handling.
+ * @param aStr the String to escape.
+ * @return the escaped String
+ */
+ private String escape(String aStr) {
+ if (aStr == null) {
+ return null;
+ }
+
+ final StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < aStr.length(); i++) {
+ char c = aStr.charAt(i);
+ switch (c) {
+ case '<':
+ buf.append("<");
+ break;
+ case '>':
+ buf.append(">");
+ break;
+ case '\"':
+ buf.append(""");
+ break;
+ case '&':
+ buf.append("&");
+ break;
+ default:
+ buf.append(c);
+ break;
+ }
+ }
+ return buf.toString();
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/EventDetails.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/EventDetails.java
new file mode 100644
index 0000000000..4b3ad94a6a
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/EventDetails.java
@@ -0,0 +1,135 @@
+/*
+ * 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.chainsaw;
+
+import org.apache.log4j.Priority;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * Represents the details of a logging event. It is intended to overcome the
+ * problem that a LoggingEvent cannot be constructed with purely fake data.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+class EventDetails {
+
+ /** the time of the event **/
+ private final long mTimeStamp;
+ /** the priority of the event **/
+ private final Priority mPriority;
+ /** the category of the event **/
+ private final String mCategoryName;
+ /** the NDC for the event **/
+ private final String mNDC;
+ /** the thread for the event **/
+ private final String mThreadName;
+ /** the msg for the event **/
+ private final String mMessage;
+ /** the throwable details the event **/
+ private final String[] mThrowableStrRep;
+ /** the location details for the event **/
+ private final String mLocationDetails;
+
+ /**
+ * Creates a new EventDetails
instance.
+ * @param aTimeStamp a long
value
+ * @param aPriority a Priority
value
+ * @param aCategoryName a String
value
+ * @param aNDC a String
value
+ * @param aThreadName a String
value
+ * @param aMessage a String
value
+ * @param aThrowableStrRep a String[]
value
+ * @param aLocationDetails a String
value
+ */
+ EventDetails(long aTimeStamp,
+ Priority aPriority,
+ String aCategoryName,
+ String aNDC,
+ String aThreadName,
+ String aMessage,
+ String[] aThrowableStrRep,
+ String aLocationDetails)
+ {
+ mTimeStamp = aTimeStamp;
+ mPriority = aPriority;
+ mCategoryName = aCategoryName;
+ mNDC = aNDC;
+ mThreadName = aThreadName;
+ mMessage = aMessage;
+ mThrowableStrRep = aThrowableStrRep;
+ mLocationDetails = aLocationDetails;
+ }
+
+ /**
+ * Creates a new EventDetails
instance.
+ *
+ * @param aEvent a LoggingEvent
value
+ */
+ EventDetails(LoggingEvent aEvent) {
+
+ this(aEvent.timeStamp,
+ aEvent.getLevel(),
+ aEvent.getLoggerName(),
+ aEvent.getNDC(),
+ aEvent.getThreadName(),
+ aEvent.getRenderedMessage(),
+ aEvent.getThrowableStrRep(),
+ (aEvent.getLocationInformation() == null)
+ ? null : aEvent.getLocationInformation().fullInfo);
+ }
+
+ /** @see #mTimeStamp **/
+ long getTimeStamp() {
+ return mTimeStamp;
+ }
+
+ /** @see #mPriority **/
+ Priority getPriority() {
+ return mPriority;
+ }
+
+ /** @see #mCategoryName **/
+ String getCategoryName() {
+ return mCategoryName;
+ }
+
+ /** @see #mNDC **/
+ String getNDC() {
+ return mNDC;
+ }
+
+ /** @see #mThreadName **/
+ String getThreadName() {
+ return mThreadName;
+ }
+
+ /** @see #mMessage **/
+ String getMessage() {
+ return mMessage;
+ }
+
+ /** @see #mLocationDetails **/
+ String getLocationDetails(){
+ return mLocationDetails;
+ }
+
+ /** @see #mThrowableStrRep **/
+ String[] getThrowableStrRep() {
+ return mThrowableStrRep;
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/EventDetails.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/EventDetails.java.orig
new file mode 100644
index 0000000000..4b3ad94a6a
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/EventDetails.java.orig
@@ -0,0 +1,135 @@
+/*
+ * 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.chainsaw;
+
+import org.apache.log4j.Priority;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * Represents the details of a logging event. It is intended to overcome the
+ * problem that a LoggingEvent cannot be constructed with purely fake data.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+class EventDetails {
+
+ /** the time of the event **/
+ private final long mTimeStamp;
+ /** the priority of the event **/
+ private final Priority mPriority;
+ /** the category of the event **/
+ private final String mCategoryName;
+ /** the NDC for the event **/
+ private final String mNDC;
+ /** the thread for the event **/
+ private final String mThreadName;
+ /** the msg for the event **/
+ private final String mMessage;
+ /** the throwable details the event **/
+ private final String[] mThrowableStrRep;
+ /** the location details for the event **/
+ private final String mLocationDetails;
+
+ /**
+ * Creates a new EventDetails
instance.
+ * @param aTimeStamp a long
value
+ * @param aPriority a Priority
value
+ * @param aCategoryName a String
value
+ * @param aNDC a String
value
+ * @param aThreadName a String
value
+ * @param aMessage a String
value
+ * @param aThrowableStrRep a String[]
value
+ * @param aLocationDetails a String
value
+ */
+ EventDetails(long aTimeStamp,
+ Priority aPriority,
+ String aCategoryName,
+ String aNDC,
+ String aThreadName,
+ String aMessage,
+ String[] aThrowableStrRep,
+ String aLocationDetails)
+ {
+ mTimeStamp = aTimeStamp;
+ mPriority = aPriority;
+ mCategoryName = aCategoryName;
+ mNDC = aNDC;
+ mThreadName = aThreadName;
+ mMessage = aMessage;
+ mThrowableStrRep = aThrowableStrRep;
+ mLocationDetails = aLocationDetails;
+ }
+
+ /**
+ * Creates a new EventDetails
instance.
+ *
+ * @param aEvent a LoggingEvent
value
+ */
+ EventDetails(LoggingEvent aEvent) {
+
+ this(aEvent.timeStamp,
+ aEvent.getLevel(),
+ aEvent.getLoggerName(),
+ aEvent.getNDC(),
+ aEvent.getThreadName(),
+ aEvent.getRenderedMessage(),
+ aEvent.getThrowableStrRep(),
+ (aEvent.getLocationInformation() == null)
+ ? null : aEvent.getLocationInformation().fullInfo);
+ }
+
+ /** @see #mTimeStamp **/
+ long getTimeStamp() {
+ return mTimeStamp;
+ }
+
+ /** @see #mPriority **/
+ Priority getPriority() {
+ return mPriority;
+ }
+
+ /** @see #mCategoryName **/
+ String getCategoryName() {
+ return mCategoryName;
+ }
+
+ /** @see #mNDC **/
+ String getNDC() {
+ return mNDC;
+ }
+
+ /** @see #mThreadName **/
+ String getThreadName() {
+ return mThreadName;
+ }
+
+ /** @see #mMessage **/
+ String getMessage() {
+ return mMessage;
+ }
+
+ /** @see #mLocationDetails **/
+ String getLocationDetails(){
+ return mLocationDetails;
+ }
+
+ /** @see #mThrowableStrRep **/
+ String[] getThrowableStrRep() {
+ return mThrowableStrRep;
+ }
+}
diff --git a/tests/src/java/org/apache/log4j/helpers/UtilLoggingLevelTest.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ExitAction.java
similarity index 52%
rename from tests/src/java/org/apache/log4j/helpers/UtilLoggingLevelTest.java
rename to modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ExitAction.java
index 58105ee8c1..55a100e29f 100644
--- a/tests/src/java/org/apache/log4j/helpers/UtilLoggingLevelTest.java
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ExitAction.java
@@ -5,42 +5,44 @@
* 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.chainsaw;
-package org.apache.log4j.helpers;
-
-import junit.framework.*;
-
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.apache.log4j.Logger;
/**
- * Unit tests for UtilLoggingLevel.
+ * Encapsulates the action to exit.
+ *
+ * @author Oliver Burn
+ * @version 1.0
*/
+class ExitAction
+ extends AbstractAction
+{
+ /** use to log messages **/
+ private static final Logger LOG = Logger.getLogger(ExitAction.class);
+ /** The instance to share **/
+ public static final ExitAction INSTANCE = new ExitAction();
-public class UtilLoggingLevelTest extends TestCase {
+ /** Stop people creating instances **/
+ private ExitAction() {}
/**
- * Create new instance of test.
- *
- * @param testName test name
+ * Will shutdown the application.
+ * @param aIgnore ignored
*/
- public UtilLoggingLevelTest(final String testName) {
- super(testName);
+ public void actionPerformed(ActionEvent aIgnore) {
+ LOG.info("shutting down");
+ System.exit(0);
}
-
- /**
- * Test toLevel("fiNeSt").
- */
- public void testToLevelFINEST() {
- assertSame(UtilLoggingLevel.FINEST, UtilLoggingLevel.toLevel("fiNeSt"));
- }
-
}
-
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ExitAction.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ExitAction.java.orig
new file mode 100644
index 0000000000..55a100e29f
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/ExitAction.java.orig
@@ -0,0 +1,48 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.apache.log4j.Logger;
+
+/**
+ * Encapsulates the action to exit.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+class ExitAction
+ extends AbstractAction
+{
+ /** use to log messages **/
+ private static final Logger LOG = Logger.getLogger(ExitAction.class);
+ /** The instance to share **/
+ public static final ExitAction INSTANCE = new ExitAction();
+
+ /** Stop people creating instances **/
+ private ExitAction() {}
+
+ /**
+ * Will shutdown the application.
+ * @param aIgnore ignored
+ */
+ public void actionPerformed(ActionEvent aIgnore) {
+ LOG.info("shutting down");
+ System.exit(0);
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoadXMLAction.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoadXMLAction.java
new file mode 100644
index 0000000000..33e5d13cf2
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoadXMLAction.java
@@ -0,0 +1,139 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import javax.swing.AbstractAction;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import org.apache.log4j.Logger;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Encapsulates the action to load an XML file.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+class LoadXMLAction
+ extends AbstractAction
+{
+ /** use to log messages **/
+ private static final Logger LOG = Logger.getLogger(LoadXMLAction.class);
+
+ /** the parent frame **/
+ private final JFrame mParent;
+
+ /**
+ * the file chooser - configured to allow only the selection of a
+ * single file.
+ */
+ private final JFileChooser mChooser = new JFileChooser();
+ {
+ mChooser.setMultiSelectionEnabled(false);
+ mChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ }
+
+ /** parser to read XML files **/
+ private final XMLReader mParser;
+ /** the content handler **/
+ private final XMLFileHandler mHandler;
+
+
+ /**
+ * Creates a new LoadXMLAction
instance.
+ *
+ * @param aParent the parent frame
+ * @param aModel the model to add events to
+ * @exception SAXException if an error occurs
+ * @throws ParserConfigurationException if an error occurs
+ */
+ LoadXMLAction(JFrame aParent, MyTableModel aModel)
+ throws SAXException, ParserConfigurationException
+ {
+ mParent = aParent;
+ mHandler = new XMLFileHandler(aModel);
+ mParser = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+ mParser.setContentHandler(mHandler);
+ }
+
+ /**
+ * Prompts the user for a file to load events from.
+ * @param aIgnore an ActionEvent
value
+ */
+ public void actionPerformed(ActionEvent aIgnore) {
+ LOG.info("load file called");
+ if (mChooser.showOpenDialog(mParent) == JFileChooser.APPROVE_OPTION) {
+ LOG.info("Need to load a file");
+ final File chosen = mChooser.getSelectedFile();
+ LOG.info("loading the contents of " + chosen.getAbsolutePath());
+ try {
+ final int num = loadFile(chosen.getAbsolutePath());
+ JOptionPane.showMessageDialog(
+ mParent,
+ "Loaded " + num + " events.",
+ "CHAINSAW",
+ JOptionPane.INFORMATION_MESSAGE);
+ } catch (Exception e) {
+ LOG.warn("caught an exception loading the file", e);
+ JOptionPane.showMessageDialog(
+ mParent,
+ "Error parsing file - " + e.getMessage(),
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ /**
+ * Loads the contents of file into the model
+ *
+ * @param aFile the file to extract events from
+ * @return the number of events loaded
+ * @throws SAXException if an error occurs
+ * @throws IOException if an error occurs
+ */
+ private int loadFile(String aFile)
+ throws SAXException, IOException
+ {
+ synchronized (mParser) {
+ // Create a dummy document to parse the file
+ final StringBuffer buf = new StringBuffer();
+ buf.append("\n");
+ buf.append("]>\n");
+ buf.append("\n");
+ buf.append("&data;\n");
+ buf.append("\n");
+
+ final InputSource is =
+ new InputSource(new StringReader(buf.toString()));
+ mParser.parse(is);
+ return mHandler.getNumEvents();
+ }
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoadXMLAction.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoadXMLAction.java.orig
new file mode 100644
index 0000000000..33e5d13cf2
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoadXMLAction.java.orig
@@ -0,0 +1,139 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import javax.swing.AbstractAction;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import org.apache.log4j.Logger;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Encapsulates the action to load an XML file.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+class LoadXMLAction
+ extends AbstractAction
+{
+ /** use to log messages **/
+ private static final Logger LOG = Logger.getLogger(LoadXMLAction.class);
+
+ /** the parent frame **/
+ private final JFrame mParent;
+
+ /**
+ * the file chooser - configured to allow only the selection of a
+ * single file.
+ */
+ private final JFileChooser mChooser = new JFileChooser();
+ {
+ mChooser.setMultiSelectionEnabled(false);
+ mChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ }
+
+ /** parser to read XML files **/
+ private final XMLReader mParser;
+ /** the content handler **/
+ private final XMLFileHandler mHandler;
+
+
+ /**
+ * Creates a new LoadXMLAction
instance.
+ *
+ * @param aParent the parent frame
+ * @param aModel the model to add events to
+ * @exception SAXException if an error occurs
+ * @throws ParserConfigurationException if an error occurs
+ */
+ LoadXMLAction(JFrame aParent, MyTableModel aModel)
+ throws SAXException, ParserConfigurationException
+ {
+ mParent = aParent;
+ mHandler = new XMLFileHandler(aModel);
+ mParser = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+ mParser.setContentHandler(mHandler);
+ }
+
+ /**
+ * Prompts the user for a file to load events from.
+ * @param aIgnore an ActionEvent
value
+ */
+ public void actionPerformed(ActionEvent aIgnore) {
+ LOG.info("load file called");
+ if (mChooser.showOpenDialog(mParent) == JFileChooser.APPROVE_OPTION) {
+ LOG.info("Need to load a file");
+ final File chosen = mChooser.getSelectedFile();
+ LOG.info("loading the contents of " + chosen.getAbsolutePath());
+ try {
+ final int num = loadFile(chosen.getAbsolutePath());
+ JOptionPane.showMessageDialog(
+ mParent,
+ "Loaded " + num + " events.",
+ "CHAINSAW",
+ JOptionPane.INFORMATION_MESSAGE);
+ } catch (Exception e) {
+ LOG.warn("caught an exception loading the file", e);
+ JOptionPane.showMessageDialog(
+ mParent,
+ "Error parsing file - " + e.getMessage(),
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ /**
+ * Loads the contents of file into the model
+ *
+ * @param aFile the file to extract events from
+ * @return the number of events loaded
+ * @throws SAXException if an error occurs
+ * @throws IOException if an error occurs
+ */
+ private int loadFile(String aFile)
+ throws SAXException, IOException
+ {
+ synchronized (mParser) {
+ // Create a dummy document to parse the file
+ final StringBuffer buf = new StringBuffer();
+ buf.append("\n");
+ buf.append("]>\n");
+ buf.append("\n");
+ buf.append("&data;\n");
+ buf.append("\n");
+
+ final InputSource is =
+ new InputSource(new StringReader(buf.toString()));
+ mParser.parse(is);
+ return mHandler.getNumEvents();
+ }
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java
new file mode 100644
index 0000000000..ca087adcc0
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java
@@ -0,0 +1,121 @@
+/*
+ * 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.chainsaw;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * A daemon thread the processes connections from a
+ * org.apache.log4j.net.SocketAppender.html
.
+ *
+ * @author Oliver Burn
+ */
+class LoggingReceiver extends Thread {
+ /** used to log messages **/
+ private static final Logger LOG = Logger.getLogger(LoggingReceiver.class);
+
+ /**
+ * Helper that actually processes a client connection. It receives events
+ * and adds them to the supplied model.
+ *
+ * @author Oliver Burn
+ */
+ private class Slurper implements Runnable {
+ /** socket connection to read events from **/
+ private final Socket mClient;
+
+ /**
+ * Creates a new Slurper
instance.
+ *
+ * @param aClient socket to receive events from
+ */
+ Slurper(Socket aClient) {
+ mClient = aClient;
+ }
+
+ /** loops getting the events **/
+ public void run() {
+ LOG.debug("Starting to get data");
+ try {
+ final ObjectInputStream ois =
+ new ObjectInputStream(mClient.getInputStream());
+ while (true) {
+ final LoggingEvent event = (LoggingEvent) ois.readObject();
+ mModel.addEvent(new EventDetails(event));
+ }
+ } catch (EOFException e) {
+ LOG.info("Reached EOF, closing connection");
+ } catch (SocketException e) {
+ LOG.info("Caught SocketException, closing connection");
+ } catch (IOException e) {
+ LOG.warn("Got IOException, closing connection", e);
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Got ClassNotFoundException, closing connection", e);
+ }
+
+ try {
+ mClient.close();
+ } catch (IOException e) {
+ LOG.warn("Error closing connection", e);
+ }
+ }
+ }
+
+ /** where to put the events **/
+ private MyTableModel mModel;
+
+ /** server for listening for connections **/
+ private ServerSocket mSvrSock;
+
+ /**
+ * Creates a new LoggingReceiver
instance.
+ *
+ * @param aModel model to place put received into
+ * @param aPort port to listen on
+ * @throws IOException if an error occurs
+ */
+ LoggingReceiver(MyTableModel aModel, int aPort) throws IOException {
+ setDaemon(true);
+ mModel = aModel;
+ mSvrSock = new ServerSocket(aPort);
+ }
+
+ /** Listens for client connections **/
+ public void run() {
+ LOG.info("Thread started");
+ try {
+ while (true) {
+ LOG.debug("Waiting for a connection");
+ final Socket client = mSvrSock.accept();
+ LOG.debug("Got a connection from " +
+ client.getInetAddress().getHostName());
+ final Thread t = new Thread(new Slurper(client));
+ t.setDaemon(true);
+ t.start();
+ }
+ } catch (IOException e) {
+ LOG.error("Error in accepting connections, stopping.", e);
+ }
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java.orig
new file mode 100644
index 0000000000..ca087adcc0
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java.orig
@@ -0,0 +1,121 @@
+/*
+ * 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.chainsaw;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * A daemon thread the processes connections from a
+ * org.apache.log4j.net.SocketAppender.html
.
+ *
+ * @author Oliver Burn
+ */
+class LoggingReceiver extends Thread {
+ /** used to log messages **/
+ private static final Logger LOG = Logger.getLogger(LoggingReceiver.class);
+
+ /**
+ * Helper that actually processes a client connection. It receives events
+ * and adds them to the supplied model.
+ *
+ * @author Oliver Burn
+ */
+ private class Slurper implements Runnable {
+ /** socket connection to read events from **/
+ private final Socket mClient;
+
+ /**
+ * Creates a new Slurper
instance.
+ *
+ * @param aClient socket to receive events from
+ */
+ Slurper(Socket aClient) {
+ mClient = aClient;
+ }
+
+ /** loops getting the events **/
+ public void run() {
+ LOG.debug("Starting to get data");
+ try {
+ final ObjectInputStream ois =
+ new ObjectInputStream(mClient.getInputStream());
+ while (true) {
+ final LoggingEvent event = (LoggingEvent) ois.readObject();
+ mModel.addEvent(new EventDetails(event));
+ }
+ } catch (EOFException e) {
+ LOG.info("Reached EOF, closing connection");
+ } catch (SocketException e) {
+ LOG.info("Caught SocketException, closing connection");
+ } catch (IOException e) {
+ LOG.warn("Got IOException, closing connection", e);
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Got ClassNotFoundException, closing connection", e);
+ }
+
+ try {
+ mClient.close();
+ } catch (IOException e) {
+ LOG.warn("Error closing connection", e);
+ }
+ }
+ }
+
+ /** where to put the events **/
+ private MyTableModel mModel;
+
+ /** server for listening for connections **/
+ private ServerSocket mSvrSock;
+
+ /**
+ * Creates a new LoggingReceiver
instance.
+ *
+ * @param aModel model to place put received into
+ * @param aPort port to listen on
+ * @throws IOException if an error occurs
+ */
+ LoggingReceiver(MyTableModel aModel, int aPort) throws IOException {
+ setDaemon(true);
+ mModel = aModel;
+ mSvrSock = new ServerSocket(aPort);
+ }
+
+ /** Listens for client connections **/
+ public void run() {
+ LOG.info("Thread started");
+ try {
+ while (true) {
+ LOG.debug("Waiting for a connection");
+ final Socket client = mSvrSock.accept();
+ LOG.debug("Got a connection from " +
+ client.getInetAddress().getHostName());
+ final Thread t = new Thread(new Slurper(client));
+ t.setDaemon(true);
+ t.start();
+ }
+ } catch (IOException e) {
+ LOG.error("Error in accepting connections, stopping.", e);
+ }
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/Main.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/Main.java
new file mode 100644
index 0000000000..c0c9aad71a
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/Main.java
@@ -0,0 +1,192 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.util.Properties;
+import javax.swing.BorderFactory;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+/**
+ * The main application.
+ *
+ * @author Oliver Burn
+ */
+public class Main
+ extends JFrame
+{
+ /** the default port number to listen on **/
+ private static final int DEFAULT_PORT = 4445;
+
+ /** name of property for port name **/
+ public static final String PORT_PROP_NAME = "chainsaw.port";
+
+ /** use to log messages **/
+ private static final Logger LOG = Logger.getLogger(Main.class);
+
+
+ /**
+ * Creates a new Main
instance.
+ */
+ private Main() {
+ super("CHAINSAW - Log4J Log Viewer");
+ // create the all important model
+ final MyTableModel model = new MyTableModel();
+
+ //Create the menu bar.
+ final JMenuBar menuBar = new JMenuBar();
+ setJMenuBar(menuBar);
+ final JMenu menu = new JMenu("File");
+ menuBar.add(menu);
+
+ try {
+ final LoadXMLAction lxa = new LoadXMLAction(this, model);
+ final JMenuItem loadMenuItem = new JMenuItem("Load file...");
+ menu.add(loadMenuItem);
+ loadMenuItem.addActionListener(lxa);
+ } catch (NoClassDefFoundError e) {
+ LOG.info("Missing classes for XML parser", e);
+ JOptionPane.showMessageDialog(
+ this,
+ "XML parser not in classpath - unable to load XML events.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (Exception e) {
+ LOG.info("Unable to create the action to load XML files", e);
+ JOptionPane.showMessageDialog(
+ this,
+ "Unable to create a XML parser - unable to load XML events.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ }
+
+ final JMenuItem exitMenuItem = new JMenuItem("Exit");
+ menu.add(exitMenuItem);
+ exitMenuItem.addActionListener(ExitAction.INSTANCE);
+
+ // Add control panel
+ final ControlPanel cp = new ControlPanel(model);
+ getContentPane().add(cp, BorderLayout.NORTH);
+
+ // Create the table
+ final JTable table = new JTable(model);
+ table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ final JScrollPane scrollPane = new JScrollPane(table);
+ scrollPane.setBorder(BorderFactory.createTitledBorder("Events: "));
+ scrollPane.setPreferredSize(new Dimension(900, 300));
+
+ // Create the details
+ final JPanel details = new DetailPanel(table, model);
+ details.setPreferredSize(new Dimension(900, 300));
+
+ // Add the table and stack trace into a splitter
+ final JSplitPane jsp =
+ new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, details);
+ getContentPane().add(jsp, BorderLayout.CENTER);
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent aEvent) {
+ ExitAction.INSTANCE.actionPerformed(null);
+ }
+ });
+
+ pack();
+ setVisible(true);
+
+ setupReceiver(model);
+ }
+
+ /**
+ * Setup recieving messages.
+ *
+ * @param aModel a MyTableModel
value
+ */
+ private void setupReceiver(MyTableModel aModel) {
+ int port = DEFAULT_PORT;
+ final String strRep = System.getProperty(PORT_PROP_NAME);
+ if (strRep != null) {
+ try {
+ port = Integer.parseInt(strRep);
+ } catch (NumberFormatException nfe) {
+ LOG.fatal("Unable to parse " + PORT_PROP_NAME +
+ " property with value " + strRep + ".");
+ JOptionPane.showMessageDialog(
+ this,
+ "Unable to parse port number from '" + strRep +
+ "', quitting.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ System.exit(1);
+ }
+ }
+
+ try {
+ final LoggingReceiver lr = new LoggingReceiver(aModel, port);
+ lr.start();
+ } catch (IOException e) {
+ LOG.fatal("Unable to connect to socket server, quiting", e);
+ JOptionPane.showMessageDialog(
+ this,
+ "Unable to create socket on port " + port + ", quitting.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ System.exit(1);
+ }
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ // static methods
+ ////////////////////////////////////////////////////////////////////////////
+
+
+ /** initialise log4j **/
+ private static void initLog4J() {
+ final Properties props = new Properties();
+ props.setProperty("log4j.rootLogger", "DEBUG, A1");
+ props.setProperty("log4j.appender.A1",
+ "org.apache.log4j.ConsoleAppender");
+ props.setProperty("log4j.appender.A1.layout",
+ "org.apache.log4j.TTCCLayout");
+ PropertyConfigurator.configure(props);
+ }
+
+ /**
+ * The main method.
+ *
+ * @param aArgs ignored
+ */
+ public static void main(String[] aArgs) {
+ initLog4J();
+ new Main();
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/Main.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/Main.java.orig
new file mode 100644
index 0000000000..c0c9aad71a
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/Main.java.orig
@@ -0,0 +1,192 @@
+/*
+ * 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.chainsaw;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.util.Properties;
+import javax.swing.BorderFactory;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+/**
+ * The main application.
+ *
+ * @author Oliver Burn
+ */
+public class Main
+ extends JFrame
+{
+ /** the default port number to listen on **/
+ private static final int DEFAULT_PORT = 4445;
+
+ /** name of property for port name **/
+ public static final String PORT_PROP_NAME = "chainsaw.port";
+
+ /** use to log messages **/
+ private static final Logger LOG = Logger.getLogger(Main.class);
+
+
+ /**
+ * Creates a new Main
instance.
+ */
+ private Main() {
+ super("CHAINSAW - Log4J Log Viewer");
+ // create the all important model
+ final MyTableModel model = new MyTableModel();
+
+ //Create the menu bar.
+ final JMenuBar menuBar = new JMenuBar();
+ setJMenuBar(menuBar);
+ final JMenu menu = new JMenu("File");
+ menuBar.add(menu);
+
+ try {
+ final LoadXMLAction lxa = new LoadXMLAction(this, model);
+ final JMenuItem loadMenuItem = new JMenuItem("Load file...");
+ menu.add(loadMenuItem);
+ loadMenuItem.addActionListener(lxa);
+ } catch (NoClassDefFoundError e) {
+ LOG.info("Missing classes for XML parser", e);
+ JOptionPane.showMessageDialog(
+ this,
+ "XML parser not in classpath - unable to load XML events.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (Exception e) {
+ LOG.info("Unable to create the action to load XML files", e);
+ JOptionPane.showMessageDialog(
+ this,
+ "Unable to create a XML parser - unable to load XML events.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ }
+
+ final JMenuItem exitMenuItem = new JMenuItem("Exit");
+ menu.add(exitMenuItem);
+ exitMenuItem.addActionListener(ExitAction.INSTANCE);
+
+ // Add control panel
+ final ControlPanel cp = new ControlPanel(model);
+ getContentPane().add(cp, BorderLayout.NORTH);
+
+ // Create the table
+ final JTable table = new JTable(model);
+ table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ final JScrollPane scrollPane = new JScrollPane(table);
+ scrollPane.setBorder(BorderFactory.createTitledBorder("Events: "));
+ scrollPane.setPreferredSize(new Dimension(900, 300));
+
+ // Create the details
+ final JPanel details = new DetailPanel(table, model);
+ details.setPreferredSize(new Dimension(900, 300));
+
+ // Add the table and stack trace into a splitter
+ final JSplitPane jsp =
+ new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, details);
+ getContentPane().add(jsp, BorderLayout.CENTER);
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent aEvent) {
+ ExitAction.INSTANCE.actionPerformed(null);
+ }
+ });
+
+ pack();
+ setVisible(true);
+
+ setupReceiver(model);
+ }
+
+ /**
+ * Setup recieving messages.
+ *
+ * @param aModel a MyTableModel
value
+ */
+ private void setupReceiver(MyTableModel aModel) {
+ int port = DEFAULT_PORT;
+ final String strRep = System.getProperty(PORT_PROP_NAME);
+ if (strRep != null) {
+ try {
+ port = Integer.parseInt(strRep);
+ } catch (NumberFormatException nfe) {
+ LOG.fatal("Unable to parse " + PORT_PROP_NAME +
+ " property with value " + strRep + ".");
+ JOptionPane.showMessageDialog(
+ this,
+ "Unable to parse port number from '" + strRep +
+ "', quitting.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ System.exit(1);
+ }
+ }
+
+ try {
+ final LoggingReceiver lr = new LoggingReceiver(aModel, port);
+ lr.start();
+ } catch (IOException e) {
+ LOG.fatal("Unable to connect to socket server, quiting", e);
+ JOptionPane.showMessageDialog(
+ this,
+ "Unable to create socket on port " + port + ", quitting.",
+ "CHAINSAW",
+ JOptionPane.ERROR_MESSAGE);
+ System.exit(1);
+ }
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ // static methods
+ ////////////////////////////////////////////////////////////////////////////
+
+
+ /** initialise log4j **/
+ private static void initLog4J() {
+ final Properties props = new Properties();
+ props.setProperty("log4j.rootLogger", "DEBUG, A1");
+ props.setProperty("log4j.appender.A1",
+ "org.apache.log4j.ConsoleAppender");
+ props.setProperty("log4j.appender.A1.layout",
+ "org.apache.log4j.TTCCLayout");
+ PropertyConfigurator.configure(props);
+ }
+
+ /**
+ * The main method.
+ *
+ * @param aArgs ignored
+ */
+ public static void main(String[] aArgs) {
+ initLog4J();
+ new Main();
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/MyTableModel.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/MyTableModel.java
new file mode 100644
index 0000000000..0d43272c9a
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/MyTableModel.java
@@ -0,0 +1,390 @@
+/*
+ * 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.chainsaw;
+
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import javax.swing.table.AbstractTableModel;
+import org.apache.log4j.Priority;
+import org.apache.log4j.Logger;
+
+/**
+ * Represents a list of EventDetails
objects that are sorted on
+ * logging time. Methods are provided to filter the events that are visible.
+ *
+ * @author Oliver Burn
+ */
+class MyTableModel
+ extends AbstractTableModel
+{
+
+ /** used to log messages **/
+ private static final Logger LOG = Logger.getLogger(MyTableModel.class);
+
+ /** use the compare logging events **/
+ private static final Comparator MY_COMP = new Comparator()
+ {
+ /** @see Comparator **/
+ public int compare(Object aObj1, Object aObj2) {
+ if ((aObj1 == null) && (aObj2 == null)) {
+ return 0; // treat as equal
+ } else if (aObj1 == null) {
+ return -1; // null less than everything
+ } else if (aObj2 == null) {
+ return 1; // think about it. :->
+ }
+
+ // will assume only have LoggingEvent
+ final EventDetails le1 = (EventDetails) aObj1;
+ final EventDetails le2 = (EventDetails) aObj2;
+
+ if (le1.getTimeStamp() < le2.getTimeStamp()) {
+ return 1;
+ }
+ // assume not two events are logged at exactly the same time
+ return -1;
+ }
+ };
+
+ /**
+ * Helper that actually processes incoming events.
+ * @author Oliver Burn
+ */
+ private class Processor
+ implements Runnable
+ {
+ /** loops getting the events **/
+ public void run() {
+ while (true) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
+ synchronized (mLock) {
+ if (mPaused) {
+ continue;
+ }
+
+ boolean toHead = true; // were events added to head
+ boolean needUpdate = false;
+ final Iterator it = mPendingEvents.iterator();
+ while (it.hasNext()) {
+ final EventDetails event = (EventDetails) it.next();
+ mAllEvents.add(event);
+ toHead = toHead && (event == mAllEvents.first());
+ needUpdate = needUpdate || matchFilter(event);
+ }
+ mPendingEvents.clear();
+
+ if (needUpdate) {
+ updateFilteredEvents(toHead);
+ }
+ }
+ }
+
+ }
+ }
+
+
+ /** names of the columns in the table **/
+ private static final String[] COL_NAMES = {
+ "Time", "Priority", "Trace", "Category", "NDC", "Message"};
+
+ /** definition of an empty list **/
+ private static final EventDetails[] EMPTY_LIST = new EventDetails[] {};
+
+ /** used to format dates **/
+ private static final DateFormat DATE_FORMATTER =
+ DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
+
+ /** the lock to control access **/
+ private final Object mLock = new Object();
+ /** set of all logged events - not filtered **/
+ private final SortedSet mAllEvents = new TreeSet(MY_COMP);
+ /** events that are visible after filtering **/
+ private EventDetails[] mFilteredEvents = EMPTY_LIST;
+ /** list of events that are buffered for processing **/
+ private final List mPendingEvents = new ArrayList();
+ /** indicates whether event collection is paused to the UI **/
+ private boolean mPaused = false;
+
+ /** filter for the thread **/
+ private String mThreadFilter = "";
+ /** filter for the message **/
+ private String mMessageFilter = "";
+ /** filter for the NDC **/
+ private String mNDCFilter = "";
+ /** filter for the category **/
+ private String mCategoryFilter = "";
+ /** filter for the priority **/
+ private Priority mPriorityFilter = Priority.DEBUG;
+
+
+ /**
+ * Creates a new MyTableModel
instance.
+ *
+ */
+ MyTableModel() {
+ final Thread t = new Thread(new Processor());
+ t.setDaemon(true);
+ t.start();
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Table Methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /** @see javax.swing.table.TableModel **/
+ public int getRowCount() {
+ synchronized (mLock) {
+ return mFilteredEvents.length;
+ }
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public int getColumnCount() {
+ // does not need to be synchronized
+ return COL_NAMES.length;
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public String getColumnName(int aCol) {
+ // does not need to be synchronized
+ return COL_NAMES[aCol];
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public Class getColumnClass(int aCol) {
+ // does not need to be synchronized
+ return (aCol == 2) ? Boolean.class : Object.class;
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public Object getValueAt(int aRow, int aCol) {
+ synchronized (mLock) {
+ final EventDetails event = mFilteredEvents[aRow];
+
+ if (aCol == 0) {
+ return DATE_FORMATTER.format(new Date(event.getTimeStamp()));
+ } else if (aCol == 1) {
+ return event.getPriority();
+ } else if (aCol == 2) {
+ return (event.getThrowableStrRep() == null)
+ ? Boolean.FALSE : Boolean.TRUE;
+ } else if (aCol == 3) {
+ return event.getCategoryName();
+ } else if (aCol == 4) {
+ return event.getNDC();
+ }
+ return event.getMessage();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Public Methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Sets the priority to filter events on. Only events of equal or higher
+ * property are now displayed.
+ *
+ * @param aPriority the priority to filter on
+ */
+ public void setPriorityFilter(Priority aPriority) {
+ synchronized (mLock) {
+ mPriorityFilter = aPriority;
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the thread field.
+ *
+ * @param aStr the string to match
+ */
+ public void setThreadFilter(String aStr) {
+ synchronized (mLock) {
+ mThreadFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the message field.
+ *
+ * @param aStr the string to match
+ */
+ public void setMessageFilter(String aStr) {
+ synchronized (mLock) {
+ mMessageFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the NDC field.
+ *
+ * @param aStr the string to match
+ */
+ public void setNDCFilter(String aStr) {
+ synchronized (mLock) {
+ mNDCFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the category field.
+ *
+ * @param aStr the string to match
+ */
+ public void setCategoryFilter(String aStr) {
+ synchronized (mLock) {
+ mCategoryFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Add an event to the list.
+ *
+ * @param aEvent a EventDetails
value
+ */
+ public void addEvent(EventDetails aEvent) {
+ synchronized (mLock) {
+ mPendingEvents.add(aEvent);
+ }
+ }
+
+ /**
+ * Clear the list of all events.
+ */
+ public void clear() {
+ synchronized (mLock) {
+ mAllEvents.clear();
+ mFilteredEvents = new EventDetails[0];
+ mPendingEvents.clear();
+ fireTableDataChanged();
+ }
+ }
+
+ /** Toggle whether collecting events **/
+ public void toggle() {
+ synchronized (mLock) {
+ mPaused = !mPaused;
+ }
+ }
+
+ /** @return whether currently paused collecting events **/
+ public boolean isPaused() {
+ synchronized (mLock) {
+ return mPaused;
+ }
+ }
+
+ /**
+ * Get the throwable information at a specified row in the filtered events.
+ *
+ * @param aRow the row index of the event
+ * @return the throwable information
+ */
+ public EventDetails getEventDetails(int aRow) {
+ synchronized (mLock) {
+ return mFilteredEvents[aRow];
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Private methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Update the filtered events data structure.
+ * @param aInsertedToFront indicates whether events were added to front of
+ * the events. If true, then the current first event must still exist
+ * in the list after the filter is applied.
+ */
+ private void updateFilteredEvents(boolean aInsertedToFront) {
+ final long start = System.currentTimeMillis();
+ final List filtered = new ArrayList();
+ final int size = mAllEvents.size();
+ final Iterator it = mAllEvents.iterator();
+
+ while (it.hasNext()) {
+ final EventDetails event = (EventDetails) it.next();
+ if (matchFilter(event)) {
+ filtered.add(event);
+ }
+ }
+
+ final EventDetails lastFirst = (mFilteredEvents.length == 0)
+ ? null
+ : mFilteredEvents[0];
+ mFilteredEvents = (EventDetails[]) filtered.toArray(EMPTY_LIST);
+
+ if (aInsertedToFront && (lastFirst != null)) {
+ final int index = filtered.indexOf(lastFirst);
+ if (index < 1) {
+ LOG.warn("In strange state");
+ fireTableDataChanged();
+ } else {
+ fireTableRowsInserted(0, index - 1);
+ }
+ } else {
+ fireTableDataChanged();
+ }
+
+ final long end = System.currentTimeMillis();
+ LOG.debug("Total time [ms]: " + (end - start)
+ + " in update, size: " + size);
+ }
+
+ /**
+ * Returns whether an event matches the filters.
+ *
+ * @param aEvent the event to check for a match
+ * @return whether the event matches
+ */
+ private boolean matchFilter(EventDetails aEvent) {
+ if (aEvent.getPriority().isGreaterOrEqual(mPriorityFilter) &&
+ (aEvent.getThreadName().indexOf(mThreadFilter) >= 0) &&
+ (aEvent.getCategoryName().indexOf(mCategoryFilter) >= 0) &&
+ ((mNDCFilter.length() == 0) ||
+ ((aEvent.getNDC() != null) &&
+ (aEvent.getNDC().indexOf(mNDCFilter) >= 0))))
+ {
+ final String rm = aEvent.getMessage();
+ if (rm == null) {
+ // only match if we have not filtering in place
+ return (mMessageFilter.length() == 0);
+ } else {
+ return (rm.indexOf(mMessageFilter) >= 0);
+ }
+ }
+
+ return false; // by default not match
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/MyTableModel.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/MyTableModel.java.orig
new file mode 100644
index 0000000000..0d43272c9a
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/MyTableModel.java.orig
@@ -0,0 +1,390 @@
+/*
+ * 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.chainsaw;
+
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import javax.swing.table.AbstractTableModel;
+import org.apache.log4j.Priority;
+import org.apache.log4j.Logger;
+
+/**
+ * Represents a list of EventDetails
objects that are sorted on
+ * logging time. Methods are provided to filter the events that are visible.
+ *
+ * @author Oliver Burn
+ */
+class MyTableModel
+ extends AbstractTableModel
+{
+
+ /** used to log messages **/
+ private static final Logger LOG = Logger.getLogger(MyTableModel.class);
+
+ /** use the compare logging events **/
+ private static final Comparator MY_COMP = new Comparator()
+ {
+ /** @see Comparator **/
+ public int compare(Object aObj1, Object aObj2) {
+ if ((aObj1 == null) && (aObj2 == null)) {
+ return 0; // treat as equal
+ } else if (aObj1 == null) {
+ return -1; // null less than everything
+ } else if (aObj2 == null) {
+ return 1; // think about it. :->
+ }
+
+ // will assume only have LoggingEvent
+ final EventDetails le1 = (EventDetails) aObj1;
+ final EventDetails le2 = (EventDetails) aObj2;
+
+ if (le1.getTimeStamp() < le2.getTimeStamp()) {
+ return 1;
+ }
+ // assume not two events are logged at exactly the same time
+ return -1;
+ }
+ };
+
+ /**
+ * Helper that actually processes incoming events.
+ * @author Oliver Burn
+ */
+ private class Processor
+ implements Runnable
+ {
+ /** loops getting the events **/
+ public void run() {
+ while (true) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
+ synchronized (mLock) {
+ if (mPaused) {
+ continue;
+ }
+
+ boolean toHead = true; // were events added to head
+ boolean needUpdate = false;
+ final Iterator it = mPendingEvents.iterator();
+ while (it.hasNext()) {
+ final EventDetails event = (EventDetails) it.next();
+ mAllEvents.add(event);
+ toHead = toHead && (event == mAllEvents.first());
+ needUpdate = needUpdate || matchFilter(event);
+ }
+ mPendingEvents.clear();
+
+ if (needUpdate) {
+ updateFilteredEvents(toHead);
+ }
+ }
+ }
+
+ }
+ }
+
+
+ /** names of the columns in the table **/
+ private static final String[] COL_NAMES = {
+ "Time", "Priority", "Trace", "Category", "NDC", "Message"};
+
+ /** definition of an empty list **/
+ private static final EventDetails[] EMPTY_LIST = new EventDetails[] {};
+
+ /** used to format dates **/
+ private static final DateFormat DATE_FORMATTER =
+ DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
+
+ /** the lock to control access **/
+ private final Object mLock = new Object();
+ /** set of all logged events - not filtered **/
+ private final SortedSet mAllEvents = new TreeSet(MY_COMP);
+ /** events that are visible after filtering **/
+ private EventDetails[] mFilteredEvents = EMPTY_LIST;
+ /** list of events that are buffered for processing **/
+ private final List mPendingEvents = new ArrayList();
+ /** indicates whether event collection is paused to the UI **/
+ private boolean mPaused = false;
+
+ /** filter for the thread **/
+ private String mThreadFilter = "";
+ /** filter for the message **/
+ private String mMessageFilter = "";
+ /** filter for the NDC **/
+ private String mNDCFilter = "";
+ /** filter for the category **/
+ private String mCategoryFilter = "";
+ /** filter for the priority **/
+ private Priority mPriorityFilter = Priority.DEBUG;
+
+
+ /**
+ * Creates a new MyTableModel
instance.
+ *
+ */
+ MyTableModel() {
+ final Thread t = new Thread(new Processor());
+ t.setDaemon(true);
+ t.start();
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Table Methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /** @see javax.swing.table.TableModel **/
+ public int getRowCount() {
+ synchronized (mLock) {
+ return mFilteredEvents.length;
+ }
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public int getColumnCount() {
+ // does not need to be synchronized
+ return COL_NAMES.length;
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public String getColumnName(int aCol) {
+ // does not need to be synchronized
+ return COL_NAMES[aCol];
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public Class getColumnClass(int aCol) {
+ // does not need to be synchronized
+ return (aCol == 2) ? Boolean.class : Object.class;
+ }
+
+ /** @see javax.swing.table.TableModel **/
+ public Object getValueAt(int aRow, int aCol) {
+ synchronized (mLock) {
+ final EventDetails event = mFilteredEvents[aRow];
+
+ if (aCol == 0) {
+ return DATE_FORMATTER.format(new Date(event.getTimeStamp()));
+ } else if (aCol == 1) {
+ return event.getPriority();
+ } else if (aCol == 2) {
+ return (event.getThrowableStrRep() == null)
+ ? Boolean.FALSE : Boolean.TRUE;
+ } else if (aCol == 3) {
+ return event.getCategoryName();
+ } else if (aCol == 4) {
+ return event.getNDC();
+ }
+ return event.getMessage();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Public Methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Sets the priority to filter events on. Only events of equal or higher
+ * property are now displayed.
+ *
+ * @param aPriority the priority to filter on
+ */
+ public void setPriorityFilter(Priority aPriority) {
+ synchronized (mLock) {
+ mPriorityFilter = aPriority;
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the thread field.
+ *
+ * @param aStr the string to match
+ */
+ public void setThreadFilter(String aStr) {
+ synchronized (mLock) {
+ mThreadFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the message field.
+ *
+ * @param aStr the string to match
+ */
+ public void setMessageFilter(String aStr) {
+ synchronized (mLock) {
+ mMessageFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the NDC field.
+ *
+ * @param aStr the string to match
+ */
+ public void setNDCFilter(String aStr) {
+ synchronized (mLock) {
+ mNDCFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Set the filter for the category field.
+ *
+ * @param aStr the string to match
+ */
+ public void setCategoryFilter(String aStr) {
+ synchronized (mLock) {
+ mCategoryFilter = aStr.trim();
+ updateFilteredEvents(false);
+ }
+ }
+
+ /**
+ * Add an event to the list.
+ *
+ * @param aEvent a EventDetails
value
+ */
+ public void addEvent(EventDetails aEvent) {
+ synchronized (mLock) {
+ mPendingEvents.add(aEvent);
+ }
+ }
+
+ /**
+ * Clear the list of all events.
+ */
+ public void clear() {
+ synchronized (mLock) {
+ mAllEvents.clear();
+ mFilteredEvents = new EventDetails[0];
+ mPendingEvents.clear();
+ fireTableDataChanged();
+ }
+ }
+
+ /** Toggle whether collecting events **/
+ public void toggle() {
+ synchronized (mLock) {
+ mPaused = !mPaused;
+ }
+ }
+
+ /** @return whether currently paused collecting events **/
+ public boolean isPaused() {
+ synchronized (mLock) {
+ return mPaused;
+ }
+ }
+
+ /**
+ * Get the throwable information at a specified row in the filtered events.
+ *
+ * @param aRow the row index of the event
+ * @return the throwable information
+ */
+ public EventDetails getEventDetails(int aRow) {
+ synchronized (mLock) {
+ return mFilteredEvents[aRow];
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Private methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Update the filtered events data structure.
+ * @param aInsertedToFront indicates whether events were added to front of
+ * the events. If true, then the current first event must still exist
+ * in the list after the filter is applied.
+ */
+ private void updateFilteredEvents(boolean aInsertedToFront) {
+ final long start = System.currentTimeMillis();
+ final List filtered = new ArrayList();
+ final int size = mAllEvents.size();
+ final Iterator it = mAllEvents.iterator();
+
+ while (it.hasNext()) {
+ final EventDetails event = (EventDetails) it.next();
+ if (matchFilter(event)) {
+ filtered.add(event);
+ }
+ }
+
+ final EventDetails lastFirst = (mFilteredEvents.length == 0)
+ ? null
+ : mFilteredEvents[0];
+ mFilteredEvents = (EventDetails[]) filtered.toArray(EMPTY_LIST);
+
+ if (aInsertedToFront && (lastFirst != null)) {
+ final int index = filtered.indexOf(lastFirst);
+ if (index < 1) {
+ LOG.warn("In strange state");
+ fireTableDataChanged();
+ } else {
+ fireTableRowsInserted(0, index - 1);
+ }
+ } else {
+ fireTableDataChanged();
+ }
+
+ final long end = System.currentTimeMillis();
+ LOG.debug("Total time [ms]: " + (end - start)
+ + " in update, size: " + size);
+ }
+
+ /**
+ * Returns whether an event matches the filters.
+ *
+ * @param aEvent the event to check for a match
+ * @return whether the event matches
+ */
+ private boolean matchFilter(EventDetails aEvent) {
+ if (aEvent.getPriority().isGreaterOrEqual(mPriorityFilter) &&
+ (aEvent.getThreadName().indexOf(mThreadFilter) >= 0) &&
+ (aEvent.getCategoryName().indexOf(mCategoryFilter) >= 0) &&
+ ((mNDCFilter.length() == 0) ||
+ ((aEvent.getNDC() != null) &&
+ (aEvent.getNDC().indexOf(mNDCFilter) >= 0))))
+ {
+ final String rm = aEvent.getMessage();
+ if (rm == null) {
+ // only match if we have not filtering in place
+ return (mMessageFilter.length() == 0);
+ } else {
+ return (rm.indexOf(mMessageFilter) >= 0);
+ }
+ }
+
+ return false; // by default not match
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java
new file mode 100644
index 0000000000..2f9af5125e
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java
@@ -0,0 +1,170 @@
+/*
+ * 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.chainsaw;
+
+import java.util.StringTokenizer;
+import org.apache.log4j.Level;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A content handler for document containing Log4J events logged using the
+ * XMLLayout class. It will create events and add them to a supplied model.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+class XMLFileHandler
+ extends DefaultHandler
+{
+ /** represents the event tag **/
+ private static final String TAG_EVENT = "log4j:event";
+ /** represents the message tag **/
+ private static final String TAG_MESSAGE = "log4j:message";
+ /** represents the ndc tag **/
+ private static final String TAG_NDC = "log4j:NDC";
+ /** represents the throwable tag **/
+ private static final String TAG_THROWABLE = "log4j:throwable";
+ /** represents the location info tag **/
+ private static final String TAG_LOCATION_INFO = "log4j:locationInfo";
+
+ /** where to put the events **/
+ private final MyTableModel mModel;
+ /** the number of events in the document **/
+ private int mNumEvents;
+
+ /** the time of the event **/
+ private long mTimeStamp;
+ /** the priority (level) of the event **/
+ private Level mLevel;
+ /** the category of the event **/
+ private String mCategoryName;
+ /** the NDC for the event **/
+ private String mNDC;
+ /** the thread for the event **/
+ private String mThreadName;
+ /** the msg for the event **/
+ private String mMessage;
+ /** the throwable details the event **/
+ private String[] mThrowableStrRep;
+ /** the location details for the event **/
+ private String mLocationDetails;
+ /** buffer for collecting text **/
+ private final StringBuffer mBuf = new StringBuffer();
+
+ /**
+ * Creates a new XMLFileHandler
instance.
+ *
+ * @param aModel where to add the events
+ */
+ XMLFileHandler(MyTableModel aModel) {
+ mModel = aModel;
+ }
+
+ /** @see DefaultHandler **/
+ public void startDocument()
+ throws SAXException
+ {
+ mNumEvents = 0;
+ }
+
+ /** @see DefaultHandler **/
+ public void characters(char[] aChars, int aStart, int aLength) {
+ mBuf.append(String.valueOf(aChars, aStart, aLength));
+ }
+
+ /** @see DefaultHandler **/
+ public void endElement(String aNamespaceURI,
+ String aLocalName,
+ String aQName)
+ {
+ if (TAG_EVENT.equals(aQName)) {
+ addEvent();
+ resetData();
+ } else if (TAG_NDC.equals(aQName)) {
+ mNDC = mBuf.toString();
+ } else if (TAG_MESSAGE.equals(aQName)) {
+ mMessage = mBuf.toString();
+ } else if (TAG_THROWABLE.equals(aQName)) {
+ final StringTokenizer st =
+ new StringTokenizer(mBuf.toString(), "\n\t");
+ mThrowableStrRep = new String[st.countTokens()];
+ if (mThrowableStrRep.length > 0) {
+ mThrowableStrRep[0] = st.nextToken();
+ for (int i = 1; i < mThrowableStrRep.length; i++) {
+ mThrowableStrRep[i] = "\t" + st.nextToken();
+ }
+ }
+ }
+ }
+
+ /** @see DefaultHandler **/
+ public void startElement(String aNamespaceURI,
+ String aLocalName,
+ String aQName,
+ Attributes aAtts)
+ {
+ mBuf.setLength(0);
+
+ if (TAG_EVENT.equals(aQName)) {
+ mThreadName = aAtts.getValue("thread");
+ mTimeStamp = Long.parseLong(aAtts.getValue("timestamp"));
+ mCategoryName = aAtts.getValue("logger");
+ mLevel = Level.toLevel(aAtts.getValue("level"));
+ } else if (TAG_LOCATION_INFO.equals(aQName)) {
+ mLocationDetails = aAtts.getValue("class") + "."
+ + aAtts.getValue("method")
+ + "(" + aAtts.getValue("file") + ":" + aAtts.getValue("line")
+ + ")";
+ }
+ }
+
+ /** @return the number of events in the document **/
+ int getNumEvents() {
+ return mNumEvents;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Private methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /** Add an event to the model **/
+ private void addEvent() {
+ mModel.addEvent(new EventDetails(mTimeStamp,
+ mLevel,
+ mCategoryName,
+ mNDC,
+ mThreadName,
+ mMessage,
+ mThrowableStrRep,
+ mLocationDetails));
+ mNumEvents++;
+ }
+
+ /** Reset the data for an event **/
+ private void resetData() {
+ mTimeStamp = 0;
+ mLevel = null;
+ mCategoryName = null;
+ mNDC = null;
+ mThreadName = null;
+ mMessage = null;
+ mThrowableStrRep = null;
+ mLocationDetails = null;
+ }
+}
diff --git a/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java.orig b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java.orig
new file mode 100644
index 0000000000..2f9af5125e
--- /dev/null
+++ b/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java.orig
@@ -0,0 +1,170 @@
+/*
+ * 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.chainsaw;
+
+import java.util.StringTokenizer;
+import org.apache.log4j.Level;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A content handler for document containing Log4J events logged using the
+ * XMLLayout class. It will create events and add them to a supplied model.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+class XMLFileHandler
+ extends DefaultHandler
+{
+ /** represents the event tag **/
+ private static final String TAG_EVENT = "log4j:event";
+ /** represents the message tag **/
+ private static final String TAG_MESSAGE = "log4j:message";
+ /** represents the ndc tag **/
+ private static final String TAG_NDC = "log4j:NDC";
+ /** represents the throwable tag **/
+ private static final String TAG_THROWABLE = "log4j:throwable";
+ /** represents the location info tag **/
+ private static final String TAG_LOCATION_INFO = "log4j:locationInfo";
+
+ /** where to put the events **/
+ private final MyTableModel mModel;
+ /** the number of events in the document **/
+ private int mNumEvents;
+
+ /** the time of the event **/
+ private long mTimeStamp;
+ /** the priority (level) of the event **/
+ private Level mLevel;
+ /** the category of the event **/
+ private String mCategoryName;
+ /** the NDC for the event **/
+ private String mNDC;
+ /** the thread for the event **/
+ private String mThreadName;
+ /** the msg for the event **/
+ private String mMessage;
+ /** the throwable details the event **/
+ private String[] mThrowableStrRep;
+ /** the location details for the event **/
+ private String mLocationDetails;
+ /** buffer for collecting text **/
+ private final StringBuffer mBuf = new StringBuffer();
+
+ /**
+ * Creates a new XMLFileHandler
instance.
+ *
+ * @param aModel where to add the events
+ */
+ XMLFileHandler(MyTableModel aModel) {
+ mModel = aModel;
+ }
+
+ /** @see DefaultHandler **/
+ public void startDocument()
+ throws SAXException
+ {
+ mNumEvents = 0;
+ }
+
+ /** @see DefaultHandler **/
+ public void characters(char[] aChars, int aStart, int aLength) {
+ mBuf.append(String.valueOf(aChars, aStart, aLength));
+ }
+
+ /** @see DefaultHandler **/
+ public void endElement(String aNamespaceURI,
+ String aLocalName,
+ String aQName)
+ {
+ if (TAG_EVENT.equals(aQName)) {
+ addEvent();
+ resetData();
+ } else if (TAG_NDC.equals(aQName)) {
+ mNDC = mBuf.toString();
+ } else if (TAG_MESSAGE.equals(aQName)) {
+ mMessage = mBuf.toString();
+ } else if (TAG_THROWABLE.equals(aQName)) {
+ final StringTokenizer st =
+ new StringTokenizer(mBuf.toString(), "\n\t");
+ mThrowableStrRep = new String[st.countTokens()];
+ if (mThrowableStrRep.length > 0) {
+ mThrowableStrRep[0] = st.nextToken();
+ for (int i = 1; i < mThrowableStrRep.length; i++) {
+ mThrowableStrRep[i] = "\t" + st.nextToken();
+ }
+ }
+ }
+ }
+
+ /** @see DefaultHandler **/
+ public void startElement(String aNamespaceURI,
+ String aLocalName,
+ String aQName,
+ Attributes aAtts)
+ {
+ mBuf.setLength(0);
+
+ if (TAG_EVENT.equals(aQName)) {
+ mThreadName = aAtts.getValue("thread");
+ mTimeStamp = Long.parseLong(aAtts.getValue("timestamp"));
+ mCategoryName = aAtts.getValue("logger");
+ mLevel = Level.toLevel(aAtts.getValue("level"));
+ } else if (TAG_LOCATION_INFO.equals(aQName)) {
+ mLocationDetails = aAtts.getValue("class") + "."
+ + aAtts.getValue("method")
+ + "(" + aAtts.getValue("file") + ":" + aAtts.getValue("line")
+ + ")";
+ }
+ }
+
+ /** @return the number of events in the document **/
+ int getNumEvents() {
+ return mNumEvents;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Private methods
+ ////////////////////////////////////////////////////////////////////////////
+
+ /** Add an event to the model **/
+ private void addEvent() {
+ mModel.addEvent(new EventDetails(mTimeStamp,
+ mLevel,
+ mCategoryName,
+ mNDC,
+ mThreadName,
+ mMessage,
+ mThrowableStrRep,
+ mLocationDetails));
+ mNumEvents++;
+ }
+
+ /** Reset the data for an event **/
+ private void resetData() {
+ mTimeStamp = 0;
+ mLevel = null;
+ mCategoryName = null;
+ mNDC = null;
+ mThreadName = null;
+ mMessage = null;
+ mThrowableStrRep = null;
+ mLocationDetails = null;
+ }
+}
diff --git a/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png
new file mode 100644
index 0000000000..1a9c26dbc2
Binary files /dev/null and b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png differ
diff --git a/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png.orig b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png.orig
new file mode 100644
index 0000000000..1a9c26dbc2
Binary files /dev/null and b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png.orig differ
diff --git a/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html
new file mode 100644
index 0000000000..5b014800ea
--- /dev/null
+++ b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+ Chainsaw Tool
+
+
+
+
+ Chainsaw is a GUI log viewer and filter for the log4j
+package. By default it listens for LoggingEvent objects sent using
+the SocketAppender and
+displays them in a table. The events can be filtered based on:
+
+
+ - Level
+
+ - Thread name
+
+ - Logger
+ - Message
+
+ - NDC
+
+
+ All the details for each event can be displayed by selecting
+ the event in the table.
+
+ Chainsaw also supports loading a events logged to a file using
+ the XMLLayout format. This
+ is great for analysing log files, and means you do not need to
+ keep Chainsaw running continously. It is easy to add support
+ for loading events from other sources like JDBC.
+
+ A picture is worth a thousand words:
+
+
.
+
+ Finally, why is it called chainsaw?
+ Because it cuts your log (file) down to size. :-)
+
+
+
+ Requirements
+
+ Chainsaw is based on the Swing API which requires JDK 1.2 or later.
+
+
+ Running chainsaw
+
+ Setup
+ You need to include the log4j.jar
in the classpath.
+
+
Usage
+
+ The command line usage is:
+
+ java -D<property>=<value> org.apache.log4j.chainsaw.Main
+
+ The default behaviour of chainsaw can be changed by setting system properties
+ using the -D<property>=<value>
arguments to java. The
+ following table describes what properties can be set:
+
+
+
+
+ Property |
+ Description |
+
+ chainsaw.port |
+ Indicates which port to listen for connections on. Defaults
+ to "4445".
+ |
+
+
+
+
+ Configuring Log4J
+
+ You will need to configure log4j to send logging events to
+ Chainsaw. Here is a sample log4j.properties
file
+ for sending logging events to Chainsaw.
+
+
+log4j.rootLogger=DEBUG, CHAINSAW_CLIENT
+
+log4j.appender.CHAINSAW_CLIENT=org.apache.log4j.net.SocketAppender
+log4j.appender.CHAINSAW_CLIENT.RemoteHost=localhost
+log4j.appender.CHAINSAW_CLIENT.Port=4445
+log4j.appender.CHAINSAW_CLIENT.LocationInfo=true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html.orig b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html.orig
new file mode 100644
index 0000000000..5b014800ea
--- /dev/null
+++ b/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html.orig
@@ -0,0 +1,118 @@
+
+
+
+
+
+ Chainsaw Tool
+
+
+
+
+ Chainsaw is a GUI log viewer and filter for the log4j
+package. By default it listens for LoggingEvent objects sent using
+the SocketAppender and
+displays them in a table. The events can be filtered based on:
+
+
+ - Level
+
+ - Thread name
+
+ - Logger
+ - Message
+
+ - NDC
+
+
+ All the details for each event can be displayed by selecting
+ the event in the table.
+
+ Chainsaw also supports loading a events logged to a file using
+ the XMLLayout format. This
+ is great for analysing log files, and means you do not need to
+ keep Chainsaw running continously. It is easy to add support
+ for loading events from other sources like JDBC.
+
+ A picture is worth a thousand words:
+
+
.
+
+ Finally, why is it called chainsaw?
+ Because it cuts your log (file) down to size. :-)
+
+
+
+ Requirements
+
+ Chainsaw is based on the Swing API which requires JDK 1.2 or later.
+
+
+ Running chainsaw
+
+ Setup
+ You need to include the log4j.jar
in the classpath.
+
+
Usage
+
+ The command line usage is:
+
+ java -D<property>=<value> org.apache.log4j.chainsaw.Main
+
+ The default behaviour of chainsaw can be changed by setting system properties
+ using the -D<property>=<value>
arguments to java. The
+ following table describes what properties can be set:
+
+
+
+
+ Property |
+ Description |
+
+ chainsaw.port |
+ Indicates which port to listen for connections on. Defaults
+ to "4445".
+ |
+
+
+
+
+ Configuring Log4J
+
+ You will need to configure log4j to send logging events to
+ Chainsaw. Here is a sample log4j.properties
file
+ for sending logging events to Chainsaw.
+
+
+log4j.rootLogger=DEBUG, CHAINSAW_CLIENT
+
+log4j.appender.CHAINSAW_CLIENT=org.apache.log4j.net.SocketAppender
+log4j.appender.CHAINSAW_CLIENT.RemoteHost=localhost
+log4j.appender.CHAINSAW_CLIENT.Port=4445
+log4j.appender.CHAINSAW_CLIENT.LocationInfo=true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contribs/CONTENTS b/modules/contribs/CONTENTS
similarity index 100%
rename from contribs/CONTENTS
rename to modules/contribs/CONTENTS
diff --git a/modules/contribs/pom.xml b/modules/contribs/pom.xml
new file mode 100644
index 0000000000..1820b5c1e9
--- /dev/null
+++ b/modules/contribs/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-modules
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-contribs
+ Apache Log4j-Contribtutions
+ bundle
+
+
+
+ org.apache.log4j
+ log4j-core
+ ${project.version}
+
+
+ org.apache.log4j
+ log4j-net
+ 1.4.0-SNAPSHOT
+ bundle
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ 2.0.1
+ true
+
+
+ org.apache.log4j.contribs.*
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contribs/JimMoore/LoggingOutputStream.java b/modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java
similarity index 99%
rename from contribs/JimMoore/LoggingOutputStream.java
rename to modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java
index bc084b30db..e4712aea92 100644
--- a/contribs/JimMoore/LoggingOutputStream.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+package org.apache.log4j;
import java.io.*;
import org.apache.log4j.*;
diff --git a/contribs/EirikLygre/mail-2001-01-18 b/modules/contribs/src/main/java/org/apache/log4j/contribs/EirikLygre/mail-2001-01-18
similarity index 100%
rename from contribs/EirikLygre/mail-2001-01-18
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/EirikLygre/mail-2001-01-18
diff --git a/contribs/JamesHouse/mail-2001-01-23 b/modules/contribs/src/main/java/org/apache/log4j/contribs/JamesHouse/mail-2001-01-23
similarity index 100%
rename from contribs/JamesHouse/mail-2001-01-23
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/JamesHouse/mail-2001-01-23
diff --git a/contribs/Jamie Tsao/mail-2001-06-20 b/modules/contribs/src/main/java/org/apache/log4j/contribs/JamieTsao/mail-2001-06-20
similarity index 100%
rename from contribs/Jamie Tsao/mail-2001-06-20
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/JamieTsao/mail-2001-06-20
diff --git a/contribs/JimMoore/mail-2001-03-12T1326 b/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1326
similarity index 100%
rename from contribs/JimMoore/mail-2001-03-12T1326
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1326
diff --git a/contribs/JimMoore/mail-2001-03-12T1454 b/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1454
similarity index 100%
rename from contribs/JimMoore/mail-2001-03-12T1454
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1454
diff --git a/contribs/JimMoore/mail-2001-03-13T0646 b/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-13T0646
similarity index 100%
rename from contribs/JimMoore/mail-2001-03-13T0646
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-13T0646
diff --git a/contribs/KevinSteppe/mail-2001-02-01 b/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2001-02-01
similarity index 100%
rename from contribs/KevinSteppe/mail-2001-02-01
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2001-02-01
diff --git a/contribs/KevinSteppe/mail-2002-03-27.txt b/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2002-03-27.txt
similarity index 100%
rename from contribs/KevinSteppe/mail-2002-03-27.txt
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2002-03-27.txt
diff --git a/contribs/KitchingSimon/mail-2001-02-07 b/modules/contribs/src/main/java/org/apache/log4j/contribs/KitchingSimon/mail-2001-02-07
similarity index 100%
rename from contribs/KitchingSimon/mail-2001-02-07
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/KitchingSimon/mail-2001-02-07
diff --git a/contribs/LeosLiterak/mail b/modules/contribs/src/main/java/org/apache/log4j/contribs/LeosLiterak/mail
similarity index 100%
rename from contribs/LeosLiterak/mail
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/LeosLiterak/mail
diff --git a/contribs/MarkDouglas/Log.txt b/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/Log.txt
similarity index 100%
rename from contribs/MarkDouglas/Log.txt
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/Log.txt
diff --git a/contribs/MarkDouglas/mail-2001-01-17 b/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/mail-2001-01-17
similarity index 100%
rename from contribs/MarkDouglas/mail-2001-01-17
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/mail-2001-01-17
diff --git a/contribs/VolkerMentzner/mail-03-05-2001 b/modules/contribs/src/main/java/org/apache/log4j/contribs/VolkerMentzner/mail-03-05-2001
similarity index 100%
rename from contribs/VolkerMentzner/mail-03-05-2001
rename to modules/contribs/src/main/java/org/apache/log4j/contribs/VolkerMentzner/mail-03-05-2001
diff --git a/contribs/CekiGulcu/AppenderTable.java b/modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java
similarity index 96%
rename from contribs/CekiGulcu/AppenderTable.java
rename to modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java
index fbb18f5aee..d5820b9545 100644
--- a/contribs/CekiGulcu/AppenderTable.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+package org.apache.log4j.gui;
import org.apache.log4j.helpers.CyclicBuffer;
import org.apache.log4j.Level;
@@ -57,7 +58,9 @@
On windows NT the test will run about twice as fast if you give
the focus to the window that runs "java AppenderTable" and not the
- window that contains the Swing JFrame. */
+ window that contains the Swing JFrame.
+
+ @author CekiGulcu */
public class AppenderTable extends JTable {
@@ -95,7 +98,7 @@ static public void main(String[] args) {
// add one new logging event to the table.
JButton button = new JButton("ADD");
container.add(button);
- button.addActionListener(new JTableAddAction(tableAppender));
+ button.addActionListener(new AppTableJTableAddAction(tableAppender));
frame.setSize(new Dimension(500,300));
frame.setVisible(true);
@@ -225,13 +228,13 @@ Object getValueAt(int row, int col) {
The JTableAddAction is called when the user clicks on the "ADD"
button.
*/
-class JTableAddAction implements ActionListener {
+class AppTableJTableAddAction implements ActionListener {
AppenderTable appenderTable;
Logger dummy = Logger.getLogger("x");
int counter = 0;
public
- JTableAddAction(AppenderTable appenderTable) {
+ AppTableJTableAddAction(AppenderTable appenderTable) {
this.appenderTable = appenderTable;
}
diff --git a/contribs/SvenReimers/gui/JListView.java b/modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java
similarity index 99%
rename from contribs/SvenReimers/gui/JListView.java
rename to modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java
index 6a93ed08e6..d762574d0d 100644
--- a/contribs/SvenReimers/gui/JListView.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java
@@ -51,6 +51,9 @@
import java.net.URL;
import java.awt.Rectangle;
+/**
+ * @author Sven Reimers
+ */
public class JListView extends JList {
@@ -255,7 +258,7 @@ public Component getListCellRendererComponent(JList list,
if(value instanceof LoggingEvent) {
LoggingEvent event = (LoggingEvent) value;
String str = layout.format(event);
- String t = event.getThrowableInformation();
+ String t = event.getThrowableInformation().toString();
if(t != null) {
setText(str + Layout.LINE_SEP + t);
diff --git a/contribs/SvenReimers/gui/JTableAppender.java b/modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java
similarity index 95%
rename from contribs/SvenReimers/gui/JTableAppender.java
rename to modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java
index 32cc23ac83..530b96cf86 100644
--- a/contribs/SvenReimers/gui/JTableAppender.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java
@@ -52,9 +52,11 @@
import java.net.URL;
import java.awt.Rectangle;
+/**
+ * @author Sven Reimers
+ */
public class JTableAppender extends JTable {
-
static Category cat = Category.getInstance(JTableAppender.class.getName());
PatternLayout layout;
@@ -101,7 +103,7 @@ static public void main(String[] args) {
container.add(button);
- button.addActionListener(new JTableAddAction(appender));
+ button.addActionListener(new JTableAppenderJTableAddAction(appender));
frame.setVisible(true);
frame.setSize(new Dimension(700,700));
@@ -148,7 +150,7 @@ public Component getTableCellRendererComponent(JTable table,
if(value instanceof LoggingEvent) {
LoggingEvent event = (LoggingEvent) value;
String str = layout.format(event);
- String t = event.getThrowableInformation();
+ String t = event.getThrowableInformation().toString();
if(t != null) {
System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
@@ -208,7 +210,7 @@ Object getValueAt(int row, int col) {
}
-class JTableAddAction implements ActionListener {
+class JTableAppenderJTableAddAction implements ActionListener {
int j;
JTableAppender appender;
@@ -216,7 +218,7 @@ class JTableAddAction implements ActionListener {
Category cat = Category.getInstance("x");
public
- JTableAddAction(JTableAppender appender) {
+ JTableAppenderJTableAddAction(JTableAppender appender) {
this.appender = appender;
j = 0;
}
diff --git a/contribs/KitchingSimon/DatagramStringWriter.java b/modules/contribs/src/main/java/org/apache/log4j/net/DatagramStringWriter.java
similarity index 100%
rename from contribs/KitchingSimon/DatagramStringWriter.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/DatagramStringWriter.java
diff --git a/contribs/VolkerMentzner/HTTPRequestHandler.java b/modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java
similarity index 98%
rename from contribs/VolkerMentzner/HTTPRequestHandler.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java
index d426e86867..b5f87b9e69 100644
--- a/contribs/VolkerMentzner/HTTPRequestHandler.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.psibt.framework.net;
+package org.apache.log4j.net;
import java.io.*;
import java.net.*;
diff --git a/contribs/ThomasFenner/JDBCAppender.java b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java
similarity index 99%
rename from contribs/ThomasFenner/JDBCAppender.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java
index 841aaade11..ed7919d3d4 100644
--- a/contribs/ThomasFenner/JDBCAppender.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package com.klopotek.utils.log;
+package org.apache.log4j.net;
import java.sql.*;
import java.util.*;
diff --git a/contribs/ThomasFenner/JDBCConnectionHandler.java b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java
similarity index 97%
rename from contribs/ThomasFenner/JDBCConnectionHandler.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java
index da90942378..0164eec4a4 100644
--- a/contribs/ThomasFenner/JDBCConnectionHandler.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package com.klopotek.utils.log;
+package org.apache.log4j.net;
import java.sql.*;
diff --git a/contribs/ThomasFenner/JDBCIDHandler.java b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java
similarity index 97%
rename from contribs/ThomasFenner/JDBCIDHandler.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java
index 9e6a765da7..0de23ba349 100644
--- a/contribs/ThomasFenner/JDBCIDHandler.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package com.klopotek.utils.log;
+package org.apache.log4j.net;
/**
diff --git a/contribs/ThomasFenner/JDBCLogger.java b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCLogger.java
similarity index 90%
rename from contribs/ThomasFenner/JDBCLogger.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/JDBCLogger.java
index 5edf2e8c43..3973511054 100644
--- a/contribs/ThomasFenner/JDBCLogger.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/JDBCLogger.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package com.klopotek.utils.log;
+package org.apache.log4j.net;
import java.sql.*;
import java.util.*;
@@ -418,51 +418,4 @@ class LogColumn
int logtype = LogType.EMPTY;
Object value = null; //Generic storage for typewrapper-classes Long, String, etc...
JDBCIDHandler idhandler = null;
-}
-
-
-/**
-This class contains all constants which are necessary to define a columns log-type.
-*/
-class LogType
-{
- //A column of this type will receive the message.
- public static final int MSG = 1;
-
- //A column of this type will be a unique identifier of the logged row.
- public static final int ID = 2;
-
- //A column of this type will contain a static, one-time-defined value.
- public static final int STATIC = 3;
-
- //A column of this type will be filled with an actual timestamp depending by the time the logging will be done.
- public static final int TIMESTAMP = 4;
-
- //A column of this type will contain no value and will not be included in logging insert-statement.
- //This could be a column which will be filled not by creation but otherwhere...
- public static final int EMPTY = 5;
-
-
- public static boolean isLogType(int _lt)
- {
- if(_lt == MSG || _lt == STATIC || _lt == ID || _lt == TIMESTAMP || _lt == EMPTY) return true;
-
- return false;
- }
-
- public static int parseLogType(String _lt)
- {
- if(_lt.equals("MSG")) return MSG;
- if(_lt.equals("ID")) return ID;
- if(_lt.equals("STATIC")) return STATIC;
- if(_lt.equals("TIMESTAMP")) return TIMESTAMP;
- if(_lt.equals("EMPTY")) return EMPTY;
-
- return -1;
- }
-}
-
-
-
-
-
+}
\ No newline at end of file
diff --git a/contribs/Jamie Tsao/JMSQueueAppender.java b/modules/contribs/src/main/java/org/apache/log4j/net/JMSQueueAppender.java
similarity index 99%
rename from contribs/Jamie Tsao/JMSQueueAppender.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/JMSQueueAppender.java
index 9e762f5e29..47b865cdf1 100644
--- a/contribs/Jamie Tsao/JMSQueueAppender.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/JMSQueueAppender.java
@@ -15,6 +15,8 @@
* limitations under the License.
*/
+package org.apache.log4j.net;
+
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ErrorHandler;
diff --git a/contribs/VolkerMentzner/Log4jRequestHandler.java b/modules/contribs/src/main/java/org/apache/log4j/net/Log4jRequestHandler.java
similarity index 99%
rename from contribs/VolkerMentzner/Log4jRequestHandler.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/Log4jRequestHandler.java
index bf231a04d3..c0de2d652a 100644
--- a/contribs/VolkerMentzner/Log4jRequestHandler.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/Log4jRequestHandler.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.psibt.framework.net;
+package org.apache.log4j.net;
import java.io.*;
import java.net.*;
diff --git a/modules/contribs/src/main/java/org/apache/log4j/net/LogType.java b/modules/contribs/src/main/java/org/apache/log4j/net/LogType.java
new file mode 100644
index 0000000000..5d621786a5
--- /dev/null
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/LogType.java
@@ -0,0 +1,42 @@
+package org.apache.log4j.net;
+
+/**
+This class contains all constants which are necessary to define a columns log-type.
+*/
+public class LogType
+{
+ //A column of this type will receive the message.
+ public static final int MSG = 1;
+
+ //A column of this type will be a unique identifier of the logged row.
+ public static final int ID = 2;
+
+ //A column of this type will contain a static, one-time-defined value.
+ public static final int STATIC = 3;
+
+ //A column of this type will be filled with an actual timestamp depending by the time the logging will be done.
+ public static final int TIMESTAMP = 4;
+
+ //A column of this type will contain no value and will not be included in logging insert-statement.
+ //This could be a column which will be filled not by creation but otherwhere...
+ public static final int EMPTY = 5;
+
+
+ public static boolean isLogType(int _lt)
+ {
+ if(_lt == MSG || _lt == STATIC || _lt == ID || _lt == TIMESTAMP || _lt == EMPTY) return true;
+
+ return false;
+ }
+
+ public static int parseLogType(String _lt)
+ {
+ if(_lt.equals("MSG")) return MSG;
+ if(_lt.equals("ID")) return ID;
+ if(_lt.equals("STATIC")) return STATIC;
+ if(_lt.equals("TIMESTAMP")) return TIMESTAMP;
+ if(_lt.equals("EMPTY")) return EMPTY;
+
+ return -1;
+ }
+}
\ No newline at end of file
diff --git a/contribs/VolkerMentzner/RootRequestHandler.java b/modules/contribs/src/main/java/org/apache/log4j/net/RootRequestHandler.java
similarity index 99%
rename from contribs/VolkerMentzner/RootRequestHandler.java
rename to modules/contribs/src/main/java/org/apache/log4j/net/RootRequestHandler.java
index 121d39b0e3..41b4946b82 100644
--- a/contribs/VolkerMentzner/RootRequestHandler.java
+++ b/modules/contribs/src/main/java/org/apache/log4j/net/RootRequestHandler.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.psibt.framework.net;
+package org.apache.log4j.net;
import java.io.*;
import java.net.*;
diff --git a/contribs/ThomasFenner/code_example1.java b/modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderLog4JTest.java
similarity index 91%
rename from contribs/ThomasFenner/code_example1.java
rename to modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderLog4JTest.java
index 8d6f7d8c25..062b9223d0 100644
--- a/contribs/ThomasFenner/code_example1.java
+++ b/modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderLog4JTest.java
@@ -1,3 +1,4 @@
+package org.apache.log4j.contribs.ThomasFenner;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -18,14 +19,13 @@
// Here is a code example to configure the JDBCAppender with a configuration-file
import org.apache.log4j.*;
+
import java.sql.*;
-import java.lang.*;
-import java.util.*;
-public class Log4JTest
+public class JDBCAppenderLog4JTest
{
// Create a category instance for this class
- static Category cat = Category.getInstance(Log4JTest.class.getName());
+ static Category cat = Category.getInstance(JDBCAppenderLog4JTest.class.getName());
public static void main(String[] args)
{
diff --git a/contribs/ThomasFenner/code_example2.java b/modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderNoConfigFileLog4JTest.java
similarity index 92%
rename from contribs/ThomasFenner/code_example2.java
rename to modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderNoConfigFileLog4JTest.java
index 40bb71d8c7..9a9511a814 100644
--- a/contribs/ThomasFenner/code_example2.java
+++ b/modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderNoConfigFileLog4JTest.java
@@ -1,3 +1,4 @@
+package org.apache.log4j.contribs.ThomasFenner;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -18,14 +19,18 @@
// Here is a code example to configure the JDBCAppender without a configuration-file
import org.apache.log4j.*;
+import org.apache.log4j.net.JDBCAppender;
+import org.apache.log4j.net.JDBCConnectionHandler;
+import org.apache.log4j.net.JDBCIDHandler;
+import org.apache.log4j.net.LogType;
+
import java.sql.*;
-import java.lang.*;
import java.util.*;
-public class Log4JTest
+public class JDBCAppenderNoConfigFileLog4JTest
{
// Create a category instance for this class
- static Category cat = Category.getInstance(Log4JTest.class.getName());
+ static Category cat = Category.getInstance(JDBCAppenderNoConfigFileLog4JTest.class.getName());
public static void main(String[] args)
{
diff --git a/contribs/ThomasFenner/Log4JTest.java b/modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderWithConfigFileLog4JTest.java
similarity index 96%
rename from contribs/ThomasFenner/Log4JTest.java
rename to modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderWithConfigFileLog4JTest.java
index d7bb30f720..5fe1a53008 100644
--- a/contribs/ThomasFenner/Log4JTest.java
+++ b/modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/JDBCAppenderWithConfigFileLog4JTest.java
@@ -1,3 +1,4 @@
+package org.apache.log4j.contribs.ThomasFenner;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -123,14 +124,16 @@
// Here is a code example to configure the JDBCAppender with a configuration-file :
import org.apache.log4j.*;
+import org.apache.log4j.net.JDBCConnectionHandler;
+import org.apache.log4j.net.JDBCIDHandler;
+
import java.sql.*;
-import java.lang.*;
import java.util.*;
-public class Log4JTest
+public class JDBCAppenderWithConfigFileLog4JTest
{
// Create a category instance for this class
- static Category cat = Category.getInstance(Log4JTest.class.getName());
+ static Category cat = Category.getInstance(JDBCAppenderWithConfigFileLog4JTest.class.getName());
public static void main(String[] args)
{
@@ -229,7 +232,7 @@ public static void main(String[] args)
*/
// Implement a sample JDBCConnectionHandler
-class MyConnectionHandler implements JDBCConnectionHandler
+class JDBCAppenderWithConfigFileLog4JTestConnectionHandler implements JDBCConnectionHandler
{
Connection con = null;
//Default connection
@@ -258,7 +261,7 @@ public Connection getConnection(String _url, String _username, String _password)
// Implement a sample JDBCIDHandler
-class MyIDHandler implements JDBCIDHandler
+class JDBCAppenderWithConfigFileIDHandler implements JDBCIDHandler
{
private static long id = 0;
diff --git a/contribs/ThomasFenner/configfile_example.txt b/modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/configfile_example.txt
similarity index 100%
rename from contribs/ThomasFenner/configfile_example.txt
rename to modules/contribs/src/stale/java/org/apache/log4j/contribs/ThomasFenner/configfile_example.txt
diff --git a/contribs/KevinSteppe/CompositeRollingAppender.java b/modules/contribs/src/stale/org/apache/log4j/CompositeRollingAppender.java
similarity index 100%
rename from contribs/KevinSteppe/CompositeRollingAppender.java
rename to modules/contribs/src/stale/org/apache/log4j/CompositeRollingAppender.java
diff --git a/contribs/EirikLygre/DailyFileAppender1.java b/modules/contribs/src/stale/org/apache/log4j/DailyFileAppender.java
similarity index 100%
rename from contribs/EirikLygre/DailyFileAppender1.java
rename to modules/contribs/src/stale/org/apache/log4j/DailyFileAppender.java
diff --git a/contribs/LeosLiterak/TempFileAppender.java b/modules/contribs/src/stale/org/apache/log4j/TempFileAppender.java
similarity index 99%
rename from contribs/LeosLiterak/TempFileAppender.java
rename to modules/contribs/src/stale/org/apache/log4j/TempFileAppender.java
index 0d8562a4af..f0516f1c4c 100644
--- a/contribs/LeosLiterak/TempFileAppender.java
+++ b/modules/contribs/src/stale/org/apache/log4j/TempFileAppender.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
- package org.apache.log4j;
+package org.apache.log4j;
import java.io.File;
import java.io.Writer;
diff --git a/contribs/JamesHouse/LogTextPanel.java b/modules/contribs/src/stale/org/apache/log4j/gui/LogTextPanel.java
similarity index 99%
rename from contribs/JamesHouse/LogTextPanel.java
rename to modules/contribs/src/stale/org/apache/log4j/gui/LogTextPanel.java
index 56b989aede..a477e42080 100644
--- a/contribs/JamesHouse/LogTextPanel.java
+++ b/modules/contribs/src/stale/org/apache/log4j/gui/LogTextPanel.java
@@ -34,6 +34,9 @@
import org.apache.log4j.*;
+/**
+ * @author James House
+ */
public class LogTextPanel extends JPanel {
private JScrollBar scrollBar;
diff --git a/contribs/SvenReimers/gui/TextPaneAppender.java b/modules/contribs/src/stale/org/apache/log4j/gui/TextPaneAppender.java
similarity index 99%
rename from contribs/SvenReimers/gui/TextPaneAppender.java
rename to modules/contribs/src/stale/org/apache/log4j/gui/TextPaneAppender.java
index 6b8fce523d..ffb1372764 100644
--- a/contribs/SvenReimers/gui/TextPaneAppender.java
+++ b/modules/contribs/src/stale/org/apache/log4j/gui/TextPaneAppender.java
@@ -56,7 +56,6 @@
*
* @author Sven Reimers
*/
-
public class TextPaneAppender extends AppenderSkeleton {
JTextPane textpane;
diff --git a/contribs/JamesHouse/TextPanelAppender.java b/modules/contribs/src/stale/org/apache/log4j/gui/TextPanelAppender.java
similarity index 99%
rename from contribs/JamesHouse/TextPanelAppender.java
rename to modules/contribs/src/stale/org/apache/log4j/gui/TextPanelAppender.java
index bb46064935..532a34a618 100644
--- a/contribs/JamesHouse/TextPanelAppender.java
+++ b/modules/contribs/src/stale/org/apache/log4j/gui/TextPanelAppender.java
@@ -37,12 +37,10 @@
import org.apache.log4j.helpers.TracerPrintWriter;
import org.apache.log4j.helpers.OptionConverter;
-
/**
*
* @author James House
*/
-
public class TextPanelAppender extends AppenderSkeleton {
TracerPrintWriter tp;
diff --git a/contribs/JamesHouse/LogTextPanelExample.java b/modules/contribs/src/stale/org/apache/log4j/gui/examples/LogTextPanelExample.java
similarity index 99%
rename from contribs/JamesHouse/LogTextPanelExample.java
rename to modules/contribs/src/stale/org/apache/log4j/gui/examples/LogTextPanelExample.java
index c8898eec32..a28ef7fefd 100644
--- a/contribs/JamesHouse/LogTextPanelExample.java
+++ b/modules/contribs/src/stale/org/apache/log4j/gui/examples/LogTextPanelExample.java
@@ -23,6 +23,9 @@
import org.apache.log4j.*;
import org.apache.log4j.gui.TextPanelAppender;
+/**
+ * @author James House
+ */
public class LogTextPanelExample {
boolean packFrame = false;
diff --git a/contribs/SvenReimers/gui/examples/TextPaneAppenderExample.java b/modules/contribs/src/stale/org/apache/log4j/gui/examples/TextPaneAppenderExample.java
similarity index 99%
rename from contribs/SvenReimers/gui/examples/TextPaneAppenderExample.java
rename to modules/contribs/src/stale/org/apache/log4j/gui/examples/TextPaneAppenderExample.java
index bd5f9d3a16..1a96250c87 100644
--- a/contribs/SvenReimers/gui/examples/TextPaneAppenderExample.java
+++ b/modules/contribs/src/stale/org/apache/log4j/gui/examples/TextPaneAppenderExample.java
@@ -17,14 +17,14 @@
package org.apache.log4j.gui.examples;
-import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import org.apache.log4j.*;
import org.apache.log4j.gui.*;
-
-
+/**
+ * @author Sven Reimers
+ */
public class TextPaneAppenderExample implements ActionListener {
JFrame mainframe;
diff --git a/contribs/KitchingSimon/SingleLineTracerPrintWriter.java b/modules/contribs/src/stale/org/apache/log4j/helpers/SingleLineTracerPrintWriter.java
similarity index 100%
rename from contribs/KitchingSimon/SingleLineTracerPrintWriter.java
rename to modules/contribs/src/stale/org/apache/log4j/helpers/SingleLineTracerPrintWriter.java
diff --git a/contribs/KitchingSimon/DatagramStringAppender.java b/modules/contribs/src/stale/org/apache/log4j/net/DatagramStringAppender.java
similarity index 100%
rename from contribs/KitchingSimon/DatagramStringAppender.java
rename to modules/contribs/src/stale/org/apache/log4j/net/DatagramStringAppender.java
diff --git a/contribs/VolkerMentzner/PluggableHTTPServer.java b/modules/contribs/src/stale/org/apache/log4j/net/PluggableHTTPServer.java
similarity index 99%
rename from contribs/VolkerMentzner/PluggableHTTPServer.java
rename to modules/contribs/src/stale/org/apache/log4j/net/PluggableHTTPServer.java
index 12aa063786..d895315a82 100644
--- a/contribs/VolkerMentzner/PluggableHTTPServer.java
+++ b/modules/contribs/src/stale/org/apache/log4j/net/PluggableHTTPServer.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.psibt.framework.net;
+package org.apache.log4j.net;
import java.net.*;
import java.io.*;
diff --git a/contribs/MarkDouglas/SocketNode2.java b/modules/contribs/src/stale/org/apache/log4j/net/SocketNode2.java
similarity index 98%
rename from contribs/MarkDouglas/SocketNode2.java
rename to modules/contribs/src/stale/org/apache/log4j/net/SocketNode2.java
index 60f63e755f..7acaaa9f67 100644
--- a/contribs/MarkDouglas/SocketNode2.java
+++ b/modules/contribs/src/stale/org/apache/log4j/net/SocketNode2.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package com.systemsunion.LoggingServer;
+package org.apache.log4j.net;
import java.net.InetAddress;
import java.net.Socket;
diff --git a/contribs/MarkDouglas/SocketServer2.java b/modules/contribs/src/stale/org/apache/log4j/net/SocketServer2.java
similarity index 98%
rename from contribs/MarkDouglas/SocketServer2.java
rename to modules/contribs/src/stale/org/apache/log4j/net/SocketServer2.java
index 96caf0ea26..8d66f7cc2f 100644
--- a/contribs/MarkDouglas/SocketServer2.java
+++ b/modules/contribs/src/stale/org/apache/log4j/net/SocketServer2.java
@@ -16,7 +16,7 @@
*/
-package com.systemsunion.LoggingServer;
+package org.apache.log4j.net;
import java.net.Socket;
import java.net.ServerSocket;
diff --git a/contribs/VolkerMentzner/UserDialogRequestHandler.java b/modules/contribs/src/stale/org/apache/log4j/net/UserDialogRequestHandler.java
similarity index 97%
rename from contribs/VolkerMentzner/UserDialogRequestHandler.java
rename to modules/contribs/src/stale/org/apache/log4j/net/UserDialogRequestHandler.java
index 4a5124dd8b..4d34cd7981 100644
--- a/contribs/VolkerMentzner/UserDialogRequestHandler.java
+++ b/modules/contribs/src/stale/org/apache/log4j/net/UserDialogRequestHandler.java
@@ -22,7 +22,12 @@
* 16.04.2001 VMentzner Created
*/
-package com.psibt.framework.net;
+package org.apache.log4j.net;
+
+import java.awt.Component;
+import java.io.Writer;
+import java.net.URL;
+
/**
* This class implements a RequestHandler for the path "/userdialog/" in the PluggableHTTPServer.
* A simple input form is presented in the browser where you can enter a message. This message will be sent
diff --git a/contribs/KevinSteppe/JDBCTest.java b/modules/contribs/src/stale/org/apache/log4j/varia/test/JDBCTest.java
similarity index 85%
rename from contribs/KevinSteppe/JDBCTest.java
rename to modules/contribs/src/stale/org/apache/log4j/varia/test/JDBCTest.java
index 8df3d18a23..37ea663b92 100644
--- a/contribs/KevinSteppe/JDBCTest.java
+++ b/modules/contribs/src/stale/org/apache/log4j/varia/test/JDBCTest.java
@@ -16,11 +16,12 @@
*/
package org.apache.log4j.varia.test;
-
-import org.apache.log4j.varia.JDBCAppender;
import org.apache.log4j.*;
+import org.apache.log4j.net.JDBCAppender;
-
+/**
+ * @author Kevin Sceppe
+ */
public class JDBCTest
{
public static void main (String argv[])
@@ -39,11 +40,11 @@ public static void main (String argv[])
Layout layout = new PatternLayout("%p [%t] %c - %m%n");
JDBCAppender appender = new JDBCAppender();
appender.setLayout(layout);
- appender.setOption(JDBCAppender.URL_OPTION, "jdbc:odbc:someDB");
+ appender.setOption(org.apache.log4j.net.URL_OPTION, "jdbc:odbc:someDB");
- appender.setOption(JDBCAppender.USER_OPTION, "auser");
- appender.setOption(JDBCAppender.PASSWORD_OPTION, "thepassword");
+ appender.setOption(org.apache.log4j.net.USER_OPTION, "auser");
+ appender.setOption(org.apache.log4j.net.PASSWORD_OPTION, "thepassword");
@@ -64,7 +65,7 @@ public static void main (String argv[])
Thread.sleep(500);
- appender.setOption(JDBCAppender.BUFFER_OPTION, "5");
+ appender.setOption(org.apache.log4j.net.BUFFER_OPTION, "5");
log.debug("Debug 2");
Thread.sleep(500);
log.info("info 2");
@@ -77,7 +78,7 @@ public static void main (String argv[])
Thread.sleep(500);
- appender.setOption(JDBCAppender.BUFFER_OPTION, "2");
+ appender.setOption(org.apache.log4j.net.BUFFER_OPTION, "2");
appender.setThreshold(Priority.WARN);
log.debug("Debug 3");
Thread.sleep(500);
diff --git a/contribs/CekiGulcu/Transform.java b/modules/contribs/src/stale/org/apache/log4j/xml/Transform.java
similarity index 99%
rename from contribs/CekiGulcu/Transform.java
rename to modules/contribs/src/stale/org/apache/log4j/xml/Transform.java
index dcd9c15396..bd0fb1c136 100644
--- a/contribs/CekiGulcu/Transform.java
+++ b/modules/contribs/src/stale/org/apache/log4j/xml/Transform.java
@@ -52,7 +52,9 @@
import java.io.FileOutputStream;
import java.io.IOException;
-
+/**
+ * @author CekiGulcu
+ */
public class Transform {
public static void main(String[] args) throws Exception {
diff --git a/contribs/KitchingSimon/logconfig.xml b/modules/contribs/src/test/resources/org/apache/log4j/contribs/KitchingSimon/logconfig.xml
similarity index 100%
rename from contribs/KitchingSimon/logconfig.xml
rename to modules/contribs/src/test/resources/org/apache/log4j/contribs/KitchingSimon/logconfig.xml
diff --git a/contribs/KitchingSimon/udpserver.pl b/modules/contribs/src/test/resources/org/apache/log4j/contribs/KitchingSimon/udpserver.pl
similarity index 100%
rename from contribs/KitchingSimon/udpserver.pl
rename to modules/contribs/src/test/resources/org/apache/log4j/contribs/KitchingSimon/udpserver.pl
diff --git a/examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java b/modules/lf5/examples/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java
similarity index 100%
rename from examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java
rename to modules/lf5/examples/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java
diff --git a/examples/lf5/InitUsingLog4JProperties/InitUsingLog4JProperties.java b/modules/lf5/examples/InitUsingLog4JProperties/InitUsingLog4JProperties.java
similarity index 100%
rename from examples/lf5/InitUsingLog4JProperties/InitUsingLog4JProperties.java
rename to modules/lf5/examples/InitUsingLog4JProperties/InitUsingLog4JProperties.java
diff --git a/examples/lf5/InitUsingLog4JProperties/log4j.properties b/modules/lf5/examples/InitUsingLog4JProperties/log4j.properties
similarity index 100%
rename from examples/lf5/InitUsingLog4JProperties/log4j.properties
rename to modules/lf5/examples/InitUsingLog4JProperties/log4j.properties
diff --git a/examples/lf5/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java b/modules/lf5/examples/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java
similarity index 100%
rename from examples/lf5/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java
rename to modules/lf5/examples/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java
diff --git a/examples/lf5/InitUsingMultipleAppenders/example.properties b/modules/lf5/examples/InitUsingMultipleAppenders/example.properties
similarity index 100%
rename from examples/lf5/InitUsingMultipleAppenders/example.properties
rename to modules/lf5/examples/InitUsingMultipleAppenders/example.properties
diff --git a/examples/lf5/InitUsingPropertiesFile/InitUsingPropertiesFile.java b/modules/lf5/examples/InitUsingPropertiesFile/InitUsingPropertiesFile.java
similarity index 100%
rename from examples/lf5/InitUsingPropertiesFile/InitUsingPropertiesFile.java
rename to modules/lf5/examples/InitUsingPropertiesFile/InitUsingPropertiesFile.java
diff --git a/examples/lf5/InitUsingPropertiesFile/example.properties b/modules/lf5/examples/InitUsingPropertiesFile/example.properties
similarity index 100%
rename from examples/lf5/InitUsingPropertiesFile/example.properties
rename to modules/lf5/examples/InitUsingPropertiesFile/example.properties
diff --git a/examples/lf5/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java b/modules/lf5/examples/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java
similarity index 100%
rename from examples/lf5/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java
rename to modules/lf5/examples/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java
diff --git a/examples/lf5/InitUsingXMLPropertiesFile/example.xml b/modules/lf5/examples/InitUsingXMLPropertiesFile/example.xml
similarity index 100%
rename from examples/lf5/InitUsingXMLPropertiesFile/example.xml
rename to modules/lf5/examples/InitUsingXMLPropertiesFile/example.xml
diff --git a/examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java b/modules/lf5/examples/UsingLogMonitorAdapter/CustomizedLogLevels.java
similarity index 100%
rename from examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java
rename to modules/lf5/examples/UsingLogMonitorAdapter/CustomizedLogLevels.java
diff --git a/examples/lf5/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java b/modules/lf5/examples/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java
similarity index 100%
rename from examples/lf5/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java
rename to modules/lf5/examples/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java
diff --git a/examples/lf5/UsingSocketAppenders/UsingSocketAppenders.java b/modules/lf5/examples/UsingSocketAppenders/UsingSocketAppenders.java
similarity index 100%
rename from examples/lf5/UsingSocketAppenders/UsingSocketAppenders.java
rename to modules/lf5/examples/UsingSocketAppenders/UsingSocketAppenders.java
diff --git a/examples/lf5/UsingSocketAppenders/socketclient.properties b/modules/lf5/examples/UsingSocketAppenders/socketclient.properties
similarity index 100%
rename from examples/lf5/UsingSocketAppenders/socketclient.properties
rename to modules/lf5/examples/UsingSocketAppenders/socketclient.properties
diff --git a/examples/lf5/UsingSocketAppenders/socketserver.properties b/modules/lf5/examples/UsingSocketAppenders/socketserver.properties
similarity index 100%
rename from examples/lf5/UsingSocketAppenders/socketserver.properties
rename to modules/lf5/examples/UsingSocketAppenders/socketserver.properties
diff --git a/examples/lf5/index.html b/modules/lf5/examples/index.html
similarity index 100%
rename from examples/lf5/index.html
rename to modules/lf5/examples/index.html
diff --git a/modules/lf5/pom.xml b/modules/lf5/pom.xml
new file mode 100644
index 0000000000..1c3f71d1de
--- /dev/null
+++ b/modules/lf5/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-modules
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-lf5
+ Apache Log4j-LF5
+ jar
+
+
+
+ org.apache.log4j
+ log4j-core
+ ${project.version}
+
+
+
+
\ No newline at end of file
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/AppenderFinalizer.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/AppenderFinalizer.java
new file mode 100644
index 0000000000..a2a7019208
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/AppenderFinalizer.java
@@ -0,0 +1,78 @@
+/*
+ * 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.lf5;
+
+import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
+
+/**
+ * AppenderFinalizer
has a single method that will finalize
+ * resources associated with a LogBrokerMonitor
in the event
+ * that the LF5Appender
class is destroyed, and the class loader
+ * is garbage collected.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class AppenderFinalizer {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ protected LogBrokerMonitor _defaultMonitor = null;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public AppenderFinalizer(LogBrokerMonitor defaultMonitor) {
+ _defaultMonitor = defaultMonitor;
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * @throws java.lang.Throwable
+ */
+ protected void finalize() throws Throwable {
+ System.out.println("Disposing of the default LogBrokerMonitor instance");
+ _defaultMonitor.dispose();
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
\ No newline at end of file
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/DefaultLF5Configurator.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/DefaultLF5Configurator.java
new file mode 100644
index 0000000000..d5c80a53b5
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/DefaultLF5Configurator.java
@@ -0,0 +1,118 @@
+/*
+ * 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.lf5;
+
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.spi.Configurator;
+import org.apache.log4j.spi.LoggerRepository;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * The DefaultLF5Configurator
provides a default
+ * configuration for the LF5Appender
.
+ *
+ * Note: The preferred method for configuring a LF5Appender
+ * is to use the LF5Manager
class. This class ensures
+ * that configuration does not occur multiple times, and improves system
+ * performance. Reconfiguring the monitor multiple times can result in
+ * unexpected behavior.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class DefaultLF5Configurator implements Configurator {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ /**
+ * This class should never be instantiated! It implements the
+ * Configurator
+ * interface, but does not provide the same functionality as full
+ * configurator class.
+ */
+ private DefaultLF5Configurator() {
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ /**
+ * This method configures the LF5Appender
using a
+ * default configuration file. The default configuration file is
+ * defaultconfig.properties.
+ * @throws java.io.IOException
+ */
+ public static void configure() throws IOException {
+ String resource =
+ "/org/apache/log4j/lf5/config/defaultconfig.properties";
+ URL configFileResource =
+ DefaultLF5Configurator.class.getResource(resource);
+
+ if (configFileResource != null) {
+ PropertyConfigurator.configure(configFileResource);
+ } else {
+ throw new IOException("Error: Unable to open the resource" +
+ resource);
+ }
+
+ }
+
+ public void doConfigure(InputStream inputStream, LoggerRepository repository) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ /**
+ * This is a dummy method that will throw an
+ * IllegalStateException
if used.
+ */
+ public void doConfigure(URL configURL, LoggerRepository repository) {
+ throw new IllegalStateException("This class should NOT be" +
+ " instantiated!");
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
\ No newline at end of file
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/LF5Appender.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/LF5Appender.java
new file mode 100644
index 0000000000..e98e9bd015
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/LF5Appender.java
@@ -0,0 +1,266 @@
+/*
+ * 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.lf5;
+
+import java.awt.Toolkit;
+
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
+import org.apache.log4j.spi.LocationInfo;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * LF5Appender
logs events to a swing based logging
+ * console. The swing console supports turning categories on and off,
+ * multiple detail level views, as well as full text searching and many
+ * other capabilties.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LF5Appender extends AppenderSkeleton {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ protected LogBrokerMonitor _logMonitor;
+ protected static LogBrokerMonitor _defaultLogMonitor;
+ protected static AppenderFinalizer _finalizer;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructs a LF5Appender
using the default instance of
+ * the LogBrokerMonitor
. This constructor should always
+ * be preferred over the
+ * LF5Appender(LogBrokerMonitor monitor)
+ * constructor, unless you need to spawn additional log monitoring
+ * windows.
+ */
+ public LF5Appender() {
+ this(getDefaultInstance());
+ }
+
+ /**
+ * Constructs a LF5Appender using an instance of
+ * a LogBrokerMonitor supplied by the user. This
+ * constructor should only be used when you need to spawn
+ * additional log monitoring windows.
+ *
+ * @param monitor An instance of a LogBrokerMonitor
+ * created by the user.
+ */
+ public LF5Appender(LogBrokerMonitor monitor) {
+
+ if (monitor != null) {
+ _logMonitor = monitor;
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Appends a LoggingEvent
record to the
+ * LF5Appender
.
+ * @param event The LoggingEvent
+ * to be appended.
+ */
+ public void append(LoggingEvent event) {
+ // Retrieve the information from the log4j LoggingEvent.
+ String category = event.getLoggerName();
+ String logMessage = event.getRenderedMessage();
+ String nestedDiagnosticContext = event.getNDC();
+ String threadDescription = event.getThreadName();
+ String level = event.getLevel().toString();
+ long time = event.timeStamp;
+ LocationInfo locationInfo = event.getLocationInformation();
+
+ // Add the logging event information to a LogRecord
+ Log4JLogRecord record = new Log4JLogRecord();
+
+ record.setCategory(category);
+ record.setMessage(logMessage);
+ record.setLocation(locationInfo.fullInfo);
+ record.setMillis(time);
+ record.setThreadDescription(threadDescription);
+
+ if (nestedDiagnosticContext != null) {
+ record.setNDC(nestedDiagnosticContext);
+ } else {
+ record.setNDC("");
+ }
+
+ if (event.getThrowableInformation() != null) {
+ record.setThrownStackTrace(event.getThrowableInformation());
+ }
+
+ try {
+ record.setLevel(LogLevel.valueOf(level));
+ } catch (LogLevelFormatException e) {
+ // If the priority level doesn't match one of the predefined
+ // log levels, then set the level to warning.
+ record.setLevel(LogLevel.WARN);
+ }
+
+ if (_logMonitor != null) {
+ _logMonitor.addMessage(record);
+ }
+ }
+
+ /**
+ * This method is an empty implementation of the close() method inherited
+ * from the org.apache.log4j.Appender
interface.
+ */
+ public void close() {
+ }
+
+ /**
+ * Returns a value that indicates whether this appender requires a
+ * Layout
. This method always returns false.
+ * No layout is required for the LF5Appender
.
+ */
+ public boolean requiresLayout() {
+ return false;
+ }
+
+ /**
+ * This method is used to set the property that controls whether
+ * the LogBrokerMonitor
is hidden or closed when a user
+ * exits
+ * the monitor. By default, the LogBrokerMonitor
will hide
+ * itself when the log window is exited, and the swing thread will
+ * continue to run in the background. If this property is
+ * set to true, the LogBrokerMonitor
will call System.exit(0)
+ * and will shut down swing thread and the virtual machine.
+ *
+ * @param callSystemExitOnClose A boolean value indicating whether
+ * to call System.exit(0) when closing the log window.
+ */
+ public void setCallSystemExitOnClose(boolean callSystemExitOnClose) {
+ _logMonitor.setCallSystemExitOnClose(callSystemExitOnClose);
+ }
+
+ /**
+ * The equals method compares two LF5Appenders and determines whether
+ * they are equal. Two Appenders
will be considered equal
+ * if, and only if, they both contain references to the same
+ * LogBrokerMonitor
.
+ *
+ * @param compareTo A boolean value indicating whether
+ * the two LF5Appenders are equal.
+ */
+ public boolean equals(LF5Appender compareTo) {
+ // If both reference the same LogBrokerMonitor, they are equal.
+ return _logMonitor == compareTo.getLogBrokerMonitor();
+ }
+
+ public LogBrokerMonitor getLogBrokerMonitor() {
+ return _logMonitor;
+ }
+
+ public static void main(String[] args) {
+ new LF5Appender();
+ }
+
+ public void setMaxNumberOfRecords(int maxNumberOfRecords) {
+ _defaultLogMonitor.setMaxNumberOfLogRecords(maxNumberOfRecords);
+ }
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * @return The default instance of the LogBrokerMonitor
.
+ */
+ protected static synchronized LogBrokerMonitor getDefaultInstance() {
+ if (_defaultLogMonitor == null) {
+ try {
+ _defaultLogMonitor =
+ new LogBrokerMonitor(LogLevel.getLog4JLevels());
+ _finalizer = new AppenderFinalizer(_defaultLogMonitor);
+
+ _defaultLogMonitor.setFrameSize(getDefaultMonitorWidth(),
+ getDefaultMonitorHeight());
+ _defaultLogMonitor.setFontSize(12);
+ _defaultLogMonitor.show();
+
+ } catch (SecurityException e) {
+ _defaultLogMonitor = null;
+ }
+ }
+
+ return _defaultLogMonitor;
+ }
+
+ /**
+ * @return the screen width from Toolkit.getScreenSize()
+ * if possible, otherwise returns 800
+ * @see java.awt.Toolkit
+ */
+ protected static int getScreenWidth() {
+ try {
+ return Toolkit.getDefaultToolkit().getScreenSize().width;
+ } catch (Throwable t) {
+ return 800;
+ }
+ }
+
+ /**
+ * @return the screen height from Toolkit.getScreenSize()
+ * if possible, otherwise returns 600
+ * @see java.awt.Toolkit
+ */
+ protected static int getScreenHeight() {
+ try {
+ return Toolkit.getDefaultToolkit().getScreenSize().height;
+ } catch (Throwable t) {
+ return 600;
+ }
+ }
+
+ protected static int getDefaultMonitorWidth() {
+ return (3 * getScreenWidth()) / 4;
+ }
+
+ protected static int getDefaultMonitorHeight() {
+ return (3 * getScreenHeight()) / 4;
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/Log4JLogRecord.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/Log4JLogRecord.java
new file mode 100644
index 0000000000..4393eb586d
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/Log4JLogRecord.java
@@ -0,0 +1,116 @@
+/*
+ * 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.lf5;
+
+import org.apache.log4j.spi.ThrowableInformation;
+
+/**
+ * A Log4JLogRecord
encapsulates
+ * the details of your log4j LoggingEvent
in a format usable
+ * by the LogBrokerMonitor
.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class Log4JLogRecord extends LogRecord {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructs an instance of a Log4JLogRecord
.
+ */
+ public Log4JLogRecord() {
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ /**
+ * Determines which Priority
levels will
+ * be displayed in colored font when the LogMonitorAppender
+ * renders this log message. By default, messages will be colored
+ * red if they are of Priority
ERROR or FATAL.
+ *
+ * @return true if the log level is ERROR or FATAL.
+ */
+ public boolean isSevereLevel() {
+ boolean isSevere = false;
+
+ if (LogLevel.ERROR.equals(getLevel()) ||
+ LogLevel.FATAL.equals(getLevel())) {
+ isSevere = true;
+ }
+
+ return isSevere;
+ }
+
+ /**
+ * Set stack trace information associated with this Log4JLogRecord.
+ * When this method is called, the stack trace in a
+ * String-based format is made
+ * available via the getThrownStackTrace() method.
+ *
+ * @param throwableInfo An org.apache.log4j.spi.ThrowableInformation to
+ * associate with this Log4JLogRecord.
+ * @see #getThrownStackTrace()
+ */
+ public void setThrownStackTrace(ThrowableInformation throwableInfo) {
+ String[] stackTraceArray = throwableInfo.getThrowableStrRep();
+
+ StringBuffer stackTrace = new StringBuffer();
+ String nextLine;
+
+ for (int i = 0; i < stackTraceArray.length; i++) {
+ nextLine = stackTraceArray[i] + "\n";
+ stackTrace.append(nextLine);
+ }
+
+ _thrownStackTrace = stackTrace.toString();
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/LogLevel.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogLevel.java
new file mode 100644
index 0000000000..080ed68795
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogLevel.java
@@ -0,0 +1,278 @@
+/*
+ * 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.lf5;
+
+import java.awt.Color;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The LogLevel class defines a set of standard logging levels.
+ *
+ * The logging Level objects are ordered and are specified by ordered
+ * integers. Enabling logging at a given level also enables logging at all
+ * higher levels.
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ * @author Brent Sprecher
+ * @author Richard Hurst
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogLevel implements java.io.Serializable {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ // log4j log levels.
+ public final static LogLevel FATAL = new LogLevel("FATAL", 0);
+ public final static LogLevel ERROR = new LogLevel("ERROR", 1);
+ public final static LogLevel WARN = new LogLevel("WARN", 2);
+ public final static LogLevel INFO = new LogLevel("INFO", 3);
+ public final static LogLevel DEBUG = new LogLevel("DEBUG", 4);
+
+ // jdk1.4 log levels NOTE: also includes INFO
+ public final static LogLevel SEVERE = new LogLevel("SEVERE", 1);
+ public final static LogLevel WARNING = new LogLevel("WARNING", 2);
+ public final static LogLevel CONFIG = new LogLevel("CONFIG", 4);
+ public final static LogLevel FINE = new LogLevel("FINE", 5);
+ public final static LogLevel FINER = new LogLevel("FINER", 6);
+ public final static LogLevel FINEST = new LogLevel("FINEST", 7);
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected String _label;
+ protected int _precedence;
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private static LogLevel[] _log4JLevels;
+ private static LogLevel[] _jdk14Levels;
+ private static LogLevel[] _allDefaultLevels;
+ private static Map _logLevelMap;
+ private static Map _logLevelColorMap;
+ private static Map _registeredLogLevelMap = new HashMap();
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ static {
+ _log4JLevels = new LogLevel[]{FATAL, ERROR, WARN, INFO, DEBUG};
+ _jdk14Levels = new LogLevel[]{SEVERE, WARNING, INFO,
+ CONFIG, FINE, FINER, FINEST};
+ _allDefaultLevels = new LogLevel[]{FATAL, ERROR, WARN, INFO, DEBUG,
+ SEVERE, WARNING, CONFIG, FINE, FINER, FINEST};
+
+ _logLevelMap = new HashMap();
+ for (int i = 0; i < _allDefaultLevels.length; i++) {
+ _logLevelMap.put(_allDefaultLevels[i].getLabel(), _allDefaultLevels[i]);
+ }
+
+ // prepopulate map with levels and text color of black
+ _logLevelColorMap = new HashMap();
+ for (int i = 0; i < _allDefaultLevels.length; i++) {
+ _logLevelColorMap.put(_allDefaultLevels[i], Color.black);
+ }
+ }
+
+ public LogLevel(String label, int precedence) {
+ _label = label;
+ _precedence = precedence;
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Return the Label of the LogLevel.
+ */
+ public String getLabel() {
+ return _label;
+ }
+
+ /**
+ * Returns true if the level supplied is encompassed by this level.
+ * For example, LogLevel.SEVERE encompasses no other LogLevels and
+ * LogLevel.FINE encompasses all other LogLevels. By definition,
+ * a LogLevel encompasses itself.
+ */
+ public boolean encompasses(LogLevel level) {
+ if (level.getPrecedence() <= getPrecedence()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert a log level label into a LogLevel object.
+ *
+ * @param level The label of a level to be converted into a LogLevel.
+ * @return LogLevel The LogLevel with a label equal to level.
+ * @throws LogLevelFormatException Is thrown when the level can not be
+ * converted into a LogLevel.
+ */
+ public static LogLevel valueOf(String level)
+ throws LogLevelFormatException {
+ LogLevel logLevel = null;
+ if (level != null) {
+ level = level.trim().toUpperCase();
+ logLevel = (LogLevel) _logLevelMap.get(level);
+ }
+
+ // Didn't match, Check for registered LogLevels
+ if (logLevel == null && _registeredLogLevelMap.size() > 0) {
+ logLevel = (LogLevel) _registeredLogLevelMap.get(level);
+ }
+
+ if (logLevel == null) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("Error while trying to parse (" + level + ") into");
+ buf.append(" a LogLevel.");
+ throw new LogLevelFormatException(buf.toString());
+ }
+ return logLevel;
+ }
+
+ /**
+ * Registers a used defined LogLevel.
+ *
+ * @param logLevel The log level to be registered. Cannot be a default LogLevel
+ * @return LogLevel The replaced log level.
+ */
+ public static LogLevel register(LogLevel logLevel) {
+ if (logLevel == null) return null;
+
+ // ensure that this is not a default log level
+ if (_logLevelMap.get(logLevel.getLabel()) == null) {
+ return (LogLevel) _registeredLogLevelMap.put(logLevel.getLabel(), logLevel);
+ }
+
+ return null;
+ }
+
+ public static void register(LogLevel[] logLevels) {
+ if (logLevels != null) {
+ for (int i = 0; i < logLevels.length; i++) {
+ register(logLevels[i]);
+ }
+ }
+ }
+
+ public static void register(List logLevels) {
+ if (logLevels != null) {
+ Iterator it = logLevels.iterator();
+ while (it.hasNext()) {
+ register((LogLevel) it.next());
+ }
+ }
+ }
+
+ public boolean equals(Object o) {
+ boolean equals = false;
+
+ if (o instanceof LogLevel) {
+ if (this.getPrecedence() ==
+ ((LogLevel) o).getPrecedence()) {
+ equals = true;
+ }
+
+ }
+
+ return equals;
+ }
+
+ public int hashCode() {
+ return _label.hashCode();
+ }
+
+ public String toString() {
+ return _label;
+ }
+
+ // set a text color for a specific log level
+ public void setLogLevelColorMap(LogLevel level, Color color) {
+ // remove the old entry
+ _logLevelColorMap.remove(level);
+ // add the new color entry
+ if (color == null) {
+ color = Color.black;
+ }
+ _logLevelColorMap.put(level, color);
+ }
+
+ public static void resetLogLevelColorMap() {
+ // empty the map
+ _logLevelColorMap.clear();
+
+ // repopulate map and reset text color black
+ for (int i = 0; i < _allDefaultLevels.length; i++) {
+ _logLevelColorMap.put(_allDefaultLevels[i], Color.black);
+ }
+ }
+
+ /**
+ * @return A List
of LogLevel
objects that map
+ * to log4j Priority
objects.
+ */
+ public static List getLog4JLevels() {
+ return Arrays.asList(_log4JLevels);
+ }
+
+ public static List getJdk14Levels() {
+ return Arrays.asList(_jdk14Levels);
+ }
+
+ public static List getAllDefaultLevels() {
+ return Arrays.asList(_allDefaultLevels);
+ }
+
+ public static Map getLogLevelColorMap() {
+ return _logLevelColorMap;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected int getPrecedence() {
+ return _precedence;
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/LogLevelFormatException.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogLevelFormatException.java
new file mode 100644
index 0000000000..1109e23836
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogLevelFormatException.java
@@ -0,0 +1,73 @@
+/*
+ * 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.lf5;
+
+/**
+ * Thrown to indicate that the client has attempted to convert a string
+ * to one the LogLevel types, but the string does not have the appropriate
+ * format.
+ *
+ * @author Michael J. Sikorsky<
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogLevelFormatException extends Exception {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public LogLevelFormatException(String message) {
+ super(message);
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/LogRecord.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogRecord.java
new file mode 100644
index 0000000000..4f4097f20a
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogRecord.java
@@ -0,0 +1,395 @@
+/*
+ * 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.lf5;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * LogRecord. A LogRecord encapsulates the details of your desired log
+ * request.
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public abstract class LogRecord implements java.io.Serializable {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected static long _seqCount = 0;
+
+ protected LogLevel _level;
+ protected String _message;
+ protected long _sequenceNumber;
+ protected long _millis;
+ protected String _category;
+ protected String _thread;
+ protected String _thrownStackTrace;
+ protected Throwable _thrown;
+ protected String _ndc;
+ protected String _location;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public LogRecord() {
+ super();
+
+ _millis = System.currentTimeMillis();
+ _category = "Debug";
+ _message = "";
+ _level = LogLevel.INFO;
+ _sequenceNumber = getNextId();
+ _thread = Thread.currentThread().toString();
+ _ndc = "";
+ _location = "";
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Get the level of this LogRecord.
+ *
+ * @return The LogLevel of this record.
+ * @see #setLevel(LogLevel)
+ * @see LogLevel
+ */
+ public LogLevel getLevel() {
+ return (_level);
+ }
+
+ /**
+ * Set the level of this LogRecord.
+ *
+ * @param level The LogLevel for this record.
+ * @see #getLevel()
+ * @see LogLevel
+ */
+ public void setLevel(LogLevel level) {
+ _level = level;
+ }
+
+ /**
+ * Abstract method. Must be overridden to indicate what log level
+ * to show in red.
+ */
+ public abstract boolean isSevereLevel();
+
+ /**
+ * @return true if getThrown().toString() is a non-empty string.
+ */
+ public boolean hasThrown() {
+ Throwable thrown = getThrown();
+ if (thrown == null) {
+ return false;
+ }
+ String thrownString = thrown.toString();
+ return thrownString != null && thrownString.trim().length() != 0;
+ }
+
+ /**
+ * @return true if isSevereLevel() or hasThrown() returns true.
+ */
+ public boolean isFatal() {
+ return isSevereLevel() || hasThrown();
+ }
+
+ /**
+ * Get the category asscociated with this LogRecord. For a more detailed
+ * description of what a category is see setCategory().
+ *
+ * @return The category of this record.
+ * @see #setCategory(String)
+ */
+ public String getCategory() {
+ return (_category);
+ }
+
+ /**
+ * Set the category associated with this LogRecord. A category represents
+ * a hierarchical dot (".") separated namespace for messages.
+ * The definition of a category is application specific, but a common convention
+ * is as follows:
+ *
+ *
+ * When logging messages
+ * for a particluar class you can use its class name:
+ * com.thoughtworks.framework.servlet.ServletServiceBroker.
+ * Futhermore, to log a message for a particular method in a class
+ * add the method name:
+ * com.thoughtworks.framework.servlet.ServletServiceBroker.init().
+ *
+ *
+ * @param category The category for this record.
+ * @see #getCategory()
+ */
+ public void setCategory(String category) {
+ _category = category;
+ }
+
+ /**
+ * Get the message asscociated with this LogRecord.
+ *
+ * @return The message of this record.
+ * @see #setMessage(String)
+ */
+ public String getMessage() {
+ return (_message);
+ }
+
+ /**
+ * Set the message associated with this LogRecord.
+ *
+ * @param message The message for this record.
+ * @see #getMessage()
+ */
+ public void setMessage(String message) {
+ _message = message;
+ }
+
+ /**
+ * Get the sequence number associated with this LogRecord. Sequence numbers
+ * are generally assigned when a LogRecord is constructed. Sequence numbers
+ * start at 0 and increase with each newly constructed LogRocord.
+ *
+ * @return The sequence number of this record.
+ * @see #setSequenceNumber(long)
+ */
+ public long getSequenceNumber() {
+ return (_sequenceNumber);
+ }
+
+ /**
+ * Set the sequence number assocsiated with this LogRecord. A sequence number
+ * will automatically be assigned to evey newly constructed LogRecord, however,
+ * this method can override the value.
+ *
+ * @param number The sequence number.
+ * @see #getSequenceNumber()
+ */
+ public void setSequenceNumber(long number) {
+ _sequenceNumber = number;
+ }
+
+ /**
+ * Get the event time of this record in milliseconds from 1970.
+ * When a LogRecord is constructed the event time is set but may be
+ * overridden by calling setMillis();
+ *
+ * @return The event time of this record in milliseconds from 1970.
+ * @see #setMillis(long)
+ */
+ public long getMillis() {
+ return _millis;
+ }
+
+ /**
+ * Set the event time of this record. When a LogRecord is constructed
+ * the event time is set but may be overridden by calling this method.
+ *
+ * @param millis The time in milliseconds from 1970.
+ * @see #getMillis()
+ */
+ public void setMillis(long millis) {
+ _millis = millis;
+ }
+
+ /**
+ * Get the thread description asscociated with this LogRecord. When a
+ * LogRecord is constructed, the thread description is set by calling:
+ * Thread.currentThread().toString(). You may supply a thread description
+ * of your own by calling the setThreadDescription(String) method.
+ *
+ * @return The thread description of this record.
+ * @see #setThreadDescription(String)
+ */
+ public String getThreadDescription() {
+ return (_thread);
+ }
+
+ /**
+ * Set the thread description associated with this LogRecord. When a
+ * LogRecord is constructed, the thread description is set by calling:
+ * Thread.currentThread().toString(). You may supply a thread description
+ * of your own by calling this method.
+ *
+ * @param threadDescription The description of the thread for this record.
+ * @see #getThreadDescription()
+ */
+ public void setThreadDescription(String threadDescription) {
+ _thread = threadDescription;
+ }
+
+ /**
+ * Get the stack trace in a String-based format for the associated Throwable
+ * of this LogRecord. The stack trace in a String-based format is set
+ * when the setThrown(Throwable) method is called.
+ *
+ *
+ * Why do we need this method considering that we
+ * have the getThrown() and setThrown() methods?
+ * A Throwable object may not be serializable, however, a String representation
+ * of it is. Users of LogRecords should generally call this method over
+ * getThrown() for the reasons of serialization.
+ *
+ *
+ * @return The Stack Trace for the asscoiated Throwable of this LogRecord.
+ * @see #setThrown(Throwable)
+ * @see #getThrown()
+ */
+ public String getThrownStackTrace() {
+ return (_thrownStackTrace);
+ }
+
+ /**
+ * Set the ThrownStackTrace for the log record.
+ *
+ * @param trace A String to associate with this LogRecord
+ * @see #getThrownStackTrace()
+ */
+ public void setThrownStackTrace(String trace) {
+ _thrownStackTrace = trace;
+ }
+
+ /**
+ * Get the Throwable associated with this LogRecord.
+ *
+ * @return The LogLevel of this record.
+ * @see #setThrown(Throwable)
+ * @see #getThrownStackTrace()
+ */
+ public Throwable getThrown() {
+ return (_thrown);
+ }
+
+ /**
+ * Set the Throwable associated with this LogRecord. When this method
+ * is called, the stack trace in a String-based format is made
+ * available via the getThrownStackTrace() method.
+ *
+ * @param thrown A Throwable to associate with this LogRecord.
+ * @see #getThrown()
+ * @see #getThrownStackTrace()
+ */
+ public void setThrown(Throwable thrown) {
+ if (thrown == null) {
+ return;
+ }
+ _thrown = thrown;
+ StringWriter sw = new StringWriter();
+ PrintWriter out = new PrintWriter(sw);
+ thrown.printStackTrace(out);
+ out.flush();
+ _thrownStackTrace = sw.toString();
+ try {
+ out.close();
+ sw.close();
+ } catch (IOException e) {
+ // Do nothing, this should not happen as it is StringWriter.
+ }
+ out = null;
+ sw = null;
+ }
+
+ /**
+ * Return a String representation of this LogRecord.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("LogRecord: [" + _level + ", " + _message + "]");
+ return (buf.toString());
+ }
+
+ /**
+ * Get the NDC (nested diagnostic context) for this record.
+ *
+ * @return The string representing the NDC.
+ */
+ public String getNDC() {
+ return _ndc;
+ }
+
+ /**
+ * Set the NDC (nested diagnostic context) for this record.
+ *
+ * @param ndc A string representing the NDC.
+ */
+ public void setNDC(String ndc) {
+ _ndc = ndc;
+ }
+
+ /**
+ * Get the location in code where this LogRecord originated.
+ *
+ * @return The string containing the location information.
+ */
+ public String getLocation() {
+ return _location;
+ }
+
+ /**
+ * Set the location in code where this LogRecord originated.
+ *
+ * @param location A string containing location information.
+ */
+ public void setLocation(String location) {
+ _location = location;
+ }
+
+ /**
+ * Resets that sequence number to 0.
+ *
+ */
+ public static synchronized void resetSequenceNumber() {
+ _seqCount = 0;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected static synchronized long getNextId() {
+ _seqCount++;
+ return _seqCount;
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/LogRecordFilter.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogRecordFilter.java
new file mode 100644
index 0000000000..25a3e53c2e
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/LogRecordFilter.java
@@ -0,0 +1,46 @@
+/*
+ * 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.lf5;
+
+
+/**
+ * An interface for classes which filters LogRecords. Implementations
+ * represent a rule or condition which LogRecords may pass or fail.
+ * @see LogRecord
+ *
+ * @author Richard Wan
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public interface LogRecordFilter {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * @return true if the specified LogRecord satisfies whatever condition
+ * implementing class tests for.
+ */
+ public boolean passes(LogRecord record);
+
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/PassingLogRecordFilter.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/PassingLogRecordFilter.java
new file mode 100644
index 0000000000..178f6cb67c
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/PassingLogRecordFilter.java
@@ -0,0 +1,74 @@
+/*
+ * 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.lf5;
+
+
+/**
+ * An implementation of LogRecordFilter which always returns true.
+ *
+ * @author Richard Wan
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class PassingLogRecordFilter implements LogRecordFilter {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * @return true;
+ */
+ public boolean passes(LogRecord record) {
+ return true;
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void reset() {
+ // do nothing
+ }
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/StartLogFactor5.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/StartLogFactor5.java
new file mode 100644
index 0000000000..1ea28c3c72
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/StartLogFactor5.java
@@ -0,0 +1,81 @@
+/*
+ * 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.lf5;
+
+import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
+
+/**
+ * Starts an instance of the LogFactor5 console for off-line viewing.
+ *
+ * @author Brad Marlborough
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class StartLogFactor5 {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Main - starts a an instance of the LogFactor5 console and configures
+ * the console settings.
+ */
+ public final static void main(String[] args) {
+
+ LogBrokerMonitor monitor = new LogBrokerMonitor(
+ LogLevel.getLog4JLevels());
+
+ monitor.setFrameSize(LF5Appender.getDefaultMonitorWidth(),
+ LF5Appender.getDefaultMonitorHeight());
+ monitor.setFontSize(12);
+ monitor.show();
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+
+}
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/util/AdapterLogRecord.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/AdapterLogRecord.java
new file mode 100644
index 0000000000..2e4ee6f02f
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/AdapterLogRecord.java
@@ -0,0 +1,114 @@
+/*
+ * 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.lf5.util;
+
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.LogRecord;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * A LogRecord to be used with the LogMonitorAdapter
+ *
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class AdapterLogRecord extends LogRecord {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private static LogLevel severeLevel = null;
+
+ private static StringWriter sw = new StringWriter();
+ private static PrintWriter pw = new PrintWriter(sw);
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public AdapterLogRecord() {
+ super();
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ public void setCategory(String category) {
+ super.setCategory(category);
+ super.setLocation(getLocationInfo(category));
+ }
+
+ public boolean isSevereLevel() {
+ if (severeLevel == null) return false;
+ return severeLevel.equals(getLevel());
+ }
+
+ public static void setSevereLevel(LogLevel level) {
+ severeLevel = level;
+ }
+
+ public static LogLevel getSevereLevel() {
+ return severeLevel;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ protected String getLocationInfo(String category) {
+ String stackTrace = stackTraceToString(new Throwable());
+ String line = parseLine(stackTrace, category);
+ return line;
+ }
+
+ protected String stackTraceToString(Throwable t) {
+ String s = null;
+
+ synchronized (sw) {
+ t.printStackTrace(pw);
+ s = sw.toString();
+ sw.getBuffer().setLength(0);
+ }
+
+ return s;
+ }
+
+ protected String parseLine(String trace, String category) {
+ int index = trace.indexOf(category);
+ if (index == -1) return null;
+ trace = trace.substring(index);
+ trace = trace.substring(0, trace.indexOf(")") + 1);
+ return trace;
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/util/DateFormatManager.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/DateFormatManager.java
new file mode 100644
index 0000000000..6bed9cc862
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/DateFormatManager.java
@@ -0,0 +1,243 @@
+/*
+ * 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.lf5.util;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Date format manager.
+ * Utility class to help manage consistent date formatting and parsing.
+ * It may be advantageous to have multiple DateFormatManagers per
+ * application. For example, one for handling the output (formatting) of
+ * dates, and another one for handling the input (parsing) of dates.
+ *
+ * @author Robert Shaw
+ * @author Michael J. Sikorsky
+ */
+
+// Contributed by ThoughtWorks Inc.
+public class DateFormatManager {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private TimeZone _timeZone = null;
+ private Locale _locale = null;
+
+ private String _pattern = null;
+ private DateFormat _dateFormat = null;
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public DateFormatManager() {
+ super();
+ configure();
+ }
+
+ public DateFormatManager(TimeZone timeZone) {
+ super();
+
+ _timeZone = timeZone;
+ configure();
+ }
+
+ public DateFormatManager(Locale locale) {
+ super();
+
+ _locale = locale;
+ configure();
+ }
+
+ public DateFormatManager(String pattern) {
+ super();
+
+ _pattern = pattern;
+ configure();
+ }
+
+ public DateFormatManager(TimeZone timeZone, Locale locale) {
+ super();
+
+ _timeZone = timeZone;
+ _locale = locale;
+ configure();
+ }
+
+ public DateFormatManager(TimeZone timeZone, String pattern) {
+ super();
+
+ _timeZone = timeZone;
+ _pattern = pattern;
+ configure();
+ }
+
+ public DateFormatManager(Locale locale, String pattern) {
+ super();
+
+ _locale = locale;
+ _pattern = pattern;
+ configure();
+ }
+
+ public DateFormatManager(TimeZone timeZone, Locale locale, String pattern) {
+ super();
+
+ _timeZone = timeZone;
+ _locale = locale;
+ _pattern = pattern;
+ configure();
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public synchronized TimeZone getTimeZone() {
+ if (_timeZone == null) {
+ return TimeZone.getDefault();
+ } else {
+ return _timeZone;
+ }
+ }
+
+ public synchronized void setTimeZone(TimeZone timeZone) {
+ _timeZone = timeZone;
+ configure();
+ }
+
+ public synchronized Locale getLocale() {
+ if (_locale == null) {
+ return Locale.getDefault();
+ } else {
+ return _locale;
+ }
+ }
+
+ public synchronized void setLocale(Locale locale) {
+ _locale = locale;
+ configure();
+ }
+
+ public synchronized String getPattern() {
+ return _pattern;
+ }
+
+ /**
+ * Set the pattern. i.e. "EEEEE, MMMMM d, yyyy hh:mm aaa"
+ */
+ public synchronized void setPattern(String pattern) {
+ _pattern = pattern;
+ configure();
+ }
+
+
+ /**
+ * This method has been deprecated in favour of getPattern().
+ * @deprecated Use getPattern().
+ */
+ public synchronized String getOutputFormat() {
+ return _pattern;
+ }
+
+ /**
+ * This method has been deprecated in favour of setPattern().
+ * @deprecated Use setPattern().
+ */
+ public synchronized void setOutputFormat(String pattern) {
+ _pattern = pattern;
+ configure();
+ }
+
+ public synchronized DateFormat getDateFormatInstance() {
+ return _dateFormat;
+ }
+
+ public synchronized void setDateFormatInstance(DateFormat dateFormat) {
+ _dateFormat = dateFormat;
+ // No reconfiguration necessary!
+ }
+
+ public String format(Date date) {
+ return getDateFormatInstance().format(date);
+ }
+
+ public String format(Date date, String pattern) {
+ DateFormat formatter = null;
+ formatter = getDateFormatInstance();
+ if (formatter instanceof SimpleDateFormat) {
+ formatter = (SimpleDateFormat) (formatter.clone());
+ ((SimpleDateFormat) formatter).applyPattern(pattern);
+ }
+ return formatter.format(date);
+ }
+
+ /**
+ * @throws java.text.ParseException
+ */
+ public Date parse(String date) throws ParseException {
+ return getDateFormatInstance().parse(date);
+ }
+
+ /**
+ * @throws java.text.ParseException
+ */
+ public Date parse(String date, String pattern) throws ParseException {
+ DateFormat formatter = null;
+ formatter = getDateFormatInstance();
+ if (formatter instanceof SimpleDateFormat) {
+ formatter = (SimpleDateFormat) (formatter.clone());
+ ((SimpleDateFormat) formatter).applyPattern(pattern);
+ }
+ return formatter.parse(date);
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+ private synchronized void configure() {
+ _dateFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.FULL,
+ DateFormat.FULL,
+ getLocale());
+ _dateFormat.setTimeZone(getTimeZone());
+
+ if (_pattern != null) {
+ ((SimpleDateFormat) _dateFormat).applyPattern(_pattern);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/util/LogFileParser.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/LogFileParser.java
new file mode 100644
index 0000000000..656d4b6a6a
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/LogFileParser.java
@@ -0,0 +1,301 @@
+/*
+ * 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.lf5.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.swing.SwingUtilities;
+
+import org.apache.log4j.lf5.Log4JLogRecord;
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.LogLevelFormatException;
+import org.apache.log4j.lf5.LogRecord;
+import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
+import org.apache.log4j.lf5.viewer.LogFactor5ErrorDialog;
+import org.apache.log4j.lf5.viewer.LogFactor5LoadingDialog;
+
+/**
+ * Provides utility methods for input and output streams.
+ *
+ * @author Brad Marlborough
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogFileParser implements Runnable {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+ public static final String RECORD_DELIMITER = "[slf5s.start]";
+ public static final String ATTRIBUTE_DELIMITER = "[slf5s.";
+ public static final String DATE_DELIMITER = ATTRIBUTE_DELIMITER + "DATE]";
+ public static final String THREAD_DELIMITER = ATTRIBUTE_DELIMITER + "THREAD]";
+ public static final String CATEGORY_DELIMITER = ATTRIBUTE_DELIMITER + "CATEGORY]";
+ public static final String LOCATION_DELIMITER = ATTRIBUTE_DELIMITER + "LOCATION]";
+ public static final String MESSAGE_DELIMITER = ATTRIBUTE_DELIMITER + "MESSAGE]";
+ public static final String PRIORITY_DELIMITER = ATTRIBUTE_DELIMITER + "PRIORITY]";
+ public static final String NDC_DELIMITER = ATTRIBUTE_DELIMITER + "NDC]";
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private static SimpleDateFormat _sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss,S");
+ private LogBrokerMonitor _monitor;
+ LogFactor5LoadingDialog _loadDialog;
+ private InputStream _in = null;
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public LogFileParser(File file) throws IOException,
+ FileNotFoundException {
+ this(new FileInputStream(file));
+ }
+
+ public LogFileParser(InputStream stream) throws IOException {
+ _in = stream;
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Starts a new thread to parse the log file and create a LogRecord.
+ * See run().
+ * @param monitor LogBrokerMonitor
+ */
+ public void parse(LogBrokerMonitor monitor) throws RuntimeException {
+ _monitor = monitor;
+ Thread t = new Thread(this);
+ t.start();
+ }
+
+ /**
+ * Parses the file and creates new log records and adds the record
+ * to the monitor.
+ */
+ public void run() {
+
+ int index = 0;
+ int counter = 0;
+ LogRecord temp;
+ boolean isLogFile = false;
+
+ _loadDialog = new LogFactor5LoadingDialog(
+ _monitor.getBaseFrame(), "Loading file...");
+
+
+ try {
+ String logRecords = loadLogFile(_in);
+
+ while ((counter = logRecords.indexOf(RECORD_DELIMITER, index)) != -1) {
+ temp = createLogRecord(logRecords.substring(index, counter));
+ isLogFile = true;
+
+ if (temp != null) {
+ _monitor.addMessage(temp);
+ }
+
+ index = counter + RECORD_DELIMITER.length();
+ }
+
+ if (index < logRecords.length() && isLogFile) {
+ temp = createLogRecord(logRecords.substring(index));
+
+ if (temp != null) {
+ _monitor.addMessage(temp);
+ }
+ }
+
+ if (isLogFile == false) {
+ throw new RuntimeException("Invalid log file format");
+ }
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ destroyDialog();
+ }
+ });
+
+ } catch (RuntimeException e) {
+ destroyDialog();
+ displayError("Error - Invalid log file format.\nPlease see documentation"
+ + " on how to load log files.");
+ } catch (IOException e) {
+ destroyDialog();
+ displayError("Error - Unable to load log file!");
+ }
+
+ _in = null;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ protected void displayError(String message) {
+ LogFactor5ErrorDialog error = new LogFactor5ErrorDialog(
+ _monitor.getBaseFrame(), message);
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+ private void destroyDialog() {
+ _loadDialog.hide();
+ _loadDialog.dispose();
+ }
+
+ /**
+ * Loads a log file from a web server into the LogFactor5 GUI.
+ */
+ private String loadLogFile(InputStream stream) throws IOException {
+ BufferedInputStream br = new BufferedInputStream(stream);
+
+ int count = 0;
+ int size = br.available();
+
+ StringBuffer sb = null;
+ if (size > 0) {
+ sb = new StringBuffer(size);
+ } else {
+ sb = new StringBuffer(1024);
+ }
+
+ while ((count = br.read()) != -1) {
+ sb.append((char) count);
+ }
+
+ br.close();
+ br = null;
+ return sb.toString();
+
+ }
+
+ private String parseAttribute(String name, String record) {
+
+ int index = record.indexOf(name);
+
+ if (index == -1) {
+ return null;
+ }
+
+ return getAttribute(index, record);
+ }
+
+ private long parseDate(String record) {
+ try {
+ String s = parseAttribute(DATE_DELIMITER, record);
+
+ if (s == null) {
+ return 0;
+ }
+
+ Date d = _sdf.parse(s);
+
+ return d.getTime();
+ } catch (ParseException e) {
+ return 0;
+ }
+ }
+
+ private LogLevel parsePriority(String record) {
+ String temp = parseAttribute(PRIORITY_DELIMITER, record);
+
+ if (temp != null) {
+ try {
+ return LogLevel.valueOf(temp);
+ } catch (LogLevelFormatException e) {
+ return LogLevel.DEBUG;
+ }
+
+ }
+
+ return LogLevel.DEBUG;
+ }
+
+ private String parseThread(String record) {
+ return parseAttribute(THREAD_DELIMITER, record);
+ }
+
+ private String parseCategory(String record) {
+ return parseAttribute(CATEGORY_DELIMITER, record);
+ }
+
+ private String parseLocation(String record) {
+ return parseAttribute(LOCATION_DELIMITER, record);
+ }
+
+ private String parseMessage(String record) {
+ return parseAttribute(MESSAGE_DELIMITER, record);
+ }
+
+ private String parseNDC(String record) {
+ return parseAttribute(NDC_DELIMITER, record);
+ }
+
+ private String parseThrowable(String record) {
+ return getAttribute(record.length(), record);
+ }
+
+ private LogRecord createLogRecord(String record) {
+ if (record == null || record.trim().length() == 0) {
+ return null;
+ }
+
+ LogRecord lr = new Log4JLogRecord();
+ lr.setMillis(parseDate(record));
+ lr.setLevel(parsePriority(record));
+ lr.setCategory(parseCategory(record));
+ lr.setLocation(parseLocation(record));
+ lr.setThreadDescription(parseThread(record));
+ lr.setNDC(parseNDC(record));
+ lr.setMessage(parseMessage(record));
+ lr.setThrownStackTrace(parseThrowable(record));
+
+ return lr;
+ }
+
+
+ private String getAttribute(int index, String record) {
+ int start = record.lastIndexOf(ATTRIBUTE_DELIMITER, index - 1);
+
+ if (start == -1) {
+ return record.substring(0, index);
+ }
+
+ start = record.indexOf("]", start);
+
+ return record.substring(start + 1, index).trim();
+ }
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/util/LogMonitorAdapter.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/LogMonitorAdapter.java
new file mode 100644
index 0000000000..6ba927cb5f
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/LogMonitorAdapter.java
@@ -0,0 +1,289 @@
+/*
+ * 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.lf5.util;
+
+import java.awt.Toolkit;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.LogRecord;
+import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
+
+/**
+ * LogMonitorAdapter facilitates the usage of the LogMonitor
+ *
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogMonitorAdapter {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+ public static final int LOG4J_LOG_LEVELS = 0;
+ public static final int JDK14_LOG_LEVELS = 1;
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private LogBrokerMonitor _logMonitor;
+ private LogLevel _defaultLevel = null;
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ private LogMonitorAdapter(List userDefinedLevels) {
+ super();
+ // set the default level to be the first entry in the list
+ _defaultLevel = (LogLevel) userDefinedLevels.get(0);
+ _logMonitor = new LogBrokerMonitor(userDefinedLevels);
+
+ _logMonitor.setFrameSize(getDefaultMonitorWidth(),
+ getDefaultMonitorHeight());
+ _logMonitor.setFontSize(12);
+ _logMonitor.show();
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ /**
+ * Creates an instance of LogMonitorAdapter using the
+ * log levels inticated by the parameter. Log4J and JDK1.4 both have default
+ * LogLevels which are set but these levels can be overriden.
+ *
+ * @param loglevels An integer representing either Log4J or JDK1.4 logging levels
+ * @return LogMonitorAdapter
+ */
+ public static LogMonitorAdapter newInstance(int loglevels) {
+ LogMonitorAdapter adapter;
+ if (loglevels == JDK14_LOG_LEVELS) {
+ adapter = newInstance(LogLevel.getJdk14Levels());
+ adapter.setDefaultLevel(LogLevel.FINEST);
+ adapter.setSevereLevel(LogLevel.SEVERE);
+ } else {
+ adapter = newInstance(LogLevel.getLog4JLevels());
+ adapter.setDefaultLevel(LogLevel.DEBUG);
+ adapter.setSevereLevel(LogLevel.FATAL);
+ }
+ return adapter;
+ }
+
+ /**
+ *
Creates an instance of LogMonitorAdapter using the specified LogLevels.
+ * The first LogLevel in the array is used as the default LogLevel unless
+ * changed using the setDefaultLevel method.
+ *
+ * @param userDefined An array of user defined LogLevel objects.
+ * @return LogMonitorAdapter
+ */
+ public static LogMonitorAdapter newInstance(LogLevel[] userDefined) {
+ if (userDefined == null) {
+ return null;
+ }
+ return newInstance(Arrays.asList(userDefined));
+ }
+
+ /**
+ *
Creates an instance of LogMonitorAdapter using the specified LogLevels.
+ * The first LogLevel in the List is used as the default LogLevel unless
+ * changed using the setDefaultLevel method.
+ *
+ * @param userDefinedLevels A list of user defined LogLevel objects.
+ * @return LogMonitorAdapter
+ */
+ public static LogMonitorAdapter newInstance(List userDefinedLevels) {
+ return new LogMonitorAdapter(userDefinedLevels);
+ }
+
+ /**
+ *
Adds a LogRecord to the LogMonitor.
+ *
+ * @param record The LogRecord object to be logged in the logging monitor.
+ */
+ public void addMessage(LogRecord record) {
+ _logMonitor.addMessage(record);
+ }
+
+ /**
+ *
Set the maximum number of records to be displayed in the monitor
+ *
+ * @param maxNumberOfRecords
+ */
+ public void setMaxNumberOfRecords(int maxNumberOfRecords) {
+ _logMonitor.setMaxNumberOfLogRecords(maxNumberOfRecords);
+ }
+
+ /**
+ *
Set the default log level to be used when logging messages without
+ * specifying a LogLevel.
+ *
+ * @param level
+ */
+ public void setDefaultLevel(LogLevel level) {
+ _defaultLevel = level;
+ }
+
+ /**
+ *
Gets the default LogLevel for the Adapter.
+ *
+ * @return LogLevel
+ */
+ public LogLevel getDefaultLevel() {
+ return _defaultLevel;
+ }
+
+ /**
+ *
Sets the Severe LogLevel.
+ *
+ * @param level
+ */
+ public void setSevereLevel(LogLevel level) {
+ AdapterLogRecord.setSevereLevel(level);
+ }
+
+ /**
+ * Gets the current Severe LogLevel
+ *
+ * @return LogLevel
+ */
+ public LogLevel getSevereLevel() {
+ return AdapterLogRecord.getSevereLevel();
+ }
+
+ /**
+ *
Log a complete message to the Monitor.
+ *
+ * @param category The category to be used
+ * @param level The log level to apply to the message
+ * @param message The message
+ * @param t The throwable content of the message
+ * @param NDC The NDC really only applies to Log4J and the parameter can
+ * usually be ignored.
+ */
+ public void log(String category, LogLevel level, String message,
+ Throwable t, String NDC) {
+ AdapterLogRecord record = new AdapterLogRecord();
+ record.setCategory(category);
+ record.setMessage(message);
+ record.setNDC(NDC);
+ record.setThrown(t);
+
+ if (level == null) {
+ record.setLevel(getDefaultLevel());
+ } else {
+ record.setLevel(level);
+ }
+
+ addMessage(record);
+ }
+
+ /**
+ *
Log a message to the Monitor and use the default LogLevel.
+ *
+ * @param category The category to be used
+ * @param message The message
+ */
+ public void log(String category, String message) {
+ log(category, null, message);
+ }
+
+ /**
+ *
Log a message to the Monitor.
+ *
+ * @param category The category to be used
+ * @param level The log level to apply to the message
+ * @param message The message
+ * @param NDC
+ */
+ public void log(String category, LogLevel level, String message, String NDC) {
+ log(category, level, message, null, NDC);
+ }
+
+ /**
+ *
Log a message to the Monitor.
+ *
+ * @param category The category to be used
+ * @param level The log level to apply to the message
+ * @param message The message
+ * @param t The throwable content of the message
+ */
+ public void log(String category, LogLevel level, String message,
+ Throwable t) {
+ log(category, level, message, t, null);
+ }
+
+ /**
+ *
Log a message to the Monitor.
+ *
+ * @param category The category to be used
+ * @param level The log level to apply to the message
+ * @param message The message
+ */
+ public void log(String category, LogLevel level, String message) {
+ log(category, level, message, null, null);
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ /**
+ * @return the screen width from Toolkit.getScreenSize()
+ * if possible, otherwise returns 800
+ * @see java.awt.Toolkit
+ */
+ protected static int getScreenWidth() {
+ try {
+ return Toolkit.getDefaultToolkit().getScreenSize().width;
+ } catch (Throwable t) {
+ return 800;
+ }
+ }
+
+ /**
+ * @return the screen height from Toolkit.getScreenSize()
+ * if possible, otherwise returns 600
+ * @see java.awt.Toolkit
+ */
+ protected static int getScreenHeight() {
+ try {
+ return Toolkit.getDefaultToolkit().getScreenSize().height;
+ } catch (Throwable t) {
+ return 600;
+ }
+ }
+
+ protected static int getDefaultMonitorWidth() {
+ return (3 * getScreenWidth()) / 4;
+ }
+
+ protected static int getDefaultMonitorHeight() {
+ return (3 * getScreenHeight()) / 4;
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/util/Resource.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/Resource.java
new file mode 100644
index 0000000000..66293cfcab
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/Resource.java
@@ -0,0 +1,156 @@
+/*
+ * 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.lf5.util;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+/**
+ * Resource encapsulates access to Resources via the Classloader.
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class Resource {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected String _name;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Default, no argument constructor.
+ */
+ public Resource() {
+ super();
+ }
+
+ /**
+ * Construct a Resource given a name.
+ *
+ * @see #setName(String)
+ */
+ public Resource(String name) {
+ _name = name;
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Set the name of the resource.
+ *
+ * A resource is some data (images, audio, text, etc) that can be accessed
+ * by class code in a way that is independent of the location of the code.
+ *
+ *
+ * The name of a resource is a "/"-separated path name that identifies
+ * the resource.
+ *
+ *
+ * @see #getName()
+ */
+ public void setName(String name) {
+ _name = name;
+ }
+
+ /**
+ * Get the name of the resource. Set setName() for a description of
+ * a resource.
+ *
+ * @see #setName
+ */
+ public String getName() {
+ return (_name);
+ }
+
+ /**
+ * Get the InputStream for this Resource. Uses the classloader
+ * from this Resource.
+ *
+ * @see #getInputStreamReader
+ * @see ResourceUtils
+ */
+ public InputStream getInputStream() {
+ InputStream in = ResourceUtils.getResourceAsStream(this, this);
+
+ return (in);
+ }
+
+ /**
+ * Get the InputStreamReader for this Resource. Uses the classloader from
+ * this Resource.
+ *
+ * @see #getInputStream
+ * @see ResourceUtils
+ */
+ public InputStreamReader getInputStreamReader() {
+ InputStream in = ResourceUtils.getResourceAsStream(this, this);
+
+ if (in == null) {
+ return null;
+ }
+
+ InputStreamReader reader = new InputStreamReader(in);
+
+ return reader;
+ }
+
+ /**
+ * Get the URL of the Resource. Uses the classloader from this Resource.
+ *
+ * @see ResourceUtils
+ */
+ public URL getURL() {
+ return (ResourceUtils.getResourceAsURL(this, this));
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/util/ResourceUtils.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/ResourceUtils.java
new file mode 100644
index 0000000000..5f022b6729
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/ResourceUtils.java
@@ -0,0 +1,133 @@
+/*
+ * 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.lf5.util;
+
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * ResourceUtils. Provide a set of convenience methods for working with
+ * Resources.
+ *
+ * @see org.apache.log4j.lf5.util.Resource
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class ResourceUtils {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Get the InputStream for this resource. Note: to convert an InputStream
+ * into an InputReader, use: new InputStreamReader(InputStream).
+ *
+ * @param object The object to grab the Classloader from.
+ * This parameter is quite important from a
+ * visibility of resources standpoint as the
+ * hierarchy of Classloaders plays a role.
+ *
+ * @param resource The resource to load.
+ *
+ * @return If the Resource was found, the InputStream, otherwise null.
+ *
+ * @see Resource
+ * @see #getResourceAsURL(Object,Resource)
+ * @see InputStream
+ */
+ public static InputStream getResourceAsStream(Object object, Resource resource) {
+ ClassLoader loader = object.getClass().getClassLoader();
+
+ InputStream in = null;
+
+ if (loader != null) {
+ in = loader.getResourceAsStream(resource.getName());
+ } else {
+ in = ClassLoader.getSystemResourceAsStream(resource.getName());
+ }
+
+ return in;
+ }
+
+ /**
+ * Get the URL for this resource.
+ *
+ * @param object The object to grab the Classloader from.
+ * This parameter is quite important from a
+ * visibility of resources standpoint as the
+ * hierarchy of Classloaders plays a role.
+ *
+ * @param resource The resource to load.
+ *
+ * @return If the Resource was found, the URL, otherwise null.
+ *
+ * @see Resource
+ * @see #getResourceAsStream(Object,Resource)
+ */
+ public static URL getResourceAsURL(Object object, Resource resource) {
+ ClassLoader loader = object.getClass().getClassLoader();
+
+ URL url = null;
+
+ if (loader != null) {
+ url = loader.getResource(resource.getName());
+ } else {
+ url = ClassLoader.getSystemResource(resource.getName());
+ }
+
+ return (url);
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/util/StreamUtils.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/StreamUtils.java
new file mode 100644
index 0000000000..183f9aad92
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/util/StreamUtils.java
@@ -0,0 +1,124 @@
+/*
+ * 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.lf5.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Provides utility methods for input and output streams.
+ *
+ * @author Richard Wan
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public abstract class StreamUtils {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Default value is 2048.
+ */
+ public static final int DEFAULT_BUFFER_SIZE = 2048;
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Copies information from the input stream to the output stream using
+ * a default buffer size of 2048 bytes.
+ * @throws java.io.IOException
+ */
+ public static void copy(InputStream input, OutputStream output)
+ throws IOException {
+ copy(input, output, DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * Copies information from the input stream to the output stream using
+ * the specified buffer size
+ * @throws java.io.IOException
+ */
+ public static void copy(InputStream input,
+ OutputStream output,
+ int bufferSize)
+ throws IOException {
+ byte[] buf = new byte[bufferSize];
+ int bytesRead = input.read(buf);
+ while (bytesRead != -1) {
+ output.write(buf, 0, bytesRead);
+ bytesRead = input.read(buf);
+ }
+ output.flush();
+ }
+
+ /**
+ * Copies information between specified streams and then closes
+ * both of the streams.
+ * @throws java.io.IOException
+ */
+ public static void copyThenClose(InputStream input, OutputStream output)
+ throws IOException {
+ copy(input, output);
+ input.close();
+ output.close();
+ }
+
+ /**
+ * @return a byte[] containing the information contained in the
+ * specified InputStream.
+ * @throws java.io.IOException
+ */
+ public static byte[] getBytes(InputStream input)
+ throws IOException {
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ copy(input, result);
+ result.close();
+ return result.toByteArray();
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/FilteredLogTableModel.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/FilteredLogTableModel.java
new file mode 100644
index 0000000000..2c68180975
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/FilteredLogTableModel.java
@@ -0,0 +1,263 @@
+/*
+ * 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.lf5.viewer;
+
+import org.apache.log4j.lf5.LogRecord;
+import org.apache.log4j.lf5.LogRecordFilter;
+import org.apache.log4j.lf5.PassingLogRecordFilter;
+
+import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * A TableModel for LogRecords which includes filtering support.
+ *
+ * @author Richard Wan
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class FilteredLogTableModel
+ extends AbstractTableModel {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ protected LogRecordFilter _filter = new PassingLogRecordFilter();
+ protected List _allRecords = new ArrayList();
+ protected List _filteredRecords;
+ protected int _maxNumberOfLogRecords = 5000;
+ protected String[] _colNames = {"Date",
+ "Thread",
+ "Message #",
+ "Level",
+ "NDC",
+ "Category",
+ "Message",
+ "Location",
+ "Thrown"};
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public FilteredLogTableModel() {
+ super();
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public void setLogRecordFilter(LogRecordFilter filter) {
+ _filter = filter;
+ }
+
+ public LogRecordFilter getLogRecordFilter() {
+ return _filter;
+ }
+
+ public String getColumnName(int i) {
+ return _colNames[i];
+ }
+
+ public int getColumnCount() {
+ return _colNames.length;
+ }
+
+ public int getRowCount() {
+ return getFilteredRecords().size();
+ }
+
+ public int getTotalRowCount() {
+ return _allRecords.size();
+ }
+
+ public Object getValueAt(int row, int col) {
+ LogRecord record = getFilteredRecord(row);
+ return getColumn(col, record);
+ }
+
+ public void setMaxNumberOfLogRecords(int maxNumRecords) {
+ if (maxNumRecords > 0) {
+ _maxNumberOfLogRecords = maxNumRecords;
+ }
+
+ }
+
+ public synchronized boolean addLogRecord(LogRecord record) {
+
+ _allRecords.add(record);
+
+ if (_filter.passes(record) == false) {
+ return false;
+ }
+ getFilteredRecords().add(record);
+ fireTableRowsInserted(getRowCount(), getRowCount());
+ trimRecords();
+ return true;
+ }
+
+ /**
+ * Forces the LogTableModel to requery its filters to determine
+ * which records to display.
+ */
+ public synchronized void refresh() {
+ _filteredRecords = createFilteredRecordsList();
+ fireTableDataChanged();
+ }
+
+ public synchronized void fastRefresh() {
+ _filteredRecords.remove(0);
+ fireTableRowsDeleted(0, 0);
+ }
+
+
+ /**
+ * Clears all records from the LogTableModel
+ */
+ public synchronized void clear() {
+ _allRecords.clear();
+ _filteredRecords.clear();
+ fireTableDataChanged();
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected List getFilteredRecords() {
+ if (_filteredRecords == null) {
+ refresh();
+ }
+ return _filteredRecords;
+ }
+
+ protected List createFilteredRecordsList() {
+ List result = new ArrayList();
+ Iterator records = _allRecords.iterator();
+ LogRecord current;
+ while (records.hasNext()) {
+ current = (LogRecord) records.next();
+ if (_filter.passes(current)) {
+ result.add(current);
+ }
+ }
+ return result;
+ }
+
+ protected LogRecord getFilteredRecord(int row) {
+ List records = getFilteredRecords();
+ int size = records.size();
+ if (row < size) {
+ return (LogRecord) records.get(row);
+ }
+ // a minor problem has happened. JTable has asked for
+ // a row outside the bounds, because the size of
+ // _filteredRecords has changed while it was looping.
+ // return the last row.
+ return (LogRecord) records.get(size - 1);
+
+ }
+
+ protected Object getColumn(int col, LogRecord lr) {
+ if (lr == null) {
+ return "NULL Column";
+ }
+ String date = new Date(lr.getMillis()).toString();
+ switch (col) {
+ case 0:
+ return date + " (" + lr.getMillis() + ")";
+ case 1:
+ return lr.getThreadDescription();
+ case 2:
+ return new Long(lr.getSequenceNumber());
+ case 3:
+ return lr.getLevel();
+ case 4:
+ return lr.getNDC();
+ case 5:
+ return lr.getCategory();
+ case 6:
+ return lr.getMessage();
+ case 7:
+ return lr.getLocation();
+ case 8:
+ return lr.getThrownStackTrace();
+ default:
+ String message = "The column number " + col + "must be between 0 and 8";
+ throw new IllegalArgumentException(message);
+ }
+ }
+
+ // We don't want the amount of rows to grow without bound,
+ // leading to a out-of-memory-exception. Especially not good
+ // in a production environment :)
+
+ // This method & clearLogRecords() are synchronized so we don't
+ // delete rows that don't exist.
+ protected void trimRecords() {
+ if (needsTrimming()) {
+ trimOldestRecords();
+ }
+ }
+
+ protected boolean needsTrimming() {
+ return (_allRecords.size() > _maxNumberOfLogRecords);
+ }
+
+ protected void trimOldestRecords() {
+ synchronized (_allRecords) {
+ int trim = numberOfRecordsToTrim();
+ if (trim > 1) {
+ List oldRecords =
+ _allRecords.subList(0, trim);
+ oldRecords.clear();
+ refresh();
+ } else {
+ _allRecords.remove(0);
+ fastRefresh();
+ }
+ }
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+ private int numberOfRecordsToTrim() {
+ return _allRecords.size() - _maxNumberOfLogRecords;
+ }
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LF5SwingUtils.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LF5SwingUtils.java
new file mode 100644
index 0000000000..ef29447ba7
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LF5SwingUtils.java
@@ -0,0 +1,153 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.Adjustable;
+
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.table.TableModel;
+
+/**
+ * Provides methods to accomplish common yet non-trivial tasks
+ * with Swing. Obvious implementations of these methods have been
+ * tried and failed.
+ *
+ * @author Richard Wan
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LF5SwingUtils {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Selects a the specified row in the specified JTable and scrolls
+ * the specified JScrollpane to the newly selected row. More importantly,
+ * the call to repaint() delayed long enough to have the table
+ * properly paint the newly selected row which may be offscre
+ * @param table should belong to the specified JScrollPane
+ */
+ public static void selectRow(int row, JTable table, JScrollPane pane) {
+ if (table == null || pane == null) {
+ return;
+ }
+ if (contains(row, table.getModel()) == false) {
+ return;
+ }
+ moveAdjustable(row * table.getRowHeight(), pane.getVerticalScrollBar());
+ selectRow(row, table.getSelectionModel());
+ // repaint must be done later because moveAdjustable
+ // posts requests to the swing thread which must execute before
+ // the repaint logic gets executed.
+ repaintLater(table);
+ }
+
+ /**
+ * Makes the specified Adjustable track if the view area expands and
+ * the specified Adjustable is located near the of the view.
+ */
+ public static void makeScrollBarTrack(Adjustable scrollBar) {
+ if (scrollBar == null) {
+ return;
+ }
+ scrollBar.addAdjustmentListener(new TrackingAdjustmentListener());
+ }
+
+ /**
+ * Makes the vertical scroll bar of the specified JScrollPane
+ * track if the view expands (e.g. if rows are added to an underlying
+ * table).
+ */
+ public static void makeVerticalScrollBarTrack(JScrollPane pane) {
+ if (pane == null) {
+ return;
+ }
+ makeScrollBarTrack(pane.getVerticalScrollBar());
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ protected static boolean contains(int row, TableModel model) {
+ if (model == null) {
+ return false;
+ }
+ if (row < 0) {
+ return false;
+ }
+ if (row >= model.getRowCount()) {
+ return false;
+ }
+ return true;
+ }
+
+ protected static void selectRow(int row, ListSelectionModel model) {
+ if (model == null) {
+ return;
+ }
+ model.setSelectionInterval(row, row);
+ }
+
+ protected static void moveAdjustable(int location, Adjustable scrollBar) {
+ if (scrollBar == null) {
+ return;
+ }
+ scrollBar.setValue(location);
+ }
+
+ /**
+ * Work around for JTable/viewport bug.
+ * @link http://developer.java.sun.com/developer/bugParade/bugs/4205145.html
+ */
+ protected static void repaintLater(final JComponent component) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ component.repaint();
+ }
+ });
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogBrokerMonitor.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogBrokerMonitor.java
new file mode 100644
index 0000000000..934ba17b55
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogBrokerMonitor.java
@@ -0,0 +1,1612 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.LogRecord;
+import org.apache.log4j.lf5.LogRecordFilter;
+import org.apache.log4j.lf5.util.DateFormatManager;
+import org.apache.log4j.lf5.util.LogFileParser;
+import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryExplorerTree;
+import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryPath;
+import org.apache.log4j.lf5.viewer.configure.ConfigurationManager;
+import org.apache.log4j.lf5.viewer.configure.MRUFileManager;
+
+/**
+ * LogBrokerMonitor
+ *.
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ * @author Brad Marlborough
+ * @author Richard Wan
+ * @author Brent Sprecher
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogBrokerMonitor {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ public static final String DETAILED_VIEW = "Detailed";
+// public static final String STANDARD_VIEW = "Standard";
+// public static final String COMPACT_VIEW = "Compact";
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected JFrame _logMonitorFrame;
+ protected int _logMonitorFrameWidth = 550;
+ protected int _logMonitorFrameHeight = 500;
+ protected LogTable _table;
+ protected CategoryExplorerTree _categoryExplorerTree;
+ protected String _searchText;
+ protected String _NDCTextFilter = "";
+ protected LogLevel _leastSevereDisplayedLogLevel = LogLevel.DEBUG;
+
+ protected JScrollPane _logTableScrollPane;
+ protected JLabel _statusLabel;
+ protected Object _lock = new Object();
+ protected JComboBox _fontSizeCombo;
+
+ protected int _fontSize = 10;
+ protected String _fontName = "Dialog";
+ protected String _currentView = DETAILED_VIEW;
+
+ protected boolean _loadSystemFonts = false;
+ protected boolean _trackTableScrollPane = true;
+ protected Dimension _lastTableViewportSize;
+ protected boolean _callSystemExitOnClose = false;
+ protected List _displayedLogBrokerProperties = new Vector();
+
+ protected Map _logLevelMenuItems = new HashMap();
+ protected Map _logTableColumnMenuItems = new HashMap();
+
+ protected List _levels = null;
+ protected List _columns = null;
+ protected boolean _isDisposed = false;
+
+ protected ConfigurationManager _configurationManager = null;
+ protected MRUFileManager _mruFileManager = null;
+ protected File _fileLocation = null;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Construct a LogBrokerMonitor.
+ */
+ public LogBrokerMonitor(List logLevels) {
+
+ _levels = logLevels;
+ _columns = LogTableColumn.getLogTableColumns();
+ // This allows us to use the LogBroker in command line tools and
+ // have the option for it to shutdown.
+
+ String callSystemExitOnClose =
+ System.getProperty("monitor.exit");
+ if (callSystemExitOnClose == null) {
+ callSystemExitOnClose = "false";
+ }
+ callSystemExitOnClose = callSystemExitOnClose.trim().toLowerCase();
+
+ if (callSystemExitOnClose.equals("true")) {
+ _callSystemExitOnClose = true;
+ }
+
+ initComponents();
+
+
+ _logMonitorFrame.addWindowListener(
+ new LogBrokerMonitorWindowAdaptor(this));
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Show the frame for the LogBrokerMonitor. Dispatched to the
+ * swing thread.
+ */
+ public void show(final int delay) {
+ if (_logMonitorFrame.isVisible()) {
+ return;
+ }
+ // This request is very low priority, let other threads execute first.
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ Thread.yield();
+ pause(delay);
+ _logMonitorFrame.setVisible(true);
+ }
+ });
+ }
+
+ public void show() {
+ show(0);
+ }
+
+ /**
+ * Dispose of the frame for the LogBrokerMonitor.
+ */
+ public void dispose() {
+ _logMonitorFrame.dispose();
+ _isDisposed = true;
+
+ if (_callSystemExitOnClose == true) {
+ System.exit(0);
+ }
+ }
+
+ /**
+ * Hide the frame for the LogBrokerMonitor.
+ */
+ public void hide() {
+ _logMonitorFrame.setVisible(false);
+ }
+
+ /**
+ * Get the DateFormatManager for formatting dates.
+ */
+ public DateFormatManager getDateFormatManager() {
+ return _table.getDateFormatManager();
+ }
+
+ /**
+ * Set the date format manager for formatting dates.
+ */
+ public void setDateFormatManager(DateFormatManager dfm) {
+ _table.setDateFormatManager(dfm);
+ }
+
+ /**
+ * Get the value of whether or not System.exit() will be called
+ * when the LogBrokerMonitor is closed.
+ */
+ public boolean getCallSystemExitOnClose() {
+ return _callSystemExitOnClose;
+ }
+
+ /**
+ * Set the value of whether or not System.exit() will be called
+ * when the LogBrokerMonitor is closed.
+ */
+ public void setCallSystemExitOnClose(boolean callSystemExitOnClose) {
+ _callSystemExitOnClose = callSystemExitOnClose;
+ }
+
+ /**
+ * Add a log record message to be displayed in the LogTable.
+ * This method is thread-safe as it posts requests to the SwingThread
+ * rather than processing directly.
+ */
+ public void addMessage(final LogRecord lr) {
+ if (_isDisposed == true) {
+ // If the frame has been disposed of, do not log any more
+ // messages.
+ return;
+ }
+
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ _categoryExplorerTree.getExplorerModel().addLogRecord(lr);
+ _table.getFilteredLogTableModel().addLogRecord(lr); // update table
+ updateStatusLabel(); // show updated counts
+ }
+ });
+ }
+
+ public void setMaxNumberOfLogRecords(int maxNumberOfLogRecords) {
+ _table.getFilteredLogTableModel().setMaxNumberOfLogRecords(maxNumberOfLogRecords);
+ }
+
+ public JFrame getBaseFrame() {
+ return _logMonitorFrame;
+ }
+
+ public void setTitle(String title) {
+ _logMonitorFrame.setTitle(title + " - LogFactor5");
+ }
+
+ public void setFrameSize(int width, int height) {
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ if (0 < width && width < screen.width) {
+ _logMonitorFrameWidth = width;
+ }
+ if (0 < height && height < screen.height) {
+ _logMonitorFrameHeight = height;
+ }
+ updateFrameSize();
+ }
+
+ public void setFontSize(int fontSize) {
+ changeFontSizeCombo(_fontSizeCombo, fontSize);
+ // setFontSizeSilently(actualFontSize); - changeFontSizeCombo fires event
+ // refreshDetailTextArea();
+ }
+
+ public void addDisplayedProperty(Object messageLine) {
+ _displayedLogBrokerProperties.add(messageLine);
+ }
+
+ public Map getLogLevelMenuItems() {
+ return _logLevelMenuItems;
+ }
+
+ public Map getLogTableColumnMenuItems() {
+ return _logTableColumnMenuItems;
+ }
+
+ public JCheckBoxMenuItem getTableColumnMenuItem(LogTableColumn column) {
+ return getLogTableColumnMenuItem(column);
+ }
+
+ public CategoryExplorerTree getCategoryExplorerTree() {
+ return _categoryExplorerTree;
+ }
+
+ // Added in version 1.2 - gets the value of the NDC text filter
+ // This value is set back to null each time the Monitor is initialized.
+ public String getNDCTextFilter() {
+ return _NDCTextFilter;
+ }
+
+ // Added in version 1.2 - sets the NDC Filter based on
+ // a String passed in by the user. This value is persisted
+ // in the XML Configuration file.
+ public void setNDCLogRecordFilter(String textFilter) {
+ _table.getFilteredLogTableModel().
+ setLogRecordFilter(createNDCLogRecordFilter(textFilter));
+ }
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected void setSearchText(String text) {
+ _searchText = text;
+ }
+
+ // Added in version 1.2 - Sets the text filter for the NDC
+ protected void setNDCTextFilter(String text) {
+ // if no value is set, set it to a blank string
+ // otherwise use the value provided
+ if (text == null) {
+ _NDCTextFilter = "";
+ } else {
+ _NDCTextFilter = text;
+ }
+ }
+
+ // Added in version 1.2 - Uses a different filter that sorts
+ // based on an NDC string passed in by the user. If the string
+ // is null or is an empty string, we do nothing.
+ protected void sortByNDC() {
+ String text = _NDCTextFilter;
+ if (text == null || text.length() == 0) {
+ return;
+ }
+
+ // Use new NDC filter
+ _table.getFilteredLogTableModel().
+ setLogRecordFilter(createNDCLogRecordFilter(text));
+ }
+
+ protected void findSearchText() {
+ String text = _searchText;
+ if (text == null || text.length() == 0) {
+ return;
+ }
+ int startRow = getFirstSelectedRow();
+ int foundRow = findRecord(
+ startRow,
+ text,
+ _table.getFilteredLogTableModel().getFilteredRecords()
+ );
+ selectRow(foundRow);
+ }
+
+ protected int getFirstSelectedRow() {
+ return _table.getSelectionModel().getMinSelectionIndex();
+ }
+
+ protected void selectRow(int foundRow) {
+ if (foundRow == -1) {
+ String message = _searchText + " not found.";
+ JOptionPane.showMessageDialog(
+ _logMonitorFrame,
+ message,
+ "Text not found",
+ JOptionPane.INFORMATION_MESSAGE
+ );
+ return;
+ }
+ LF5SwingUtils.selectRow(foundRow, _table, _logTableScrollPane);
+ }
+
+ protected int findRecord(
+ int startRow,
+ String searchText,
+ List records
+ ) {
+ if (startRow < 0) {
+ startRow = 0; // start at first element if no rows are selected
+ } else {
+ startRow++; // start after the first selected row
+ }
+ int len = records.size();
+
+ for (int i = startRow; i < len; i++) {
+ if (matches((LogRecord) records.get(i), searchText)) {
+ return i; // found a record
+ }
+ }
+ // wrap around to beginning if when we reach the end with no match
+ len = startRow;
+ for (int i = 0; i < len; i++) {
+ if (matches((LogRecord) records.get(i), searchText)) {
+ return i; // found a record
+ }
+ }
+ // nothing found
+ return -1;
+ }
+
+ /**
+ * Check to see if the any records contain the search string.
+ * Searching now supports NDC messages and date.
+ */
+ protected boolean matches(LogRecord record, String text) {
+ String message = record.getMessage();
+ String NDC = record.getNDC();
+
+ if (message == null && NDC == null || text == null) {
+ return false;
+ }
+ if (message.toLowerCase().indexOf(text.toLowerCase()) == -1 &&
+ NDC.toLowerCase().indexOf(text.toLowerCase()) == -1) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * When the fontsize of a JTextArea is changed, the word-wrapped lines
+ * may become garbled. This method clears and resets the text of the
+ * text area.
+ */
+ protected void refresh(JTextArea textArea) {
+ String text = textArea.getText();
+ textArea.setText("");
+ textArea.setText(text);
+ }
+
+ protected void refreshDetailTextArea() {
+ refresh(_table._detailTextArea);
+ }
+
+ protected void clearDetailTextArea() {
+ _table._detailTextArea.setText("");
+ }
+
+ /**
+ * Changes the font selection in the combo box and returns the
+ * size actually selected.
+ * @return -1 if unable to select an appropriate font
+ */
+ protected int changeFontSizeCombo(JComboBox box, int requestedSize) {
+ int len = box.getItemCount();
+ int currentValue;
+ Object currentObject;
+ Object selectedObject = box.getItemAt(0);
+ int selectedValue = Integer.parseInt(String.valueOf(selectedObject));
+ for (int i = 0; i < len; i++) {
+ currentObject = box.getItemAt(i);
+ currentValue = Integer.parseInt(String.valueOf(currentObject));
+ if (selectedValue < currentValue && currentValue <= requestedSize) {
+ selectedValue = currentValue;
+ selectedObject = currentObject;
+ }
+ }
+ box.setSelectedItem(selectedObject);
+ return selectedValue;
+ }
+
+ /**
+ * Does not update gui or cause any events to be fired.
+ */
+ protected void setFontSizeSilently(int fontSize) {
+ _fontSize = fontSize;
+ setFontSize(_table._detailTextArea, fontSize);
+ selectRow(0);
+ setFontSize(_table, fontSize);
+ }
+
+ protected void setFontSize(Component component, int fontSize) {
+ Font oldFont = component.getFont();
+ Font newFont =
+ new Font(oldFont.getFontName(), oldFont.getStyle(), fontSize);
+ component.setFont(newFont);
+ }
+
+ protected void updateFrameSize() {
+ _logMonitorFrame.setSize(_logMonitorFrameWidth, _logMonitorFrameHeight);
+ centerFrame(_logMonitorFrame);
+ }
+
+ protected void pause(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+
+ }
+ }
+
+ protected void initComponents() {
+ //
+ // Configure the Frame.
+ //
+ _logMonitorFrame = new JFrame("LogFactor5");
+
+ _logMonitorFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+ String resource =
+ "/org/apache/log4j/lf5/viewer/images/lf5_small_icon.gif";
+ URL lf5IconURL = getClass().getResource(resource);
+
+ if (lf5IconURL != null) {
+ _logMonitorFrame.setIconImage(new ImageIcon(lf5IconURL).getImage());
+ }
+ updateFrameSize();
+
+ //
+ // Configure the LogTable.
+ //
+ JTextArea detailTA = createDetailTextArea();
+ JScrollPane detailTAScrollPane = new JScrollPane(detailTA);
+ _table = new LogTable(detailTA);
+ setView(_currentView, _table);
+ _table.setFont(new Font(_fontName, Font.PLAIN, _fontSize));
+ _logTableScrollPane = new JScrollPane(_table);
+
+ if (_trackTableScrollPane) {
+ _logTableScrollPane.getVerticalScrollBar().addAdjustmentListener(
+ new TrackingAdjustmentListener()
+ );
+ }
+
+
+ // Configure the SplitPane between the LogTable & DetailTextArea
+ //
+
+ JSplitPane tableViewerSplitPane = new JSplitPane();
+ tableViewerSplitPane.setOneTouchExpandable(true);
+ tableViewerSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
+ tableViewerSplitPane.setLeftComponent(_logTableScrollPane);
+ tableViewerSplitPane.setRightComponent(detailTAScrollPane);
+ // Make sure to do this last..
+ //tableViewerSplitPane.setDividerLocation(1.0); Doesn't work
+ //the same under 1.2.x & 1.3
+ // "350" is a magic number that provides the correct default
+ // behaviour under 1.2.x & 1.3. For example, bumping this
+ // number to 400, causes the pane to be completely open in 1.2.x
+ // and closed in 1.3
+ tableViewerSplitPane.setDividerLocation(350);
+
+ //
+ // Configure the CategoryExplorer
+ //
+
+ _categoryExplorerTree = new CategoryExplorerTree();
+
+ _table.getFilteredLogTableModel().setLogRecordFilter(createLogRecordFilter());
+
+ JScrollPane categoryExplorerTreeScrollPane =
+ new JScrollPane(_categoryExplorerTree);
+ categoryExplorerTreeScrollPane.setPreferredSize(new Dimension(130, 400));
+
+ // Load most recently used file list
+ _mruFileManager = new MRUFileManager();
+
+ //
+ // Configure the SplitPane between the CategoryExplorer & (LogTable/Detail)
+ //
+
+ JSplitPane splitPane = new JSplitPane();
+ splitPane.setOneTouchExpandable(true);
+ splitPane.setRightComponent(tableViewerSplitPane);
+ splitPane.setLeftComponent(categoryExplorerTreeScrollPane);
+ // Do this last.
+ splitPane.setDividerLocation(130);
+ //
+ // Add the MenuBar, StatusArea, CategoryExplorer|LogTable to the
+ // LogMonitorFrame.
+ //
+ _logMonitorFrame.getRootPane().setJMenuBar(createMenuBar());
+ _logMonitorFrame.getContentPane().add(splitPane, BorderLayout.CENTER);
+ _logMonitorFrame.getContentPane().add(createToolBar(),
+ BorderLayout.NORTH);
+ _logMonitorFrame.getContentPane().add(createStatusArea(),
+ BorderLayout.SOUTH);
+
+ makeLogTableListenToCategoryExplorer();
+ addTableModelProperties();
+
+ //
+ // Configure ConfigurationManager
+ //
+ _configurationManager = new ConfigurationManager(this, _table);
+
+ }
+
+ protected LogRecordFilter createLogRecordFilter() {
+ LogRecordFilter result = new LogRecordFilter() {
+ public boolean passes(LogRecord record) {
+ CategoryPath path = new CategoryPath(record.getCategory());
+ return
+ getMenuItem(record.getLevel()).isSelected() &&
+ _categoryExplorerTree.getExplorerModel().isCategoryPathActive(path);
+ }
+ };
+ return result;
+ }
+
+ // Added in version 1.2 - Creates a new filter that sorts records based on
+ // an NDC string passed in by the user.
+ protected LogRecordFilter createNDCLogRecordFilter(String text) {
+ _NDCTextFilter = text;
+ LogRecordFilter result = new LogRecordFilter() {
+ public boolean passes(LogRecord record) {
+ String NDC = record.getNDC();
+ CategoryPath path = new CategoryPath(record.getCategory());
+ if (NDC == null || _NDCTextFilter == null) {
+ return false;
+ } else if (NDC.toLowerCase().indexOf(_NDCTextFilter.toLowerCase()) == -1) {
+ return false;
+ } else {
+ return getMenuItem(record.getLevel()).isSelected() &&
+ _categoryExplorerTree.getExplorerModel().isCategoryPathActive(path);
+ }
+ }
+ };
+
+ return result;
+ }
+
+
+ protected void updateStatusLabel() {
+ _statusLabel.setText(getRecordsDisplayedMessage());
+ }
+
+ protected String getRecordsDisplayedMessage() {
+ FilteredLogTableModel model = _table.getFilteredLogTableModel();
+ return getStatusText(model.getRowCount(), model.getTotalRowCount());
+ }
+
+ protected void addTableModelProperties() {
+ final FilteredLogTableModel model = _table.getFilteredLogTableModel();
+
+ addDisplayedProperty(new Object() {
+ public String toString() {
+ return getRecordsDisplayedMessage();
+ }
+ });
+ addDisplayedProperty(new Object() {
+ public String toString() {
+ return "Maximum number of displayed LogRecords: "
+ + model._maxNumberOfLogRecords;
+ }
+ });
+ }
+
+ protected String getStatusText(int displayedRows, int totalRows) {
+ StringBuffer result = new StringBuffer();
+ result.append("Displaying: ");
+ result.append(displayedRows);
+ result.append(" records out of a total of: ");
+ result.append(totalRows);
+ result.append(" records.");
+ return result.toString();
+ }
+
+ protected void makeLogTableListenToCategoryExplorer() {
+ ActionListener listener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _table.getFilteredLogTableModel().refresh();
+ updateStatusLabel();
+ }
+ };
+ _categoryExplorerTree.getExplorerModel().addActionListener(listener);
+ }
+
+ protected JPanel createStatusArea() {
+ JPanel statusArea = new JPanel();
+ JLabel status =
+ new JLabel("No log records to display.");
+ _statusLabel = status;
+ status.setHorizontalAlignment(JLabel.LEFT);
+
+ statusArea.setBorder(BorderFactory.createEtchedBorder());
+ statusArea.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ statusArea.add(status);
+
+ return (statusArea);
+ }
+
+ protected JTextArea createDetailTextArea() {
+ JTextArea detailTA = new JTextArea();
+ detailTA.setFont(new Font("Monospaced", Font.PLAIN, 14));
+ detailTA.setTabSize(3);
+ detailTA.setLineWrap(true);
+ detailTA.setWrapStyleWord(false);
+ return (detailTA);
+ }
+
+ protected JMenuBar createMenuBar() {
+ JMenuBar menuBar = new JMenuBar();
+ menuBar.add(createFileMenu());
+ menuBar.add(createEditMenu());
+ menuBar.add(createLogLevelMenu());
+ menuBar.add(createViewMenu());
+ menuBar.add(createConfigureMenu());
+ menuBar.add(createHelpMenu());
+
+ return (menuBar);
+ }
+
+ protected JMenu createLogLevelMenu() {
+ JMenu result = new JMenu("Log Level");
+ result.setMnemonic('l');
+ Iterator levels = getLogLevels();
+ while (levels.hasNext()) {
+ result.add(getMenuItem((LogLevel) levels.next()));
+ }
+
+ result.addSeparator();
+ result.add(createAllLogLevelsMenuItem());
+ result.add(createNoLogLevelsMenuItem());
+ result.addSeparator();
+ result.add(createLogLevelColorMenu());
+ result.add(createResetLogLevelColorMenuItem());
+
+ return result;
+ }
+
+ protected JMenuItem createAllLogLevelsMenuItem() {
+ JMenuItem result = new JMenuItem("Show all LogLevels");
+ result.setMnemonic('s');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ selectAllLogLevels(true);
+ _table.getFilteredLogTableModel().refresh();
+ updateStatusLabel();
+ }
+ });
+ return result;
+ }
+
+ protected JMenuItem createNoLogLevelsMenuItem() {
+ JMenuItem result = new JMenuItem("Hide all LogLevels");
+ result.setMnemonic('h');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ selectAllLogLevels(false);
+ _table.getFilteredLogTableModel().refresh();
+ updateStatusLabel();
+ }
+ });
+ return result;
+ }
+
+ protected JMenu createLogLevelColorMenu() {
+ JMenu colorMenu = new JMenu("Configure LogLevel Colors");
+ colorMenu.setMnemonic('c');
+ Iterator levels = getLogLevels();
+ while (levels.hasNext()) {
+ colorMenu.add(createSubMenuItem((LogLevel) levels.next()));
+ }
+
+ return colorMenu;
+ }
+
+ protected JMenuItem createResetLogLevelColorMenuItem() {
+ JMenuItem result = new JMenuItem("Reset LogLevel Colors");
+ result.setMnemonic('r');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ // reset the level colors in the map
+ LogLevel.resetLogLevelColorMap();
+
+ // refresh the table
+ _table.getFilteredLogTableModel().refresh();
+ }
+ });
+ return result;
+ }
+
+ protected void selectAllLogLevels(boolean selected) {
+ Iterator levels = getLogLevels();
+ while (levels.hasNext()) {
+ getMenuItem((LogLevel) levels.next()).setSelected(selected);
+ }
+ }
+
+ protected JCheckBoxMenuItem getMenuItem(LogLevel level) {
+ JCheckBoxMenuItem result = (JCheckBoxMenuItem) (_logLevelMenuItems.get(level));
+ if (result == null) {
+ result = createMenuItem(level);
+ _logLevelMenuItems.put(level, result);
+ }
+ return result;
+ }
+
+ protected JMenuItem createSubMenuItem(LogLevel level) {
+ final JMenuItem result = new JMenuItem(level.toString());
+ final LogLevel logLevel = level;
+ result.setMnemonic(level.toString().charAt(0));
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ showLogLevelColorChangeDialog(result, logLevel);
+ }
+ });
+
+ return result;
+
+ }
+
+ protected void showLogLevelColorChangeDialog(JMenuItem result, LogLevel level) {
+ JMenuItem menuItem = result;
+ Color newColor = JColorChooser.showDialog(
+ _logMonitorFrame,
+ "Choose LogLevel Color",
+ result.getForeground());
+
+ if (newColor != null) {
+ // set the color for the record
+ level.setLogLevelColorMap(level, newColor);
+ _table.getFilteredLogTableModel().refresh();
+ }
+
+ }
+
+ protected JCheckBoxMenuItem createMenuItem(LogLevel level) {
+ JCheckBoxMenuItem result = new JCheckBoxMenuItem(level.toString());
+ result.setSelected(true);
+ result.setMnemonic(level.toString().charAt(0));
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _table.getFilteredLogTableModel().refresh();
+ updateStatusLabel();
+ }
+ });
+ return result;
+ }
+
+ // view menu
+ protected JMenu createViewMenu() {
+ JMenu result = new JMenu("View");
+ result.setMnemonic('v');
+ Iterator columns = getLogTableColumns();
+ while (columns.hasNext()) {
+ result.add(getLogTableColumnMenuItem((LogTableColumn) columns.next()));
+ }
+
+ result.addSeparator();
+ result.add(createAllLogTableColumnsMenuItem());
+ result.add(createNoLogTableColumnsMenuItem());
+ return result;
+ }
+
+ protected JCheckBoxMenuItem getLogTableColumnMenuItem(LogTableColumn column) {
+ JCheckBoxMenuItem result = (JCheckBoxMenuItem) (_logTableColumnMenuItems.get(column));
+ if (result == null) {
+ result = createLogTableColumnMenuItem(column);
+ _logTableColumnMenuItems.put(column, result);
+ }
+ return result;
+ }
+
+ protected JCheckBoxMenuItem createLogTableColumnMenuItem(LogTableColumn column) {
+ JCheckBoxMenuItem result = new JCheckBoxMenuItem(column.toString());
+
+ result.setSelected(true);
+ result.setMnemonic(column.toString().charAt(0));
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ // update list of columns and reset the view
+ List selectedColumns = updateView();
+ _table.setView(selectedColumns);
+ }
+ });
+ return result;
+ }
+
+ protected List updateView() {
+ ArrayList updatedList = new ArrayList();
+ Iterator columnIterator = _columns.iterator();
+ while (columnIterator.hasNext()) {
+ LogTableColumn column = (LogTableColumn) columnIterator.next();
+ JCheckBoxMenuItem result = getLogTableColumnMenuItem(column);
+ // check and see if the checkbox is checked
+ if (result.isSelected()) {
+ updatedList.add(column);
+ }
+ }
+
+ return updatedList;
+ }
+
+ protected JMenuItem createAllLogTableColumnsMenuItem() {
+ JMenuItem result = new JMenuItem("Show all Columns");
+ result.setMnemonic('s');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ selectAllLogTableColumns(true);
+ // update list of columns and reset the view
+ List selectedColumns = updateView();
+ _table.setView(selectedColumns);
+ }
+ });
+ return result;
+ }
+
+ protected JMenuItem createNoLogTableColumnsMenuItem() {
+ JMenuItem result = new JMenuItem("Hide all Columns");
+ result.setMnemonic('h');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ selectAllLogTableColumns(false);
+ // update list of columns and reset the view
+ List selectedColumns = updateView();
+ _table.setView(selectedColumns);
+ }
+ });
+ return result;
+ }
+
+ protected void selectAllLogTableColumns(boolean selected) {
+ Iterator columns = getLogTableColumns();
+ while (columns.hasNext()) {
+ getLogTableColumnMenuItem((LogTableColumn) columns.next()).setSelected(selected);
+ }
+ }
+
+ protected JMenu createFileMenu() {
+ JMenu fileMenu = new JMenu("File");
+ fileMenu.setMnemonic('f');
+ JMenuItem exitMI;
+ fileMenu.add(createOpenMI());
+ fileMenu.add(createOpenURLMI());
+ fileMenu.addSeparator();
+ fileMenu.add(createCloseMI());
+ createMRUFileListMI(fileMenu);
+ fileMenu.addSeparator();
+ fileMenu.add(createExitMI());
+ return fileMenu;
+ }
+
+ /**
+ * Menu item added to allow log files to be opened with
+ * the LF5 GUI.
+ */
+ protected JMenuItem createOpenMI() {
+ JMenuItem result = new JMenuItem("Open...");
+ result.setMnemonic('o');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ requestOpen();
+ }
+ });
+ return result;
+ }
+
+ /**
+ * Menu item added to allow log files loaded from a URL
+ * to be opened by the LF5 GUI.
+ */
+ protected JMenuItem createOpenURLMI() {
+ JMenuItem result = new JMenuItem("Open URL...");
+ result.setMnemonic('u');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ requestOpenURL();
+ }
+ });
+ return result;
+ }
+
+ protected JMenuItem createCloseMI() {
+ JMenuItem result = new JMenuItem("Close");
+ result.setMnemonic('c');
+ result.setAccelerator(KeyStroke.getKeyStroke("control Q"));
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ requestClose();
+ }
+ });
+ return result;
+ }
+
+ /**
+ * Creates a Most Recently Used file list to be
+ * displayed in the File menu
+ */
+ protected void createMRUFileListMI(JMenu menu) {
+
+ String[] files = _mruFileManager.getMRUFileList();
+
+ if (files != null) {
+ menu.addSeparator();
+ for (int i = 0; i < files.length; i++) {
+ JMenuItem result = new JMenuItem((i + 1) + " " + files[i]);
+ result.setMnemonic(i + 1);
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ requestOpenMRU(e);
+ }
+ });
+ menu.add(result);
+ }
+ }
+ }
+
+ protected JMenuItem createExitMI() {
+ JMenuItem result = new JMenuItem("Exit");
+ result.setMnemonic('x');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ requestExit();
+ }
+ });
+ return result;
+ }
+
+ protected JMenu createConfigureMenu() {
+ JMenu configureMenu = new JMenu("Configure");
+ configureMenu.setMnemonic('c');
+ configureMenu.add(createConfigureSave());
+ configureMenu.add(createConfigureReset());
+ configureMenu.add(createConfigureMaxRecords());
+
+ return configureMenu;
+ }
+
+ protected JMenuItem createConfigureSave() {
+ JMenuItem result = new JMenuItem("Save");
+ result.setMnemonic('s');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ saveConfiguration();
+ }
+ });
+
+ return result;
+ }
+
+ protected JMenuItem createConfigureReset() {
+ JMenuItem result = new JMenuItem("Reset");
+ result.setMnemonic('r');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ resetConfiguration();
+ }
+ });
+
+ return result;
+ }
+
+ protected JMenuItem createConfigureMaxRecords() {
+ JMenuItem result = new JMenuItem("Set Max Number of Records");
+ result.setMnemonic('m');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ setMaxRecordConfiguration();
+ }
+ });
+
+ return result;
+ }
+
+
+ protected void saveConfiguration() {
+ _configurationManager.save();
+ }
+
+ protected void resetConfiguration() {
+ _configurationManager.reset();
+ }
+
+ protected void setMaxRecordConfiguration() {
+ LogFactor5InputDialog inputDialog = new LogFactor5InputDialog(
+ getBaseFrame(), "Set Max Number of Records", "", 10);
+
+ String temp = inputDialog.getText();
+
+ if (temp != null) {
+ try {
+ setMaxNumberOfLogRecords(Integer.parseInt(temp));
+ } catch (NumberFormatException e) {
+ LogFactor5ErrorDialog error = new LogFactor5ErrorDialog(
+ getBaseFrame(),
+ "'" + temp + "' is an invalid parameter.\nPlease try again.");
+ setMaxRecordConfiguration();
+ }
+ }
+ }
+
+
+ protected JMenu createHelpMenu() {
+ JMenu helpMenu = new JMenu("Help");
+ helpMenu.setMnemonic('h');
+ helpMenu.add(createHelpProperties());
+ return helpMenu;
+ }
+
+ protected JMenuItem createHelpProperties() {
+ final String title = "LogFactor5 Properties";
+ final JMenuItem result = new JMenuItem(title);
+ result.setMnemonic('l');
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ showPropertiesDialog(title);
+ }
+ });
+ return result;
+ }
+
+ protected void showPropertiesDialog(String title) {
+ JOptionPane.showMessageDialog(
+ _logMonitorFrame,
+ _displayedLogBrokerProperties.toArray(),
+ title,
+ JOptionPane.PLAIN_MESSAGE
+ );
+ }
+
+ protected JMenu createEditMenu() {
+ JMenu editMenu = new JMenu("Edit");
+ editMenu.setMnemonic('e');
+ editMenu.add(createEditFindMI());
+ editMenu.add(createEditFindNextMI());
+ editMenu.addSeparator();
+ editMenu.add(createEditSortNDCMI());
+ editMenu.add(createEditRestoreAllNDCMI());
+ return editMenu;
+ }
+
+ protected JMenuItem createEditFindNextMI() {
+ JMenuItem editFindNextMI = new JMenuItem("Find Next");
+ editFindNextMI.setMnemonic('n');
+ editFindNextMI.setAccelerator(KeyStroke.getKeyStroke("F3"));
+ editFindNextMI.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ findSearchText();
+ }
+ });
+ return editFindNextMI;
+ }
+
+ protected JMenuItem createEditFindMI() {
+ JMenuItem editFindMI = new JMenuItem("Find");
+ editFindMI.setMnemonic('f');
+ editFindMI.setAccelerator(KeyStroke.getKeyStroke("control F"));
+
+ editFindMI.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ String inputValue =
+ JOptionPane.showInputDialog(
+ _logMonitorFrame,
+ "Find text: ",
+ "Search Record Messages",
+ JOptionPane.QUESTION_MESSAGE
+ );
+ setSearchText(inputValue);
+ findSearchText();
+ }
+ }
+
+ );
+ return editFindMI;
+ }
+
+ // Added version 1.2 - Allows users to Sort Log Records by an
+ // NDC text filter. A new LogRecordFilter was created to
+ // sort the records.
+ protected JMenuItem createEditSortNDCMI() {
+ JMenuItem editSortNDCMI = new JMenuItem("Sort by NDC");
+ editSortNDCMI.setMnemonic('s');
+ editSortNDCMI.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ String inputValue =
+ JOptionPane.showInputDialog(
+ _logMonitorFrame,
+ "Sort by this NDC: ",
+ "Sort Log Records by NDC",
+ JOptionPane.QUESTION_MESSAGE
+ );
+ setNDCTextFilter(inputValue);
+ sortByNDC();
+ _table.getFilteredLogTableModel().refresh();
+ updateStatusLabel();
+ }
+ }
+
+ );
+ return editSortNDCMI;
+ }
+
+ // Added in version 1.2 - Resets the LogRecordFilter back to default
+ // filter.
+ protected JMenuItem createEditRestoreAllNDCMI() {
+ JMenuItem editRestoreAllNDCMI = new JMenuItem("Restore all NDCs");
+ editRestoreAllNDCMI.setMnemonic('r');
+ editRestoreAllNDCMI.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _table.getFilteredLogTableModel().setLogRecordFilter(createLogRecordFilter());
+ // reset the text filter
+ setNDCTextFilter("");
+ _table.getFilteredLogTableModel().refresh();
+ updateStatusLabel();
+ }
+ }
+ );
+ return editRestoreAllNDCMI;
+ }
+
+ protected JToolBar createToolBar() {
+ JToolBar tb = new JToolBar();
+ tb.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
+ JComboBox fontCombo = new JComboBox();
+ JComboBox fontSizeCombo = new JComboBox();
+ _fontSizeCombo = fontSizeCombo;
+
+ ClassLoader cl = this.getClass().getClassLoader();
+ if(cl == null) {
+ cl = ClassLoader.getSystemClassLoader();
+ }
+ URL newIconURL = cl.getResource("org/apache/log4j/lf5/viewer/" +
+ "images/channelexplorer_new.gif");
+
+ ImageIcon newIcon = null;
+
+ if (newIconURL != null) {
+ newIcon = new ImageIcon(newIconURL);
+ }
+
+ JButton newButton = new JButton("Clear Log Table");
+
+ if (newIcon != null) {
+ newButton.setIcon(newIcon);
+ }
+
+ newButton.setToolTipText("Clear Log Table.");
+ //newButton.setBorder(BorderFactory.createEtchedBorder());
+
+ newButton.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _table.clearLogRecords();
+ _categoryExplorerTree.getExplorerModel().resetAllNodeCounts();
+ updateStatusLabel();
+ clearDetailTextArea();
+ LogRecord.resetSequenceNumber();
+ }
+ }
+ );
+
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ // This will actually grab all the fonts
+
+ String[] fonts;
+
+ if (_loadSystemFonts) {
+ fonts = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
+ } else {
+ fonts = tk.getFontList();
+ }
+
+ for (int j = 0; j < fonts.length; j++) {
+ fontCombo.addItem(fonts[j]);
+ }
+
+ fontCombo.setSelectedItem(_fontName);
+
+ fontCombo.addActionListener(
+
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComboBox box = (JComboBox) e.getSource();
+ String font = (String) box.getSelectedItem();
+ _table.setFont(new Font(font, Font.PLAIN, _fontSize));
+ _fontName = font;
+ }
+ }
+ );
+
+ fontSizeCombo.addItem("8");
+ fontSizeCombo.addItem("9");
+ fontSizeCombo.addItem("10");
+ fontSizeCombo.addItem("12");
+ fontSizeCombo.addItem("14");
+ fontSizeCombo.addItem("16");
+ fontSizeCombo.addItem("18");
+ fontSizeCombo.addItem("24");
+
+ fontSizeCombo.setSelectedItem(String.valueOf(_fontSize));
+ fontSizeCombo.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComboBox box = (JComboBox) e.getSource();
+ String size = (String) box.getSelectedItem();
+ int s = Integer.valueOf(size).intValue();
+
+ setFontSizeSilently(s);
+ refreshDetailTextArea();
+ _fontSize = s;
+ }
+ }
+ );
+
+ tb.add(new JLabel(" Font: "));
+ tb.add(fontCombo);
+ tb.add(fontSizeCombo);
+ tb.addSeparator();
+ tb.addSeparator();
+ tb.add(newButton);
+
+ newButton.setAlignmentY(0.5f);
+ newButton.setAlignmentX(0.5f);
+
+ fontCombo.setMaximumSize(fontCombo.getPreferredSize());
+ fontSizeCombo.setMaximumSize(
+ fontSizeCombo.getPreferredSize());
+
+ return (tb);
+ }
+
+// protected void setView(String viewString, LogTable table) {
+// if (STANDARD_VIEW.equals(viewString)) {
+// table.setStandardView();
+// } else if (COMPACT_VIEW.equals(viewString)) {
+// table.setCompactView();
+// } else if (DETAILED_VIEW.equals(viewString)) {
+// table.setDetailedView();
+// } else {
+// String message = viewString + "does not match a supported view.";
+// throw new IllegalArgumentException(message);
+// }
+// _currentView = viewString;
+// }
+
+ protected void setView(String viewString, LogTable table) {
+ if (DETAILED_VIEW.equals(viewString)) {
+ table.setDetailedView();
+ } else {
+ String message = viewString + "does not match a supported view.";
+ throw new IllegalArgumentException(message);
+ }
+ _currentView = viewString;
+ }
+
+ protected JComboBox createLogLevelCombo() {
+ JComboBox result = new JComboBox();
+ Iterator levels = getLogLevels();
+ while (levels.hasNext()) {
+ result.addItem(levels.next());
+ }
+ result.setSelectedItem(_leastSevereDisplayedLogLevel);
+
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComboBox box = (JComboBox) e.getSource();
+ LogLevel level = (LogLevel) box.getSelectedItem();
+ setLeastSevereDisplayedLogLevel(level);
+ }
+ });
+ result.setMaximumSize(result.getPreferredSize());
+ return result;
+ }
+
+ protected void setLeastSevereDisplayedLogLevel(LogLevel level) {
+ if (level == null || _leastSevereDisplayedLogLevel == level) {
+ return; // nothing to do
+ }
+ _leastSevereDisplayedLogLevel = level;
+ _table.getFilteredLogTableModel().refresh();
+ updateStatusLabel();
+ }
+
+ /**
+ * Ensures that the Table's ScrollPane Viewport will "track" with updates
+ * to the Table. When the vertical scroll bar is at its bottom anchor
+ * and tracking is enabled then viewport will stay at the bottom most
+ * point of the component. The purpose of this feature is to allow
+ * a developer to watch the table as messages arrive and not have to
+ * scroll after each new message arrives. When the vertical scroll bar
+ * is at any other location, then no tracking will happen.
+ * @deprecated tracking is now done automatically.
+ */
+ protected void trackTableScrollPane() {
+ // do nothing
+ }
+
+ protected void centerFrame(JFrame frame) {
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension comp = frame.getSize();
+
+ frame.setLocation(((screen.width - comp.width) / 2),
+ ((screen.height - comp.height) / 2));
+
+ }
+
+ /**
+ * Uses a JFileChooser to select a file to opened with the
+ * LF5 GUI.
+ */
+ protected void requestOpen() {
+ JFileChooser chooser;
+
+ if (_fileLocation == null) {
+ chooser = new JFileChooser();
+ } else {
+ chooser = new JFileChooser(_fileLocation);
+ }
+
+ int returnVal = chooser.showOpenDialog(_logMonitorFrame);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ File f = chooser.getSelectedFile();
+ if (loadLogFile(f)) {
+ _fileLocation = chooser.getSelectedFile();
+ _mruFileManager.set(f);
+ updateMRUList();
+ }
+ }
+ }
+
+ /**
+ * Uses a Dialog box to accept a URL to a file to be opened
+ * with the LF5 GUI.
+ */
+ protected void requestOpenURL() {
+ LogFactor5InputDialog inputDialog = new LogFactor5InputDialog(
+ getBaseFrame(), "Open URL", "URL:");
+ String temp = inputDialog.getText();
+
+ if (temp != null) {
+ if (temp.indexOf("://") == -1) {
+ temp = "http://" + temp;
+ }
+
+ try {
+ URL url = new URL(temp);
+ if (loadLogFile(url)) {
+ _mruFileManager.set(url);
+ updateMRUList();
+ }
+ } catch (MalformedURLException e) {
+ LogFactor5ErrorDialog error = new LogFactor5ErrorDialog(
+ getBaseFrame(), "Error reading URL.");
+ }
+ }
+ }
+
+ /**
+ * Removes old file list and creates a new file list
+ * with the updated MRU list.
+ */
+ protected void updateMRUList() {
+ JMenu menu = _logMonitorFrame.getJMenuBar().getMenu(0);
+ menu.removeAll();
+ menu.add(createOpenMI());
+ menu.add(createOpenURLMI());
+ menu.addSeparator();
+ menu.add(createCloseMI());
+ createMRUFileListMI(menu);
+ menu.addSeparator();
+ menu.add(createExitMI());
+ }
+
+ protected void requestClose() {
+ setCallSystemExitOnClose(false);
+ closeAfterConfirm();
+ }
+
+ /**
+ * Opens a file in the MRU list.
+ */
+ protected void requestOpenMRU(ActionEvent e) {
+ String file = e.getActionCommand();
+ StringTokenizer st = new StringTokenizer(file);
+ String num = st.nextToken().trim();
+ file = st.nextToken("\n");
+
+ try {
+ int index = Integer.parseInt(num) - 1;
+
+ InputStream in = _mruFileManager.getInputStream(index);
+ LogFileParser lfp = new LogFileParser(in);
+ lfp.parse(this);
+
+ _mruFileManager.moveToTop(index);
+ updateMRUList();
+
+ } catch (Exception me) {
+ LogFactor5ErrorDialog error = new LogFactor5ErrorDialog(
+ getBaseFrame(), "Unable to load file " + file);
+ }
+
+ }
+
+ protected void requestExit() {
+ _mruFileManager.save();
+ setCallSystemExitOnClose(true);
+ closeAfterConfirm();
+ }
+
+ protected void closeAfterConfirm() {
+ StringBuffer message = new StringBuffer();
+
+ if (_callSystemExitOnClose == false) {
+ message.append("Are you sure you want to close the logging ");
+ message.append("console?\n");
+ message.append("(Note: This will not shut down the Virtual Machine,\n");
+ message.append("or the Swing event thread.)");
+ } else {
+ message.append("Are you sure you want to exit?\n");
+ message.append("This will shut down the Virtual Machine.\n");
+ }
+
+ String title =
+ "Are you sure you want to dispose of the Logging Console?";
+
+ if (_callSystemExitOnClose == true) {
+ title = "Are you sure you want to exit?";
+ }
+ int value = JOptionPane.showConfirmDialog(
+ _logMonitorFrame,
+ message.toString(),
+ title,
+ JOptionPane.OK_CANCEL_OPTION,
+ JOptionPane.QUESTION_MESSAGE,
+ null
+ );
+
+ if (value == JOptionPane.OK_OPTION) {
+ dispose();
+ }
+ }
+
+ protected Iterator getLogLevels() {
+ return _levels.iterator();
+ }
+
+ protected Iterator getLogTableColumns() {
+ return _columns.iterator();
+ }
+
+ /**
+ * Loads and parses a log file.
+ */
+ protected boolean loadLogFile(File file) {
+ boolean ok = false;
+ try {
+ LogFileParser lfp = new LogFileParser(file);
+ lfp.parse(this);
+ ok = true;
+ } catch (IOException e) {
+ LogFactor5ErrorDialog error = new LogFactor5ErrorDialog(
+ getBaseFrame(), "Error reading " + file.getName());
+ }
+
+ return ok;
+ }
+
+ /**
+ * Loads a parses a log file running on a server.
+ */
+ protected boolean loadLogFile(URL url) {
+ boolean ok = false;
+ try {
+ LogFileParser lfp = new LogFileParser(url.openStream());
+ lfp.parse(this);
+ ok = true;
+ } catch (IOException e) {
+ LogFactor5ErrorDialog error = new LogFactor5ErrorDialog(
+ getBaseFrame(), "Error reading URL:" + url.getFile());
+ }
+ return ok;
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+ class LogBrokerMonitorWindowAdaptor extends WindowAdapter {
+ protected LogBrokerMonitor _monitor;
+
+ public LogBrokerMonitorWindowAdaptor(LogBrokerMonitor monitor) {
+ _monitor = monitor;
+ }
+
+ public void windowClosing(WindowEvent ev) {
+ _monitor.requestClose();
+ }
+ }
+}
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5Dialog.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5Dialog.java
new file mode 100644
index 0000000000..763d870269
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5Dialog.java
@@ -0,0 +1,151 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Label;
+import java.awt.Toolkit;
+import java.awt.Window;
+
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+
+/**
+ * LogFactor5Dialog
+ *
+ * @author Richard Hurst
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public abstract class LogFactor5Dialog extends JDialog {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+ protected static final Font DISPLAY_FONT = new Font("Arial", Font.BOLD, 12);
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ protected LogFactor5Dialog(JFrame jframe, String message, boolean modal) {
+ super(jframe, message, modal);
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ public void show() {
+ pack();
+ minimumSizeDialog(this, 200, 100);
+ centerWindow(this);
+ super.show();
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+ protected void centerWindow(Window win) {
+ Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
+
+ // If larger than screen, reduce window width or height
+ if (screenDim.width < win.getSize().width) {
+ win.setSize(screenDim.width, win.getSize().height);
+ }
+
+ if (screenDim.height < win.getSize().height) {
+ win.setSize(win.getSize().width, screenDim.height);
+ }
+
+ // Center Frame, Dialogue or Window on screen
+ int x = (screenDim.width - win.getSize().width) / 2;
+ int y = (screenDim.height - win.getSize().height) / 2;
+ win.setLocation(x, y);
+ }
+
+ protected void wrapStringOnPanel(String message,
+ Container container) {
+ GridBagConstraints c = getDefaultConstraints();
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ // Insets() args are top, left, bottom, right
+ c.insets = new Insets(0, 0, 0, 0);
+ GridBagLayout gbLayout = (GridBagLayout) container.getLayout();
+
+
+ while (message.length() > 0) {
+ int newLineIndex = message.indexOf('\n');
+ String line;
+ if (newLineIndex >= 0) {
+ line = message.substring(0, newLineIndex);
+ message = message.substring(newLineIndex + 1);
+ } else {
+ line = message;
+ message = "";
+ }
+ Label label = new Label(line);
+ label.setFont(DISPLAY_FONT);
+ gbLayout.setConstraints(label, c);
+ container.add(label);
+ }
+ }
+
+ protected GridBagConstraints getDefaultConstraints() {
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ constraints.gridheight = 1; // One row high
+ // Insets() args are top, left, bottom, right
+ constraints.insets = new Insets(4, 4, 4, 4);
+ // fill of NONE means do not change size
+ constraints.fill = GridBagConstraints.NONE;
+ // WEST means align left
+ constraints.anchor = GridBagConstraints.WEST;
+
+ return constraints;
+ }
+
+ protected void minimumSizeDialog(Component component,
+ int minWidth,
+ int minHeight) {
+ // set the min width
+ if (component.getSize().width < minWidth)
+ component.setSize(minWidth, component.getSize().height);
+ // set the min height
+ if (component.getSize().height < minHeight)
+ component.setSize(component.getSize().width, minHeight);
+ }
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
\ No newline at end of file
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5ErrorDialog.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5ErrorDialog.java
new file mode 100644
index 0000000000..64b2e21597
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5ErrorDialog.java
@@ -0,0 +1,92 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+/**
+ * LogFactor5ErrorDialog
+ *
+ * @author Richard Hurst
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogFactor5ErrorDialog extends LogFactor5Dialog {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public LogFactor5ErrorDialog(JFrame jframe, String message) {
+ super(jframe, "Error", true);
+
+ JButton ok = new JButton("Ok");
+ ok.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ hide();
+ }
+ });
+
+ JPanel bottom = new JPanel();
+ bottom.setLayout(new FlowLayout());
+ bottom.add(ok);
+
+ JPanel main = new JPanel();
+ main.setLayout(new GridBagLayout());
+ wrapStringOnPanel(message, main);
+
+ getContentPane().add(main, BorderLayout.CENTER);
+ getContentPane().add(bottom, BorderLayout.SOUTH);
+ show();
+
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
\ No newline at end of file
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5InputDialog.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5InputDialog.java
new file mode 100644
index 0000000000..890e6dbfea
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5InputDialog.java
@@ -0,0 +1,145 @@
+/*
+ * 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.lf5.viewer;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+/**
+ * LogFactor5InputDialog
+ *
+ * Creates a popup input dialog box so that users can enter
+ * a URL to open a log file from.
+ *
+ * @author Richard Hurst
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogFactor5InputDialog extends LogFactor5Dialog {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+ public static final int SIZE = 30;
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private JTextField _textField;
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Configures an input dialog box using a defualt size for the text field.
+ * param jframe the frame where the dialog will be loaded from.
+ * param title the title of the dialog box.
+ * param label the label to be put in the dialog box.
+ */
+ public LogFactor5InputDialog(JFrame jframe, String title, String label) {
+ this(jframe, title, label, SIZE);
+ }
+
+ /**
+ * Configures an input dialog box.
+ * param jframe the frame where the dialog will be loaded from.
+ * param title the title of the dialog box.
+ * param label the label to be put in the dialog box.
+ * param size the size of the text field.
+ */
+ public LogFactor5InputDialog(JFrame jframe, String title, String label,
+ int size) {
+ super(jframe, title, true);
+
+ JPanel bottom = new JPanel();
+ bottom.setLayout(new FlowLayout());
+
+ JPanel main = new JPanel();
+ main.setLayout(new FlowLayout());
+ main.add(new JLabel(label));
+ _textField = new JTextField(size);
+ main.add(_textField);
+
+ addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_ENTER) {
+ hide();
+ }
+ }
+ });
+
+ JButton ok = new JButton("Ok");
+ ok.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ hide();
+ }
+ });
+
+ JButton cancel = new JButton("Cancel");
+ cancel.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ hide();
+ // set the text field to blank just in case
+ // a file was selected before the Cancel
+ // button was pressed.
+ _textField.setText("");
+ }
+ });
+
+ bottom.add(ok);
+ bottom.add(cancel);
+ getContentPane().add(main, BorderLayout.CENTER);
+ getContentPane().add(bottom, BorderLayout.SOUTH);
+ pack();
+ centerWindow(this);
+ show();
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ public String getText() {
+ String s = _textField.getText();
+
+ if (s != null && s.trim().length() == 0) {
+ return null;
+ }
+
+ return s;
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
\ No newline at end of file
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5LoadingDialog.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5LoadingDialog.java
new file mode 100644
index 0000000000..3e5a62b019
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogFactor5LoadingDialog.java
@@ -0,0 +1,82 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridBagLayout;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+/**
+ * LogFactor5LoadingDialog
+ *
+ * @author Richard Hurst
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogFactor5LoadingDialog extends LogFactor5Dialog {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public LogFactor5LoadingDialog(JFrame jframe, String message) {
+ super(jframe, "LogFactor5", false);
+
+ JPanel bottom = new JPanel();
+ bottom.setLayout(new FlowLayout());
+
+ JPanel main = new JPanel();
+ main.setLayout(new GridBagLayout());
+ wrapStringOnPanel(message, main);
+
+ getContentPane().add(main, BorderLayout.CENTER);
+ getContentPane().add(bottom, BorderLayout.SOUTH);
+ show();
+
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
\ No newline at end of file
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTable.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTable.java
new file mode 100644
index 0000000000..6bea10d15a
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTable.java
@@ -0,0 +1,277 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+
+import org.apache.log4j.lf5.util.DateFormatManager;
+
+/**
+ * LogTable.
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ * @author Brad Marlborough
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogTable extends JTable {
+ private static final long serialVersionUID = 4867085140195148458L;
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected int _rowHeight = 30;
+ protected JTextArea _detailTextArea;
+
+ // For the columns:
+ protected int _numCols = 9;
+ protected TableColumn[] _tableColumns = new TableColumn[_numCols];
+ protected int[] _colWidths = {40, 40, 40, 70, 70, 360, 440, 200, 60};
+ protected LogTableColumn[] _colNames = LogTableColumn.getLogTableColumnArray();
+ protected int _colDate = 0;
+ protected int _colThread = 1;
+ protected int _colMessageNum = 2;
+ protected int _colLevel = 3;
+ protected int _colNDC = 4;
+ protected int _colCategory = 5;
+ protected int _colMessage = 6;
+ protected int _colLocation = 7;
+ protected int _colThrown = 8;
+
+ protected DateFormatManager _dateFormatManager = null;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public LogTable(JTextArea detailTextArea) {
+ super();
+
+ init();
+
+ _detailTextArea = detailTextArea;
+
+ setModel(new FilteredLogTableModel());
+
+ Enumeration columns = getColumnModel().getColumns();
+ int i = 0;
+ while (columns.hasMoreElements()) {
+ TableColumn col = (TableColumn) columns.nextElement();
+ col.setCellRenderer(new LogTableRowRenderer());
+ col.setPreferredWidth(_colWidths[i]);
+
+ _tableColumns[i] = col;
+ i++;
+ }
+
+ ListSelectionModel rowSM = getSelectionModel();
+ rowSM.addListSelectionListener(new LogTableListSelectionListener(this));
+
+ //setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Get the DateFormatManager for formatting dates.
+ */
+ public DateFormatManager getDateFormatManager() {
+ return _dateFormatManager;
+ }
+
+ /**
+ * Set the date format manager for formatting dates.
+ */
+ public void setDateFormatManager(DateFormatManager dfm) {
+ _dateFormatManager = dfm;
+ }
+
+ public synchronized void clearLogRecords() {
+ //For JDK1.3
+ //((DefaultTableModel)getModel()).setRowCount(0);
+
+ // For JDK1.2.x
+ getFilteredLogTableModel().clear();
+ }
+
+ public FilteredLogTableModel getFilteredLogTableModel() {
+ return (FilteredLogTableModel) getModel();
+ }
+
+ // default view if a view is not set and saved
+ public void setDetailedView() {
+ //TODO: Defineable Views.
+ TableColumnModel model = getColumnModel();
+ // Remove all the columns:
+ for (int f = 0; f < _numCols; f++) {
+ model.removeColumn(_tableColumns[f]);
+ }
+ // Add them back in the correct order:
+ for (int i = 0; i < _numCols; i++) {
+ model.addColumn(_tableColumns[i]);
+ }
+ //SWING BUG:
+ sizeColumnsToFit(-1);
+ }
+
+ public void setView(List columns) {
+ TableColumnModel model = getColumnModel();
+
+ // Remove all the columns:
+ for (int f = 0; f < _numCols; f++) {
+ model.removeColumn(_tableColumns[f]);
+ }
+ Iterator selectedColumns = columns.iterator();
+ Vector columnNameAndNumber = getColumnNameAndNumber();
+ while (selectedColumns.hasNext()) {
+ // add the column to the view
+ model.addColumn(_tableColumns[columnNameAndNumber.indexOf(selectedColumns.next())]);
+ }
+
+ //SWING BUG:
+ sizeColumnsToFit(-1);
+ }
+
+ public void setFont(Font font) {
+ super.setFont(font);
+ Graphics g = this.getGraphics();
+ if (g != null) {
+ FontMetrics fm = g.getFontMetrics(font);
+ int height = fm.getHeight();
+ _rowHeight = height + height / 3;
+ setRowHeight(_rowHeight);
+ }
+
+
+ }
+
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected void init() {
+ setRowHeight(_rowHeight);
+ setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ }
+
+ // assign a column number to a column name
+ protected Vector getColumnNameAndNumber() {
+ Vector columnNameAndNumber = new Vector();
+ for (int i = 0; i < _colNames.length; i++) {
+ columnNameAndNumber.add(i, _colNames[i]);
+ }
+ return columnNameAndNumber;
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+ class LogTableListSelectionListener implements ListSelectionListener {
+ protected JTable _table;
+
+ public LogTableListSelectionListener(JTable table) {
+ _table = table;
+ }
+
+ public void valueChanged(ListSelectionEvent e) {
+ //Ignore extra messages.
+ if (e.getValueIsAdjusting()) {
+ return;
+ }
+
+ ListSelectionModel lsm = (ListSelectionModel) e.getSource();
+ if (lsm.isSelectionEmpty()) {
+ //no rows are selected
+ } else {
+ StringBuffer buf = new StringBuffer();
+ int selectedRow = lsm.getMinSelectionIndex();
+
+ for (int i = 0; i < _numCols - 1; i++) {
+ String value = "";
+ Object obj = _table.getModel().getValueAt(selectedRow, i);
+ if (obj != null) {
+ value = obj.toString();
+ }
+
+ buf.append(_colNames[i] + ":");
+ buf.append("\t");
+
+ if (i == _colThread || i == _colMessage || i == _colLevel) {
+ buf.append("\t"); // pad out the date.
+ }
+
+ if (i == _colDate || i == _colNDC) {
+ buf.append("\t\t"); // pad out the date.
+ }
+
+// if( i == _colSequence)
+// {
+// buf.append("\t\t\t"); // pad out the Sequnce.
+// }
+
+ buf.append(value);
+ buf.append("\n");
+ }
+ buf.append(_colNames[_numCols - 1] + ":\n");
+ Object obj = _table.getModel().getValueAt(selectedRow, _numCols - 1);
+ if (obj != null) {
+ buf.append(obj.toString());
+ }
+
+ _detailTextArea.setText(buf.toString());
+ }
+ }
+ }
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableColumn.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableColumn.java
new file mode 100644
index 0000000000..c86c6bbefe
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableColumn.java
@@ -0,0 +1,166 @@
+/*
+ * 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.lf5.viewer;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * LogTableColumn
+ *
+ * @author Michael J. Sikorsky
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogTableColumn implements java.io.Serializable {
+ private static final long serialVersionUID = -4275827753626456547L;
+
+ // log4j table columns.
+ public final static LogTableColumn DATE = new LogTableColumn("Date");
+ public final static LogTableColumn THREAD = new LogTableColumn("Thread");
+ public final static LogTableColumn MESSAGE_NUM = new LogTableColumn("Message #");
+ public final static LogTableColumn LEVEL = new LogTableColumn("Level");
+ public final static LogTableColumn NDC = new LogTableColumn("NDC");
+ public final static LogTableColumn CATEGORY = new LogTableColumn("Category");
+ public final static LogTableColumn MESSAGE = new LogTableColumn("Message");
+ public final static LogTableColumn LOCATION = new LogTableColumn("Location");
+ public final static LogTableColumn THROWN = new LogTableColumn("Thrown");
+
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected String _label;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private static LogTableColumn[] _log4JColumns;
+ private static Map _logTableColumnMap;
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ static {
+ _log4JColumns = new LogTableColumn[]{DATE, THREAD, MESSAGE_NUM, LEVEL, NDC, CATEGORY,
+ MESSAGE, LOCATION, THROWN};
+
+ _logTableColumnMap = new HashMap();
+
+ for (int i = 0; i < _log4JColumns.length; i++) {
+ _logTableColumnMap.put(_log4JColumns[i].getLabel(), _log4JColumns[i]);
+ }
+ }
+
+
+ public LogTableColumn(String label) {
+ _label = label;
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Return the Label of the LogLevel.
+ */
+ public String getLabel() {
+ return _label;
+ }
+
+ /**
+ * Convert a column label into a LogTableColumn object.
+ *
+ * @param column The label of a level to be converted into a LogTableColumn.
+ * @return LogTableColumn The LogTableColumn with a label equal to column.
+ * @throws LogTableColumnFormatException Is thrown when the column can not be
+ * converted into a LogTableColumn.
+ */
+ public static LogTableColumn valueOf(String column)
+ throws LogTableColumnFormatException {
+ LogTableColumn tableColumn = null;
+ if (column != null) {
+ column = column.trim();
+ tableColumn = (LogTableColumn) _logTableColumnMap.get(column);
+ }
+
+ if (tableColumn == null) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("Error while trying to parse (" + column + ") into");
+ buf.append(" a LogTableColumn.");
+ throw new LogTableColumnFormatException(buf.toString());
+ }
+ return tableColumn;
+ }
+
+
+ public boolean equals(Object o) {
+ boolean equals = false;
+
+ if (o instanceof LogTableColumn) {
+ if (this.getLabel() ==
+ ((LogTableColumn) o).getLabel()) {
+ equals = true;
+ }
+ }
+
+ return equals;
+ }
+
+ public int hashCode() {
+ return _label.hashCode();
+ }
+
+ public String toString() {
+ return _label;
+ }
+
+ /**
+ * @return A List
of LogTableColumn/code> objects that map
+ * to log4j Column
objects.
+ */
+ public static List getLogTableColumns() {
+ return Arrays.asList(_log4JColumns);
+ }
+
+ public static LogTableColumn[] getLogTableColumnArray() {
+ return _log4JColumns;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableColumnFormatException.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableColumnFormatException.java
new file mode 100644
index 0000000000..b161fe7bcb
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableColumnFormatException.java
@@ -0,0 +1,74 @@
+/*
+ * 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.lf5.viewer;
+
+/**
+ * Thrown to indicate that the client has attempted to convert a string
+ * to one the LogLevel types, but the string does not have the appropriate
+ * format.
+ *
+ * @author Michael J. Sikorsky
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogTableColumnFormatException extends Exception {
+ private static final long serialVersionUID = 6529165785030431653L;
+
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public LogTableColumnFormatException(String message) {
+ super(message);
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableModel.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableModel.java
new file mode 100644
index 0000000000..3b60000bfc
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableModel.java
@@ -0,0 +1,77 @@
+/*
+ * 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.lf5.viewer;
+
+import javax.swing.table.DefaultTableModel;
+
+/**
+ * LogTableModel
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogTableModel extends DefaultTableModel {
+ private static final long serialVersionUID = 3593300685868700894L;
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public LogTableModel(Object[] colNames, int numRows) {
+ super(colNames, numRows);
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public boolean isCellEditable(int row, int column) {
+ return (false);
+ }
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableRowRenderer.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableRowRenderer.java
new file mode 100644
index 0000000000..3d1e397cd5
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/LogTableRowRenderer.java
@@ -0,0 +1,109 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.Color;
+import java.awt.Component;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.LogRecord;
+
+/**
+ * LogTableRowRenderer
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class LogTableRowRenderer extends DefaultTableCellRenderer {
+ private static final long serialVersionUID = -3951639953706443213L;
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected boolean _highlightFatal = true;
+ protected Color _color = new Color(230, 230, 230);
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public Component getTableCellRendererComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int col) {
+
+ if ((row % 2) == 0) {
+ setBackground(_color);
+ } else {
+ setBackground(Color.white);
+ }
+
+ FilteredLogTableModel model = (FilteredLogTableModel) table.getModel();
+ LogRecord record = model.getFilteredRecord(row);
+
+ setForeground(getLogLevelColor(record.getLevel()));
+
+ return (super.getTableCellRendererComponent(table,
+ value,
+ isSelected,
+ hasFocus,
+ row, col));
+ }
+
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ protected Color getLogLevelColor(LogLevel level) {
+ return (Color) LogLevel.getLogLevelColorMap().get(level);
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/TrackingAdjustmentListener.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/TrackingAdjustmentListener.java
new file mode 100644
index 0000000000..4aa959c999
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/TrackingAdjustmentListener.java
@@ -0,0 +1,86 @@
+/*
+ * 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.lf5.viewer;
+
+import java.awt.Adjustable;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+
+/**
+ * An AdjustmentListener which ensures that an Adjustable (e.g. a Scrollbar)
+ * will "track" when the Adjustable expands.
+ * For example, when a vertical scroll bar is at its bottom anchor,
+ * the scrollbar will remain at the bottom. When the vertical scroll bar
+ * is at any other location, then no tracking will happen.
+ * An instance of this class should only listen to one Adjustable as
+ * it retains state information about the Adjustable it listens to.
+ *
+ * @author Richard Wan
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class TrackingAdjustmentListener implements AdjustmentListener {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ protected int _lastMaximum = -1;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public void adjustmentValueChanged(AdjustmentEvent e) {
+ Adjustable bar = e.getAdjustable();
+ int currentMaximum = bar.getMaximum();
+ if (bar.getMaximum() == _lastMaximum) {
+ return; // nothing to do, the adjustable has not expanded
+ }
+ int bottom = bar.getValue() + bar.getVisibleAmount();
+
+ if (bottom + bar.getUnitIncrement() >= _lastMaximum) {
+ bar.setValue(bar.getMaximum()); // use the most recent maximum
+ }
+ _lastMaximum = currentMaximum;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryAbstractCellEditor.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryAbstractCellEditor.java
new file mode 100644
index 0000000000..e5bbaa640e
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryAbstractCellEditor.java
@@ -0,0 +1,172 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import java.awt.Component;
+import java.awt.event.MouseEvent;
+import java.util.EventObject;
+
+import javax.swing.JTable;
+import javax.swing.JTree;
+import javax.swing.event.CellEditorListener;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.EventListenerList;
+import javax.swing.table.TableCellEditor;
+import javax.swing.tree.TreeCellEditor;
+
+/**
+ * CategoryAbstractCellEditor. Base class to handle the some common
+ * details of cell editing.
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryAbstractCellEditor implements TableCellEditor, TreeCellEditor {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected EventListenerList _listenerList = new EventListenerList();
+ protected Object _value;
+ protected ChangeEvent _changeEvent = null;
+ protected int _clickCountToStart = 1;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public Object getCellEditorValue() {
+ return _value;
+ }
+
+ public void setCellEditorValue(Object value) {
+ _value = value;
+ }
+
+ public void setClickCountToStart(int count) {
+ _clickCountToStart = count;
+ }
+
+ public int getClickCountToStart() {
+ return _clickCountToStart;
+ }
+
+ public boolean isCellEditable(EventObject anEvent) {
+ if (anEvent instanceof MouseEvent) {
+ if (((MouseEvent) anEvent).getClickCount() < _clickCountToStart) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean shouldSelectCell(EventObject anEvent) {
+ if (this.isCellEditable(anEvent)) {
+ if (anEvent == null ||
+ ((MouseEvent) anEvent).getClickCount() >= _clickCountToStart) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean stopCellEditing() {
+ fireEditingStopped();
+ return true;
+ }
+
+ public void cancelCellEditing() {
+ fireEditingCanceled();
+ }
+
+ public void addCellEditorListener(CellEditorListener l) {
+ _listenerList.add(CellEditorListener.class, l);
+ }
+
+ public void removeCellEditorListener(CellEditorListener l) {
+ _listenerList.remove(CellEditorListener.class, l);
+ }
+
+ public Component getTreeCellEditorComponent(
+ JTree tree, Object value,
+ boolean isSelected,
+ boolean expanded,
+ boolean leaf, int row) {
+ return null;
+ }
+
+ public Component getTableCellEditorComponent(
+ JTable table, Object value,
+ boolean isSelected,
+ int row, int column) {
+ return null;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ protected void fireEditingStopped() {
+ Object[] listeners = _listenerList.getListenerList();
+
+ for (int i = listeners.length - 2; i >= 0; i -= 2) {
+ if (listeners[i] == CellEditorListener.class) {
+ if (_changeEvent == null) {
+ _changeEvent = new ChangeEvent(this);
+ }
+
+ ((CellEditorListener) listeners[i + 1]).editingStopped(_changeEvent);
+ }
+ }
+ }
+
+ protected void fireEditingCanceled() {
+ Object[] listeners = _listenerList.getListenerList();
+
+ for (int i = listeners.length - 2; i >= 0; i -= 2) {
+ if (listeners[i] == CellEditorListener.class) {
+ if (_changeEvent == null) {
+ _changeEvent = new ChangeEvent(this);
+ }
+
+ ((CellEditorListener) listeners[i + 1]).editingCanceled(_changeEvent);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryElement.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryElement.java
new file mode 100644
index 0000000000..1391fd574a
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryElement.java
@@ -0,0 +1,84 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+/**
+ * CategoryElement represents a single element or part of a Category.
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryElement {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected String _categoryTitle;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public CategoryElement() {
+ super();
+ }
+
+ public CategoryElement(String title) {
+ _categoryTitle = title;
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public String getTitle() {
+ return (_categoryTitle);
+ }
+
+ public void setTitle(String title) {
+ _categoryTitle = title;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerLogRecordFilter.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerLogRecordFilter.java
new file mode 100644
index 0000000000..63f91aef2d
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerLogRecordFilter.java
@@ -0,0 +1,98 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import org.apache.log4j.lf5.LogRecord;
+import org.apache.log4j.lf5.LogRecordFilter;
+
+import java.util.Enumeration;
+
+/**
+ * An implementation of LogRecordFilter based on a CategoryExplorerModel
+ *
+ * @author Richard Wan
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryExplorerLogRecordFilter implements LogRecordFilter {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ protected CategoryExplorerModel _model;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public CategoryExplorerLogRecordFilter(CategoryExplorerModel model) {
+ _model = model;
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * @return true if the CategoryExplorer model specified at construction
+ * is accepting the category of the specified LogRecord. Has a side-effect
+ * of adding the CategoryPath of the LogRecord to the explorer model
+ * if the CategoryPath is new.
+ */
+ public boolean passes(LogRecord record) {
+ CategoryPath path = new CategoryPath(record.getCategory());
+ return _model.isCategoryPathActive(path);
+ }
+
+ /**
+ * Resets the counters for the contained CategoryNodes to zero.
+ */
+ public void reset() {
+ resetAllNodes();
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected void resetAllNodes() {
+ Enumeration nodes = _model.getRootCategoryNode().depthFirstEnumeration();
+ CategoryNode current;
+ while (nodes.hasMoreElements()) {
+ current = (CategoryNode) nodes.nextElement();
+ current.resetNumberOfContainedRecords();
+ _model.nodeChanged(current);
+ }
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerModel.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerModel.java
new file mode 100644
index 0000000000..c70b55c884
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerModel.java
@@ -0,0 +1,347 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import java.awt.AWTEventMulticaster;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Enumeration;
+
+import javax.swing.SwingUtilities;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import org.apache.log4j.lf5.LogRecord;
+
+/**
+ * CategoryExplorerModel
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ * @author Brent Sprecher
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryExplorerModel extends DefaultTreeModel {
+ private static final long serialVersionUID = -3413887384316015901L;
+
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ protected boolean _renderFatal = true;
+ protected ActionListener _listener = null;
+ protected ActionEvent _event = new ActionEvent(this,
+ ActionEvent.ACTION_PERFORMED,
+ "Nodes Selection changed");
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public CategoryExplorerModel(CategoryNode node) {
+ super(node);
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public void addLogRecord(LogRecord lr) {
+ CategoryPath path = new CategoryPath(lr.getCategory());
+ addCategory(path); // create category path if it is new
+ CategoryNode node = getCategoryNode(path);
+ node.addRecord(); // update category node
+ if (_renderFatal && lr.isFatal()) {
+ TreeNode[] nodes = getPathToRoot(node);
+ int len = nodes.length;
+ CategoryNode parent;
+
+ // i = 0 gives root node
+ // skip node and root, loop through "parents" in between
+ for (int i = 1; i < len - 1; i++) {
+ parent = (CategoryNode) nodes[i];
+ parent.setHasFatalChildren(true);
+ nodeChanged(parent);
+ }
+ node.setHasFatalRecords(true);
+ nodeChanged(node);
+ }
+ }
+
+ public CategoryNode getRootCategoryNode() {
+ return (CategoryNode) getRoot();
+ }
+
+ public CategoryNode getCategoryNode(String category) {
+ CategoryPath path = new CategoryPath(category);
+ return (getCategoryNode(path));
+ }
+
+ /**
+ * returns null if no CategoryNode exists.
+ */
+ public CategoryNode getCategoryNode(CategoryPath path) {
+ CategoryNode root = (CategoryNode) getRoot();
+ CategoryNode parent = root; // Start condition.
+
+ for (int i = 0; i < path.size(); i++) {
+ CategoryElement element = path.categoryElementAt(i);
+
+ // If the two nodes have matching titles they are considered equal.
+ Enumeration children = parent.children();
+
+ boolean categoryAlreadyExists = false;
+ while (children.hasMoreElements()) {
+ CategoryNode node = (CategoryNode) children.nextElement();
+ String title = node.getTitle().toLowerCase();
+
+ String pathLC = element.getTitle().toLowerCase();
+ if (title.equals(pathLC)) {
+ categoryAlreadyExists = true;
+ // This is now the new parent node.
+ parent = node;
+ break; // out of the while, and back to the for().
+ }
+ }
+
+ if (categoryAlreadyExists == false) {
+ return null; // Didn't find the Node.
+ }
+ }
+
+ return (parent);
+ }
+
+ /**
+ * @return true if all the nodes in the specified CategoryPath are
+ * selected.
+ */
+ public boolean isCategoryPathActive(CategoryPath path) {
+ CategoryNode root = (CategoryNode) getRoot();
+ CategoryNode parent = root; // Start condition.
+ boolean active = false;
+
+ for (int i = 0; i < path.size(); i++) {
+ CategoryElement element = path.categoryElementAt(i);
+
+ // If the two nodes have matching titles they are considered equal.
+ Enumeration children = parent.children();
+
+ boolean categoryAlreadyExists = false;
+ active = false;
+
+ while (children.hasMoreElements()) {
+ CategoryNode node = (CategoryNode) children.nextElement();
+ String title = node.getTitle().toLowerCase();
+
+ String pathLC = element.getTitle().toLowerCase();
+ if (title.equals(pathLC)) {
+ categoryAlreadyExists = true;
+ // This is now the new parent node.
+ parent = node;
+
+ if (parent.isSelected()) {
+ active = true;
+ }
+
+ break; // out of the while, and back to the for().
+ }
+ }
+
+ if (active == false || categoryAlreadyExists == false) {
+ return false;
+ }
+ }
+
+ return (active);
+ }
+
+
+ /**
+ * Method altered by Richard Hurst such that it returns the CategoryNode
+ * corresponding to the CategoryPath
+ *
+ * @param path category path.
+ * @return CategoryNode
+ */
+ public CategoryNode addCategory(CategoryPath path) {
+ CategoryNode root = (CategoryNode) getRoot();
+ CategoryNode parent = root; // Start condition.
+
+ for (int i = 0; i < path.size(); i++) {
+ CategoryElement element = path.categoryElementAt(i);
+
+ // If the two nodes have matching titles they are considered equal.
+ Enumeration children = parent.children();
+
+ boolean categoryAlreadyExists = false;
+ while (children.hasMoreElements()) {
+ CategoryNode node = (CategoryNode) children.nextElement();
+ String title = node.getTitle().toLowerCase();
+
+ String pathLC = element.getTitle().toLowerCase();
+ if (title.equals(pathLC)) {
+ categoryAlreadyExists = true;
+ // This is now the new parent node.
+ parent = node;
+ break;
+ }
+ }
+
+ if (categoryAlreadyExists == false) {
+ // We need to add the node.
+ CategoryNode newNode = new CategoryNode(element.getTitle());
+
+ //This method of adding a new node cause parent roots to be
+ // collapsed.
+ //parent.add( newNode );
+ //reload(parent);
+
+ // This doesn't force the nodes to collapse.
+ insertNodeInto(newNode, parent, parent.getChildCount());
+ refresh(newNode);
+
+ // The newly added node is now the parent.
+ parent = newNode;
+
+ }
+ }
+
+ return parent;
+ }
+
+ public void update(CategoryNode node, boolean selected) {
+ if (node.isSelected() == selected) {
+ return; // nothing was changed, nothing to do
+ }
+ // select parents or deselect children
+ if (selected) {
+ setParentSelection(node, true);
+ } else {
+ setDescendantSelection(node, false);
+ }
+ }
+
+ public void setDescendantSelection(CategoryNode node, boolean selected) {
+ Enumeration descendants = node.depthFirstEnumeration();
+ CategoryNode current;
+ while (descendants.hasMoreElements()) {
+ current = (CategoryNode) descendants.nextElement();
+ // does the current node need to be changed?
+ if (current.isSelected() != selected) {
+ current.setSelected(selected);
+ nodeChanged(current);
+ }
+ }
+ notifyActionListeners();
+ }
+
+ public void setParentSelection(CategoryNode node, boolean selected) {
+ TreeNode[] nodes = getPathToRoot(node);
+ int len = nodes.length;
+ CategoryNode parent;
+
+ // i = 0 gives root node, i=len-1 gives this node
+ // skip the root node
+ for (int i = 1; i < len; i++) {
+ parent = (CategoryNode) nodes[i];
+ if (parent.isSelected() != selected) {
+ parent.setSelected(selected);
+ nodeChanged(parent);
+ }
+ }
+ notifyActionListeners();
+ }
+
+
+ public synchronized void addActionListener(ActionListener l) {
+ _listener = AWTEventMulticaster.add(_listener, l);
+ }
+
+ public synchronized void removeActionListener(ActionListener l) {
+ _listener = AWTEventMulticaster.remove(_listener, l);
+ }
+
+ public void resetAllNodeCounts() {
+ Enumeration nodes = getRootCategoryNode().depthFirstEnumeration();
+ CategoryNode current;
+ while (nodes.hasMoreElements()) {
+ current = (CategoryNode) nodes.nextElement();
+ current.resetNumberOfContainedRecords();
+ nodeChanged(current);
+ }
+ }
+
+ /**
+ * Returns the CategoryPath to the specified CategoryNode
+ *
+ * @param node The target CategoryNode
+ * @return CategoryPath
+ */
+ public TreePath getTreePathToRoot(CategoryNode node) {
+ if (node == null) {
+ return null;
+ }
+ return (new TreePath(getPathToRoot(node)));
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ protected void notifyActionListeners() {
+ if (_listener != null) {
+ _listener.actionPerformed(_event);
+ }
+ }
+
+ /**
+ * Fires a nodechanged event on the SwingThread.
+ */
+ protected void refresh(final CategoryNode node) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ nodeChanged(node); // remind the tree to render the new node
+ }
+ });
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerTree.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerTree.java
new file mode 100644
index 0000000000..a8e97f5f04
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryExplorerTree.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.lf5.viewer.categoryexplorer;
+
+import java.awt.event.MouseEvent;
+
+import javax.swing.JTree;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.tree.TreePath;
+
+/**
+ * CategoryExplorerTree
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ * @author Brent Sprecher
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryExplorerTree extends JTree {
+ private static final long serialVersionUID = 8066257446951323576L;
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected CategoryExplorerModel _model;
+ protected boolean _rootAlreadyExpanded = false;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Construct a CategoryExplorerTree with a specific model.
+ */
+ public CategoryExplorerTree(CategoryExplorerModel model) {
+ super(model);
+
+ _model = model;
+ init();
+ }
+
+ /**
+ * Construct a CategoryExplorerTree and create a default CategoryExplorerModel.
+ */
+ public CategoryExplorerTree() {
+ super();
+
+ CategoryNode rootNode = new CategoryNode("Categories");
+
+ _model = new CategoryExplorerModel(rootNode);
+
+ setModel(_model);
+
+ init();
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public CategoryExplorerModel getExplorerModel() {
+ return (_model);
+ }
+
+ public String getToolTipText(MouseEvent e) {
+
+ try {
+ return super.getToolTipText(e);
+ } catch (Exception ex) {
+ return "";
+ }
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected void init() {
+ // Put visible lines on the JTree.
+ putClientProperty("JTree.lineStyle", "Angled");
+
+ // Configure the Tree with the appropriate Renderers and Editors.
+
+ CategoryNodeRenderer renderer = new CategoryNodeRenderer();
+ setEditable(true);
+ setCellRenderer(renderer);
+
+ CategoryNodeEditor editor = new CategoryNodeEditor(_model);
+
+ setCellEditor(new CategoryImmediateEditor(this,
+ new CategoryNodeRenderer(),
+ editor));
+ setShowsRootHandles(true);
+
+ setToolTipText("");
+
+ ensureRootExpansion();
+
+ }
+
+ protected void expandRootNode() {
+ if (_rootAlreadyExpanded) {
+ return;
+ }
+ _rootAlreadyExpanded = true;
+ TreePath path = new TreePath(_model.getRootCategoryNode().getPath());
+ expandPath(path);
+ }
+
+ protected void ensureRootExpansion() {
+ _model.addTreeModelListener(new TreeModelAdapter() {
+ public void treeNodesInserted(TreeModelEvent e) {
+ expandRootNode();
+ }
+ });
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryImmediateEditor.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryImmediateEditor.java
new file mode 100644
index 0000000000..4c7374b88c
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryImmediateEditor.java
@@ -0,0 +1,148 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import java.util.EventObject;
+
+import javax.swing.Icon;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultTreeCellEditor;
+import javax.swing.tree.TreePath;
+
+/**
+ * CategoryImmediateEditor
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryImmediateEditor extends DefaultTreeCellEditor {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ private CategoryNodeRenderer renderer;
+ protected Icon editingIcon = null;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public CategoryImmediateEditor(JTree tree,
+ CategoryNodeRenderer renderer,
+ CategoryNodeEditor editor) {
+ super(tree, renderer, editor);
+ this.renderer = renderer;
+ renderer.setIcon(null);
+ renderer.setLeafIcon(null);
+ renderer.setOpenIcon(null);
+ renderer.setClosedIcon(null);
+
+ super.editingIcon = null;
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ public boolean shouldSelectCell(EventObject e) {
+ boolean rv = false; // only mouse events
+
+ if (e instanceof MouseEvent) {
+ MouseEvent me = (MouseEvent) e;
+ TreePath path = tree.getPathForLocation(me.getX(),
+ me.getY());
+ CategoryNode node = (CategoryNode)
+ path.getLastPathComponent();
+
+ rv = node.isLeaf() /*|| !inCheckBoxHitRegion(me)*/;
+ }
+ return rv;
+ }
+
+ public boolean inCheckBoxHitRegion(MouseEvent e) {
+ TreePath path = tree.getPathForLocation(e.getX(),
+ e.getY());
+ if (path == null) {
+ return false;
+ }
+ CategoryNode node = (CategoryNode) path.getLastPathComponent();
+ boolean rv = false;
+
+ if (true) {
+ // offset and lastRow DefaultTreeCellEditor
+ // protected members
+
+ Rectangle bounds = tree.getRowBounds(lastRow);
+ Dimension checkBoxOffset =
+ renderer.getCheckBoxOffset();
+
+ bounds.translate(offset + checkBoxOffset.width,
+ checkBoxOffset.height);
+
+ rv = bounds.contains(e.getPoint());
+ }
+ return true;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected boolean canEditImmediately(EventObject e) {
+ boolean rv = false;
+
+ if (e instanceof MouseEvent) {
+ MouseEvent me = (MouseEvent) e;
+ rv = inCheckBoxHitRegion(me);
+ }
+
+ return rv;
+ }
+
+ protected void determineOffset(JTree tree, Object value,
+ boolean isSelected, boolean expanded,
+ boolean leaf, int row) {
+ // Very important: means that the tree won't jump around.
+ offset = 0;
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNode.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNode.java
new file mode 100644
index 0000000000..95bdc4280b
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNode.java
@@ -0,0 +1,197 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeNode;
+import java.util.Enumeration;
+
+/**
+ * CategoryNode
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryNode extends DefaultMutableTreeNode {
+ private static final long serialVersionUID = 5958994817693177319L;
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected boolean _selected = true;
+ protected int _numberOfContainedRecords = 0;
+ protected int _numberOfRecordsFromChildren = 0;
+ protected boolean _hasFatalChildren = false;
+ protected boolean _hasFatalRecords = false;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ /**
+ *
+ */
+ public CategoryNode(String title) {
+ setUserObject(title);
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ public String getTitle() {
+ return (String) getUserObject();
+ }
+
+ public void setSelected(boolean s) {
+ if (s != _selected) {
+ _selected = s;
+ }
+ }
+
+ public boolean isSelected() {
+ return _selected;
+ }
+
+ /**
+ * @deprecated
+ */
+ public void setAllDescendantsSelected() {
+ Enumeration children = children();
+ while (children.hasMoreElements()) {
+ CategoryNode node = (CategoryNode) children.nextElement();
+ node.setSelected(true);
+ node.setAllDescendantsSelected();
+ }
+ }
+
+ /**
+ * @deprecated
+ */
+ public void setAllDescendantsDeSelected() {
+ Enumeration children = children();
+ while (children.hasMoreElements()) {
+ CategoryNode node = (CategoryNode) children.nextElement();
+ node.setSelected(false);
+ node.setAllDescendantsDeSelected();
+ }
+ }
+
+ public String toString() {
+ return (getTitle());
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof CategoryNode) {
+ CategoryNode node = (CategoryNode) obj;
+ String tit1 = getTitle().toLowerCase();
+ String tit2 = node.getTitle().toLowerCase();
+
+ if (tit1.equals(tit2)) {
+ return (true);
+ }
+ }
+ return (false);
+ }
+
+ public int hashCode() {
+ return (getTitle().hashCode());
+ }
+
+ public void addRecord() {
+ _numberOfContainedRecords++;
+ addRecordToParent();
+ }
+
+ public int getNumberOfContainedRecords() {
+ return _numberOfContainedRecords;
+ }
+
+ public void resetNumberOfContainedRecords() {
+ _numberOfContainedRecords = 0;
+ _numberOfRecordsFromChildren = 0;
+ _hasFatalRecords = false;
+ _hasFatalChildren = false;
+ }
+
+ public boolean hasFatalRecords() {
+ return _hasFatalRecords;
+ }
+
+ public boolean hasFatalChildren() {
+ return _hasFatalChildren;
+ }
+
+ public void setHasFatalRecords(boolean flag) {
+ _hasFatalRecords = flag;
+ }
+
+ public void setHasFatalChildren(boolean flag) {
+ _hasFatalChildren = flag;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected int getTotalNumberOfRecords() {
+ return getNumberOfRecordsFromChildren() + getNumberOfContainedRecords();
+ }
+
+ /**
+ * Passes up the addition from child to parent
+ */
+ protected void addRecordFromChild() {
+ _numberOfRecordsFromChildren++;
+ addRecordToParent();
+ }
+
+ protected int getNumberOfRecordsFromChildren() {
+ return _numberOfRecordsFromChildren;
+ }
+
+ protected void addRecordToParent() {
+ TreeNode parent = getParent();
+ if (parent == null) {
+ return;
+ }
+ ((CategoryNode) parent).addRecordFromChild();
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeEditor.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeEditor.java
new file mode 100644
index 0000000000..b653cd71a9
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeEditor.java
@@ -0,0 +1,291 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import javax.swing.JCheckBox;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.JTree;
+import javax.swing.tree.TreePath;
+
+/**
+ * CategoryNodeEditor
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryNodeEditor extends CategoryAbstractCellEditor {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected CategoryNodeEditorRenderer _renderer;
+ protected CategoryNode _lastEditedNode;
+ protected JCheckBox _checkBox;
+ protected CategoryExplorerModel _categoryModel;
+ protected JTree _tree;
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public CategoryNodeEditor(CategoryExplorerModel model) {
+ _renderer = new CategoryNodeEditorRenderer();
+ _checkBox = _renderer.getCheckBox();
+ _categoryModel = model;
+
+ _checkBox.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _categoryModel.update(_lastEditedNode, _checkBox.isSelected());
+ stopCellEditing();
+ }
+ });
+
+ _renderer.addMouseListener(new MouseAdapter() {
+ public void mousePressed(MouseEvent e) {
+ if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0) {
+ showPopup(_lastEditedNode, e.getX(), e.getY());
+ }
+ stopCellEditing();
+ }
+ });
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public Component getTreeCellEditorComponent(JTree tree, Object value,
+ boolean selected, boolean expanded,
+ boolean leaf, int row) {
+ _lastEditedNode = (CategoryNode) value;
+ _tree = tree;
+
+ return _renderer.getTreeCellRendererComponent(tree,
+ value, selected, expanded,
+ leaf, row, true);
+ // hasFocus ignored
+ }
+
+ public Object getCellEditorValue() {
+ return _lastEditedNode.getUserObject();
+ }
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected JMenuItem createPropertiesMenuItem(final CategoryNode node) {
+ JMenuItem result = new JMenuItem("Properties");
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ showPropertiesDialog(node);
+ }
+ });
+ return result;
+ }
+
+ protected void showPropertiesDialog(CategoryNode node) {
+ JOptionPane.showMessageDialog(
+ _tree,
+ getDisplayedProperties(node),
+ "Category Properties: " + node.getTitle(),
+ JOptionPane.PLAIN_MESSAGE
+ );
+ }
+
+ protected Object getDisplayedProperties(CategoryNode node) {
+ ArrayList result = new ArrayList();
+ result.add("Category: " + node.getTitle());
+ if (node.hasFatalRecords()) {
+ result.add("Contains at least one fatal LogRecord.");
+ }
+ if (node.hasFatalChildren()) {
+ result.add("Contains descendants with a fatal LogRecord.");
+ }
+ result.add("LogRecords in this category alone: " +
+ node.getNumberOfContainedRecords());
+ result.add("LogRecords in descendant categories: " +
+ node.getNumberOfRecordsFromChildren());
+ result.add("LogRecords in this category including descendants: " +
+ node.getTotalNumberOfRecords());
+ return result.toArray();
+ }
+
+ protected void showPopup(CategoryNode node, int x, int y) {
+ JPopupMenu popup = new JPopupMenu();
+ popup.setSize(150, 400);
+ //
+ // Configure the Popup
+ //
+ if (node.getParent() == null) {
+ popup.add(createRemoveMenuItem());
+ popup.addSeparator();
+ }
+ popup.add(createSelectDescendantsMenuItem(node));
+ popup.add(createUnselectDescendantsMenuItem(node));
+ popup.addSeparator();
+ popup.add(createExpandMenuItem(node));
+ popup.add(createCollapseMenuItem(node));
+ popup.addSeparator();
+ popup.add(createPropertiesMenuItem(node));
+ popup.show(_renderer, x, y);
+ }
+
+ protected JMenuItem createSelectDescendantsMenuItem(final CategoryNode node) {
+ JMenuItem selectDescendants =
+ new JMenuItem("Select All Descendant Categories");
+ selectDescendants.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _categoryModel.setDescendantSelection(node, true);
+ }
+ }
+ );
+ return selectDescendants;
+ }
+
+ protected JMenuItem createUnselectDescendantsMenuItem(final CategoryNode node) {
+ JMenuItem unselectDescendants =
+ new JMenuItem("Deselect All Descendant Categories");
+ unselectDescendants.addActionListener(
+
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _categoryModel.setDescendantSelection(node, false);
+ }
+ }
+
+ );
+ return unselectDescendants;
+ }
+
+ protected JMenuItem createExpandMenuItem(final CategoryNode node) {
+ JMenuItem result = new JMenuItem("Expand All Descendant Categories");
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ expandDescendants(node);
+ }
+ });
+ return result;
+ }
+
+ protected JMenuItem createCollapseMenuItem(final CategoryNode node) {
+ JMenuItem result = new JMenuItem("Collapse All Descendant Categories");
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ collapseDescendants(node);
+ }
+ });
+ return result;
+ }
+
+ /**
+ * This featured was moved from the LogBrokerMonitor class
+ * to the CategoryNodeExplorer so that the Category tree
+ * could be pruned from the Category Explorer popup menu.
+ * This menu option only appears when a user right clicks on
+ * the Category parent node.
+ *
+ * See removeUnusedNodes()
+ */
+ protected JMenuItem createRemoveMenuItem() {
+ JMenuItem result = new JMenuItem("Remove All Empty Categories");
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ while (removeUnusedNodes() > 0) ;
+ }
+ });
+ return result;
+ }
+
+ protected void expandDescendants(CategoryNode node) {
+ Enumeration descendants = node.depthFirstEnumeration();
+ CategoryNode current;
+ while (descendants.hasMoreElements()) {
+ current = (CategoryNode) descendants.nextElement();
+ expand(current);
+ }
+ }
+
+ protected void collapseDescendants(CategoryNode node) {
+ Enumeration descendants = node.depthFirstEnumeration();
+ CategoryNode current;
+ while (descendants.hasMoreElements()) {
+ current = (CategoryNode) descendants.nextElement();
+ collapse(current);
+ }
+ }
+
+ /**
+ * Removes any inactive nodes from the Category tree.
+ */
+ protected int removeUnusedNodes() {
+ int count = 0;
+ CategoryNode root = _categoryModel.getRootCategoryNode();
+ Enumeration enumeration = root.depthFirstEnumeration();
+ while (enumeration.hasMoreElements()) {
+ CategoryNode node = (CategoryNode) enumeration.nextElement();
+ if (node.isLeaf() && node.getNumberOfContainedRecords() == 0
+ && node.getParent() != null) {
+ _categoryModel.removeNodeFromParent(node);
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ protected void expand(CategoryNode node) {
+ _tree.expandPath(getTreePath(node));
+ }
+
+ protected TreePath getTreePath(CategoryNode node) {
+ return new TreePath(node.getPath());
+ }
+
+ protected void collapse(CategoryNode node) {
+ _tree.collapsePath(getTreePath(node));
+ }
+
+ //-----------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeEditorRenderer.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeEditorRenderer.java
new file mode 100644
index 0000000000..57be9fce90
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeEditorRenderer.java
@@ -0,0 +1,84 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import java.awt.Component;
+
+import javax.swing.JCheckBox;
+import javax.swing.JTree;
+
+/**
+ * CategoryNodeEditorRenderer
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryNodeEditorRenderer extends CategoryNodeRenderer {
+ private static final long serialVersionUID = -6094804684259929574L;
+
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public Component getTreeCellRendererComponent(
+ JTree tree, Object value,
+ boolean selected, boolean expanded,
+ boolean leaf, int row,
+ boolean hasFocus) {
+ Component c = super.getTreeCellRendererComponent(tree,
+ value, selected, expanded,
+ leaf, row, hasFocus);
+
+ return c;
+ }
+
+ public JCheckBox getCheckBox() {
+ return _checkBox;
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeRenderer.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeRenderer.java
new file mode 100644
index 0000000000..4eb461dd43
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryNodeRenderer.java
@@ -0,0 +1,151 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import javax.swing.*;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import java.awt.*;
+import java.net.URL;
+
+/**
+ * CategoryNodeRenderer
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryNodeRenderer extends DefaultTreeCellRenderer {
+ private static final long serialVersionUID = -6046702673278595048L;
+
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ public static final Color FATAL_CHILDREN = new Color(189, 113, 0);
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected JCheckBox _checkBox = new JCheckBox();
+ protected JPanel _panel = new JPanel();
+ protected static ImageIcon _sat = null;
+// protected JLabel _label = new JLabel();
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public CategoryNodeRenderer() {
+ _panel.setBackground(UIManager.getColor("Tree.textBackground"));
+
+ if (_sat == null) {
+ // Load the satellite image.
+ String resource =
+ "/org/apache/log4j/lf5/viewer/images/channelexplorer_satellite.gif";
+ URL satURL = getClass().getResource(resource);
+
+ _sat = new ImageIcon(satURL);
+ }
+
+ setOpaque(false);
+ _checkBox.setOpaque(false);
+ _panel.setOpaque(false);
+
+ // The flowlayout set to LEFT is very important so that the editor
+ // doesn't jump around.
+ _panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ _panel.add(_checkBox);
+ _panel.add(this);
+
+ setOpenIcon(_sat);
+ setClosedIcon(_sat);
+ setLeafIcon(_sat);
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ public Component getTreeCellRendererComponent(
+ JTree tree, Object value,
+ boolean selected, boolean expanded,
+ boolean leaf, int row,
+ boolean hasFocus) {
+
+ CategoryNode node = (CategoryNode) value;
+ //FileNode node = (FileNode)value;
+ //String s = tree.convertValueToText(value, selected,
+ // expanded, leaf, row, hasFocus);
+
+ super.getTreeCellRendererComponent(
+ tree, value, selected, expanded,
+ leaf, row, hasFocus);
+
+ if (row == 0) {
+ // Root row -- no check box
+ _checkBox.setVisible(false);
+ } else {
+ _checkBox.setVisible(true);
+ _checkBox.setSelected(node.isSelected());
+ }
+ String toolTip = buildToolTip(node);
+ _panel.setToolTipText(toolTip);
+ if (node.hasFatalChildren()) {
+ this.setForeground(FATAL_CHILDREN);
+ }
+ if (node.hasFatalRecords()) {
+ this.setForeground(Color.red);
+ }
+
+ return _panel;
+ }
+
+ public Dimension getCheckBoxOffset() {
+ return new Dimension(0, 0);
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ protected String buildToolTip(CategoryNode node) {
+ StringBuffer result = new StringBuffer();
+ result.append(node.getTitle()).append(" contains a total of ");
+ result.append(node.getTotalNumberOfRecords());
+ result.append(" LogRecords.");
+ result.append(" Right-click for more info.");
+ return result.toString();
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryPath.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryPath.java
new file mode 100644
index 0000000000..8cc3da1632
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/CategoryPath.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.lf5.viewer.categoryexplorer;
+
+import java.util.LinkedList;
+import java.util.StringTokenizer;
+
+/**
+ * CategoryPath is a collection of CategoryItems which represent a
+ * path of categories.
+ *
+ * @author Michael J. Sikorsky
+ * @author Robert Shaw
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CategoryPath {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+ protected LinkedList _categoryElements = new LinkedList();
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ public CategoryPath() {
+ super();
+ }
+
+ /**
+ * Construct a CategoryPath. If the category is null, it defaults to "Debug".
+ */
+ public CategoryPath(String category) {
+ String processedCategory = category;
+
+ if (processedCategory == null) {
+ processedCategory = "Debug";
+ }
+
+ processedCategory = processedCategory.replace('/', '.');
+ processedCategory = processedCategory.replace('\\', '.');
+
+ StringTokenizer st = new StringTokenizer(processedCategory, ".");
+ while (st.hasMoreTokens()) {
+ String element = st.nextToken();
+ addCategoryElement(new CategoryElement(element));
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * returns the number of CategoryElements.
+ */
+ public int size() {
+ int count = _categoryElements.size();
+
+ return (count);
+ }
+
+ public boolean isEmpty() {
+ boolean empty = false;
+
+ if (_categoryElements.size() == 0) {
+ empty = true;
+ }
+
+ return (empty);
+ }
+
+
+ /**
+ * Removes all categoryElements.
+ */
+ public void removeAllCategoryElements() {
+ _categoryElements.clear();
+ }
+
+ /**
+ * Adds the specified categoryElement to the end of the categoryElement set.
+ */
+ public void addCategoryElement(CategoryElement categoryElement) {
+ _categoryElements.addLast(categoryElement);
+ }
+
+ /**
+ * Returns the CategoryElement at the specified index.
+ */
+ public CategoryElement categoryElementAt(int index) {
+ return ((CategoryElement) _categoryElements.get(index));
+ }
+
+
+ public String toString() {
+ StringBuffer out = new StringBuffer(100);
+
+ out.append("\n");
+ out.append("===========================\n");
+ out.append("CategoryPath: \n");
+ out.append("---------------------------\n");
+
+ out.append("\nCategoryPath:\n\t");
+
+ if (this.size() > 0) {
+ for (int i = 0; i < this.size(); i++) {
+ out.append(this.categoryElementAt(i).toString());
+ out.append("\n\t");
+ }
+ } else {
+ out.append("<>");
+ }
+
+ out.append("\n");
+ out.append("===========================\n");
+
+ return (out.toString());
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/TreeModelAdapter.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/TreeModelAdapter.java
new file mode 100644
index 0000000000..7323dcc08e
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/categoryexplorer/TreeModelAdapter.java
@@ -0,0 +1,75 @@
+/*
+ * 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.lf5.viewer.categoryexplorer;
+
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+
+/**
+ * Default implementation of TreeModelListener which does nothing.
+ *
+ * @author Richard Wan
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class TreeModelAdapter implements TreeModelListener {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+ public void treeNodesChanged(TreeModelEvent e) {
+ }
+
+ public void treeNodesInserted(TreeModelEvent e) {
+ }
+
+ public void treeNodesRemoved(TreeModelEvent e) {
+ }
+
+ public void treeStructureChanged(TreeModelEvent e) {
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/configure/ConfigurationManager.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/configure/ConfigurationManager.java
new file mode 100644
index 0000000000..a94ffab5fa
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/configure/ConfigurationManager.java
@@ -0,0 +1,466 @@
+/*
+ * 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.lf5.viewer.configure;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.tree.TreePath;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.LogLevelFormatException;
+import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
+import org.apache.log4j.lf5.viewer.LogTable;
+import org.apache.log4j.lf5.viewer.LogTableColumn;
+import org.apache.log4j.lf5.viewer.LogTableColumnFormatException;
+import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryExplorerModel;
+import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryExplorerTree;
+import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryNode;
+import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * ConfigurationManager handles the storage and retrival of the state of
+ * the CategoryExplorer
+ *
+ * @author Richard Hurst
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class ConfigurationManager extends Object {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+ private static final String CONFIG_FILE_NAME = "lf5_configuration.xml";
+ private static final String NAME = "name";
+ private static final String PATH = "path";
+ private static final String SELECTED = "selected";
+ private static final String EXPANDED = "expanded";
+ private static final String CATEGORY = "category";
+ private static final String FIRST_CATEGORY_NAME = "Categories";
+ private static final String LEVEL = "level";
+ private static final String COLORLEVEL = "colorlevel";
+ private static final String RED = "red";
+ private static final String GREEN = "green";
+ private static final String BLUE = "blue";
+ private static final String COLUMN = "column";
+ private static final String NDCTEXTFILTER = "searchtext";
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private LogBrokerMonitor _monitor = null;
+ private LogTable _table = null;
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public ConfigurationManager(LogBrokerMonitor monitor, LogTable table) {
+ super();
+ _monitor = monitor;
+ _table = table;
+ load();
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public void save() {
+ CategoryExplorerModel model = _monitor.getCategoryExplorerTree().getExplorerModel();
+ CategoryNode root = model.getRootCategoryNode();
+
+ StringBuffer xml = new StringBuffer(2048);
+ openXMLDocument(xml);
+ openConfigurationXML(xml);
+ processLogRecordFilter(_monitor.getNDCTextFilter(), xml);
+ processLogLevels(_monitor.getLogLevelMenuItems(), xml);
+ processLogLevelColors(_monitor.getLogLevelMenuItems(),
+ LogLevel.getLogLevelColorMap(), xml);
+ processLogTableColumns(LogTableColumn.getLogTableColumns(), xml);
+ processConfigurationNode(root, xml);
+ closeConfigurationXML(xml);
+ store(xml.toString());
+ }
+
+ public void reset() {
+ deleteConfigurationFile();
+ collapseTree();
+ selectAllNodes();
+ }
+
+ public static String treePathToString(TreePath path) {
+ // count begins at one so as to not include the 'Categories' - root category
+ StringBuffer sb = new StringBuffer();
+ CategoryNode n = null;
+ Object[] objects = path.getPath();
+ for (int i = 1; i < objects.length; i++) {
+ n = (CategoryNode) objects[i];
+ if (i > 1) {
+ sb.append(".");
+ }
+ sb.append(n.getTitle());
+ }
+ return sb.toString();
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ protected void load() {
+ File file = new File(getFilename());
+ if (file.exists()) {
+ try {
+ DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.
+ newInstance();
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.parse(file);
+ processRecordFilter(doc);
+ processCategories(doc);
+ processLogLevels(doc);
+ processLogLevelColors(doc);
+ processLogTableColumns(doc);
+ } catch (Exception e) {
+ // ignore all error and just continue as if there was no
+ // configuration xml file but do report a message
+ System.err.println("Unable process configuration file at " +
+ getFilename() + ". Error Message=" + e.getMessage());
+ }
+ }
+
+ }
+
+ // Added in version 1.2 - reads in the NDC text filter from the
+ // xml configuration file. If the value of the filter is not null
+ // or an empty string ("") then the manager will set the LogBrokerMonitor's
+ // LogRecordFilter to use the NDC LogRecordFilter. Otherwise, the
+ // LogBrokerMonitor will use the default LogRecordFilter.
+ protected void processRecordFilter(Document doc) {
+ NodeList nodeList = doc.getElementsByTagName(NDCTEXTFILTER);
+
+ // there is only one value stored
+ Node n = nodeList.item(0);
+ // add check for backwards compatibility as this feature was added in
+ // version 1.2
+ if (n == null) {
+ return;
+ }
+
+ NamedNodeMap map = n.getAttributes();
+ String text = getValue(map, NAME);
+
+ if (text == null || text.equals("")) {
+ return;
+ }
+ _monitor.setNDCLogRecordFilter(text);
+ }
+
+ protected void processCategories(Document doc) {
+ CategoryExplorerTree tree = _monitor.getCategoryExplorerTree();
+ CategoryExplorerModel model = tree.getExplorerModel();
+ NodeList nodeList = doc.getElementsByTagName(CATEGORY);
+
+ // determine where the starting node is
+ NamedNodeMap map = nodeList.item(0).getAttributes();
+ int j = (getValue(map, NAME).equalsIgnoreCase(FIRST_CATEGORY_NAME)) ? 1 : 0;
+ // iterate backwards throught the nodeList so that expansion of the
+ // list can occur
+ for (int i = nodeList.getLength() - 1; i >= j; i--) {
+ Node n = nodeList.item(i);
+ map = n.getAttributes();
+ CategoryNode chnode = model.addCategory(new CategoryPath(getValue(map, PATH)));
+ chnode.setSelected((getValue(map, SELECTED).equalsIgnoreCase("true")) ? true : false);
+ if (getValue(map, EXPANDED).equalsIgnoreCase("true")) ;
+ tree.expandPath(model.getTreePathToRoot(chnode));
+ }
+
+ }
+
+ protected void processLogLevels(Document doc) {
+ NodeList nodeList = doc.getElementsByTagName(LEVEL);
+ Map menuItems = _monitor.getLogLevelMenuItems();
+
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node n = nodeList.item(i);
+ NamedNodeMap map = n.getAttributes();
+ String name = getValue(map, NAME);
+ try {
+ JCheckBoxMenuItem item =
+ (JCheckBoxMenuItem) menuItems.get(LogLevel.valueOf(name));
+ item.setSelected(getValue(map, SELECTED).equalsIgnoreCase("true"));
+ } catch (LogLevelFormatException e) {
+ // ignore it will be on by default.
+ }
+ }
+ }
+
+ protected void processLogLevelColors(Document doc) {
+ NodeList nodeList = doc.getElementsByTagName(COLORLEVEL);
+ LogLevel.getLogLevelColorMap();
+
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node n = nodeList.item(i);
+ // check for backwards compatibility since this feature was added
+ // in version 1.3
+ if (n == null) {
+ return;
+ }
+
+ NamedNodeMap map = n.getAttributes();
+ String name = getValue(map, NAME);
+ try {
+ LogLevel level = LogLevel.valueOf(name);
+ int red = Integer.parseInt(getValue(map, RED));
+ int green = Integer.parseInt(getValue(map, GREEN));
+ int blue = Integer.parseInt(getValue(map, BLUE));
+ Color c = new Color(red, green, blue);
+ if (level != null) {
+ level.setLogLevelColorMap(level, c);
+ }
+
+ } catch (LogLevelFormatException e) {
+ // ignore it will be on by default.
+ }
+ }
+ }
+
+ protected void processLogTableColumns(Document doc) {
+ NodeList nodeList = doc.getElementsByTagName(COLUMN);
+ Map menuItems = _monitor.getLogTableColumnMenuItems();
+ List selectedColumns = new ArrayList();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node n = nodeList.item(i);
+ // check for backwards compatibility since this feature was added
+ // in version 1.3
+ if (n == null) {
+ return;
+ }
+ NamedNodeMap map = n.getAttributes();
+ String name = getValue(map, NAME);
+ try {
+ LogTableColumn column = LogTableColumn.valueOf(name);
+ JCheckBoxMenuItem item =
+ (JCheckBoxMenuItem) menuItems.get(column);
+ item.setSelected(getValue(map, SELECTED).equalsIgnoreCase("true"));
+
+ if (item.isSelected()) {
+ selectedColumns.add(column);
+ }
+ } catch (LogTableColumnFormatException e) {
+ // ignore it will be on by default.
+ }
+
+ if (selectedColumns.isEmpty()) {
+ _table.setDetailedView();
+ } else {
+ _table.setView(selectedColumns);
+ }
+
+ }
+ }
+
+ protected String getValue(NamedNodeMap map, String attr) {
+ Node n = map.getNamedItem(attr);
+ return n.getNodeValue();
+ }
+
+ protected void collapseTree() {
+ // collapse everything except the first category
+ CategoryExplorerTree tree = _monitor.getCategoryExplorerTree();
+ for (int i = tree.getRowCount() - 1; i > 0; i--) {
+ tree.collapseRow(i);
+ }
+ }
+
+ protected void selectAllNodes() {
+ CategoryExplorerModel model = _monitor.getCategoryExplorerTree().getExplorerModel();
+ CategoryNode root = model.getRootCategoryNode();
+ Enumeration all = root.breadthFirstEnumeration();
+ CategoryNode n = null;
+ while (all.hasMoreElements()) {
+ n = (CategoryNode) all.nextElement();
+ n.setSelected(true);
+ }
+ }
+
+ protected void store(String s) {
+
+ try {
+ PrintWriter writer = new PrintWriter(new FileWriter(getFilename()));
+ writer.print(s);
+ writer.close();
+ } catch (IOException e) {
+ // do something with this error.
+ e.printStackTrace();
+ }
+
+ }
+
+ protected void deleteConfigurationFile() {
+ try {
+ File f = new File(getFilename());
+ if (f.exists()) {
+ f.delete();
+ }
+ } catch (SecurityException e) {
+ System.err.println("Cannot delete " + getFilename() +
+ " because a security violation occured.");
+ }
+ }
+
+ protected String getFilename() {
+ String home = System.getProperty("user.home");
+ String sep = System.getProperty("file.separator");
+
+ return home + sep + "lf5" + sep + CONFIG_FILE_NAME;
+ }
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+ private void processConfigurationNode(CategoryNode node, StringBuffer xml) {
+ CategoryExplorerModel model = _monitor.getCategoryExplorerTree().getExplorerModel();
+
+ Enumeration all = node.breadthFirstEnumeration();
+ CategoryNode n = null;
+ while (all.hasMoreElements()) {
+ n = (CategoryNode) all.nextElement();
+ exportXMLElement(n, model.getTreePathToRoot(n), xml);
+ }
+
+ }
+
+ private void processLogLevels(Map logLevelMenuItems, StringBuffer xml) {
+ xml.append("\t\r\n");
+ Iterator it = logLevelMenuItems.keySet().iterator();
+ while (it.hasNext()) {
+ LogLevel level = (LogLevel) it.next();
+ JCheckBoxMenuItem item = (JCheckBoxMenuItem) logLevelMenuItems.get(level);
+ exportLogLevelXMLElement(level.getLabel(), item.isSelected(), xml);
+ }
+
+ xml.append("\t\r\n");
+ }
+
+ private void processLogLevelColors(Map logLevelMenuItems, Map logLevelColors, StringBuffer xml) {
+ xml.append("\t\r\n");
+ // iterate through the list of log levels being used (log4j, jdk1.4, custom levels)
+ Iterator it = logLevelMenuItems.keySet().iterator();
+ while (it.hasNext()) {
+ LogLevel level = (LogLevel) it.next();
+ // for each level, get the associated color from the log level color map
+ Color color = (Color) logLevelColors.get(level);
+ exportLogLevelColorXMLElement(level.getLabel(), color, xml);
+ }
+
+ xml.append("\t\r\n");
+ }
+
+
+ private void processLogTableColumns(List logTableColumnMenuItems, StringBuffer xml) {
+ xml.append("\t\r\n");
+ Iterator it = logTableColumnMenuItems.iterator();
+ while (it.hasNext()) {
+ LogTableColumn column = (LogTableColumn) it.next();
+ JCheckBoxMenuItem item = _monitor.getTableColumnMenuItem(column);
+ exportLogTableColumnXMLElement(column.getLabel(), item.isSelected(), xml);
+ }
+
+ xml.append("\t\r\n");
+ }
+
+ // Added in version 1.2 - stores the NDC text filter in the xml file
+ // for future use.
+ private void processLogRecordFilter(String text, StringBuffer xml) {
+ xml.append("\t<").append(NDCTEXTFILTER).append(" ");
+ xml.append(NAME).append("=\"").append(text).append("\"");
+ xml.append("/>\r\n");
+ }
+
+ private void openXMLDocument(StringBuffer xml) {
+ xml.append("\r\n");
+ }
+
+ private void openConfigurationXML(StringBuffer xml) {
+ xml.append("\r\n");
+ }
+
+ private void closeConfigurationXML(StringBuffer xml) {
+ xml.append("\r\n");
+ }
+
+ private void exportXMLElement(CategoryNode node, TreePath path, StringBuffer xml) {
+ CategoryExplorerTree tree = _monitor.getCategoryExplorerTree();
+
+ xml.append("\t<").append(CATEGORY).append(" ");
+ xml.append(NAME).append("=\"").append(node.getTitle()).append("\" ");
+ xml.append(PATH).append("=\"").append(treePathToString(path)).append("\" ");
+ xml.append(EXPANDED).append("=\"").append(tree.isExpanded(path)).append("\" ");
+ xml.append(SELECTED).append("=\"").append(node.isSelected()).append("\"/>\r\n");
+ }
+
+ private void exportLogLevelXMLElement(String label, boolean selected, StringBuffer xml) {
+ xml.append("\t\t<").append(LEVEL).append(" ").append(NAME);
+ xml.append("=\"").append(label).append("\" ");
+ xml.append(SELECTED).append("=\"").append(selected);
+ xml.append("\"/>\r\n");
+ }
+
+ private void exportLogLevelColorXMLElement(String label, Color color, StringBuffer xml) {
+ xml.append("\t\t<").append(COLORLEVEL).append(" ").append(NAME);
+ xml.append("=\"").append(label).append("\" ");
+ xml.append(RED).append("=\"").append(color.getRed()).append("\" ");
+ xml.append(GREEN).append("=\"").append(color.getGreen()).append("\" ");
+ xml.append(BLUE).append("=\"").append(color.getBlue());
+ xml.append("\"/>\r\n");
+ }
+
+ private void exportLogTableColumnXMLElement(String label, boolean selected, StringBuffer xml) {
+ xml.append("\t\t<").append(COLUMN).append(" ").append(NAME);
+ xml.append("=\"").append(label).append("\" ");
+ xml.append(SELECTED).append("=\"").append(selected);
+ xml.append("\"/>\r\n");
+ }
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
+
+
+
+
+
+
diff --git a/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/configure/MRUFileManager.java b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/configure/MRUFileManager.java
new file mode 100644
index 0000000000..6ff275d4b8
--- /dev/null
+++ b/modules/lf5/src/main/java/org/apache/log4j/lf5/viewer/configure/MRUFileManager.java
@@ -0,0 +1,293 @@
+/*
+ * 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.lf5.viewer.configure;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+
+/**
+ *
MRUFileManager handles the storage and retrival the most
+ * recently opened log files.
+ *
+ * @author Brad Marlborough
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class MRUFileManager {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+ private static final String CONFIG_FILE_NAME = "mru_file_manager";
+ private static final int DEFAULT_MAX_SIZE = 3;
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private int _maxSize = 0;
+ private LinkedList _mruFileList;
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+ public MRUFileManager() {
+ load();
+ setMaxSize(DEFAULT_MAX_SIZE);
+ }
+
+ public MRUFileManager(int maxSize) {
+ load();
+ setMaxSize(maxSize);
+ }
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ /**
+ * Saves a list of MRU files out to a file.
+ */
+ public void save() {
+ File file = new File(getFilename());
+
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(new
+ FileOutputStream(file));
+ oos.writeObject(_mruFileList);
+ oos.flush();
+ oos.close();
+ } catch (Exception e) {
+ // do nothing
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Gets the size of the MRU file list.
+ */
+ public int size() {
+ return _mruFileList.size();
+ }
+
+ /**
+ * Returns a particular file name stored in a MRU file
+ * list based on an index value.
+ */
+ public Object getFile(int index) {
+ if (index < size()) {
+ return _mruFileList.get(index);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a input stream to the resource at the specified index
+ */
+ public InputStream getInputStream(int index) throws IOException,
+ FileNotFoundException {
+ if (index < size()) {
+ Object o = getFile(index);
+ if (o instanceof File) {
+ return getInputStream((File) o);
+ } else {
+ return getInputStream((URL) o);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Adds a file name to the MRU file list.
+ */
+ public void set(File file) {
+ setMRU(file);
+ }
+
+ /**
+ * Adds a url to the MRU file list.
+ */
+ public void set(URL url) {
+ setMRU(url);
+ }
+
+ /**
+ * Gets the list of files stored in the MRU file list.
+ */
+ public String[] getMRUFileList() {
+ if (size() == 0) {
+ return null;
+ }
+
+ String[] ss = new String[size()];
+
+ for (int i = 0; i < size(); i++) {
+ Object o = getFile(i);
+ if (o instanceof File) {
+ ss[i] = ((File) o).getAbsolutePath();
+ } else // must be a url
+ {
+ ss[i] = o.toString();
+ }
+
+ }
+
+ return ss;
+ }
+
+ /**
+ * Moves the the index to the top of the MRU List
+ *
+ * @param index The index to be first in the mru list
+ */
+ public void moveToTop(int index) {
+ _mruFileList.add(0, _mruFileList.remove(index));
+ }
+
+ /**
+ * Creates the directory where the MRU file list will be written.
+ * The "lf5" directory is created in the Documents and Settings
+ * directory on Windows 2000 machines and where ever the user.home
+ * variable points on all other platforms.
+ */
+ public static void createConfigurationDirectory() {
+ String home = System.getProperty("user.home");
+ String sep = System.getProperty("file.separator");
+ File f = new File(home + sep + "lf5");
+ if (!f.exists()) {
+ try {
+ f.mkdir();
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+ /**
+ * Gets an input stream for the corresponding file.
+ *
+ * @param file The file to create the input stream from.
+ * @return InputStream
+ */
+ protected InputStream getInputStream(File file) throws IOException,
+ FileNotFoundException {
+ BufferedInputStream reader =
+ new BufferedInputStream(new FileInputStream(file));
+
+ return reader;
+ }
+
+ /**
+ * Gets an input stream for the corresponding URL.
+ *
+ * @param url The url to create the input stream from.
+ * @return InputStream
+ */
+ protected InputStream getInputStream(URL url) throws IOException {
+ return url.openStream();
+ }
+
+ /**
+ * Adds an object to the mru.
+ */
+ protected void setMRU(Object o) {
+ int index = _mruFileList.indexOf(o);
+
+ if (index == -1) {
+ _mruFileList.add(0, o);
+ setMaxSize(_maxSize);
+ } else {
+ moveToTop(index);
+ }
+ }
+
+ /**
+ * Loads the MRU file list in from a file and stores it in a LinkedList.
+ * If no file exists, a new LinkedList is created.
+ */
+ protected void load() {
+ createConfigurationDirectory();
+ File file = new File(getFilename());
+ if (file.exists()) {
+ try {
+ ObjectInputStream ois = new ObjectInputStream(
+ new FileInputStream(file));
+ _mruFileList = (LinkedList) ois.readObject();
+ ois.close();
+
+ // check that only files and url are in linked list
+ Iterator it = _mruFileList.iterator();
+ while (it.hasNext()) {
+ Object o = it.next();
+ if (!(o instanceof File) && !(o instanceof URL)) {
+ it.remove();
+ }
+ }
+ } catch (Exception e) {
+ _mruFileList = new LinkedList();
+ }
+ } else {
+ _mruFileList = new LinkedList();
+ }
+
+ }
+
+ protected String getFilename() {
+ String home = System.getProperty("user.home");
+ String sep = System.getProperty("file.separator");
+
+ return home + sep + "lf5" + sep + CONFIG_FILE_NAME;
+ }
+
+ /**
+ * Ensures that the MRU list will have a MaxSize.
+ */
+ protected void setMaxSize(int maxSize) {
+ if (maxSize < _mruFileList.size()) {
+ for (int i = 0; i < _mruFileList.size() - maxSize; i++) {
+ _mruFileList.removeLast();
+ }
+ }
+
+ _maxSize = maxSize;
+ }
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces
+ //--------------------------------------------------------------------------
+}
\ No newline at end of file
diff --git a/modules/lf5/src/main/resources/org/apache/log4j/lf5/config/defaultconfig.properties b/modules/lf5/src/main/resources/org/apache/log4j/lf5/config/defaultconfig.properties
new file mode 100644
index 0000000000..5c066d940d
--- /dev/null
+++ b/modules/lf5/src/main/resources/org/apache/log4j/lf5/config/defaultconfig.properties
@@ -0,0 +1,31 @@
+# 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.
+
+# For the general syntax of property based configuration files see the
+# documenation of org.apache.log4j.PropertyConfigurator.
+
+# The root category uses the appender called A1. Since no priority is
+# specified, the root category assumes the default priority for root
+# which is DEBUG in log4j. The root category is the only category that
+# has a default priority. All other categories need not be assigned a
+# priority in which case they inherit their priority from the
+# hierarchy.
+
+log4j.rootCategory=, A1
+
+# A1 is set to be a LogMonitorAppender which outputs to a swing
+# logging console.
+
+log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
diff --git a/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/channelexplorer_new.gif b/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/channelexplorer_new.gif
new file mode 100644
index 0000000000..1cc488d452
Binary files /dev/null and b/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/channelexplorer_new.gif differ
diff --git a/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/channelexplorer_satellite.gif b/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/channelexplorer_satellite.gif
new file mode 100644
index 0000000000..f706cd94bd
Binary files /dev/null and b/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/channelexplorer_satellite.gif differ
diff --git a/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/lf5_small_icon.gif b/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/lf5_small_icon.gif
new file mode 100644
index 0000000000..c17300c52a
Binary files /dev/null and b/modules/lf5/src/main/resources/org/apache/log4j/lf5/viewer/images/lf5_small_icon.gif differ
diff --git a/modules/net/pom.xml b/modules/net/pom.xml
new file mode 100644
index 0000000000..0d13faeb67
--- /dev/null
+++ b/modules/net/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-modules
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-net
+ Apache Log4j-Net
+ Apache Log4j Network Module
+ bundle
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ 2.0.1
+ true
+
+
+ org.apache.log4j.net.*
+ javax.mail.*;resolution:=optional,
+ *
+ http://logging.apache.org/log4j
+
+
+
+
+
+
+
+
+ org.apache.log4j
+ log4j-core
+ ${project.version}
+ compile
+
+
+ javax.mail
+ mail
+ 1.4.1
+ true
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/apache/log4j/net/JMSAppender.java b/modules/net/src/main/java/org/apache/log4j/net/JMSAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/JMSAppender.java
rename to modules/net/src/main/java/org/apache/log4j/net/JMSAppender.java
diff --git a/src/main/java/org/apache/log4j/net/JMSSink.java b/modules/net/src/main/java/org/apache/log4j/net/JMSSink.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/JMSSink.java
rename to modules/net/src/main/java/org/apache/log4j/net/JMSSink.java
diff --git a/src/main/java/org/apache/log4j/net/SMTPAppender.java b/modules/net/src/main/java/org/apache/log4j/net/SMTPAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/SMTPAppender.java
rename to modules/net/src/main/java/org/apache/log4j/net/SMTPAppender.java
diff --git a/src/main/java/org/apache/log4j/net/SimpleSocketServer.java b/modules/net/src/main/java/org/apache/log4j/net/SimpleSocketServer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/SimpleSocketServer.java
rename to modules/net/src/main/java/org/apache/log4j/net/SimpleSocketServer.java
diff --git a/src/main/java/org/apache/log4j/net/SocketAppender.java b/modules/net/src/main/java/org/apache/log4j/net/SocketAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/SocketAppender.java
rename to modules/net/src/main/java/org/apache/log4j/net/SocketAppender.java
diff --git a/src/main/java/org/apache/log4j/net/SocketHubAppender.java b/modules/net/src/main/java/org/apache/log4j/net/SocketHubAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/SocketHubAppender.java
rename to modules/net/src/main/java/org/apache/log4j/net/SocketHubAppender.java
diff --git a/src/main/java/org/apache/log4j/net/SocketNode.java b/modules/net/src/main/java/org/apache/log4j/net/SocketNode.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/SocketNode.java
rename to modules/net/src/main/java/org/apache/log4j/net/SocketNode.java
diff --git a/src/main/java/org/apache/log4j/net/SocketServer.java b/modules/net/src/main/java/org/apache/log4j/net/SocketServer.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/SocketServer.java
rename to modules/net/src/main/java/org/apache/log4j/net/SocketServer.java
diff --git a/src/main/java/org/apache/log4j/net/SyslogAppender.java b/modules/net/src/main/java/org/apache/log4j/net/SyslogAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/SyslogAppender.java
rename to modules/net/src/main/java/org/apache/log4j/net/SyslogAppender.java
diff --git a/src/main/java/org/apache/log4j/net/TelnetAppender.java b/modules/net/src/main/java/org/apache/log4j/net/TelnetAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/TelnetAppender.java
rename to modules/net/src/main/java/org/apache/log4j/net/TelnetAppender.java
diff --git a/src/main/java/org/apache/log4j/net/ZeroConfSupport.java b/modules/net/src/main/java/org/apache/log4j/net/ZeroConfSupport.java
similarity index 100%
rename from src/main/java/org/apache/log4j/net/ZeroConfSupport.java
rename to modules/net/src/main/java/org/apache/log4j/net/ZeroConfSupport.java
diff --git a/src/main/java/org/apache/log4j/net/package.html b/modules/net/src/main/java/org/apache/log4j/net/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/net/package.html
rename to modules/net/src/main/java/org/apache/log4j/net/package.html
diff --git a/tests/src/java/org/apache/log4j/net/SMTPAppenderTest.java b/modules/net/src/test/java/org/apache/log4j/net/SMTPAppenderTest.java
similarity index 96%
rename from tests/src/java/org/apache/log4j/net/SMTPAppenderTest.java
rename to modules/net/src/test/java/org/apache/log4j/net/SMTPAppenderTest.java
index 583a5bd85d..b6ecc22837 100644
--- a/tests/src/java/org/apache/log4j/net/SMTPAppenderTest.java
+++ b/modules/net/src/test/java/org/apache/log4j/net/SMTPAppenderTest.java
@@ -54,7 +54,7 @@ public boolean isTriggeringEvent(final LoggingEvent event) {
* Tests that triggeringPolicy element will set evaluator.
*/
public void testTrigger() {
- DOMConfigurator.configure("input/xml/smtpAppender1.xml");
+ DOMConfigurator.configure("target/test-classes/input/xml/smtpAppender1.xml");
SMTPAppender appender = (SMTPAppender) Logger.getRootLogger().getAppender("A1");
TriggeringEventEvaluator evaluator = appender.getEvaluator();
assertTrue(evaluator instanceof MockTriggeringEventEvaluator);
diff --git a/tests/src/java/org/apache/log4j/net/ShortSocketServer.java b/modules/net/src/test/java/org/apache/log4j/net/ShortSocketServer.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/net/ShortSocketServer.java
rename to modules/net/src/test/java/org/apache/log4j/net/ShortSocketServer.java
diff --git a/tests/src/java/org/apache/log4j/net/SocketAppenderTest.java b/modules/net/src/test/java/org/apache/log4j/net/SocketAppenderTest.java
similarity index 96%
rename from tests/src/java/org/apache/log4j/net/SocketAppenderTest.java
rename to modules/net/src/test/java/org/apache/log4j/net/SocketAppenderTest.java
index 8a18d0ac83..29b4ce295c 100644
--- a/tests/src/java/org/apache/log4j/net/SocketAppenderTest.java
+++ b/modules/net/src/test/java/org/apache/log4j/net/SocketAppenderTest.java
@@ -34,7 +34,7 @@ public SocketAppenderTest(final String testName) {
/* JUnit's setUp and tearDown */
protected void setUp() {
- DOMConfigurator.configure("input/xml/SocketAppenderTestConfig.xml");
+ DOMConfigurator.configure("target/test-classes/input/xml/SocketAppenderTestConfig.xml");
logger = Logger.getLogger(SocketAppenderTest.class);
secondary = (LastOnlyAppender) Logger.getLogger(
diff --git a/tests/src/java/org/apache/log4j/net/SocketServerTestCase.java b/modules/net/src/test/java/org/apache/log4j/net/SocketServerTestCase.java
similarity index 95%
rename from tests/src/java/org/apache/log4j/net/SocketServerTestCase.java
rename to modules/net/src/test/java/org/apache/log4j/net/SocketServerTestCase.java
index 59194076a3..d72f6b2e85 100644
--- a/tests/src/java/org/apache/log4j/net/SocketServerTestCase.java
+++ b/modules/net/src/test/java/org/apache/log4j/net/SocketServerTestCase.java
@@ -142,7 +142,7 @@ public void test2() throws Exception {
new JunitTestRunnerFilter(),
new SunReflectFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/socketServer.2"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/socketServer.2"));
}
/**
@@ -165,7 +165,7 @@ public void test3() throws Exception {
new JunitTestRunnerFilter(),
new SunReflectFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/socketServer.3"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/socketServer.3"));
}
/**
@@ -195,7 +195,7 @@ public void test4() throws Exception {
new JunitTestRunnerFilter(),
new SunReflectFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/socketServer.4"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/socketServer.4"));
}
}
@@ -238,7 +238,7 @@ public void test5() throws Exception {
new JunitTestRunnerFilter(),
new SunReflectFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/socketServer.5"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/socketServer.5"));
}
}
@@ -275,7 +275,7 @@ public void test6() throws Exception {
new JunitTestRunnerFilter(),
new SunReflectFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/socketServer.6"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/socketServer.6"));
}
}
@@ -307,7 +307,7 @@ public void test7() throws Exception {
new Filter[] { cf, new LineNumberFilter(),
new JunitTestRunnerFilter(),
new SunReflectFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/socketServer.7"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/socketServer.7"));
}
}
@@ -349,7 +349,7 @@ public void test8() throws Exception {
new Filter[] { cf, new LineNumberFilter(),
new JunitTestRunnerFilter(),
new SunReflectFilter() });
- assertTrue(Compare.compare(FILTERED, "witness/socketServer.8"));
+ assertTrue(Compare.compare(FILTERED, "target/test-classes/witness/socketServer.8"));
}
}
diff --git a/tests/src/java/org/apache/log4j/net/SyslogAppenderTest.java b/modules/net/src/test/java/org/apache/log4j/net/SyslogAppenderTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/net/SyslogAppenderTest.java
rename to modules/net/src/test/java/org/apache/log4j/net/SyslogAppenderTest.java
diff --git a/tests/src/java/org/apache/log4j/net/TelnetAppenderTest.java b/modules/net/src/test/java/org/apache/log4j/net/TelnetAppenderTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/net/TelnetAppenderTest.java
rename to modules/net/src/test/java/org/apache/log4j/net/TelnetAppenderTest.java
diff --git a/tests/input/socketServer1.properties b/modules/net/src/test/resources/input/socketServer1.properties
similarity index 100%
rename from tests/input/socketServer1.properties
rename to modules/net/src/test/resources/input/socketServer1.properties
diff --git a/tests/input/socketServer2.properties b/modules/net/src/test/resources/input/socketServer2.properties
similarity index 100%
rename from tests/input/socketServer2.properties
rename to modules/net/src/test/resources/input/socketServer2.properties
diff --git a/tests/input/socketServer3.properties b/modules/net/src/test/resources/input/socketServer3.properties
similarity index 100%
rename from tests/input/socketServer3.properties
rename to modules/net/src/test/resources/input/socketServer3.properties
diff --git a/tests/input/socketServer4.properties b/modules/net/src/test/resources/input/socketServer4.properties
similarity index 100%
rename from tests/input/socketServer4.properties
rename to modules/net/src/test/resources/input/socketServer4.properties
diff --git a/tests/input/socketServer5.properties b/modules/net/src/test/resources/input/socketServer5.properties
similarity index 100%
rename from tests/input/socketServer5.properties
rename to modules/net/src/test/resources/input/socketServer5.properties
diff --git a/tests/input/socketServer6.properties b/modules/net/src/test/resources/input/socketServer6.properties
similarity index 100%
rename from tests/input/socketServer6.properties
rename to modules/net/src/test/resources/input/socketServer6.properties
diff --git a/tests/input/socketServer7.properties b/modules/net/src/test/resources/input/socketServer7.properties
similarity index 100%
rename from tests/input/socketServer7.properties
rename to modules/net/src/test/resources/input/socketServer7.properties
diff --git a/tests/input/socketServer8.properties b/modules/net/src/test/resources/input/socketServer8.properties
similarity index 100%
rename from tests/input/socketServer8.properties
rename to modules/net/src/test/resources/input/socketServer8.properties
diff --git a/tests/input/xml/SocketAppenderTestConfig.xml b/modules/net/src/test/resources/input/xml/SocketAppenderTestConfig.xml
similarity index 100%
rename from tests/input/xml/SocketAppenderTestConfig.xml
rename to modules/net/src/test/resources/input/xml/SocketAppenderTestConfig.xml
diff --git a/tests/input/xml/smtpAppender1.xml b/modules/net/src/test/resources/input/xml/smtpAppender1.xml
similarity index 100%
rename from tests/input/xml/smtpAppender1.xml
rename to modules/net/src/test/resources/input/xml/smtpAppender1.xml
diff --git a/modules/nt/pom.xml b/modules/nt/pom.xml
new file mode 100644
index 0000000000..47fcea8461
--- /dev/null
+++ b/modules/nt/pom.xml
@@ -0,0 +1,190 @@
+
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-modules
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-nt
+ Apache Log4j-Windows NT Event Log Appender
+ bundle
+
+
+ ${java.home}/../Classes/classes.jar
+ ${user.home}/.m2/repository
+ build
+
+
+
+
+ org.apache.log4j
+ log4j-core
+ ${project.version}
+
+
+
+
+
+
+ maven-antrun-plugin
+ 1.2
+
+
+
+ process-classes
+ ntdll
+
+
+
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+ test-compile
+ mkdir_tests_output
+
+
+
+
+
+
+ run
+
+
+
+ clean
+ rmdir_tests_output
+
+
+
+
+
+
+
+ run
+
+
+
+ test
+ runAll
+
+
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+ site
+ untag-site
+
+
+
+
+
+
+
+
+
+
+ run
+
+
+
+ post-site
+ post-site
+
+
+
+
+
+
+ run
+
+
+
+ site-deploy
+ site-deploy
+
+
+
+
+
+
+ run
+
+
+
+
+
+ ant
+ ant-nodeps
+ 1.6.5
+
+
+ ant-contrib
+ ant-contrib
+ 1.0b2
+
+
+ ant
+ ant-junit
+ 1.6.5
+
+
+ junit
+ junit
+ 3.8.1
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java b/modules/nt/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java
similarity index 100%
rename from src/main/java/org/apache/log4j/nt/NTEventLogAppender.java
rename to modules/nt/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java
diff --git a/src/main/java/org/apache/log4j/nt/package.html b/modules/nt/src/main/java/org/apache/log4j/nt/package.html
similarity index 100%
rename from src/main/java/org/apache/log4j/nt/package.html
rename to modules/nt/src/main/java/org/apache/log4j/nt/package.html
diff --git a/src/ntdll/EventLogCategories.mc b/modules/nt/src/ntdll/EventLogCategories.mc
similarity index 100%
rename from src/ntdll/EventLogCategories.mc
rename to modules/nt/src/ntdll/EventLogCategories.mc
diff --git a/src/ntdll/MSG00001.bin b/modules/nt/src/ntdll/MSG00001.bin
similarity index 100%
rename from src/ntdll/MSG00001.bin
rename to modules/nt/src/ntdll/MSG00001.bin
diff --git a/NTEventLogAppender.amd64.dll b/modules/nt/src/ntdll/NTEventLogAppender.amd64.dll
similarity index 100%
rename from NTEventLogAppender.amd64.dll
rename to modules/nt/src/ntdll/NTEventLogAppender.amd64.dll
diff --git a/src/ntdll/NTEventLogAppender.def b/modules/nt/src/ntdll/NTEventLogAppender.def
similarity index 100%
rename from src/ntdll/NTEventLogAppender.def
rename to modules/nt/src/ntdll/NTEventLogAppender.def
diff --git a/src/ntdll/NTEventLogAppender.rc b/modules/nt/src/ntdll/NTEventLogAppender.rc
similarity index 100%
rename from src/ntdll/NTEventLogAppender.rc
rename to modules/nt/src/ntdll/NTEventLogAppender.rc
diff --git a/src/ntdll/build.xml b/modules/nt/src/ntdll/build.xml
similarity index 100%
rename from src/ntdll/build.xml
rename to modules/nt/src/ntdll/build.xml
diff --git a/src/ntdll/nteventlog.cpp b/modules/nt/src/ntdll/nteventlog.cpp
similarity index 100%
rename from src/ntdll/nteventlog.cpp
rename to modules/nt/src/ntdll/nteventlog.cpp
diff --git a/tests/src/java/org/apache/log4j/nt/NTEventLogAppenderTest.java b/modules/nt/src/tests/java/org/apache/log4j/nt/NTEventLogAppenderTest.java
similarity index 100%
rename from tests/src/java/org/apache/log4j/nt/NTEventLogAppenderTest.java
rename to modules/nt/src/tests/java/org/apache/log4j/nt/NTEventLogAppenderTest.java
diff --git a/tests/build.xml b/modules/nt/tests/build.xml
similarity index 100%
rename from tests/build.xml
rename to modules/nt/tests/build.xml
diff --git a/modules/performance/pom.xml b/modules/performance/pom.xml
new file mode 100644
index 0000000000..c9531df65f
--- /dev/null
+++ b/modules/performance/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-modules
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-performance
+ Apache Log4j-Performance Code
+ bundle
+
+
+
+ org.apache.log4j
+ log4j-core
+ ${project.version}
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ 2.0.1
+ true
+
+
+ org.apache.log4j.performance.*
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/performance/java/org/apache/log4j/performance/ListVsVector.java b/modules/performance/src/main/java/org/apache/log4j/performance/ListVsVector.java
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/ListVsVector.java
rename to modules/performance/src/main/java/org/apache/log4j/performance/ListVsVector.java
diff --git a/src/performance/java/org/apache/log4j/performance/NOPWriter.java b/modules/performance/src/main/java/org/apache/log4j/performance/NOPWriter.java
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/NOPWriter.java
rename to modules/performance/src/main/java/org/apache/log4j/performance/NOPWriter.java
diff --git a/src/performance/java/org/apache/log4j/performance/NewVsSetLen.java b/modules/performance/src/main/java/org/apache/log4j/performance/NewVsSetLen.java
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/NewVsSetLen.java
rename to modules/performance/src/main/java/org/apache/log4j/performance/NewVsSetLen.java
diff --git a/src/performance/java/org/apache/log4j/performance/NullAppender.java b/modules/performance/src/main/java/org/apache/log4j/performance/NullAppender.java
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/NullAppender.java
rename to modules/performance/src/main/java/org/apache/log4j/performance/NullAppender.java
diff --git a/src/performance/java/org/apache/log4j/performance/SystemTime.java b/modules/performance/src/main/java/org/apache/log4j/performance/SystemTime.java
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/SystemTime.java
rename to modules/performance/src/main/java/org/apache/log4j/performance/SystemTime.java
diff --git a/src/performance/java/org/apache/log4j/performance/history/FALKNIS.logging b/modules/performance/src/main/java/org/apache/log4j/performance/history/FALKNIS.logging
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/history/FALKNIS.logging
rename to modules/performance/src/main/java/org/apache/log4j/performance/history/FALKNIS.logging
diff --git a/src/performance/java/org/apache/log4j/performance/history/GIL.logging b/modules/performance/src/main/java/org/apache/log4j/performance/history/GIL.logging
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/history/GIL.logging
rename to modules/performance/src/main/java/org/apache/log4j/performance/history/GIL.logging
diff --git a/src/performance/java/org/apache/log4j/performance/history/NAPOLI.logging b/modules/performance/src/main/java/org/apache/log4j/performance/history/NAPOLI.logging
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/history/NAPOLI.logging
rename to modules/performance/src/main/java/org/apache/log4j/performance/history/NAPOLI.logging
diff --git a/src/performance/java/org/apache/log4j/performance/history/TORINO.logging b/modules/performance/src/main/java/org/apache/log4j/performance/history/TORINO.logging
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/history/TORINO.logging
rename to modules/performance/src/main/java/org/apache/log4j/performance/history/TORINO.logging
diff --git a/src/performance/java/org/apache/log4j/performance/logging b/modules/performance/src/main/java/org/apache/log4j/performance/logging
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/logging
rename to modules/performance/src/main/java/org/apache/log4j/performance/logging
diff --git a/src/performance/java/org/apache/log4j/performance/package.html b/modules/performance/src/main/java/org/apache/log4j/performance/package.html
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/package.html
rename to modules/performance/src/main/java/org/apache/log4j/performance/package.html
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging1.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging1.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging1.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging1.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging10.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging10.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging10.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging10.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging100.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging100.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging100.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging100.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging1000.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging1000.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging1000.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging1000.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging101.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging101.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging101.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging101.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging102.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging102.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging102.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging102.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging103.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging103.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging103.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging103.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging104.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging104.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging104.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging104.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging105.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging105.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging105.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging105.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging106.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging106.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging106.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging106.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging107.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging107.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging107.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging107.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging11.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging11.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging11.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging11.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging12.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging12.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging12.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging12.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging13.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging13.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging13.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging13.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging2.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging2.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging2.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging2.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging200.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging200.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging200.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging200.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging201.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging201.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging201.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging201.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging202.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging202.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging202.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging202.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging203.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging203.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging203.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging203.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging204.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging204.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging204.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging204.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging205.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging205.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging205.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging205.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging206.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging206.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging206.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging206.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging207.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging207.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging207.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging207.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging220.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging220.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging220.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging220.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging221.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging221.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging221.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging221.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging222.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging222.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging222.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging222.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging223.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging223.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging223.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging223.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging224.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging224.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging224.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging224.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging225.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging225.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging225.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging225.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging226.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging226.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging226.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging226.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging227.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging227.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging227.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging227.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging3.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging3.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging3.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging3.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging300.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging300.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging300.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging300.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging301.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging301.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging301.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging301.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging302.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging302.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging302.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging302.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging303.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging303.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging303.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging303.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging304.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging304.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging304.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging304.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging305.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging305.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging305.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging305.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging306.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging306.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging306.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging306.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging307.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging307.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging307.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging307.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging4.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging4.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging4.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging4.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging5.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging5.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging5.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging5.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging6.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging6.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging6.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging6.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging7.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging7.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging7.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging7.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging8.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging8.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging8.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging8.xml
diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging9.xml b/modules/performance/src/main/java/org/apache/log4j/performance/xml/logging9.xml
similarity index 100%
rename from src/performance/java/org/apache/log4j/performance/xml/logging9.xml
rename to modules/performance/src/main/java/org/apache/log4j/performance/xml/logging9.xml
diff --git a/modules/pom.xml b/modules/pom.xml
new file mode 100644
index 0000000000..2c0821d0cd
--- /dev/null
+++ b/modules/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+
+ org.apache.log4j
+ log4j-parent
+ 1.4.0-SNAPSHOT
+
+ org.apache.log4j
+ log4j-modules
+ Apache Log4j-Modules POM
+ Apache Log4j Modules Container
+ pom
+
+
+ chainsaw
+ contribs
+ lf5
+ net
+
+ performance
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index cfacd832ff..582bc3e609 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,27 +15,20 @@
limitations under the License.
-->
-
-
+
4.0.0
- log4j
- log4j
- bundle
- Apache Log4j
- 1.2.18-SNAPSHOT
- Apache Log4j 1.2
- http://logging.apache.org/log4j/1.2/
+ org.apache.log4j
+ log4j-parent
+ pom
+ Apache Log4j-Parent POM
+ 1.4.0-SNAPSHOT
+ Apache Log4j parent module container.
+ http://logging.apache.org/log4j/
+
+ core
+ modules
+
+
Bugzilla
https://issues.apache.org/bugzilla/describecomponents.cgi?product=Log4j
@@ -98,52 +91,7 @@ target platform and specify -Dntdll_target=msbuild on the mvn command line.
maven-surefire-plugin
2.5
- tests
- plain
pertest
- false
-
- org/apache/log4j/LevelTest.java
- org/apache/log4j/PriorityTest.java
- org/apache/log4j/CategoryTest.java
- org/apache/log4j/FileAppenderTest.java
- org/apache/log4j/LogManagerTest.java
- org/apache/log4j/helpers.LogLogTest.java
- org/apache/log4j/LayoutTest.java
- org/apache/log4j/helpers.DateLayoutTest.java
- org/apache/log4j/TTCCLayoutTest.java
- org/apache/log4j/xml.XMLLayoutTest.java
- org/apache/log4j/HTMLLayoutTest.java
- org/apache/log4j/PatternLayoutTest.java
- org/apache/log4j/spi.LoggingEventTest.java
- org/apache/log4j/spi.ThrowableInformationTest.java
- org/apache/log4j/spi.LocationInfoTest.java
- org/apache/log4j/PropertyConfiguratorTest.java
- org/apache/log4j/MinimumTestCase.java
- org/apache/log4j/LoggerTestCase.java
- org/apache/log4j/PatternLayoutTestCase.java
- org/apache/log4j/HierarchyThresholdTestCase.java
- org/apache/log4j/xml/DOMTestCase.java
- org/apache/log4j/xml/CustomLevelTestCase.java
- org/apache/log4j/customLogger/XLoggerTestCase.java
-
-
- org/apache/log4j/xml/XMLLayoutTestCase.java
- org/apache/log4j/xml/AsyncAppenderTestCase.java
- org/apache/log4j/varia/LevelMatchFilterTestCase.java
-
-
- org/apache/log4j/helpers/BoundedFIFOTestCase.java
- org/apache/log4j/helpers/CyclicBufferTestCase.java
- org/apache/log4j/helpers/PatternParserTestCase.java
- org/apache/log4j/or/ORTestCase.java
- org/apache/log4j/DRFATestCase.java
- org/apache/log4j/RFATestCase.java
- org/apache/log4j/varia/ERFATestCase.java
- org/apache/log4j/net/SyslogAppenderTest
- org/apache/log4j/nt/NTEventLogAppenderTest
- org/apache/log4j/net/SocketAppenderTest
-
@@ -155,204 +103,6 @@ target platform and specify -Dntdll_target=msbuild on the mvn command line.
UTF-8
-
- maven-jar-plugin
- 2.3
-
-
-
-
- org/apache/log4j/
-
- *
- log4j
- ${project.version}
- "Apache Software Foundation"
-
-
-
-
-
-
-
- maven-antrun-plugin
- 1.2
-
-
-
- process-classes
- ntdll
-
-
-
-
-
-
-
-
-
-
-
- run
-
-
-
-
-
-
- site
- untag-site
-
-
-
-
-
-
-
-
-
-
- run
-
-
-
-
-
-
-
-
-
- javadoc.resources
- generate-sources
-
- run
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ant
- ant-nodeps
- 1.6.5
-
-
- ant-contrib
- ant-contrib
- 1.0b2
-
-
- ant
- ant-junit
- 1.6.5
-
-
- junit
- junit
- 3.8.1
- compile
-
-
- sun.jdk
- tools
- 1.4.2
- system
- ${tools.jar}
-
-
-
maven-assembly-plugin
2.2-beta-5
@@ -430,11 +180,9 @@ target platform and specify -Dntdll_target=msbuild on the mvn command line.
rat-maven-plugin
1.0-alpha-3
-
- tests/witness/**
- tests/output/**
- tests/classes/**
-
+
+ src/tests/witness/**
+
@@ -471,98 +219,8 @@ target platform and specify -Dntdll_target=msbuild on the mvn command line.
- tests/src/java
-
-
- tests/resources
-
-
-
-
-
- maven-project-info-reports-plugin
- 2.4
-
-
-
- scm
- dependencies
- cim
- issue-tracking
- mailing-list
- license
-
-
-
-
-
- maven-jxr-plugin
- 2.1
-
-
- maven-changes-plugin
- 2.7
-
-
-
- changes-report
-
-
-
-
-
-
-
-
- mac
-
-
- mac
-
-
-
- ${java.home}/../Classes/classes.jar
- ${user.home}/.m2/repository
- build
-
-
-
- default
-
- true
-
-
- ${java.home}/../lib/tools.jar
- ${user.home}/.m2/repository
- build
-
-
-
-
-
- maven2-repository.dev.java.net
- Java.net Repository for Maven
- http://download.java.net/maven/2/
- default
-
-
-
- javax.mail
- mail
- 1.4.3
- true
-
-
- org.apache.openejb
- javaee-api
- 5.0-2
- jar
- provided
-
-
oro
oro