[dna-commits] DNA SVN: r776 - in trunk/dna-jcr/src: test/java/org/jboss/dna/jcr and 1 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Thu Mar 12 16:54:55 EDT 2009


Author: rhauch
Date: 2009-03-12 16:54:55 -0400 (Thu, 12 Mar 2009)
New Revision: 776

Modified:
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrDocumentViewExporter.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java
   trunk/dna-jcr/src/test/resources/repositoryForTckTests.xml
Log:
DNA-297 JcrSession.exportDocumentView Does Not Export Carriage Returns, Line Feeds, and Tabs Correctly

Applied the "redux" patch, and verified that all tests do pass.

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrDocumentViewExporter.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrDocumentViewExporter.java	2009-03-12 20:40:20 UTC (rev 775)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrDocumentViewExporter.java	2009-03-12 20:54:55 UTC (rev 776)
@@ -24,7 +24,11 @@
 package org.jboss.dna.jcr;
 
 import java.io.OutputStream;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.Property;
@@ -33,6 +37,8 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.common.text.XmlNameEncoder;
 import org.jboss.dna.graph.ExecutionContext;
 import org.jboss.dna.graph.property.Name;
 import org.jboss.dna.graph.property.ValueFactories;
@@ -50,6 +56,8 @@
 @NotThreadSafe
 class JcrDocumentViewExporter extends AbstractJcrExporter {
 
+    private static final TextEncoder VALUE_ENCODER = new JcrDocumentViewExporter.JcrDocumentViewPropertyEncoder();
+    
     JcrDocumentViewExporter( JcrSession session ) {
         super(session, Collections.<String>emptyList());
     }
@@ -111,7 +119,7 @@
                               propName.getLocalName(),
                               localPropName,
                               PropertyType.nameFromValue(prop.getType()),
-                              value.getString());
+                              VALUE_ENCODER.encode(value.getString()));
         }
 
         Name name;
@@ -211,4 +219,74 @@
         return xmlCharacters.getValue().getString();
     }
 
+    /**
+     * Special {@link TextEncoder} that implements the subset of XML name encoding suggested by section 6.4.4 of the JCR 1.0.1
+     * specification.  This encoder only encodes space (0x20), carriage return (0x0D), new line (0x0A), tab (0x09), and any
+     * underscore characters that might otherwise suggest an encoding, as defined in {@link XmlNameEncoder}.
+     *
+     */
+    protected static class JcrDocumentViewPropertyEncoder extends XmlNameEncoder {
+        private static final Set<Character> MAPPED_CHARACTERS;
+        
+        static {
+            MAPPED_CHARACTERS = new HashSet<Character>();
+            MAPPED_CHARACTERS.add(' ');
+            MAPPED_CHARACTERS.add('\r');
+            MAPPED_CHARACTERS.add('\n');
+            MAPPED_CHARACTERS.add('\t');
+            
+        }
+        
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.common.text.TextEncoder#encode(java.lang.String)
+         */
+        // See section 6.4.4 of the JCR 1.0.1 spec for why these hoops must be jumped through
+        @Override
+        public String encode( String text ) {
+            if (text == null) return null;
+            if (text.length() == 0) return text;
+            StringBuilder sb = new StringBuilder();
+            String hex = null;
+            CharacterIterator iter = new StringCharacterIterator(text);
+            for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
+                if (c == '_') {
+                    // Read the next character (if there is one) ...
+                    char next = iter.next();
+                    if (next == CharacterIterator.DONE) {
+                        sb.append(c);
+                        break;
+                    }
+                    // If the next character is not 'x', then these are just regular characters ...
+                    if (next != 'x') {
+                        sb.append(c).append(next);
+                        continue;
+                    }
+                    // The next character is 'x', so write out the '_' character in encoded form ...
+                    sb.append("_x005f_");
+                    // And then write out the next character ...
+                    sb.append(next);
+                } else if (!MAPPED_CHARACTERS.contains(c)) {
+                    // Legal characters for an XML Name ...
+                    sb.append(c);
+                } else {
+                    // All other characters must be escaped with '_xHHHH_' where 'HHHH' is the hex string for the code point
+                    hex = Integer.toHexString(c);
+                    // The hex string excludes the leading '0's, so check the character values so we know how many to prepend
+                    if (c >= '\u0000' && c <= '\u000f') {
+                        sb.append("_x000").append(hex);
+                    } else if (c >= '\u0010' && c <= '\u00ff') {
+                        sb.append("_x00").append(hex);
+                    } else if (c >= '\u0100' && c <= '\u0fff') {
+                        sb.append("_x0").append(hex);
+                    } else {
+                        sb.append("_x").append(hex);
+                    }
+                    sb.append('_');
+                }
+            }
+            return sb.toString();
+        }
+    }
 }

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java	2009-03-12 20:40:20 UTC (rev 775)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java	2009-03-12 20:54:55 UTC (rev 776)
@@ -1,5 +1,5 @@
 /*
- * JBoss DNA (http://www.jboss.org/dna)
+* JBoss DNA (http://www.jboss.org/dna)
  * See the COPYRIGHT.txt file distributed with this work for information
  * regarding copyright ownership.  Some portions may be licensed
  * to Red Hat, Inc. under one or more contributor license agreements.
@@ -23,6 +23,7 @@
  */
 package org.jboss.dna.jcr;
 
+import static org.junit.Assert.assertTrue;
 import static org.hamcrest.core.Is.is;
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
 import static org.hamcrest.core.IsNot.not;
@@ -31,7 +32,9 @@
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.stub;
+import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.security.AccessControlException;
 import java.security.Principal;
 import java.util.Calendar;
@@ -67,6 +70,8 @@
  */
 public class JcrSessionTest {
 
+    private static final String MULTI_LINE_VALUE = "Line\t1\nLine 2\rLine 3\r\nLine 4";
+    
     private String workspaceName;
     private ExecutionContext context;
     private InMemoryRepositorySource source;
@@ -96,7 +101,8 @@
         graph.create("/a").and().create("/a/b").and().create("/a/b/c");
         graph.set("booleanProperty").on("/a/b").to(true);
         graph.set("stringProperty").on("/a/b/c").to("value");
-
+        graph.set("multiLineProperty").on("/a/b/c").to(MULTI_LINE_VALUE);
+        
         // Make sure the path to the namespaces exists ...
         graph.create("/jcr:system").and().create("/jcr:system/dna:namespaces");
 
@@ -388,4 +394,14 @@
         assertThat(session.getNamespaceURI("sv"), is("http://www.jcp.org/jcr/sv/1.0"));
         // assertThat(session.getNamespaceURI("xml"), is("http://www.w3.org/XML/1998/namespace"));
     }
+    
+    @Test
+    public void shouldExportMultiLinePropertiesInSystemView() throws Exception {
+        OutputStream os = new ByteArrayOutputStream();
+        
+        session.exportSystemView("/a/b/c", os, false, true);
+        
+        String fileContents = os.toString();
+        assertTrue(fileContents.contains(MULTI_LINE_VALUE)); 
+    }
 }

Modified: trunk/dna-jcr/src/test/resources/repositoryForTckTests.xml
===================================================================
--- trunk/dna-jcr/src/test/resources/repositoryForTckTests.xml	2009-03-12 20:40:20 UTC (rev 775)
+++ trunk/dna-jcr/src/test/resources/repositoryForTckTests.xml	2009-03-12 20:54:55 UTC (rev 776)
@@ -25,14 +25,27 @@
   ~ Boston, MA  02110-1301  USA
   -->
 <testroot xmlns:jcr="http://www.jcp.org/jcr/1.0" 
-            xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
-            xmlns:dna="http://www.jboss.org/dna/1.0"
-    jcr:primaryType="nt:unstructured">
-	<nt:unstructured jcr:name="node1" prop1="&lt;foo&amp;foo&gt;" >
-	<!--  This stanza checks for the jcr:xmltext special case for document export.  DO NOT change this element. -->
-	   <nt:unstructured jcr:name="jcr:xmltext" jcr:xmlcharacters="This is my &quot;XML&quot; text!" />
-	</nt:unstructured>
-	<nt:unstructured jcr:name="node2 has a multi-word name" prop2="bar" />
-	<nt:unstructured jcr:name="node3" />
-	<nt:unstructured jcr:name="node4" />
+          xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+          xmlns:dna="http://www.jboss.org/dna/1.0"
+          jcr:primaryType="nt:unstructured">
+    <nt:unstructured jcr:name="node1" prop1="&lt;foo&amp;foo&gt;" >
+       <!--  
+           This stanza checks for the jcr:xmltext special case for export as per JCR 1.0.1 section 6.4.2.3
+         -->
+       <nt:unstructured jcr:name="jcr:xmltext" jcr:xmlcharacters="This is my &quot;XML&quot; text!" />
+    </nt:unstructured>
+    <nt:unstructured jcr:name="node2 has a multi-word name" multi-valued-property="bar baz blah">
+       <!--  
+           This stanza checks that consecutive jcr:xmltext elements will be merged in the export as 
+           per JCR 1.0.1 section 6.4.2.3
+         -->
+       <nt:unstructured jcr:name="jcr:xmltext" jcr:xmlcharacters="This is my &quot;XML&quot; text!" />
+       <nt:unstructured jcr:name="jcr:xmltext" jcr:xmlcharacters="This is my &quot;other&quot; text!" />
+    </nt:unstructured>
+    <nt:unstructured jcr:name="node3" />
+    <!--  
+       Test of unprintable character exports.
+       Cannot test \r character here on Windows as TCK XML Parser will replace it with \n and fail the comparison 
+      -->
+    <nt:unstructured jcr:name="node4" multi-line-property="Line&#009;1&#010;Line 2"/>
 </testroot>
\ No newline at end of file




More information about the dna-commits mailing list