You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2008/01/27 03:36:01 UTC

svn commit: r615546 - in /logging/log4cxx/trunk/src: main/cpp/ main/include/log4cxx/ main/include/log4cxx/spi/ main/include/log4cxx/xml/ test/cpp/ test/cpp/xml/ test/resources/witness/

Author: carnold
Date: Sat Jan 26 18:35:58 2008
New Revision: 615546

URL: http://svn.apache.org/viewvc?rev=615546&view=rev
Log:
LOGCXX-60: Port log4j XMLLayout enhancements

Added:
    logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttest.cpp
      - copied, changed from r612852, logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java
Modified:
    logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp
    logging/log4cxx/trunk/src/main/cpp/transform.cpp
    logging/log4cxx/trunk/src/main/cpp/xmllayout.cpp
    logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.h.in
    logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.hw
    logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h
    logging/log4cxx/trunk/src/main/include/log4cxx/xml/xmllayout.h
    logging/log4cxx/trunk/src/test/cpp/Makefile.am
    logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttestcase.cpp
    logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.1
    logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.2
    logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.3
    logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.1
    logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.2
    logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.null

Modified: logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp Sat Jan 26 18:35:58 2008
@@ -129,9 +129,9 @@
 
 }
 
-std::set<LogString> LoggingEvent::getMDCKeySet() const
+LoggingEvent::KeySet LoggingEvent::getMDCKeySet() const
 {
-        std::set<LogString> set;
+        LoggingEvent::KeySet set;
 
         if (mdcCopy != 0 && !mdcCopy->empty())
         {
@@ -184,9 +184,9 @@
         return false;
 }
 
-std::set<LogString> LoggingEvent::getPropertyKeySet() const
+LoggingEvent::KeySet LoggingEvent::getPropertyKeySet() const
 {
-        std::set<LogString> set;
+        LoggingEvent::KeySet set;
 
         if (properties != 0)
         {

Modified: logging/log4cxx/trunk/src/main/cpp/transform.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/transform.cpp?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/transform.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/transform.cpp Sat Jan 26 18:35:58 2008
@@ -33,26 +33,42 @@
    {
       return;
    }
-
-   LogString::const_iterator it = input.begin();
-   LogString::const_iterator itEnd = input.end();
-   logchar ch;
-   while(it != itEnd)
-   {
-      ch = *it++;
-      if(ch == 0x3C /* '<' */)
-      {
-         buf.append(LOG4CXX_STR("&lt;"));
-      }
-      else if(ch == 0x3E /* '>' */)
-      {
-         buf.append(LOG4CXX_STR("&gt;"));
-      }
-      else
-      {
-         buf.append(1, ch);
-      }
+   
+   logchar specials[] = { 0x22 /* " */, 0x26 /* & */, 0x3C /* < */, 0x3E /* > */ };
+   size_t start = 0;
+   size_t special = input.find_first_of(specials, start);
+   while(special != LogString::npos) {
+        if (special > start) {
+            buf.append(input, start, special - start);
+        }
+        switch(input[special]) {
+            case 0x22:
+            buf.append(LOG4CXX_STR("&quot;"));
+            break;
+            
+            case 0x26:
+            buf.append(LOG4CXX_STR("&amp;"));
+            break;
+            
+            case 0x3C:
+            buf.append(LOG4CXX_STR("&lt;"));
+            break;
+            
+            default:
+            buf.append(LOG4CXX_STR("&gt;"));
+            break;
+        }
+        start = special+1;
+        if (special < input.size()) {
+            special = input.find_first_of(specials, start);
+        } else {
+            special = LogString::npos;
+        }
    }
+   
+   if (start < input.size()) {
+        buf.append(input, start, input.size() - start);
+    }
 }
 
 void Transform::appendEscapingCDATA(

Modified: logging/log4cxx/trunk/src/main/cpp/xmllayout.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/xmllayout.cpp?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/xmllayout.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/xmllayout.cpp Sat Jan 26 18:35:58 2008
@@ -35,7 +35,7 @@
 IMPLEMENT_LOG4CXX_OBJECT(XMLLayout)
 
 XMLLayout::XMLLayout()
-: locationInfo(false)
+: locationInfo(false), properties(false)
 {
 }
 
@@ -46,6 +46,10 @@
         {
                 setLocationInfo(OptionConverter::toBoolean(value, false));
         }
+        if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("PROPERTIES"), LOG4CXX_STR("properties")))
+        {
+                setProperties(OptionConverter::toBoolean(value, false));
+        }
 }
 
 void XMLLayout::format(LogString& output,
@@ -53,108 +57,80 @@
      Pool& p) const
 {
         output.append(LOG4CXX_STR("<log4j:event logger=\""));
-        output.append(event->getLoggerName());
+        Transform::appendEscapingTags(output, event->getLoggerName());
         output.append(LOG4CXX_STR("\" timestamp=\""));
         StringHelper::toString(event->getTimeStamp()/1000L, p, output);
         output.append(LOG4CXX_STR("\" level=\""));
-        output.append(event->getLevel()->toString());
+        Transform::appendEscapingTags(output, event->getLevel()->toString());
         output.append(LOG4CXX_STR("\" thread=\""));
-        output.append(event->getThreadName());
-        output.append(LOG4CXX_STR("\">"));
-        output.append(LOG4CXX_EOL);
+        Transform::appendEscapingTags(output, event->getThreadName());
+        output.append(LOG4CXX_STR("\">\r\n"));
 
         output.append(LOG4CXX_STR("<log4j:message><![CDATA["));
         // Append the rendered message. Also make sure to escape any
         // existing CDATA sections.
         Transform::appendEscapingCDATA(output, event->getRenderedMessage());
-        output.append(LOG4CXX_STR("]]></log4j:message>"));
-        output.append(LOG4CXX_EOL);
+        output.append(LOG4CXX_STR("]]></log4j:message>\r\n"));
 
         LogString ndc;
         if(event->getNDC(ndc)) {
                 output.append(LOG4CXX_STR("<log4j:NDC><![CDATA["));
-                output.append(ndc);
-                output.append(LOG4CXX_STR("]]></log4j:NDC>"));
-                output.append(LOG4CXX_EOL);
+                Transform::appendEscapingCDATA(output, ndc);
+                output.append(LOG4CXX_STR("]]></log4j:NDC>\r\n"));
         }
 
-        //
-        //  TODO: looks pretty inefficient if empty
-        //
-        std::set<LogString> mdcKeySet = event->getMDCKeySet();
-
-        if(!mdcKeySet.empty()) {
-                /**
-                * Normally a sort isn't required, but for Test Case purposes
-                * we need to guarantee a particular order.
-                *
-                * Besides which, from a human readable point of view, the sorting
-                * of the keys is kinda nice..
-                */
-
-                output.append(LOG4CXX_STR("<log4j:MDC>"));
-                output.append(LOG4CXX_EOL);
-                for (std::set<LogString>::iterator i = mdcKeySet.begin();
-                        i != mdcKeySet.end(); i++)
-                {
-                        LogString propName = *i;
-                        LogString propValue;
-                        if(event->getMDC(propName, propValue)) {
-                            output.append(LOG4CXX_STR("    <log4j:data name=\""));
-                            output.append(propName);
-                            output.append(LOG4CXX_STR("\" value=\""));
-                            output.append(propValue);
-                            output.append(LOG4CXX_STR("\"/>"));
-                            output.append(LOG4CXX_EOL);
-                        }
-                }
-                output.append(LOG4CXX_STR("</log4j:MDC>"));
-                output.append(LOG4CXX_EOL);
-    }
-
         if(locationInfo)
         {
                 output.append(LOG4CXX_STR("<log4j:locationInfo class=\""));
                 const LocationInfo& locInfo = event->getLocationInformation();
                 LOG4CXX_DECODE_CHAR(className, locInfo.getClassName());
-                output.append(className);
+                Transform::appendEscapingTags(output, className);
                 output.append(LOG4CXX_STR("\" method=\""));
                 LOG4CXX_DECODE_CHAR(method, locInfo.getMethodName());
-                output.append(method);
+                Transform::appendEscapingTags(output, method);
                 output.append(LOG4CXX_STR("\" file=\""));
                 LOG4CXX_DECODE_CHAR(fileName, locInfo.getFileName());
-                output.append(fileName);
+                Transform::appendEscapingTags(output, fileName);
                 output.append(LOG4CXX_STR("\" line=\""));
                 StringHelper::toString(locInfo.getLineNumber(), p, output);
-                output.append(LOG4CXX_STR("\"/>"));
-                output.append(LOG4CXX_EOL);
+                output.append(LOG4CXX_STR("\"/>\r\n"));
         }
-
-    std::set<LogString> propertySet = event->getPropertyKeySet();
-
-    if (!propertySet.empty())
-        {
-                output.append(LOG4CXX_STR("<log4j:properties>"));
-                output.append(LOG4CXX_EOL);
-                for (std::set<LogString>::iterator i = propertySet.begin();
-                        i != propertySet.end(); i++)
-                {
-                        LogString propName = *i;
-                        LogString propValue;
-                        if(event->getProperty(propName, propValue)) {
+        
+        if (properties) {
+            LoggingEvent::KeySet propertySet(event->getPropertyKeySet());
+            LoggingEvent::KeySet keySet(event->getMDCKeySet());
+            if (!(keySet.empty() && propertySet.empty())) {
+                output.append(LOG4CXX_STR("<log4j:properties>\r\n"));
+                for (LoggingEvent::KeySet::const_iterator i = keySet.begin();
+                        i != keySet.end(); 
+                        i++) {
+                        LogString key(*i);
+                        LogString value;
+                        if(event->getMDC(key, value)) {
                             output.append(LOG4CXX_STR("<log4j:data name=\""));
-                            output.append(propName);
+                            Transform::appendEscapingTags(output, key);
                             output.append(LOG4CXX_STR("\" value=\""));
-                            output.append(propValue);
-                            output.append(LOG4CXX_STR("\"/>"));
-                            output.append(LOG4CXX_EOL);
+                            Transform::appendEscapingTags(output, value);
+                            output.append(LOG4CXX_STR("\"/>\r\n"));
                         }
                 }
-                output.append(LOG4CXX_STR("</log4j:properties>"));
-                output.append(LOG4CXX_EOL);
-    }
+                for (LoggingEvent::KeySet::const_iterator i = propertySet.begin();
+                        i != propertySet.end(); 
+                        i++) {
+                        LogString key(*i);
+                        LogString value;
+                        if(event->getProperty(key, value)) {
+                            output.append(LOG4CXX_STR("<log4j:data name=\""));
+                            Transform::appendEscapingTags(output, key);
+                            output.append(LOG4CXX_STR("\" value=\""));
+                            Transform::appendEscapingTags(output, value);
+                            output.append(LOG4CXX_STR("\"/>\r\n"));
+                        }
+                }
+                output.append(LOG4CXX_STR("</log4j:properties>\r\n"));
+            }
+        }
 
-        output.append(LOG4CXX_STR("</log4j:event>"));
-        output.append(LOG4CXX_EOL);
+        output.append(LOG4CXX_STR("</log4j:event>\r\n\r\n"));
 }
 

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.h.in
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.h.in?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.h.in (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.h.in Sat Jan 26 18:35:58 2008
@@ -46,6 +46,7 @@
 #define LOG4CXX_EXPORT
 #define LOG4CXX_PTR_DEF(T) typedef log4cxx::helpers::ObjectPtrT<T> T##Ptr;
 #define LOG4CXX_LIST_DEF(N, T) typedef std::vector<T> N;
+#define LOG4CXX_SET_DEF(N, T) typedef std::set<T> N;
 
 
 #endif

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.hw
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.hw?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.hw (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/log4cxx.hw Sat Jan 26 18:35:58 2008
@@ -55,6 +55,7 @@
 #define LOG4CXX_EXPORT
 #define LOG4CXX_PTR_DEF(T) typedef log4cxx::helpers::ObjectPtrT<T> T##Ptr;
 #define LOG4CXX_LIST_DEF(N, T) typedef std::vector<T> N;
+#define LOG4CXX_SET_DEF(N, T) typedef std::set<T> N;
 
 //   definitions used when building DLL
 #elif defined(LOG4CXX)
@@ -68,6 +69,11 @@
 template class LOG4CXX_EXPORT std::vector<T>; \
 typedef std::vector<T> N;
 
+#define LOG4CXX_SET_DEF(N, T) \
+template class LOG4CXX_EXPORT std::allocator<T>; \
+template class LOG4CXX_EXPORT std::set<T>; \
+typedef std::set<T> N;
+
 #else
 //    definitions used when using DLL
 #define LOG4CXX_EXPORT __declspec(dllimport)
@@ -79,6 +85,11 @@
 extern template class LOG4CXX_EXPORT std::allocator<T>; \
 extern template class LOG4CXX_EXPORT std::vector<T>; \
 typedef std::vector<T> N;
+
+#define LOG4CXX_SET_DEF(N, T) \
+extern template class LOG4CXX_EXPORT std::allocator<T>; \
+extern template class LOG4CXX_EXPORT std::set<T>; \
+typedef std::set<T> N;
 
 #endif
 

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h Sat Jan 26 18:35:58 2008
@@ -158,6 +158,7 @@
                         */
                         bool getMDC(const LogString& key, LogString& dest) const;
 
+                        LOG4CXX_SET_DEF(KeySet, LogString)
                         /**
                         * Returns the set of of the key values in the MDC for the event.
                         * The returned set is unmodifiable by the caller.
@@ -165,7 +166,7 @@
                         * @return Set an unmodifiable set of the MDC keys.
                         * @since 1.3
                         */
-                        std::set<LogString> getMDCKeySet() const;
+                        KeySet getMDCKeySet() const;
 
                         /**
                         Obtain a copy of this thread's MDC prior to serialization
@@ -186,7 +187,7 @@
                         *
                         * @return Set an unmodifiable set of the property keys.
                         */
-                        std::set<LogString> getPropertyKeySet() const;
+                        KeySet getPropertyKeySet() const;
 
                         /**
                         * Set a string property using a key and a string value.  since 1.3

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/xml/xmllayout.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/xml/xmllayout.h?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/xml/xmllayout.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/xml/xmllayout.h Sat Jan 26 18:35:58 2008
@@ -58,6 +58,7 @@
 
                         // Print no location info by default
                         bool locationInfo; //= false
+                        bool properties; // = false
 
                 public:
                         DECLARE_LOG4CXX_OBJECT(XMLLayout)
@@ -87,6 +88,25 @@
                         */
                         inline bool getLocationInfo() const
                                 { return locationInfo; }
+                                
+                        /**
+                         * Sets whether MDC key-value pairs should be output, default false.
+                         * @param flag new value.
+                         * @since 0.10
+                        */
+                        inline void setProperties(bool flag) {
+                            properties = flag;
+                        }
+
+                        /**
+                        * Gets whether MDC key-value pairs should be output.
+                        * @return true if MDC key-value pairs are output.
+                        * @since 0.10
+                        */
+                        inline bool getProperties() {
+                            return properties;
+                        }
+                              
 
                         /** No options to activate. */
                         void activateOptions(log4cxx::helpers::Pool& /* p */) { }

Modified: logging/log4cxx/trunk/src/test/cpp/Makefile.am
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/Makefile.am?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/Makefile.am (original)
+++ logging/log4cxx/trunk/src/test/cpp/Makefile.am Sat Jan 26 18:35:58 2008
@@ -111,7 +111,8 @@
 	xml/customleveltestcase.cpp \
 	xml/domtestcase.cpp \
 	xml/xlevel.cpp \
-	xml/xmllayouttestcase.cpp
+	xml/xmllayouttestcase.cpp \
+    xml/xmllayouttest.cpp
 
 nt_tests = \
 	nt/nteventlogappendertestcase.cpp

Copied: logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttest.cpp (from r612852, logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java)
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttest.cpp?p2=logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttest.cpp&p1=logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java&r1=612852&r2=615546&rev=615546&view=diff
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java (original)
+++ logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttest.cpp Sat Jan 26 18:35:58 2008
@@ -15,37 +15,62 @@
  * limitations under the License.
  */
 
-package org.apache.log4j.xml;
-
-import org.apache.log4j.Layout;
-import org.apache.log4j.LayoutTest;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.apache.log4j.NDC;
-import org.apache.log4j.MDC;
-import org.apache.log4j.spi.LoggingEvent;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import org.xml.sax.InputSource;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Hashtable;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
 
+#include <log4cxx/logger.h>
+#include <log4cxx/xml/xmllayout.h>
+#include <log4cxx/fileappender.h>
+#include <log4cxx/mdc.h>
+
+#include "../util/transformer.h"
+#include "../util/compare.h"
+#include "../util/xmltimestampfilter.h"
+#include "../util/xmllineattributefilter.h"
+#include "../util/xmlthreadfilter.h"
+#include "../util/filenamefilter.h"
+#include <iostream>
+#include <log4cxx/helpers/stringhelper.h>
+#include "../testchar.h"
+#include <log4cxx/spi/loggerrepository.h>
+#include <apr_xml.h>
+#include <log4cxx/ndc.h>
+#include <log4cxx/mdc.h>
+#include "../xml/xlevel.h"
+#include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/helpers/transcoder.h>
+
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+using namespace log4cxx::xml;
+using namespace log4cxx::spi;
+
+#if defined(__LOG4CXX_FUNC__)
+#undef __LOG4CXX_FUNC__
+#define __LOG4CXX_FUNC__ "X::X()"
+#else
+#error __LOG4CXX_FUNC__ expected to be defined
+#endif
 /**
  * Test for XMLLayout.
  *
- * @author Curt Arnold
  */
-public class XMLLayoutTest extends LayoutTest {
+class XMLLayoutTest : public CppUnit::TestFixture {
+        CPPUNIT_TEST_SUITE(XMLLayoutTest);
+                CPPUNIT_TEST(testGetContentType);
+                CPPUNIT_TEST(testIgnoresThrowable);
+                CPPUNIT_TEST(testGetHeader);
+                CPPUNIT_TEST(testGetFooter);
+                CPPUNIT_TEST(testFormat);
+                CPPUNIT_TEST(testFormatWithNDC);
+                CPPUNIT_TEST(testGetSetLocationInfo);
+                CPPUNIT_TEST(testActivateOptions);
+                CPPUNIT_TEST(testProblemCharacters);
+                CPPUNIT_TEST(testNDCWithCDATA);
+        CPPUNIT_TEST_SUITE_END();
+
+#if 0
   /**
    * Construct new instance of XMLLayoutTest.
    *
@@ -54,63 +79,132 @@
   public XMLLayoutTest(final String testName) {
     super(testName, "text/plain", false, null, null);
   }
-
+#endif  
+  
+public:  
     /**
      * Clear MDC and NDC before test.
      */
-  public void setUp() {
-      NDC.clear();
-      if (MDC.getContext() != null) {
-        MDC.getContext().clear();
-      }
+  void setUp() {
+      NDC::clear();
+      MDC::clear();
   }
 
     /**
      * Clear MDC and NDC after test.
      */
-  public void tearDown() {
+  void tearDown() {
       setUp();
   }
 
+
+public:
+  /**
+   * Tests getContentType.
+   */
+  void testGetContentType() {
+    LogString expected(LOG4CXX_STR("text/plain"));
+    LogString actual(XMLLayout().getContentType());
+    CPPUNIT_ASSERT(expected == actual);
+  }
+
   /**
-   * @{inheritDoc}
+   * Tests ignoresThrowable.
    */
-  protected Layout createLayout() {
-    return new XMLLayout();
+  void testIgnoresThrowable() {
+    CPPUNIT_ASSERT_EQUAL(false, XMLLayout().ignoresThrowable());
   }
 
   /**
+   * Tests getHeader.
+   */
+  void testGetHeader() {
+    Pool p;
+    LogString header;
+    XMLLayout().appendHeader(header, p);
+    CPPUNIT_ASSERT_EQUAL((size_t) 0, header.size());
+  }
+
+  /**
+   * Tests getFooter.
+   */
+  void testGetFooter() {
+    Pool p;
+    LogString footer;
+    XMLLayout().appendFooter(footer, p);
+    CPPUNIT_ASSERT_EQUAL((size_t) 0, footer.size());
+  }
+
+private:
+  /**
    * Parses the string as the body of an XML document and returns the document element.
    * @param source source string.
    * @return document element.
    * @throws Exception if parser can not be constructed or source is not a valid XML document.
    */
-  private Element parse(final String source) throws Exception {
-    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-    factory.setNamespaceAware(false);
-    factory.setCoalescing(true);
-
-    DocumentBuilder builder = factory.newDocumentBuilder();
-    Reader reader = new StringReader(source);
-    Document doc = builder.parse(new InputSource(reader));
-
-    return doc.getDocumentElement();
+  static apr_xml_elem* parse(const LogString& source, Pool& p) {
+    char backing[3000];
+    ByteBuffer buf(backing, sizeof(backing));
+    CharsetEncoderPtr encoder(CharsetEncoder::getUTF8Encoder());
+    LogString header(LOG4CXX_STR("<log4j:eventSet xmlns:log4j='http://jakarta.apache.org/log4j/'>"));
+    LogString::const_iterator iter(header.begin());
+    encoder->encode(header, iter, buf);
+    CPPUNIT_ASSERT(iter == header.end());
+    iter = source.begin();
+    encoder->encode(source, iter, buf);
+    CPPUNIT_ASSERT(iter == source.end());
+    LogString footer(LOG4CXX_STR("</log4j:eventSet>"));
+    iter = footer.begin();
+    encoder->encode(footer, iter, buf);
+    buf.flip();
+    apr_pool_t* apr_pool = (apr_pool_t*) p.getAPRPool();
+    apr_xml_parser* parser = apr_xml_parser_create(apr_pool);
+    CPPUNIT_ASSERT(parser != 0);
+    apr_status_t stat = apr_xml_parser_feed(parser, buf.data(), buf.remaining());
+    CPPUNIT_ASSERT_EQUAL(APR_SUCCESS, stat);
+    apr_xml_doc* doc = 0;
+    stat = apr_xml_parser_done(parser, &doc);
+    CPPUNIT_ASSERT(doc != 0);
+    apr_xml_elem* eventSet = doc->root;
+    CPPUNIT_ASSERT(eventSet != 0);
+    apr_xml_elem* event = eventSet->first_child;
+    CPPUNIT_ASSERT(event != 0);
+    return event;    
+  }
+
+  std::string getAttribute(apr_xml_elem* elem, const char* attrName) {
+     for(apr_xml_attr* attr = elem->attr;
+         attr != NULL;
+         attr = attr->next) {
+         if (strcmp(attr->name, attrName) == 0) {
+            return attr->value;
+         }
+     }
+     return "";
+  }
+
+  std::string getText(apr_xml_elem* elem) {
+    std::string dMessage;
+        for(apr_text* t = elem->first_cdata.first;
+            t != NULL;
+            t = t->next) {
+            dMessage.append(t->text);
+        }
+    return dMessage;
   }
-
   /**
    * Checks a log4j:event element against expectations.
    * @param element element, may not be null.
    * @param event event, may not be null.
    */
-  private void checkEventElement(
-    final Element element, final LoggingEvent event) {
-    assertEquals("log4j:event", element.getTagName());
-    assertEquals(
-      event.getLoggerName(), element.getAttribute("logger"));
-    assertEquals(
-      Long.toString(event.timeStamp), element.getAttribute("timestamp"));
-    assertEquals(event.getLevel().toString(), element.getAttribute("level"));
-    assertEquals(event.getThreadName(), element.getAttribute("thread"));
+  void checkEventElement(
+    apr_xml_elem* element, LoggingEventPtr& event) {
+    std::string tagName("event");
+    CPPUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);
+    LOG4CXX_ENCODE_CHAR(cLoggerName, event->getLoggerName());
+    CPPUNIT_ASSERT_EQUAL(cLoggerName, getAttribute(element, "logger"));
+    LOG4CXX_ENCODE_CHAR(cLevelName, event->getLevel()->toString());
+    CPPUNIT_ASSERT_EQUAL(cLevelName, getAttribute(element, "level"));
   }
 
   /**
@@ -118,15 +212,11 @@
    * @param element element, may not be null.
    * @param message expected message.
    */
-  private void checkMessageElement(
-    final Element element, final String message) {
-    assertEquals("log4j:message", element.getTagName());
-
-    Node messageNode = element.getFirstChild();
-    assertNotNull(messageNode);
-    assertEquals(Node.TEXT_NODE, messageNode.getNodeType());
-    assertEquals(message, messageNode.getNodeValue());
-    assertNull(messageNode.getNextSibling());
+  void checkMessageElement(
+    apr_xml_elem* element, std::string message) {
+    std::string tagName = "message";
+    CPPUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);
+    CPPUNIT_ASSERT_EQUAL(message, getText(element));
   }
 
   /**
@@ -134,33 +224,13 @@
    * @param element element, may not be null.
    * @param message expected message.
    */
-  private void checkNDCElement(final Element element, final String message) {
-    assertEquals("log4j:NDC", element.getTagName());
-
-    Node messageNode = element.getFirstChild();
-    assertNotNull(messageNode);
-    assertEquals(Node.TEXT_NODE, messageNode.getNodeType());
-    assertEquals(message, messageNode.getNodeValue());
-    assertNull(messageNode.getNextSibling());
+  void checkNDCElement(apr_xml_elem* element, std::string message) {
+    std::string tagName = "NDC";
+    CPPUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);
+    std::string dMessage = getText(element);
+    CPPUNIT_ASSERT_EQUAL(message, dMessage);
   }
 
-  /**
-   * Checks a log4j:throwable element against expectations.
-   * @param element element, may not be null.
-   * @param ex exception, may not be null.
-   */
-  private void checkThrowableElement(
-    final Element element, final Exception ex) {
-    assertEquals("log4j:throwable", element.getTagName());
-
-    Node messageNode = element.getFirstChild();
-    assertNotNull(messageNode);
-    assertEquals(Node.TEXT_NODE, messageNode.getNodeType());
-
-    String msg = ex.toString();
-    assertEquals(msg, messageNode.getNodeValue().substring(0, msg.length()));
-    assertNull(messageNode.getNextSibling());
-  }
 
     /**
      * Checks a log4j:properties element against expectations.
@@ -168,333 +238,193 @@
      * @param key key.
      * @param value value.
      */
-    private void checkPropertiesElement(
-      final Element element, final String key, final String value) {
-      assertEquals("log4j:properties", element.getTagName());
-
-      int childNodeCount = 0;
-      for(Node child = element.getFirstChild();
-               child != null;
-               child = child.getNextSibling()) {
-          if (child.getNodeType() == Node.ELEMENT_NODE) {
-              assertEquals("log4j:data", child.getNodeName());
-              Element childElement = (Element) child;
-              assertEquals(key, childElement.getAttribute("name"));
-              assertEquals(value, childElement.getAttribute("value"));
-              childNodeCount++;
-          }
-      }
-      assertEquals(1, childNodeCount);  
+    void checkPropertiesElement(
+      apr_xml_elem* element, std::string key, std::string value) {
+    std::string tagName = "properties";
+    std::string dataTag = "data";
+    int childNodeCount = 0;
+    CPPUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);
+    for(apr_xml_elem* child = element->first_child;
+        child != NULL;
+        child = child->next) {
+            CPPUNIT_ASSERT_EQUAL(dataTag, (std::string) child->name);
+            CPPUNIT_ASSERT_EQUAL(key, getAttribute(child, "name"));
+            CPPUNIT_ASSERT_EQUAL(value, getAttribute(child, "value"));
+            childNodeCount++;        
+    }
+    CPPUNIT_ASSERT_EQUAL(1, childNodeCount);
     }
 
+public:
   /**
    * Tests formatted results.
    * @throws Exception if parser can not be constructed or source is not a valid XML document.
    */
-  public void testFormat() throws Exception {
-    Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest");
-    LoggingEvent event =
+  void testFormat() {
+    LoggerPtr logger = Logger::getLogger("org.apache.log4j.xml.XMLLayoutTest");
+    LoggingEventPtr event =
       new LoggingEvent(
-        "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", null);
-    XMLLayout layout = (XMLLayout) createLayout();
-    String result = layout.format(event);
-    Element parsedResult = parse(result);
+        logger, Level::getInfo(), LOG4CXX_STR("Hello, World"), LOG4CXX_LOCATION);
+    Pool p;
+    XMLLayout layout;
+    LogString result;
+    layout.format(result, event, p);
+    apr_xml_elem* parsedResult = parse(result, p);
     checkEventElement(parsedResult, event);
 
     int childElementCount = 0;
-
     for (
-      Node node = parsedResult.getFirstChild(); node != null;
-        node = node.getNextSibling()) {
-      switch (node.getNodeType()) {
-      case Node.ELEMENT_NODE:
+      apr_xml_elem* node = parsedResult->first_child; 
+      node != NULL;
+      node = node->next) {
         childElementCount++;
-        checkMessageElement((Element) node, "Hello, World");
-
-        break;
-
-      case Node.COMMENT_NODE:
-        break;
-
-      case Node.TEXT_NODE:
-
-        //  should only be whitespace
-        break;
-
-      default:
-        fail("Unexpected node type");
-
-        break;
-      }
+        checkMessageElement(node, "Hello, World");
     }
 
-    assertEquals(1, childElementCount);
+    CPPUNIT_ASSERT_EQUAL(1, childElementCount);
   }
 
-  /**
-   * Tests formatted results with an exception.
-   * @throws Exception if parser can not be constructed or source is not a valid XML document.
-   */
-  public void testFormatWithException() throws Exception {
-    Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest");
-    Exception ex = new IllegalArgumentException("'foo' is not a valid name");
-    LoggingEvent event =
-      new LoggingEvent(
-        "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", ex);
-    XMLLayout layout = (XMLLayout) createLayout();
-    String result = layout.format(event);
-    Element parsedResult = parse(result);
-    checkEventElement(parsedResult, event);
-
-    int childElementCount = 0;
-
-    for (
-      Node node = parsedResult.getFirstChild(); node != null;
-        node = node.getNextSibling()) {
-      switch (node.getNodeType()) {
-      case Node.ELEMENT_NODE:
-        childElementCount++;
-
-        if (childElementCount == 1) {
-          checkMessageElement((Element) node, "Hello, World");
-        } else {
-          checkThrowableElement((Element) node, ex);
-        }
-
-        break;
-
-      case Node.COMMENT_NODE:
-        break;
-
-      case Node.TEXT_NODE:
-
-        //  should only be whitespace
-        break;
-
-      default:
-        fail("Unexpected node type");
-
-        break;
-      }
-    }
-
-    assertEquals(2, childElementCount);
-  }
 
   /**
    * Tests formatted results with an exception.
    * @throws Exception if parser can not be constructed or source is not a valid XML document.
    */
-  public void testFormatWithNDC() throws Exception {
-    Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest");
-    NDC.push("NDC goes here");
+  void testFormatWithNDC() {
+    LoggerPtr logger = Logger::getLogger("org.apache.log4j.xml.XMLLayoutTest");
+    NDC::push("NDC goes here");
 
-    LoggingEvent event =
+    LoggingEventPtr event =
       new LoggingEvent(
-        "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", null);
-    XMLLayout layout = (XMLLayout) createLayout();
-    String result = layout.format(event);
-    NDC.pop();
+        logger, Level::getInfo(), LOG4CXX_STR("Hello, World"), LOG4CXX_LOCATION);
+    Pool p;
+    XMLLayout layout;
+    LogString result;
+    layout.format(result, event, p);
+    NDC::pop();
 
-    Element parsedResult = parse(result);
+    apr_xml_elem* parsedResult = parse(result, p);
     checkEventElement(parsedResult, event);
 
     int childElementCount = 0;
 
     for (
-      Node node = parsedResult.getFirstChild(); node != null;
-        node = node.getNextSibling()) {
-      switch (node.getNodeType()) {
-      case Node.ELEMENT_NODE:
+      apr_xml_elem* node = parsedResult->first_child; node != NULL;
+        node = node->next) {
         childElementCount++;
 
         if (childElementCount == 1) {
-          checkMessageElement((Element) node, "Hello, World");
+          checkMessageElement(node, "Hello, World");
         } else {
-          checkNDCElement((Element) node, "NDC goes here");
+          checkNDCElement(node, "NDC goes here");
         }
-
-        break;
-
-      case Node.COMMENT_NODE:
-        break;
-
-      case Node.TEXT_NODE:
-
-        //  should only be whitespace
-        break;
-
-      default:
-        fail("Unexpected node type");
-
-        break;
-      }
     }
 
-    assertEquals(2, childElementCount);
+    CPPUNIT_ASSERT_EQUAL(2, childElementCount);
   }
 
   /**
    * Tests getLocationInfo and setLocationInfo.
    */
-  public void testGetSetLocationInfo() {
-    XMLLayout layout = new XMLLayout();
-    assertEquals(false, layout.getLocationInfo());
+ void testGetSetLocationInfo() {
+    XMLLayout layout;
+    CPPUNIT_ASSERT_EQUAL(false, layout.getLocationInfo());
     layout.setLocationInfo(true);
-    assertEquals(true, layout.getLocationInfo());
+    CPPUNIT_ASSERT_EQUAL(true, layout.getLocationInfo());
     layout.setLocationInfo(false);
-    assertEquals(false, layout.getLocationInfo());
+    CPPUNIT_ASSERT_EQUAL(false, layout.getLocationInfo());
   }
 
   /**
    * Tests activateOptions().
    */
-  public void testActivateOptions() {
-    XMLLayout layout = new XMLLayout();
-    layout.activateOptions();
+  void testActivateOptions() {
+    Pool p;
+    XMLLayout layout;
+    layout.activateOptions(p);
   }
 
     /**
-     * Level with arbitrary toString value.
-     */
-    private static final class ProblemLevel extends Level {
-        /**
-         * Construct new instance.
-         * @param levelName level name, may not be null.
-         */
-        public ProblemLevel(final String levelName) {
-            super(6000, levelName, 6);
-        }
-    }
-
-    /**
      * Tests problematic characters in multiple fields.
      * @throws Exception if parser can not be constructed or source is not a valid XML document.
      */
-    public void testProblemCharacters() throws Exception {
-      String problemName = "com.example.bar<>&\"'";
-      Logger logger = Logger.getLogger(problemName);
-      Level level = new ProblemLevel(problemName);
-      Exception ex = new IllegalArgumentException(problemName);
-      String threadName = Thread.currentThread().getName();
-      Thread.currentThread().setName(problemName);
-      NDC.push(problemName);
-      Hashtable mdcMap = MDC.getContext();
-      if (mdcMap != null) {
-          mdcMap.clear();
-      }
-      MDC.put(problemName, problemName);
-      LoggingEvent event =
-        new LoggingEvent(
-          problemName, logger, level, problemName, ex);
-      XMLLayout layout = (XMLLayout) createLayout();
+    void testProblemCharacters()  {
+      std::string problemName = "com.example.bar<>&\"'";
+      LogString problemNameLS = LOG4CXX_STR("com.example.bar<>&\"'");
+      LoggerPtr logger = Logger::getLogger(problemName);
+      LevelPtr level = new XLevel(6000, problemNameLS, 7);
+      NDC::push(problemName);
+      MDC::clear();
+      MDC::put(problemName, problemName);
+      LoggingEventPtr event =
+        new LoggingEvent(logger, level, problemNameLS, LOG4CXX_LOCATION);
+      XMLLayout layout;
       layout.setProperties(true);
-      String result = layout.format(event);
-      mdcMap = MDC.getContext();
-      if (mdcMap != null) {
-          mdcMap.clear();
-      }
-      Thread.currentThread().setName(threadName);
+      Pool p;
+      LogString result;
+      layout.format(result, event, p);
+      MDC::clear();
 
-      Element parsedResult = parse(result);
+      apr_xml_elem* parsedResult = parse(result, p);
       checkEventElement(parsedResult, event);
 
       int childElementCount = 0;
 
       for (
-        Node node = parsedResult.getFirstChild(); node != null;
-          node = node.getNextSibling()) {
-        switch (node.getNodeType()) {
-        case Node.ELEMENT_NODE:
+        apr_xml_elem* node = parsedResult->first_child; node != NULL;
+          node = node->next) {
           childElementCount++;
           switch(childElementCount) {
               case 1:
-              checkMessageElement((Element) node, problemName);
+              checkMessageElement(node, problemName);
               break;
 
               case 2:
-              checkNDCElement((Element) node, problemName);
+              checkNDCElement(node, problemName);
               break;
 
               case 3:
-              checkThrowableElement((Element) node, ex);
-              break;
-
-              case 4:
-              checkPropertiesElement((Element) node, problemName, problemName);
+              checkPropertiesElement(node, problemName.c_str(), problemName.c_str());
               break;
 
               default:
-              fail("Unexpected element");
               break;
           }
 
-          break;
-
-        case Node.COMMENT_NODE:
-          break;
-
-        case Node.TEXT_NODE:
-
-          //  should only be whitespace
-          break;
-
-        default:
-          fail("Unexpected node type");
-
-          break;
-        }
       }
+      CPPUNIT_ASSERT_EQUAL(3, childElementCount);
     }
 
     /**
       * Tests CDATA element within NDC content.  See bug 37560.
       */
-    public void testNDCWithCDATA() throws Exception {
-        Logger logger = Logger.getLogger("com.example.bar");
-        Level level = Level.INFO;
-        String ndcMessage ="<envelope><faultstring><![CDATA[The EffectiveDate]]></faultstring><envelope>";
-        NDC.push(ndcMessage);
-        LoggingEvent event =
+    void testNDCWithCDATA() {
+        LoggerPtr logger = Logger::getLogger("com.example.bar");
+        LevelPtr level = Level::getInfo();
+        std::string ndcMessage ="<envelope><faultstring><![CDATA[The EffectiveDate]]></faultstring><envelope>";
+        NDC::push(ndcMessage);
+        LoggingEventPtr event =
           new LoggingEvent(
-            "com.example.bar", logger, level, "Hello, World", null);
-        Layout layout = createLayout();
-        String result = layout.format(event);
-        NDC.clear();
-        Element parsedResult = parse(result);
-        NodeList ndcs = parsedResult.getElementsByTagName("log4j:NDC");
-        assertEquals(1, ndcs.getLength());
-        StringBuffer buf = new StringBuffer();
-        for(Node child = ndcs.item(0).getFirstChild();
-                child != null;
-                child = child.getNextSibling()) {
-            buf.append(child.getNodeValue());
+            logger, level, LOG4CXX_STR("Hello, World"), LOG4CXX_LOCATION);
+        XMLLayout layout;
+        Pool p;
+        LogString result;
+        layout.format(result, event, p);
+        NDC::clear();
+        apr_xml_elem* parsedResult = parse(result, p);
+        int ndcCount = 0;
+        for(apr_xml_elem* node = parsedResult->first_child;
+            node != NULL;
+            node = node->next) {
+            if (strcmp(node->name, "NDC") == 0) {
+                ndcCount++;
+                CPPUNIT_ASSERT_EQUAL(ndcMessage, getText(node));
+            }
         }
-        assertEquals(ndcMessage, buf.toString());
+        CPPUNIT_ASSERT_EQUAL(1, ndcCount);
    }
 
-    /**
-      * Tests CDATA element within exception.  See bug 37560.
-      */
-    public void testExceptionWithCDATA() throws Exception {
-        Logger logger = Logger.getLogger("com.example.bar");
-        Level level = Level.INFO;
-        String exceptionMessage ="<envelope><faultstring><![CDATA[The EffectiveDate]]></faultstring><envelope>";
-        LoggingEvent event =
-          new LoggingEvent(
-            "com.example.bar", logger, level, "Hello, World", new Exception(exceptionMessage));
-        Layout layout = createLayout();
-        String result = layout.format(event);
-        Element parsedResult = parse(result);
-        NodeList throwables = parsedResult.getElementsByTagName("log4j:throwable");
-        assertEquals(1, throwables.getLength());
-        StringBuffer buf = new StringBuffer();
-        for(Node child = throwables.item(0).getFirstChild();
-                child != null;
-                child = child.getNextSibling()) {
-            buf.append(child.getNodeValue());
-        }
-        assertTrue(buf.toString().indexOf(exceptionMessage) != -1);
-   }
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION(XMLLayoutTest);
 
-}

Modified: logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttestcase.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttestcase.cpp?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttestcase.cpp (original)
+++ logging/log4cxx/trunk/src/test/cpp/xml/xmllayouttestcase.cpp Sat Jan 26 18:35:58 2008
@@ -65,8 +65,9 @@
                 CPPUNIT_TEST(basic);
                 CPPUNIT_TEST(locationInfo);
                 CPPUNIT_TEST(testCDATA);
-                CPPUNIT_TEST(testNULL);
+                CPPUNIT_TEST(testNull);
                 CPPUNIT_TEST(testMDC);
+                CPPUNIT_TEST(testMDCEscaped);
         CPPUNIT_TEST_SUITE_END();
 
         LoggerPtr root;
@@ -76,7 +77,9 @@
         void setUp()
         {
                 root = Logger::getRootLogger();
+                root->setLevel(Level::getTrace());
                 logger = Logger::getLogger(LOG4CXX_TEST_STR("org.apache.log4j.xml.XMLLayoutTestCase"));
+                logger->setLevel(Level::getTrace());
         }
 
         void tearDown()
@@ -126,7 +129,7 @@
 
                 XMLTimestampFilter xmlTimestampFilter;
                 XMLThreadFilter xmlThreadFilter;
-                FilenameFilter xmlFilenameFilter(__FILE__, "xmllayouttestcase.cpp");
+                FilenameFilter xmlFilenameFilter(__FILE__, "XMLLayoutTestCase.java");
                 Filter line2XX("[23][0-9][0-9]", "X");
                 Filter line5X("56", "X");
 
@@ -167,12 +170,14 @@
                 FileAppenderPtr appender(new FileAppender(xmlLayout, tempFileName, false));
                 root->addAppender(appender);
 
+                LOG4CXX_TRACE(logger,
+                        LOG4CXX_TEST_STR("Message with embedded <![CDATA[<hello>hi</hello>]]>."));
                 LOG4CXX_DEBUG(logger,
                         LOG4CXX_TEST_STR("Message with embedded <![CDATA[<hello>hi</hello>]]>."));
 
                 XMLTimestampFilter xmlTimestampFilter;
                 XMLThreadFilter xmlThreadFilter;
-                FilenameFilter xmlFilenameFilter(__FILE__, "xmllayouttestcase.cpp");
+                FilenameFilter xmlFilenameFilter(__FILE__, "XMLLayoutTestCase.java");
                 Filter line1xx("1[0-9][0-9]", "X");
 
                 std::vector<Filter *> filters;
@@ -194,7 +199,7 @@
                 CPPUNIT_ASSERT(Compare::compare(filteredFile, LOG4CXX_FILE("witness/xmlLayout.3")));
         }
 
-        void testNULL()
+        void testNull()
         {
                 const LogString tempFileName(LOG4CXX_STR("output/temp.xmlLayout.null"));
                 const File filteredFile("output/filtered.xmlLayout.null");
@@ -204,7 +209,8 @@
                 root->addAppender(appender);
 
                 LOG4CXX_DEBUG(logger, LOG4CXX_TEST_STR("hi"));
-                LOG4CXX_DEBUG(logger, LOG4CXX_TEST_STR(""));
+                LOG4CXX_DEBUG(logger, (char*) 0);
+                LOG4CXX_DEBUG(logger, "hi");
 
                 XMLTimestampFilter xmlTimestampFilter;
                 XMLThreadFilter xmlThreadFilter;
@@ -232,6 +238,7 @@
                 const File filteredFile("output/filtered.xmlLayout.mdc.1");
 
                 XMLLayoutPtr xmlLayout = new XMLLayout();
+                xmlLayout->setProperties(true);
                 FileAppenderPtr appender(new FileAppender(xmlLayout, tempFileName, false));
                 root->addAppender(appender);
 
@@ -264,18 +271,19 @@
         }
 
         // not incuded in the tests for the moment !
-        void holdTestMDCEscaped()
+        void testMDCEscaped()
         {
                 const LogString tempFileName(LOG4CXX_STR("output/temp.xmlLayout.mdc.2"));
                 const File filteredFile("output/filtered.xmlLayout.mdc.2");
 
                 XMLLayoutPtr xmlLayout = new XMLLayout();
+                xmlLayout->setProperties(true);
                 FileAppenderPtr appender(new FileAppender(xmlLayout, tempFileName, false));
                 root->addAppender(appender);
 
                 MDC::clear();
-                MDC::put(LOG4CXX_TEST_STR("blahAttribute"), LOG4CXX_TEST_STR("<blah value=\"blah\">"));
-                MDC::put(LOG4CXX_TEST_STR("<blahKey value=\"blah\"/>"), LOG4CXX_TEST_STR("blahValue"));
+                MDC::put(LOG4CXX_TEST_STR("blahAttribute"), LOG4CXX_TEST_STR("<blah value='blah'>"));
+                MDC::put(LOG4CXX_TEST_STR("<blahKey value='blah'/>"), LOG4CXX_TEST_STR("blahValue"));
 
                 LOG4CXX_DEBUG(logger, LOG4CXX_TEST_STR("Hello"));
 
@@ -310,25 +318,41 @@
 
         void common()
         {
-                int i = -1;
+                int i = 0;
                 X x;
 
 				std::string msg("Message ");
 
-                LOG4CXX_DEBUG(logger, msg << ++i);
+                LOG4CXX_TRACE(logger, msg << i);
+                LOG4CXX_TRACE(root, msg << i);
+
+                i++;
+                LOG4CXX_DEBUG(logger, msg << i);
                 LOG4CXX_DEBUG(root, msg << i);
 
-                LOG4CXX_INFO(logger, msg << ++i);
+                i++;
+                LOG4CXX_INFO(logger, msg << i);
                 LOG4CXX_INFO(root, msg << i);
 
-                LOG4CXX_WARN(logger, msg << ++i);
+                i++;
+                LOG4CXX_WARN(logger, msg << i);
                 LOG4CXX_WARN(root, msg << i);
 
-                LOG4CXX_ERROR(logger, msg << ++i);
+                i++;
+                LOG4CXX_ERROR(logger, msg << i);
                 LOG4CXX_ERROR(root, msg << i);
 
-                LOG4CXX_FATAL(logger, msg << ++i);
+                i++;
+                LOG4CXX_FATAL(logger, msg << i);
                 LOG4CXX_FATAL(root, msg << i);
+
+                i++;
+                LOG4CXX_DEBUG(logger, "Message " << i);
+                LOG4CXX_DEBUG(root, "Message " << i);
+
+                i++;
+                LOG4CXX_ERROR(logger, "Message " << i);
+                LOG4CXX_ERROR(root, "Message " << i);
         }
 };
 

Modified: logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.1
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.1?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.1 (original)
+++ logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.1 Sat Jan 26 18:35:58 2008
@@ -1,33 +1,68 @@
 <log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase$X" timestamp="XXX" level="INFO" thread="main">
 <log4j:message><![CDATA[in X() constructor]]></log4j:message>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="TRACE" thread="main">
 <log4j:message><![CDATA[Message 0]]></log4j:message>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="DEBUG" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="TRACE" thread="main">
 <log4j:message><![CDATA[Message 0]]></log4j:message>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="INFO" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[Message 1]]></log4j:message>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="INFO" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[Message 1]]></log4j:message>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="WARN" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="INFO" thread="main">
 <log4j:message><![CDATA[Message 2]]></log4j:message>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="WARN" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="INFO" thread="main">
 <log4j:message><![CDATA[Message 2]]></log4j:message>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="ERROR" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="WARN" thread="main">
 <log4j:message><![CDATA[Message 3]]></log4j:message>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="ERROR" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="WARN" thread="main">
 <log4j:message><![CDATA[Message 3]]></log4j:message>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="FATAL" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="ERROR" thread="main">
 <log4j:message><![CDATA[Message 4]]></log4j:message>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="FATAL" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="ERROR" thread="main">
 <log4j:message><![CDATA[Message 4]]></log4j:message>
 </log4j:event>
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="FATAL" thread="main">
+<log4j:message><![CDATA[Message 5]]></log4j:message>
+</log4j:event>
+
+<log4j:event logger="root" timestamp="XXX" level="FATAL" thread="main">
+<log4j:message><![CDATA[Message 5]]></log4j:message>
+</log4j:event>
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
+<log4j:message><![CDATA[Message 6]]></log4j:message>
+</log4j:event>
+
+<log4j:event logger="root" timestamp="XXX" level="DEBUG" thread="main">
+<log4j:message><![CDATA[Message 6]]></log4j:message>
+</log4j:event>
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="ERROR" thread="main">
+<log4j:message><![CDATA[Message 7]]></log4j:message>
+</log4j:event>
+
+<log4j:event logger="root" timestamp="XXX" level="ERROR" thread="main">
+<log4j:message><![CDATA[Message 7]]></log4j:message>
+</log4j:event>
+

Modified: logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.2
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.2?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.2 (original)
+++ logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.2 Sat Jan 26 18:35:58 2008
@@ -1,44 +1,85 @@
 <log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase$X" timestamp="XXX" level="INFO" thread="main">
 <log4j:message><![CDATA[in X() constructor]]></log4j:message>
-<log4j:locationInfo class="X" method="X" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="X" method="X" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="TRACE" thread="main">
 <log4j:message><![CDATA[Message 0]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="DEBUG" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="TRACE" thread="main">
 <log4j:message><![CDATA[Message 0]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="INFO" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[Message 1]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="INFO" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[Message 1]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="WARN" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="INFO" thread="main">
 <log4j:message><![CDATA[Message 2]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="WARN" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="INFO" thread="main">
 <log4j:message><![CDATA[Message 2]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="ERROR" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="WARN" thread="main">
 <log4j:message><![CDATA[Message 3]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="ERROR" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="WARN" thread="main">
 <log4j:message><![CDATA[Message 3]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="FATAL" thread="main">
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="ERROR" thread="main">
 <log4j:message><![CDATA[Message 4]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
-<log4j:event logger="root" timestamp="XXX" level="FATAL" thread="main">
+
+<log4j:event logger="root" timestamp="XXX" level="ERROR" thread="main">
 <log4j:message><![CDATA[Message 4]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
+</log4j:event>
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="FATAL" thread="main">
+<log4j:message><![CDATA[Message 5]]></log4j:message>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
+</log4j:event>
+
+<log4j:event logger="root" timestamp="XXX" level="FATAL" thread="main">
+<log4j:message><![CDATA[Message 5]]></log4j:message>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
+</log4j:event>
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
+<log4j:message><![CDATA[Message 6]]></log4j:message>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
+</log4j:event>
+
+<log4j:event logger="root" timestamp="XXX" level="DEBUG" thread="main">
+<log4j:message><![CDATA[Message 6]]></log4j:message>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
+</log4j:event>
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="ERROR" thread="main">
+<log4j:message><![CDATA[Message 7]]></log4j:message>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
+</log4j:event>
+
+<log4j:event logger="root" timestamp="XXX" level="ERROR" thread="main">
+<log4j:message><![CDATA[Message 7]]></log4j:message>
+<log4j:locationInfo class="XMLLayoutTestCase" method="common" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
+

Modified: logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.3
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.3?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.3 (original)
+++ logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.3 Sat Jan 26 18:35:58 2008
@@ -1,4 +1,10 @@
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="TRACE" thread="main">
+<log4j:message><![CDATA[Message with embedded <![CDATA[<hello>hi</hello>]]>]]&gt;<![CDATA[.]]></log4j:message>
+<log4j:locationInfo class="XMLLayoutTestCase" method="testCDATA" file="XMLLayoutTestCase.java" line="X"/>
+</log4j:event>
+
 <log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[Message with embedded <![CDATA[<hello>hi</hello>]]>]]&gt;<![CDATA[.]]></log4j:message>
-<log4j:locationInfo class="XMLLayoutTestCase" method="testCDATA" file="xmllayouttestcase.cpp" line="X"/>
+<log4j:locationInfo class="XMLLayoutTestCase" method="testCDATA" file="XMLLayoutTestCase.java" line="X"/>
 </log4j:event>
+

Modified: logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.1
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.1?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.1 (original)
+++ logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.1 Sat Jan 26 18:35:58 2008
@@ -1,7 +1,8 @@
 <log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[Hello]]></log4j:message>
-<log4j:MDC>
-    <log4j:data name="key1" value="val1"/>
-    <log4j:data name="key2" value="val2"/>
-</log4j:MDC>
+<log4j:properties>
+<log4j:data name="key1" value="val1"/>
+<log4j:data name="key2" value="val2"/>
+</log4j:properties>
 </log4j:event>
+

Modified: logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.2
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.2?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.2 (original)
+++ logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.mdc.2 Sat Jan 26 18:35:58 2008
@@ -1,7 +1,8 @@
 <log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[Hello]]></log4j:message>
-<log4j:MDC>
-    <log4j:data name="<![CDATA[<blahKey value="blah"/>]]>" value="<![CDATA[blahValue]]>"/>
-    <log4j:data name="<![CDATA[blahAttribute]]>" value="<![CDATA[<blah value="blah">]]>"/>
-</log4j:MDC>
+<log4j:properties>
+<log4j:data name="&lt;blahKey value='blah'/&gt;" value="blahValue"/>
+<log4j:data name="blahAttribute" value="&lt;blah value='blah'&gt;"/>
+</log4j:properties>
 </log4j:event>
+

Modified: logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.null
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.null?rev=615546&r1=615545&r2=615546&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.null (original)
+++ logging/log4cxx/trunk/src/test/resources/witness/xmlLayout.null Sat Jan 26 18:35:58 2008
@@ -1,6 +1,12 @@
 <log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
 <log4j:message><![CDATA[hi]]></log4j:message>
 </log4j:event>
+
 <log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
-<log4j:message><![CDATA[]]></log4j:message>
+<log4j:message><![CDATA[null]]></log4j:message>
 </log4j:event>
+
+<log4j:event logger="org.apache.log4j.xml.XMLLayoutTestCase" timestamp="XXX" level="DEBUG" thread="main">
+<log4j:message><![CDATA[hi]]></log4j:message>
+</log4j:event>
+