JCRVLT-334 Regression of JCRVLT-271: Property names mixed case problem

git-svn-id: https://svn.apache.org/repos/asf/jackrabbit/commons/filevault/trunk@1855563 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/vault-core/.ratignore b/vault-core/.ratignore
index b962820..ff54a87 100644
--- a/vault-core/.ratignore
+++ b/vault-core/.ratignore
@@ -1,2 +1,3 @@
 .ratignore
-src/test/resources/org/apache/jackrabbit/vault/fs/filter/workspacefilters/complex-expected.xml
\ No newline at end of file
+src/test/resources/org/apache/jackrabbit/vault/fs/filter/workspacefilters/complex-expected.xml
+src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/formatted.xml
\ No newline at end of file
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/xml/serialize/AttributeNameComparator.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/xml/serialize/AttributeNameComparator.java
index 9fbed39..fa11b42 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/xml/serialize/AttributeNameComparator.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/xml/serialize/AttributeNameComparator.java
@@ -26,25 +26,30 @@
     public static final AttributeNameComparator INSTANCE = new AttributeNameComparator();
 
     @Override
-    public int compare(String o1, String o2) {
-        String n1 = o1.toLowerCase();
-        String n2 = o2.toLowerCase();
+    public int compare(final String o1, final String o2) {
+        final String n1 = o1.toLowerCase();
+        final String n2 = o2.toLowerCase();
         // order xmlns(:<prefix>)? attributes always to the front
-        boolean isXmlNs1 = n1.startsWith(XMLSymbols.PREFIX_XMLNS);
-        boolean isXmlNs2 = n2.startsWith(XMLSymbols.PREFIX_XMLNS);
+        final boolean isXmlNs1 = n1.startsWith(XMLSymbols.PREFIX_XMLNS);
+        final boolean isXmlNs2 = n2.startsWith(XMLSymbols.PREFIX_XMLNS);
         if (isXmlNs1 && !isXmlNs2) {
             return -1;
         } else if (!isXmlNs1 && isXmlNs2) {
             return 1;
         }
-        int i1 = n1.indexOf(':');
-        int i2 = n2.indexOf(':');
+        final int i1 = n1.indexOf(':');
+        final int i2 = n2.indexOf(':');
         if (i1 >=0 && i2 < 0) {
             return -1;
         } else if (i1 < 0 && i2 >=0) {
             return 1;
         } else {
-            return n1.compareTo(n2);
+            // if the lowercase versions are equal, they could differ in case (see JCRVLT-334)
+            final int c = n1.compareTo(n2);
+            if (c == 0) {
+                return o1.compareTo(o2);
+            }
+            return c;
         }
     }
 }
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSaxFormatterTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSaxFormatterTest.java
index 6f49d51..164e99c 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSaxFormatterTest.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSaxFormatterTest.java
@@ -22,6 +22,7 @@
 import java.util.Map;
 
 import javax.jcr.GuestCredentials;
+import javax.jcr.Node;
 import javax.jcr.PropertyType;
 import javax.jcr.Session;
 import javax.jcr.Value;
@@ -114,4 +115,32 @@
                 "    jcr:primaryType=\"nt:unstructured\"/>\n", out.toString("utf-8"));
     }
 
+    /**
+     * Tests export of mixed case named properties serialization
+     */
+    @Test
+    public void testMixedCaseSerialization() throws Exception {
+        Node node = JcrUtils.getOrCreateByPath("/testroot", NodeType.NT_UNSTRUCTURED, admin);
+        node.setProperty("testproperty", "lowercase");
+        node.setProperty("TestProperty", "MixedCase");
+        admin.save();
+
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        filter.add(new PathFilterSet("/testroot"));
+        RepositoryAddress addr = new RepositoryAddress("/" + admin.getWorkspace().getName() + "/");
+        VaultFileSystem jcrfs = Mounter.mount(null, filter, addr, null, admin);
+        Aggregate a = jcrfs.getAggregateManager().getRoot().getAggregate("testroot");
+        DocViewSerializer s = new DocViewSerializer(a);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        s.writeContent(out);
+
+        assertEquals("valid xml",
+                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+                "<jcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\"\n" +
+                "    jcr:primaryType=\"nt:unstructured\"\n" +
+                "    TestProperty=\"MixedCase\"\n" +
+                "    testproperty=\"lowercase\"/>\n", out.toString("utf-8"));
+    }
+
 }
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/DocViewFormatTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/DocViewFormatTest.java
index 6391157..45240db 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/DocViewFormatTest.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/fs/io/DocViewFormatTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.jackrabbit.vault.fs.io;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -30,6 +31,7 @@
 import java.util.List;
 import java.util.regex.Pattern;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.util.ISO8601;
 import org.junit.After;
@@ -79,5 +81,10 @@
         assertFalse("malformed.xml is expected to be malformed", format.format(dir, patterns, true).isEmpty());
         format.format(dir, patterns, false);
         assertTrue("malformed.xml is expected to be formatted", format.format(dir, patterns, true).isEmpty());
+
+        final String expected = IOUtils.toString(this.getClass().getClassLoader()
+                .getResourceAsStream("org/apache/jackrabbit/vault/fs/io/DocViewFormat/formatted.xml"), "utf-8");
+        final String result = FileUtils.readFileToString(docViewFile, "utf-8");
+        assertEquals(expected, result);
     }
 }
diff --git a/vault-core/src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/formatted.xml b/vault-core/src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/formatted.xml
new file mode 100644
index 0000000..6454b3b
--- /dev/null
+++ b/vault-core/src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/formatted.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="nt:unstructured"
+    jcr:title="Test node">
+    <testChild
+        jcr:primaryType="nt:unstructured"
+        foo="bar"
+        TestProperty="test"
+        testProperty="test"/>
+</jcr:root>
diff --git a/vault-core/src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/malformed.xml b/vault-core/src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/malformed.xml
index 534606c..7f46faa 100644
--- a/vault-core/src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/malformed.xml
+++ b/vault-core/src/test/resources/org/apache/jackrabbit/vault/fs/io/DocViewFormat/malformed.xml
@@ -19,5 +19,7 @@
           jcr:primaryType="nt:unstructured"
           jcr:title="Test node">
     <testChild jcr:primaryType="nt:unstructured"
-               foo="bar"/>
+                  testProperty="test"
+TestProperty="test"
+               foo="bar"></testChild>
 </jcr:root>