You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2013/10/04 12:13:45 UTC
svn commit: r1529116 - in /jackrabbit/trunk:
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/
jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/
Author: reschke
Date: Fri Oct 4 10:13:44 2013
New Revision: 1529116
URL: http://svn.apache.org/r1529116
Log:
JCR-3675: test cases for "similarly" named nodes, diagnostics for names not in NFC
Added:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/NodeNameNormalizer.java
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/AddNodeTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=1529116&r1=1529115&r2=1529116&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Fri Oct 4 10:13:44 2013
@@ -92,6 +92,7 @@ import org.apache.jackrabbit.core.query.
import org.apache.jackrabbit.core.security.AccessManager;
import org.apache.jackrabbit.core.security.authorization.Permission;
import org.apache.jackrabbit.core.session.AddNodeOperation;
+import org.apache.jackrabbit.core.session.NodeNameNormalizer;
import org.apache.jackrabbit.core.session.SessionContext;
import org.apache.jackrabbit.core.session.SessionOperation;
import org.apache.jackrabbit.core.session.SessionWriteOperation;
@@ -1283,6 +1284,9 @@ public class NodeImpl extends ItemImpl i
nt = (NodeTypeImpl) def.getDefaultPrimaryType();
}
+ // check the new name
+ NodeNameNormalizer.check(nodeName);
+
// check for name collisions
NodeState thisState = data.getNodeState();
ChildNodeEntry cne = thisState.getChildNodeEntry(nodeName, 1);
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/NodeNameNormalizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/NodeNameNormalizer.java?rev=1529116&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/NodeNameNormalizer.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/NodeNameNormalizer.java Fri Oct 4 10:13:44 2013
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.session;
+
+import java.text.Normalizer;
+import java.text.Normalizer.Form;
+
+import org.apache.jackrabbit.spi.Name;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Convenience class for checking/logging "weird" node names.
+ * <p>
+ * For now, it only checks that a node name being created uses NFC
+ *
+ * @see http://www.unicode.org/reports/tr15/tr15-23.html
+ */
+public class NodeNameNormalizer {
+
+ private static Logger log = LoggerFactory.getLogger(NodeNameNormalizer.class);
+
+ public static void check(Name name) {
+ if (log.isDebugEnabled()) {
+ String lname = name.getLocalName();
+ String normalized = Normalizer.normalize(lname, Form.NFC);
+ if (!lname.equals(normalized)) {
+ String message = "The new node name '" + dump(lname) + "' is not in Unicode NFC form ('" + dump(normalized) + "').";
+ log.debug(message, new Exception("Call chain"));
+ }
+ }
+ }
+
+ private static String dump(String lname) {
+ StringBuilder sb = new StringBuilder();
+ for (char c : lname.toCharArray()) {
+ if (c > ' ' && c < 127) {
+ sb.append(c);
+ } else {
+ sb.append(String.format("\\u%04x", (int) c));
+ }
+ }
+ return sb.toString();
+ }
+}
Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/AddNodeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/AddNodeTest.java?rev=1529116&r1=1529115&r2=1529116&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/AddNodeTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/AddNodeTest.java Fri Oct 4 10:13:44 2013
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.test.api;
+import java.text.Normalizer;
+
import org.apache.jackrabbit.test.AbstractJCRTest;
import org.apache.jackrabbit.test.NotExecutableException;
@@ -264,4 +266,61 @@ public class AddNodeTest extends Abstrac
// ok, works as expected.
}
}
+
+ /**
+ * Tests the behavior with respect to case-sensitivity
+ */
+ public void testSimilarNodeNamesUpperLower() throws RepositoryException {
+
+ internalTestSimilarNodeNames("Test-a", "Test-A");
+ }
+
+ /**
+ * Tests the behavior with respect to Unicode normalization
+ */
+ public void testSimilarNodeNamesNfcNfd() throws RepositoryException {
+
+ String precomposed = "Test-\u00e4"; // a umlaut
+ String decomposed = Normalizer.normalize(precomposed, Normalizer.Form.NFD);
+ assertFalse(precomposed.equals(decomposed)); // sanity check
+ internalTestSimilarNodeNames(precomposed, decomposed);
+ }
+
+ /**
+ * Tests behavior for creation of "similarly" named nodes
+ * @throws RepositoryException
+ */
+ private void internalTestSimilarNodeNames(String name1, String name2) throws RepositoryException {
+
+ Node n1 = null, n2 = null;
+ Session s = testRootNode.getSession();
+
+ try {
+ n1 = testRootNode.addNode(name1);
+ assertEquals(name1, n1.getName());
+ s.save();
+
+ assertFalse(testRootNode.hasNode(name2));
+ } catch (ConstraintViolationException e) {
+ // accepted
+ }
+ try {
+ n2 = testRootNode.addNode(name2);
+ assertEquals(name2, n2.getName());
+ s.save();
+ } catch (ConstraintViolationException e) {
+ // accepted
+ }
+
+ // If both nodes have been created, do further checks
+ if (n1 != null && n2 != null) {
+ assertFalse(n1.isSame(n2));
+ assertFalse(n1.getIdentifier().equals(n2.getIdentifier()));
+ String n2path = n2.getPath();
+ n1.remove();
+ s.save();
+ Node n3 = s.getNode(n2path);
+ assertTrue(n3.isSame(n2));
+ }
+ }
}
\ No newline at end of file