You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2005/11/03 17:12:06 UTC

svn commit: r330575 - in /incubator/jackrabbit/trunk/jackrabbit/src: main/java/org/apache/jackrabbit/core/query/xpath/ main/java/org/apache/jackrabbit/core/util/ main/java/org/apache/jackrabbit/core/xml/ main/java/org/apache/jackrabbit/name/ test/java/...

Author: mreutegg
Date: Thu Nov  3 08:11:47 2005
New Revision: 330575

URL: http://svn.apache.org/viewcvs?rev=330575&view=rev
Log:
Move ISO9075 class from package o.a.j.core.util to o.a.j.name

Added:
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/name/ISO9075.java   (with props)
    incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/ISO9075Test.java   (with props)
Removed:
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/util/ISO9075.java
    incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/ISO9075Test.java
Modified:
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryFormat.java
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
    incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java
    incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/TestAll.java

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryFormat.java?rev=330575&r1=330574&r2=330575&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryFormat.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryFormat.java Thu Nov  3 08:11:47 2005
@@ -31,10 +31,11 @@
 import org.apache.jackrabbit.core.query.QueryRootNode;
 import org.apache.jackrabbit.core.query.RelationQueryNode;
 import org.apache.jackrabbit.core.query.TextsearchQueryNode;
-import org.apache.jackrabbit.core.util.ISO9075;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.jackrabbit.util.ISO8601;
 
 import javax.jcr.query.InvalidQueryException;

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java?rev=330575&r1=330574&r2=330575&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java Thu Nov  3 08:11:47 2005
@@ -31,12 +31,13 @@
 import org.apache.jackrabbit.core.query.QueryRootNode;
 import org.apache.jackrabbit.core.query.RelationQueryNode;
 import org.apache.jackrabbit.core.query.TextsearchQueryNode;
-import org.apache.jackrabbit.core.util.ISO9075;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.jackrabbit.name.IllegalNameException;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.jackrabbit.util.ISO8601;
 
 import javax.jcr.query.InvalidQueryException;

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java?rev=330575&r1=330574&r2=330575&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java Thu Nov  3 08:11:47 2005
@@ -17,9 +17,10 @@
 package org.apache.jackrabbit.core.xml;
 
 import org.apache.jackrabbit.BaseException;
-import org.apache.jackrabbit.core.util.ISO9075;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.log4j.Logger;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java?rev=330575&r1=330574&r2=330575&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java Thu Nov  3 08:11:47 2005
@@ -17,8 +17,9 @@
 package org.apache.jackrabbit.core.xml;
 
 import org.apache.jackrabbit.BaseException;
-import org.apache.jackrabbit.core.util.ISO9075;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.ISO9075;
 import org.apache.jackrabbit.value.ValueHelper;
 import org.apache.log4j.Logger;
 import org.xml.sax.ContentHandler;

Added: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/name/ISO9075.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/name/ISO9075.java?rev=330575&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/name/ISO9075.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/name/ISO9075.java Thu Nov  3 08:11:47 2005
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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.jackrabbit.name;
+
+import org.apache.xerces.util.XMLChar;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Implements the encode and decode routines as specified for XML name to SQL
+ * identifier conversion in ISO 9075-14:2003.<br/>
+ * If a character <code>c</code> is not valid at a certain position in an XML 1.0
+ * NCName it is encoded in the form: '_x' + hexValueOf(c) + '_'
+ * <p/>
+ * Note that only the local part of a {@link org.apache.jackrabbit.name.QName}
+ * is encoded / decoded. A URI namespace will always be valid and does not
+ * need encoding.
+ */
+public class ISO9075 {
+
+    /** Hidden constructor. */
+    private ISO9075() { }
+
+    /** Pattern on an encoded character */
+    private static final Pattern ENCODE_PATTERN = Pattern.compile("_x\\p{XDigit}{4}_");
+
+    /** Padding characters */
+    private static final char[] PADDING = new char[] {'0', '0', '0'};
+
+    /** All the possible hex digits */
+    private static final String HEX_DIGITS = "0123456789abcdefABCDEF";
+
+    /**
+     * Encodes the local part of <code>name</code> as specified in ISO 9075.
+     * @param name the <code>QName</code> to encode.
+     * @return the encoded <code>QName</code> or <code>name</code> if it does
+     *   not need encoding.
+     */
+    public static QName encode(QName name) {
+        String encoded = encode(name.getLocalName());
+        if (encoded == name.getLocalName()) {
+            return name;
+        } else {
+            return new QName(name.getNamespaceURI(), encoded);
+        }
+    }
+
+    /**
+     * Encodes <code>name</code> as specified in ISO 9075.
+     * @param name the <code>String</code> to encode.
+     * @return the encoded <code>String</code> or <code>name</code> if it does
+     *   not need encoding.
+     */
+    public static String encode(String name) {
+        // quick check for root node name
+        if (name.length() == 0) {
+            return name;
+        }
+        if (XMLChar.isValidName(name) && name.indexOf("_x") < 0) {
+            // already valid
+            return name;
+        } else {
+            // encode
+            StringBuffer encoded = new StringBuffer();
+            for (int i = 0; i < name.length(); i++) {
+                if (i == 0) {
+                    // first character of name
+                    if (XMLChar.isNameStart(name.charAt(i))) {
+                        if (needsEscaping(name, i)) {
+                            // '_x' must be encoded
+                            encode('_', encoded);
+                        } else {
+                            encoded.append(name.charAt(i));
+                        }
+                    } else {
+                        // not valid as first character -> encode
+                        encode(name.charAt(i), encoded);
+                    }
+                } else if (!XMLChar.isName(name.charAt(i))) {
+                    encode(name.charAt(i), encoded);
+                } else {
+                    if (needsEscaping(name, i)) {
+                        // '_x' must be encoded
+                        encode('_', encoded);
+                    } else {
+                        encoded.append(name.charAt(i));
+                    }
+                }
+            }
+            return encoded.toString();
+        }
+    }
+
+    /**
+     * Decodes the <code>name</code>.
+     * @param name the <code>QName</code> to decode.
+     * @return the decoded <code>QName</code>.
+     */
+    public static QName decode(QName name) {
+        String decoded = decode(name.getLocalName());
+        if (decoded == name.getLocalName()) {
+            return name;
+        } else {
+            return new QName(name.getNamespaceURI(), decoded.toString());
+        }
+    }
+
+    /**
+     * Decodes the <code>name</code>.
+     * @param name the <code>String</code> to decode.
+     * @return the decoded <code>String</code>.
+     */
+    public static String decode(String name) {
+        // quick check
+        if (name.indexOf("_x") < 0) {
+            // not encoded
+            return name;
+        }
+        StringBuffer decoded = new StringBuffer();
+        Matcher m = ENCODE_PATTERN.matcher(name);
+        while (m.find()) {
+            m.appendReplacement(decoded, Character.toString((char) Integer.parseInt(m.group().substring(2, 6), 16)));
+        }
+        m.appendTail(decoded);
+        return decoded.toString();
+    }
+
+    //-------------------------< internal >-------------------------------------
+
+    /**
+     * Encodes the character <code>c</code> as a String in the following form:
+     * <code>"_x" + hex value of c + "_"</code>. Where the hex value has
+     * four digits if the character with possibly leading zeros.
+     * <p/>
+     * Example: ' ' (the space character) is encoded to: _x0020_
+     * @param c the character to encode
+     * @param b the encoded character is appended to <code>StringBuffer</code>
+     *  <code>b</code>.
+     */
+    private static void encode(char c, StringBuffer b) {
+        b.append("_x");
+        String hex = Integer.toHexString(c);
+        b.append(PADDING, 0, 4 - hex.length());
+        b.append(hex);
+        b.append("_");
+    }
+
+    /**
+     * Returns true if <code>name.charAt(location)</code> is the underscore
+     * character and the following character sequence is 'xHHHH_' where H
+     * is a hex digit.
+     * @param name the name to check.
+     * @param location the location to look at.
+     * @throws ArrayIndexOutOfBoundsException if location > name.length()
+     */
+    private static boolean needsEscaping(String name, int location)
+            throws ArrayIndexOutOfBoundsException {
+        if (name.charAt(location) == '_' && name.length() >= location + 6) {
+            return name.charAt(location + 1) == 'x'
+                && HEX_DIGITS.indexOf(name.charAt(location + 2)) != -1
+                && HEX_DIGITS.indexOf(name.charAt(location + 3)) != -1
+                && HEX_DIGITS.indexOf(name.charAt(location + 4)) != -1
+                && HEX_DIGITS.indexOf(name.charAt(location + 5)) != -1;
+        } else {
+            return false;
+        }
+    }
+}

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/name/ISO9075.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java?rev=330575&r1=330574&r2=330575&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java Thu Nov  3 08:11:47 2005
@@ -35,7 +35,6 @@
     public static Test suite() {
         TestSuite suite = new TestSuite("Search tests");
 
-        suite.addTestSuite(ISO9075Test.class);
         suite.addTestSuite(SimpleQueryTest.class);
         suite.addTestSuite(FulltextQueryTest.class);
         suite.addTestSuite(SelectClauseTest.class);

Added: incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/ISO9075Test.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/ISO9075Test.java?rev=330575&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/ISO9075Test.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/ISO9075Test.java Thu Nov  3 08:11:47 2005
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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.jackrabbit.name;
+
+import org.apache.xerces.util.XMLChar;
+import junit.framework.TestCase;
+
+/**
+ * Test cases for ISO9075 encode / decode.
+ */
+public class ISO9075Test extends TestCase {
+
+    public void testSpecExamples() {
+        assertEquals("My_x0020_Documents", ISO9075.encode("My Documents"));
+        assertEquals("_x0031_234id", ISO9075.encode("1234id"));
+        assertEquals("My_Documents", ISO9075.encode("My_Documents"));
+        assertEquals("My_x005f_x0020Documents", ISO9075.encode("My_x0020Documents"));
+        assertEquals("My_x005f_x0020_Documents", ISO9075.encode("My_x0020_Documents"));
+        assertEquals("My_x005f_x0020_", ISO9075.encode("My_x0020_"));
+        assertEquals("My_x002", ISO9075.encode("My_x002"));
+        assertEquals("My_x005f_x0020", ISO9075.encode("My_x0020"));
+        assertEquals("My_", ISO9075.encode("My_"));
+        assertEquals("My_x005f_x0020_x0020_Documents", ISO9075.encode("My_x0020 Documents"));
+    }
+
+    /**
+     * This is a disabled brute force test. It tests permutations of characters:
+     * <code>' ', '_', 'x', '0', '2', 'a', 'b', '{'</code>, encodes and decodes
+     * the sequences and test whether the initial sequence equals the resulting
+     * sequence that went through the encoding / decoding process.
+     * </p>
+     * The test takes about 30 seconds on my 1.2G P3.
+     * </p>
+     * To enable the test remove the 'disabled_' refix from the method name.
+     */
+    public void disabled_testBrute() {
+        char[] chars = new char[] {' ', '_', 'x', '0', '2', 'a', 'b', '{'};
+        long start = Long.parseLong("1000000", 8);
+        long end = Long.parseLong("7777777", 8);
+        for (long i = start; i < end; i++) {
+            String s = Long.toString(i, chars.length);
+            StringBuffer b = new StringBuffer(s.length());
+            for (int j = 0; j < s.length(); j++) {
+                b.append(chars[s.charAt(j) - '0']);
+            }
+            // encode and decode
+            QName initial = new QName("", b.toString());
+            if ((i % 100000) == 0) {
+                System.out.println(initial);
+            }
+            QName encoded = ISO9075.encode(initial);
+            assertTrue(XMLChar.isValidName(encoded.getLocalName()));
+            QName decoded = ISO9075.decode(encoded);
+            assertEquals(initial, decoded);
+        }
+    }
+
+}

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/ISO9075Test.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/TestAll.java?rev=330575&r1=330574&r2=330575&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/TestAll.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/name/TestAll.java Thu Nov  3 08:11:47 2005
@@ -35,6 +35,7 @@
     public static Test suite() {
         TestSuite suite = new TestSuite("name tests");
 
+        suite.addTestSuite(ISO9075Test.class);
         suite.addTestSuite(PathTest.class);
         suite.addTestSuite(QNameTest.class);