Author: stillalex
Date: Mon Jun 11 08:02:29 2018
New Revision: 1833309

URL: http://svn.apache.org/viewvc?rev=1833309&view=rev
Log:
OAK-7533 NameValidator is not using namespaces defined in the current 
transaction


Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorProvider.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java?rev=1833309&r1=1833308&r2=1833309&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java
 Mon Jun 11 08:02:29 2018
@@ -16,6 +16,10 @@
  */
 package org.apache.jackrabbit.oak.plugins.name;
 
+import static com.google.common.collect.Sets.newHashSet;
+import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_NSDATA;
+import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_PREFIXES;
+
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -31,10 +35,12 @@ import org.apache.jackrabbit.oak.spi.sta
  */
 class NameValidator extends DefaultValidator {
 
+    private final NodeState namespaces;
     private final Set<String> prefixes;
 
-    NameValidator(Set<String> prefixes) {
-        this.prefixes = prefixes;
+    NameValidator(NodeState namespaces) {
+        this.namespaces = namespaces;
+        this.prefixes = 
newHashSet(namespaces.getChildNode(REP_NSDATA).getStrings(REP_PREFIXES));
     }
 
     // escape non-printable non-USASCII characters using standard Java escapes
@@ -65,7 +71,7 @@ class NameValidator extends DefaultValid
         int colon = name.indexOf(':');
         if (colon > 0) {
             String prefix = name.substring(0, colon);
-            if (prefix.isEmpty() || !prefixes.contains(prefix)) {
+            if (prefix.isEmpty() || !contains(prefixes, namespaces, prefix)) {
                 throw new CommitFailedException(
                         CommitFailedException.NAME, 1, "Invalid namespace 
prefix("+prefixes+"): " + prefix);
             }
@@ -93,6 +99,10 @@ class NameValidator extends DefaultValid
         }
     }
 
+    private static boolean contains(Set<String> prefixes, NodeState 
namespaces, String prefix) {
+        return prefixes.contains(prefix) || 
Namespaces.collectNamespaces(namespaces.getProperties()).containsKey(prefix);
+    }
+
     protected void checkValidValue(PropertyState property)
             throws CommitFailedException {
         if (Type.NAME.equals(property.getType()) || 
Type.NAMES.equals(property.getType())) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorProvider.java?rev=1833309&r1=1833308&r2=1833309&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorProvider.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorProvider.java
 Mon Jun 11 08:02:29 2018
@@ -23,11 +23,8 @@ import org.apache.jackrabbit.oak.spi.com
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.osgi.service.component.annotations.Component;
 
-import static com.google.common.collect.Sets.newHashSet;
 import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
 import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_NAMESPACES;
-import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_NSDATA;
-import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_PREFIXES;
 
 /**
  * Validator service that checks that all node and property names as well
@@ -40,11 +37,9 @@ public class NameValidatorProvider exten
     @Override
     public Validator getRootValidator(
             NodeState before, NodeState after, CommitInfo info) {
-        return new NameValidator(newHashSet(after
+        return new NameValidator(after
                 .getChildNode(JCR_SYSTEM)
-                .getChildNode(REP_NAMESPACES)
-                .getChildNode(REP_NSDATA)
-                .getStrings(REP_PREFIXES)));
+                .getChildNode(REP_NAMESPACES));
     }
 
 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java?rev=1833309&r1=1833308&r2=1833309&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
 Mon Jun 11 08:02:29 2018
@@ -16,14 +16,10 @@
 */
 package org.apache.jackrabbit.oak.plugins.name;
 
-import java.util.Arrays;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-import com.google.common.collect.Sets;
-
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Type;
@@ -143,24 +139,17 @@ public class Namespaces implements Names
         // that's not stored along with the other mappings
         Set<String> prefixes = newHashSet("");
         Set<String> uris = newHashSet("");
-        Map<String, String> reverse = new HashMap<String, String>();
-
-        for (PropertyState property : namespaces.getProperties()) {
-            String prefix = property.getName();
-            if (STRING.equals(property.getType()) && isValidPrefix(prefix)) {
-                prefixes.add(prefix);
-                String uri = property.getValue(STRING);
-                uris.add(uri);
-                reverse.put(uri, prefix);
-            }
-        }
+        Map<String, String> nsmap = 
collectNamespaces(namespaces.getProperties());
+        prefixes.addAll(nsmap.keySet());
+        uris.addAll(nsmap.values());
 
         NodeBuilder data = namespaces.setChildNode(REP_NSDATA);
         data.setProperty(JCR_PRIMARYTYPE, 
NodeTypeConstants.NT_REP_UNSTRUCTURED, Type.NAME);
         data.setProperty(REP_PREFIXES, prefixes, Type.STRINGS);
         data.setProperty(REP_URIS, uris, Type.STRINGS);
-        for (Entry<String, String> e : reverse.entrySet()) {
-            data.setProperty(encodeUri(e.getKey()), e.getValue());
+        for (Entry<String, String> e : nsmap.entrySet()) {
+            // persist as reverse index
+            data.setProperty(encodeUri(e.getValue()), e.getKey());
         }
     }
 
@@ -169,31 +158,22 @@ public class Namespaces implements Names
     }
 
     public static Map<String, String> getNamespaceMap(Tree root) {
-        Map<String, String> map = newHashMap();
+        Map<String, String> map = 
collectNamespaces(getNamespaceTree(root).getProperties());
         map.put("", ""); // default namespace, not included in tree
+        return map;
+    }
 
-        Tree namespaces = getNamespaceTree(root);
-        for (PropertyState property : namespaces.getProperties()) {
+    static Map<String, String> collectNamespaces(Iterable<? extends 
PropertyState> properties) {
+        Map<String, String> map = newHashMap();
+        for (PropertyState property : properties) {
             String prefix = property.getName();
             if (STRING.equals(property.getType()) && isValidPrefix(prefix)) {
                 map.put(prefix, property.getValue(STRING));
             }
         }
-
         return map;
     }
 
-    static String[] getNamespacePrefixes(Tree root) {
-        Set<String> prefSet = getNamespacePrefixesAsSet(root);
-        String[] prefixes = prefSet.toArray(new String[prefSet.size()]);
-        Arrays.sort(prefixes);
-        return prefixes;
-    }
-
-    static Set<String> getNamespacePrefixesAsSet(Tree root) {
-        return safeGet(getNamespaceTree(root).getChild(REP_NSDATA), 
REP_PREFIXES);
-    }
-
     public static String getNamespacePrefix(Tree root, String uri) {
         if (uri.isEmpty()) {
             return uri;
@@ -208,11 +188,6 @@ public class Namespaces implements Names
         return null;
     }
 
-    static String[] getNamespaceURIs(Tree root) {
-        Set<String> uris = 
safeGet(getNamespaceTree(root).getChild(REP_NSDATA), REP_URIS);
-        return uris.toArray(new String[uris.size()]);
-    }
-
     public static String getNamespaceURI(Tree root, String prefix) {
         if (prefix.isEmpty()) {
             return prefix;
@@ -248,14 +223,6 @@ public class Namespaces implements Names
         return encoded;
     }
 
-    static Set<String> safeGet(Tree tree, String name) {
-        PropertyState ps = tree.getProperty(name);
-        if (ps == null) {
-            return Sets.newHashSet();
-        }
-        return Sets.newHashSet(ps.getValue(Type.STRINGS));
-    }
-
     // validation
 
     public static boolean isValidPrefix(String prefix) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorTest.java?rev=1833309&r1=1833308&r2=1833309&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NameValidatorTest.java
 Mon Jun 11 08:02:29 2018
@@ -17,18 +17,22 @@
 package org.apache.jackrabbit.oak.plugins.name;
 
 import static 
org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_NSDATA;
+import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_PREFIXES;
 import static org.junit.Assert.assertEquals;
 
 import java.util.Collections;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.junit.Test;
 
 public class NameValidatorTest {
 
-    private final Validator validator =
-            new NameValidator(Collections.singleton("valid"));
+    private final Validator validator = new 
NameValidator(newNamespaceNode("valid"));
 
     @Test(expected = CommitFailedException.class)
     public void testCurrentPath() throws CommitFailedException {
@@ -110,4 +114,20 @@ public class NameValidatorTest {
         assertEquals("\\t\\r\\n\\b\\f", 
NameValidator.getPrintableName("\t\r\n\b\f"));
         assertEquals("\\u00e0", NameValidator.getPrintableName("\u00e0"));
     }
+
+    @Test
+    public void testTransientNs() throws CommitFailedException {
+        NodeBuilder builder = newNamespaceNode("valid").builder();
+        builder.setProperty("testNVT", "testuri");
+
+        Validator validator = new NameValidator(builder.getNodeState());
+        validator.childNodeAdded("testNVT:test", EMPTY_NODE);
+    }
+
+    private static NodeState newNamespaceNode(String valid) {
+        NodeBuilder ns = EMPTY_NODE.builder();
+        ns.child(REP_NSDATA).setProperty(REP_PREFIXES, 
Collections.singleton(valid), Type.STRINGS);
+        return ns.getNodeState();
+    }
+
 }


Reply via email to