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(); + } + }