You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by js...@apache.org on 2021/07/02 09:28:54 UTC

[jackrabbit-filevault] branch bugfix/JCRVLT-544-refactored-EffectiveNodeType created (now 7ed67c4)

This is an automated email from the ASF dual-hosted git repository.

jsedding pushed a change to branch bugfix/JCRVLT-544-refactored-EffectiveNodeType
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git.


      at 7ed67c4  JCRVLT-544 never create intermediate nodes of type nt:base or nt:hierarchyNode

This branch includes the following new commits:

     new 7ed67c4  JCRVLT-544 never create intermediate nodes of type nt:base or nt:hierarchyNode

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[jackrabbit-filevault] 01/01: JCRVLT-544 never create intermediate nodes of type nt:base or nt:hierarchyNode

Posted by js...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jsedding pushed a commit to branch bugfix/JCRVLT-544-refactored-EffectiveNodeType
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit 7ed67c4f55988f9ad9432a40896ede52ca539bfa
Author: Julian Sedding <js...@apache.org>
AuthorDate: Fri Jul 2 11:28:28 2021 +0200

    JCRVLT-544 never create intermediate nodes of type nt:base or nt:hierarchyNode
    
    - refactored EffectiveNodeType
---
 .../vault/fs/impl/io/DocViewSAXImporter.java       | 17 ++---
 .../vault/fs/impl/io/FolderArtifactHandler.java    |  9 ++-
 .../jackrabbit/vault/util/EffectiveNodeType.java   | 84 +++++++++++-----------
 3 files changed, 49 insertions(+), 61 deletions(-)

diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java
index a2369f5..084f4d9 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java
@@ -20,7 +20,6 @@ package org.apache.jackrabbit.vault.fs.impl.io;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.HashMap;
@@ -29,8 +28,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 import javax.jcr.ImportUUIDBehavior;
 import javax.jcr.Item;
@@ -1114,16 +1111,12 @@ public class DocViewSAXImporter extends RejectingEntityDefaultHandler implements
     * 
      * @param effectiveNodeType the effective node type
      * @param docViewProperty the property
-     * @return{@code true} in case the property is protected, {@code false} otherwise
-     * @throws RepositoryException 
+     * @return {@code true} in case the property is protected, {@code false} otherwise
      */
-    private static boolean isPropertyProtected(@NotNull EffectiveNodeType effectiveNodeType, @NotNull DocViewProperty docViewProperty) throws RepositoryException {
-        PropertyDefinition propDef = effectiveNodeType.getPropertyDef(docViewProperty.name, docViewProperty.isMulti, docViewProperty.type);
-        if (propDef == null) {
-            return false;
-        } else {
-            return propDef.isProtected();
-        }
+    private static boolean isPropertyProtected(@NotNull EffectiveNodeType effectiveNodeType, @NotNull DocViewProperty docViewProperty) {
+        return effectiveNodeType.getPropertyDef(docViewProperty.name, docViewProperty.isMulti, docViewProperty.type)
+                .map(PropertyDefinition::isProtected)
+                .orElse(false);
     }
 
     private Node getNodeByUUIDLabelOrName(@NotNull Node currentNode, @NotNull DocViewNode ni) throws RepositoryException {
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java
index 4151d0a..b142c6a 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/FolderArtifactHandler.java
@@ -87,11 +87,10 @@ public class FolderArtifactHandler extends AbstractArtifactHandler {
 
     private @Nullable String getDefaultPrimaryChildNodeType(Node parent, String intermediateNodeName) throws RepositoryException {
         EffectiveNodeType effectiveNodeType = EffectiveNodeType.ofNode(parent);
-        NodeDefinition nodeDefinition = effectiveNodeType.getChildNodeDef(nd -> nd.getDefaultPrimaryType() != null, intermediateNodeName);
-        if (nodeDefinition != null) {
-            return nodeDefinition.getDefaultPrimaryTypeName();
-        }
-        return null;
+        return effectiveNodeType.getChildNodeDef(intermediateNodeName)
+                .filter(nd -> nd.getDefaultPrimaryType() != null)
+                .map(NodeDefinition::getDefaultPrimaryTypeName)
+                .orElse(null);
     }
 
     /**
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/EffectiveNodeType.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/EffectiveNodeType.java
index 73ba2ac..b75d14b 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/EffectiveNodeType.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/EffectiveNodeType.java
@@ -18,12 +18,7 @@ package org.apache.jackrabbit.vault.util;
 
 import static javax.jcr.PropertyType.UNDEFINED;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
+import org.jetbrains.annotations.NotNull;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
@@ -31,9 +26,12 @@ import javax.jcr.nodetype.ItemDefinition;
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.PropertyDefinition;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Effective node type as defined by <a href="https://docs.adobe.com/content/docs/en/spec/jcr/2.0/3_Repository_Model.html#3.7.6.5%20Effective%20Node%20Type">JCR 2.0, Chapter 3.7.6.5</a>.
@@ -48,10 +46,8 @@ public final class EffectiveNodeType {
     }
 
     public static EffectiveNodeType ofPrimaryTypeAndMixins(NodeType primaryType, NodeType... mixinTypes) {
-        List<NodeType> types = new ArrayList<>();
-        types.add(primaryType);
-        Arrays.stream(mixinTypes).forEach(types::add);
-        return new EffectiveNodeType(types);
+        return Stream.concat(Stream.of(primaryType), Stream.of(mixinTypes))
+                .collect(Collectors.collectingAndThen(Collectors.toList(), EffectiveNodeType::new));
     }
 
     private final List<NodeType> nodeTypes;
@@ -69,47 +65,47 @@ public final class EffectiveNodeType {
      * 
      * This replicates the logic from https://github.com/apache/jackrabbit-oak/blob/274f92402a12978040939965e92ee4519f2ce1c3/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeImpl.java#L365
      */
-    public @Nullable PropertyDefinition getPropertyDef(@NotNull String name, boolean isMultiple, int type) {
-        return getPropertyDef(pd -> isMultiple == pd.isMultiple() && (type == pd.getRequiredType() || UNDEFINED == type || UNDEFINED == pd.getRequiredType()), name);
+    public @NotNull Optional<PropertyDefinition> getPropertyDef(@NotNull String name, boolean isMultiple, int type) {
+        return getPropertyDef(name)
+                .filter(pd -> isMultiple == pd.isMultiple())
+                .filter(pd -> type == pd.getRequiredType() || UNDEFINED == type || UNDEFINED == pd.getRequiredType());
     }
 
-    public @Nullable PropertyDefinition getPropertyDef(Predicate<PropertyDefinition> predicate, @NotNull String name) {
-        List<PropertyDefinition> propertyDefinitions = nodeTypes.stream().flatMap(nt -> Arrays.stream(nt.getPropertyDefinitions())).collect(Collectors.toList());
-        // first named then unnamed
-        PropertyDefinition namedPropertyDef = EffectiveNodeType.<PropertyDefinition>getItemDefinition(propertyDefinitions, predicate, name);
-        if (namedPropertyDef == null) {
-            // then unnamed
-            return EffectiveNodeType.<PropertyDefinition>getItemDefinition(propertyDefinitions, predicate, null);
-        } else {
-            return namedPropertyDef;
-        }
+    public @NotNull Optional<PropertyDefinition> getPropertyDef(@NotNull String name) {
+        return nodeTypes.stream()
+                .flatMap(nt -> Stream.of(nt.getPropertyDefinitions()))
+                .filter(byName(name))
+                .min(Comparator.comparing(ItemDefinition::getName, wildcardAwareNameComparator()));
     }
 
-    public @Nullable NodeDefinition getChildNodeDef(Predicate<NodeDefinition> predicate, @NotNull String name) {
-        List<NodeDefinition> nodeDefinitions = nodeTypes.stream().flatMap(nt -> Arrays.stream(nt.getChildNodeDefinitions())).collect(Collectors.toList());
-        // first named then unnamed
-        NodeDefinition namedNodeDef = EffectiveNodeType.<NodeDefinition>getItemDefinition(nodeDefinitions, predicate, name);
-        if (namedNodeDef == null) {
-            // then unnamed
-            return EffectiveNodeType.<NodeDefinition>getItemDefinition(nodeDefinitions, predicate, null);
-        } else {
-            return namedNodeDef;
-        }
+    public @NotNull Optional<NodeDefinition> getChildNodeDef(@NotNull String name) {
+        return nodeTypes.stream()
+                .flatMap(nt -> Stream.of(nt.getChildNodeDefinitions()))
+                .filter(byName(name))
+                .min(Comparator.comparing(ItemDefinition::getName, wildcardAwareNameComparator()));
     }
 
-    private static @Nullable <T extends ItemDefinition> T getItemDefinition(List<T> itemDefinitions, Predicate<T> predicate, @Nullable String name) {
-        final Predicate<ItemDefinition> namePredicate;
+    private static Predicate<? super ItemDefinition> byName(String name) {
+        final Predicate<? super ItemDefinition> namePredicate;
         if (name != null) {
-            namePredicate = pd -> name.equals(pd.getName());
+            namePredicate = pd -> name.equals(pd.getName()) || "*".equals(pd.getName());
         } else {
             namePredicate = pd -> "*".equals(pd.getName());
         }
-        // either named or residual child node definitions
-        Optional<T> childNodeDef = itemDefinitions.stream().filter(predicate).filter(namePredicate).findFirst();
-        if (childNodeDef.isPresent()) {
-            return childNodeDef.get();
-        }
-        return null;
+        return namePredicate;
+    }
+
+    // always sort wildcard(s) last
+    private static Comparator<String> wildcardAwareNameComparator() {
+        return (a, b) -> {
+            if (a.equals("*")) {
+                return (b.equals("*")) ? 0 : 1;
+            } else if (b.equals("*")) {
+                return -1;
+            } else {
+                return a.compareTo(b);
+            }
+        };
     }
 
 }