Author: tomekr
Date: Tue May  9 10:15:59 2017
New Revision: 1794521

URL: http://svn.apache.org/viewvc?rev=1794521&view=rev
Log:
OAK-6188: Allow to exclude nodes containing name fragment during the migration

Modified:
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
 Tue May  9 10:15:59 2017
@@ -62,6 +62,7 @@ import static org.apache.jackrabbit.JcrC
 import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
 import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants.NT_REP_PERMISSION_STORE;
 import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants.REP_PERMISSION_STORE;
+import static 
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.DEFAULT_EXCLUDE_FRAGMENTS;
 import static 
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.DEFAULT_EXCLUDE_PATHS;
 import static 
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.DEFAULT_INCLUDE_PATHS;
 import static 
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.DEFAULT_MERGE_PATHS;
@@ -98,6 +99,11 @@ public class RepositorySidegrade {
     private Set<String> excludePaths = DEFAULT_EXCLUDE_PATHS;
 
     /**
+     * Fragments to exclude during the copy process. Empty by default.
+     */
+    private Set<String> excludeFragments = DEFAULT_EXCLUDE_FRAGMENTS;
+
+    /**
      * Paths to merge during the copy process. Empty by default.
      */
     private Set<String> mergePaths = DEFAULT_MERGE_PATHS;
@@ -204,6 +210,16 @@ public class RepositorySidegrade {
         this.excludePaths = copyOf(checkNotNull(excludes));
     }
 
+    /**
+     * Sets the name fragments that should be excluded when the source 
repository
+     * is copied to the target repository.
+     *
+     * @param excludes Name fragments to be excluded from the copy.
+     */
+    public void setExcludeFragments(@Nonnull String... excludes) {
+        this.excludeFragments = copyOf(checkNotNull(excludes));
+    }
+
     public void setIncludeIndex(boolean includeIndex) {
         this.includeIndex = includeIndex;
     }
@@ -390,7 +406,7 @@ public class RepositorySidegrade {
     }
 
     private boolean isCompleteMigration() {
-        return includePaths.equals(DEFAULT_INCLUDE_PATHS) && 
excludePaths.equals(DEFAULT_EXCLUDE_PATHS) && 
mergePaths.equals(DEFAULT_MERGE_PATHS);
+        return includePaths.equals(DEFAULT_INCLUDE_PATHS) && 
excludePaths.equals(DEFAULT_EXCLUDE_PATHS) && 
excludeFragments.equals(DEFAULT_EXCLUDE_FRAGMENTS) && 
mergePaths.equals(DEFAULT_MERGE_PATHS);
     }
 
     private void copyWorkspace(NodeState sourceRoot, NodeBuilder targetRoot) {
@@ -406,6 +422,7 @@ public class RepositorySidegrade {
         NodeStateCopier.builder()
             .include(includes)
             .exclude(excludes)
+            .excludeFragments(excludeFragments)
             .merge(merges)
             .copy(sourceRoot, targetRoot);
 

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
 Tue May  9 10:15:59 2017
@@ -154,6 +154,8 @@ public class RepositoryUpgrade {
 
     public static final Set<String> DEFAULT_EXCLUDE_PATHS = NONE;
 
+    public static final Set<String> DEFAULT_EXCLUDE_FRAGMENTS = NONE;
+
     public static final Set<String> DEFAULT_MERGE_PATHS = NONE;
 
     /**
@@ -177,6 +179,11 @@ public class RepositoryUpgrade {
     private Set<String> excludePaths = DEFAULT_EXCLUDE_PATHS;
 
     /**
+     * Fragments to exclude during the copy process. Empty by default.
+     */
+    private Set<String> excludeFragments = DEFAULT_EXCLUDE_FRAGMENTS;
+
+    /**
      * Paths to merge during the copy process. Empty by default.
      */
     private Set<String> mergePaths = DEFAULT_MERGE_PATHS;
@@ -333,6 +340,16 @@ public class RepositoryUpgrade {
     }
 
     /**
+     * Sets the name fragments that should be excluded when the source 
repository
+     * is copied to the target repository.
+     *
+     * @param excludes Name fragments to be excluded from the copy.
+     */
+    public void setExcludeFragments(@Nonnull String... excludes) {
+        this.excludeFragments = copyOf(checkNotNull(excludes));
+    }
+
+    /**
      * Sets the paths that should be merged when the source repository
      * is copied to the target repository.
      *
@@ -931,6 +948,7 @@ public class RepositoryUpgrade {
         NodeStateCopier.builder()
                 .include(includes)
                 .exclude(excludes)
+                .excludeFragments(excludeFragments)
                 .merge(merges)
                 .copy(sourceRoot, targetRoot);
 

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
 Tue May  9 10:15:59 2017
@@ -85,6 +85,9 @@ public class MigrationFactory {
         if (options.getExcludePaths() != null) {
             upgrade.setExcludes(options.getExcludePaths());
         }
+        if (options.getExcludeFragments() != null) {
+            upgrade.setExcludeFragments(options.getExcludeFragments());
+        }
         if (options.getMergePaths() != null) {
             upgrade.setMerges(options.getMergePaths());
         }
@@ -110,6 +113,9 @@ public class MigrationFactory {
         if (options.getExcludePaths() != null) {
             sidegrade.setExcludes(options.getExcludePaths());
         }
+        if (options.getExcludeFragments() != null) {
+            sidegrade.setExcludeFragments(options.getExcludeFragments());
+        }
         if (options.getMergePaths() != null) {
             sidegrade.setMerges(options.getMergePaths());
         }

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java
 Tue May  9 10:15:59 2017
@@ -46,6 +46,8 @@ public class MigrationOptions {
 
     private final String[] excludePaths;
 
+    private final String[] excludeFragments;
+
     private final String[] mergePaths;
 
     private final boolean includeIndex;
@@ -115,6 +117,7 @@ public class MigrationOptions {
         }
         this.includePaths = 
checkPaths(args.getOptionList(OptionParserFactory.INCLUDE_PATHS));
         this.excludePaths = 
checkPaths(args.getOptionList(OptionParserFactory.EXCLUDE_PATHS));
+        this.excludeFragments = 
args.getOptionList(OptionParserFactory.EXCLUDE_FRAGMENTS);
         this.mergePaths = 
checkPaths(args.getOptionList(OptionParserFactory.MERGE_PATHS));
         this.includeIndex = args.hasOption(OptionParserFactory.INCLUDE_INDEX);
         this.failOnError = args.hasOption(OptionParserFactory.FAIL_ON_ERROR);
@@ -177,6 +180,10 @@ public class MigrationOptions {
         return excludePaths;
     }
 
+    public String[] getExcludeFragments() {
+        return excludeFragments;
+    }
+
     public String[] getMergePaths() {
         return mergePaths;
     }

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java
 Tue May  9 10:15:59 2017
@@ -70,6 +70,8 @@ public class OptionParserFactory {
 
     public static final String EXCLUDE_PATHS = "exclude-paths";
 
+    public static final String EXCLUDE_FRAGMENTS = "exclude-fragments";
+
     public static final String MERGE_PATHS = "merge-paths";
 
     public static final String SKIP_INIT = "skip-init";
@@ -131,6 +133,8 @@ public class OptionParserFactory {
                 .ofType(String.class);
         op.accepts(EXCLUDE_PATHS, "Comma-separated list of paths to exclude 
during copy.").withRequiredArg()
                 .ofType(String.class);
+        op.accepts(EXCLUDE_FRAGMENTS, "Comma-separated list of fragments to 
exclude during copy.").withRequiredArg()
+                .ofType(String.class);
         op.accepts(MERGE_PATHS, "Comma-separated list of paths to merge during 
copy.").withRequiredArg()
                 .ofType(String.class);
         op.accepts(INCLUDE_INDEX, "Copy index data for paths specified in the 
" + INCLUDE_PATHS + " option");

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
 Tue May  9 10:15:59 2017
@@ -67,6 +67,8 @@ public class FilteringNodeState extends
 
     private final Set<String> excludedPaths;
 
+    private final Set<String> excludedFragments;
+
     /**
      * Factory method that conditionally decorates the given node-state
      * iff the node-state is (a) hidden itself or (b) has hidden descendants.
@@ -75,6 +77,7 @@ public class FilteringNodeState extends
      * @param delegate The node-state to decorate.
      * @param includePaths A Set of paths that should be visible. Defaults to 
["/"] if {@code null}.
      * @param excludePaths A Set of paths that should be hidden. Empty if 
{@code null}.
+     * @param excludedFragments A Set of name fragments that should be hidden. 
Empty if {@code null}.
      * @return The decorated node-state if required, the original node-state 
if decoration is unnecessary.
      */
     @Nonnull
@@ -82,12 +85,14 @@ public class FilteringNodeState extends
             @Nonnull final String path,
             @Nonnull final NodeState delegate,
             @Nullable final Set<String> includePaths,
-            @Nullable final Set<String> excludePaths
+            @Nullable final Set<String> excludePaths,
+            @Nullable final Set<String> excludedFragments
     ) {
         final Set<String> includes = defaultIfEmpty(includePaths, ALL);
         final Set<String> excludes = defaultIfEmpty(excludePaths, NONE);
-        if (hasHiddenDescendants(path, includes, excludes)) {
-            return new FilteringNodeState(path, delegate, includes, excludes);
+        final Set<String> safeExcludedFragments = 
defaultIfEmpty(excludedFragments, NONE);
+        if (hasHiddenDescendants(path, includes, excludes, 
safeExcludedFragments)) {
+            return new FilteringNodeState(path, delegate, includes, excludes, 
safeExcludedFragments);
         }
         return delegate;
     }
@@ -96,24 +101,26 @@ public class FilteringNodeState extends
             @Nonnull final String path,
             @Nonnull final NodeState delegate,
             @Nonnull final Set<String> includedPaths,
-            @Nonnull final Set<String> excludedPaths
+            @Nonnull final Set<String> excludedPaths,
+            @Nonnull final Set<String> excludedFragments
     ) {
         super(delegate);
         this.path = path;
         this.includedPaths = includedPaths;
         this.excludedPaths = excludedPaths;
+        this.excludedFragments = excludedFragments;
     }
 
     @Nonnull
     @Override
     protected NodeState decorateChild(@Nonnull final String name, @Nonnull 
final NodeState child) {
         final String childPath = PathUtils.concat(path, name);
-        return wrap(childPath, child, includedPaths, excludedPaths);
+        return wrap(childPath, child, includedPaths, excludedPaths, 
excludedFragments);
     }
 
     @Override
     protected boolean hideChild(@Nonnull final String name, @Nonnull final 
NodeState delegateChild) {
-        return isHidden(PathUtils.concat(path, name), includedPaths, 
excludedPaths);
+        return isHidden(PathUtils.concat(path, name), includedPaths, 
excludedPaths, excludedFragments);
     }
 
     @Override
@@ -128,14 +135,16 @@ public class FilteringNodeState extends
      * @param path Path to be checked
      * @param includes Include paths
      * @param excludes Exclude paths
+     * @param excludedFragments Exclude fragments
      * @return Whether the {@code path} is hidden or not.
      */
     private static boolean isHidden(
             @Nonnull final String path,
             @Nonnull final Set<String> includes,
-            @Nonnull final Set<String> excludes
+            @Nonnull final Set<String> excludes,
+            @Nonnull final Set<String> excludedFragments
     ) {
-        return isExcluded(path, excludes) || !isIncluded(path, includes);
+        return isExcluded(path, excludes, excludedFragments) || 
!isIncluded(path, includes);
     }
 
     /**
@@ -145,14 +154,16 @@ public class FilteringNodeState extends
      * @param path Path to be checked
      * @param includePaths Include paths
      * @param excludePaths Exclude paths
+     * @param excludedFragments Exclude fragments
      * @return Whether the {@code path} or any of its descendants are hidden 
or not.
      */
     private static boolean hasHiddenDescendants(
             @Nonnull final String path,
             @Nonnull final Set<String> includePaths,
-            @Nonnull final Set<String> excludePaths
+            @Nonnull final Set<String> excludePaths,
+            @Nonnull final Set<String> excludedFragments
     ) {
-        return isHidden(path, includePaths, excludePaths)
+        return isHidden(path, includePaths, excludePaths, excludedFragments)
                 || isAncestorOfAnyPath(path, excludePaths)
                 || isAncestorOfAnyPath(path, includePaths);
     }
@@ -181,10 +192,11 @@ public class FilteringNodeState extends
      *
      * @param path Path to be checked
      * @param excludePaths Exclude paths
+     * @param excludedFragments Exclude fragments
      * @return Whether the path is covered by the excldue paths or not.
      */
-    private static boolean isExcluded(@Nonnull final String path, @Nonnull 
final Set<String> excludePaths) {
-        return excludePaths.contains(path) || isDescendantOfAnyPath(path, 
excludePaths);
+    private static boolean isExcluded(@Nonnull final String path, @Nonnull 
final Set<String> excludePaths, @Nonnull final Set<String> excludedFragments) {
+        return excludePaths.contains(path) || isDescendantOfAnyPath(path, 
excludePaths) || containsAnyFragment(path, excludedFragments);
     }
 
     /**
@@ -218,6 +230,22 @@ public class FilteringNodeState extends
                 return true;
             }
         }
+        return false;
+    }
+
+    /**
+     * Utility method to check whether the passed path contains any of the 
provided {@code fragments}.
+     *
+     * @param path Path
+     * @param fragments Fragments, which the path may contain
+     * @return true if {@code path} contains any of the {@code fragments}, 
false otherwise.
+     */
+    private static boolean containsAnyFragment(@Nonnull final String path, 
@Nonnull final Set<String> fragments) {
+        for (final String f : fragments) {
+            if (path.contains(f)) {
+                return true;
+            }
+        }
         return false;
     }
 

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
 Tue May  9 10:15:59 2017
@@ -65,6 +65,9 @@ import static java.util.Collections.empt
  * <b>Exclude paths:</b> if exclude paths are set, any nodes matching
  * or below the excluded path are not copied. If an excluded node does
  * exist in the target, it is removed (see also merge paths).
+ * <b>Exclude fragments:</b> if exclude fragments are set, nodes with names
+ * matching any of the fragments (and their subtrees) are not copied. If an
+ * excluded node does exist in the target, it is removed.
  * <b>Merge paths:</b> if merge paths are set, any nodes matching or
  * below the merged path will not be deleted from target, even if they
  * are missing in (or excluded from) the source.
@@ -77,11 +80,14 @@ public class NodeStateCopier {
 
     private final Set<String> excludePaths;
 
+    private final Set<String> excludeFragments;
+
     private final Set<String> mergePaths;
 
-    private NodeStateCopier(Set<String> includePaths, Set<String> 
excludePaths, Set<String> mergePaths) {
+    private NodeStateCopier(Set<String> includePaths, Set<String> 
excludePaths, Set<String> excludeFragments, Set<String> mergePaths) {
         this.includePaths = includePaths;
         this.excludePaths = excludePaths;
+        this.excludeFragments = excludeFragments;
         this.mergePaths = mergePaths;
     }
 
@@ -141,7 +147,7 @@ public class NodeStateCopier {
     }
 
     private boolean copyNodeState(@Nonnull final NodeState sourceRoot, 
@Nonnull final NodeBuilder targetRoot) {
-        final NodeState wrappedSource = FilteringNodeState.wrap("/", 
sourceRoot, this.includePaths, this.excludePaths);
+        final NodeState wrappedSource = FilteringNodeState.wrap("/", 
sourceRoot, this.includePaths, this.excludePaths, this.excludeFragments);
         boolean hasChanges = false;
         for (String includePath : this.includePaths) {
             hasChanges = copyMissingAncestors(sourceRoot, targetRoot, 
includePath) || hasChanges;
@@ -294,6 +300,8 @@ public class NodeStateCopier {
 
         private Set<String> excludePaths = emptySet();
 
+        private Set<String> excludeFragments = emptySet();
+
         private Set<String> mergePaths = emptySet();
 
         private Builder() {}
@@ -304,7 +312,7 @@ public class NodeStateCopier {
          *
          * @param paths include paths
          * @return this Builder instance
-         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set)
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
          */
         @Nonnull
         public Builder include(@Nonnull Set<String> paths) {
@@ -319,7 +327,7 @@ public class NodeStateCopier {
          *
          * @param paths include paths
          * @return this Builder instance
-         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set)
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
          */
         @Nonnull
         public Builder include(@Nonnull String... paths) {
@@ -331,7 +339,7 @@ public class NodeStateCopier {
          *
          * @param paths exclude paths
          * @return this Builder instance
-         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set)
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
          */
         @Nonnull
         public Builder exclude(@Nonnull Set<String> paths) {
@@ -346,7 +354,7 @@ public class NodeStateCopier {
          *
          * @param paths exclude paths
          * @return this Builder instance
-         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set)
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
          */
         @Nonnull
         public Builder exclude(@Nonnull String... paths) {
@@ -354,11 +362,38 @@ public class NodeStateCopier {
         }
 
         /**
+         * Set exclude fragments.
+         *
+         * @param fragments exclude fragments
+         * @return this Builder instance
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
+         */
+        @Nonnull
+        public Builder excludeFragments(@Nonnull Set<String> fragments) {
+            if (!checkNotNull(fragments).isEmpty()) {
+                this.excludeFragments = copyOf(fragments);
+            }
+            return this;
+        }
+
+        /**
+         * Convenience wrapper for {@link #exclude(Set)}.
+         *
+         * @param fragments exclude fragments
+         * @return this Builder instance
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
+         */
+        @Nonnull
+        public Builder excludeFragments(@Nonnull String... fragments) {
+            return exclude(copyOf(checkNotNull(fragments)));
+        }
+
+        /**
          * Set merge paths.
          *
          * @param paths merge paths
          * @return this Builder instance
-         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set)
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
          */
         @Nonnull
         public Builder merge(@Nonnull Set<String> paths) {
@@ -373,7 +408,7 @@ public class NodeStateCopier {
          *
          * @param paths merge paths
          * @return this Builder instance
-         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set)
+         * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set)
          */
         @Nonnull
         public Builder merge(@Nonnull String... paths) {
@@ -394,7 +429,7 @@ public class NodeStateCopier {
          *         the same content
          */
         public boolean copy(@Nonnull final NodeState sourceRoot, @Nonnull 
final NodeBuilder targetRoot) {
-            final NodeStateCopier copier = new NodeStateCopier(includePaths, 
excludePaths, mergePaths);
+            final NodeStateCopier copier = new NodeStateCopier(includePaths, 
excludePaths, excludeFragments, mergePaths);
             return copier.copyNodeState(checkNotNull(sourceRoot), 
checkNotNull(targetRoot));
         }
 

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java
 Tue May  9 10:15:59 2017
@@ -81,6 +81,9 @@ public class IncludeExcludeSidegradeTest
                     "/content/assets/foo/2011",
                     "/content/assets/foo/2010"
             );
+            sidegrade.setExcludeFragments(
+                    "oak-mount-libs-xyz"
+            );
             sidegrade.copy();
         } finally {
             fileStore.close();

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java
 Tue May  9 10:15:59 2017
@@ -46,7 +46,10 @@ public class IncludeExcludeUpgradeTest e
         JcrUtils.getOrCreateByPath("/content/assets/foo/2011", "nt:folder", 
session);
         JcrUtils.getOrCreateByPath("/content/assets/foo/2010", "nt:folder", 
session);
         JcrUtils.getOrCreateByPath("/content/assets/foo/2010/12", "nt:folder", 
session);
-        JcrUtils.getOrCreateByPath("/content/assets/foo/2010/11", "nt:folder", 
session);
+        
JcrUtils.getOrCreateByPath("/content/assets/foo/oak-mount-libs-xyz/node1", 
"nt:folder", session);
+        
JcrUtils.getOrCreateByPath("/content/assets/foo/oak-mount-libs-xyz/node2", 
"nt:folder", session);
+        
JcrUtils.getOrCreateByPath("/content/assets/foo/oak-mount-apps-abc/node3", 
"nt:folder", session);
+        
JcrUtils.getOrCreateByPath("/content/assets/foo/oak-mount-apps-abc/node4", 
"nt:folder", session);
         session.save();
     }
 
@@ -66,6 +69,9 @@ public class IncludeExcludeUpgradeTest e
                     "/content/assets/foo/2011",
                     "/content/assets/foo/2010"
             );
+            upgrade.setExcludeFragments(
+                    "oak-mount-libs-xyz"
+            );
             upgrade.copy(null);
         } finally {
             context.getRepository().shutdown();
@@ -78,7 +84,9 @@ public class IncludeExcludeUpgradeTest e
                 "/content/foo/en",
                 "/content/assets/foo/2015/02",
                 "/content/assets/foo/2015/01",
-                "/content/assets/foo/2014"
+                "/content/assets/foo/2014",
+                "/content/assets/foo/oak-mount-apps-abc/node3",
+                "/content/assets/foo/oak-mount-apps-abc/node4"
         );
     }
 
@@ -97,7 +105,9 @@ public class IncludeExcludeUpgradeTest e
                 "/content/assets/foo/2013",
                 "/content/assets/foo/2012",
                 "/content/assets/foo/2011",
-                "/content/assets/foo/2010"
+                "/content/assets/foo/2010",
+                "/content/assets/foo/oak-mount-libs-xyz/node1",
+                "/content/assets/foo/oak-mount-libs-xyz/node2"
         );
     }
 }

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java?rev=1794521&r1=1794520&r2=1794521&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java
 Tue May  9 10:15:59 2017
@@ -80,46 +80,46 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldNotDecorateForNullArgs() {
-        final NodeState decorated = wrap("/", rootNodeState, null, null);
+        final NodeState decorated = wrap("/", rootNodeState, null, null, null);
         assertSame("root should be identical to decorated", rootNodeState, 
decorated);
     }
 
     @Test
     public void shouldNotDecorateForDefaultIncludes() {
-        final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, 
null);
+        final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, 
null, null);
         assertSame("root should be identical to decorated", rootNodeState, 
decorated);
     }
 
     @Test
     public void shouldNotDecorateForDefaultExcludes() {
-        final NodeState decorated = wrap("/", rootNodeState, null, 
DEFAULT_EXCLUDES);
+        final NodeState decorated = wrap("/", rootNodeState, null, 
DEFAULT_EXCLUDES, null);
         assertSame("root should be identical to decorated", rootNodeState, 
decorated);
     }
 
     @Test
     public void shouldNotDecorateForDefaultIncludesAndExcludes() {
-        final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, 
DEFAULT_EXCLUDES);
+        final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, 
DEFAULT_EXCLUDES, null);
         assertSame("root should be identical to decorated", rootNodeState, 
decorated);
     }
 
     @Test
     public void shouldNotDecorateIncludedPath() {
         final NodeState content = getNodeState(rootNodeState, "/content");
-        final NodeState decorated = wrap("/content", content, of("/content"), 
null);
+        final NodeState decorated = wrap("/content", content, of("/content"), 
null, null);
         assertSame("content should be identical to decorated", content, 
decorated);
     }
 
     @Test
     public void shouldNotDecorateIncludedDescendants() {
         final NodeState foo = getNodeState(rootNodeState, "/content/foo");
-        final NodeState decorated = wrap("/content/foo", foo, of("/content"), 
null);
+        final NodeState decorated = wrap("/content/foo", foo, of("/content"), 
null, null);
         assertSame("foo should be identical to decorated", foo, decorated);
     }
 
     @Test
     public void shouldDecorateAncestorOfExcludedDescendants() {
         final NodeState foo = getNodeState(rootNodeState, "/content/foo");
-        final NodeState decorated = wrap("/content/foo", foo, of("/content"), 
of("/content/foo/de"));
+        final NodeState decorated = wrap("/content/foo", foo, of("/content"), 
of("/content/foo/de"), null);
         assertNotSame("foo should not be identical to decorated", foo, 
decorated);
 
         assertMissing(decorated, "de");
@@ -135,7 +135,7 @@ public class FilteringNodeStateTest {
     @Test
     public void shouldHaveCorrectChildOrderProperty() throws 
CommitFailedException {
         final NodeState content = rootNodeState.getChildNode("content");
-        final NodeState decorated = wrap("/content", content, null, 
of("/content/foo"));
+        final NodeState decorated = wrap("/content", content, null, 
of("/content/foo"), null);
 
         assertTrue(decorated.hasProperty(OAK_CHILD_ORDER));
 
@@ -160,7 +160,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldDecorateExcludedNode() {
-        final NodeState decoratedRoot = wrap("/", rootNodeState, 
of("/content"), of("/content/foo/de"));
+        final NodeState decoratedRoot = wrap("/", rootNodeState, 
of("/content"), of("/content/foo/de"), null);
         final NodeState de = getNodeState(rootNodeState, "/content/foo/de");
         final NodeState decorated = getNodeState(decoratedRoot, 
"/content/foo/de");
         assertFalse("de should not be equal to decorated", 
de.equals(decorated));
@@ -170,14 +170,14 @@ public class FilteringNodeStateTest {
     @Test
     public void shouldDecorateImplicitlyExcludedNode() {
         final NodeState content = getNodeState(rootNodeState, "/content");
-        final NodeState decorated = wrap("/content", content, of("/apps"), 
null);
+        final NodeState decorated = wrap("/content", content, of("/apps"), 
null, null);
         assertNotSame("content should not be identical to decorated", content, 
decorated);
     }
 
 
     @Test
     public void shouldHideExcludedPathsViaExists() {
-        final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", 
"/libs"));
+        final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", 
"/libs"), null);
         assertMissing(decorated, "apps");
         assertMissing(decorated, "libs/foo/install");
 
@@ -187,7 +187,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldHideExcludedPathsViaHasChildNode() {
-        final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", 
"/libs"));
+        final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", 
"/libs"), null);
 
         assertExistingHasChildNode(decorated, "content");
         assertMissingHasChildNode(decorated, "apps");
@@ -196,7 +196,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldHideExcludedPathsViaGetChildNodeNames() {
-        final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", 
"/libs"));
+        final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", 
"/libs"), null);
 
         assertExistingChildNodeName(decorated, "content");
         assertMissingChildNodeName(decorated, "apps");
@@ -205,7 +205,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldHideMissingIncludedPathsViaExists() {
-        final NodeState decorated = wrap("/", rootNodeState, of("/content"), 
null);
+        final NodeState decorated = wrap("/", rootNodeState, of("/content"), 
null, null);
         assertMissing(decorated, "apps");
         assertMissing(decorated, "libs/foo/install");
 
@@ -215,7 +215,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldHideMissingIncludedPathsViaHasChildNode() {
-        final NodeState decorated = wrap("/", rootNodeState, of("/content"), 
null);
+        final NodeState decorated = wrap("/", rootNodeState, of("/content"), 
null, null);
 
         assertExistingHasChildNode(decorated, "content");
         assertMissingHasChildNode(decorated, "apps");
@@ -224,7 +224,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldHideMissingIncludedPathsViaGetChildNodeNames() {
-        final NodeState decorated = wrap("/", rootNodeState, of("/content"), 
null);
+        final NodeState decorated = wrap("/", rootNodeState, of("/content"), 
null, null);
 
         assertExistingChildNodeName(decorated, "content");
         assertMissingChildNodeName(decorated, "apps");
@@ -233,15 +233,15 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldGivePrecedenceForExcludesOverIncludes() {
-        final NodeState conflictingRules = wrap("/", rootNodeState, 
of("/content"), of("/content"));
+        final NodeState conflictingRules = wrap("/", rootNodeState, 
of("/content"), of("/content"), null);
         assertMissingChildNodeName(conflictingRules, "content");
 
-        final NodeState overlappingRules = wrap("/", rootNodeState, 
of("/content"), of("/content/foo"));
+        final NodeState overlappingRules = wrap("/", rootNodeState, 
of("/content"), of("/content/foo"), null);
         assertExistingChildNodeName(overlappingRules, "content");
         assertMissingChildNodeName(overlappingRules.getChildNode("content"), 
"foo");
 
 
-        final NodeState overlappingRules2 = wrap("/", rootNodeState, 
of("/content/foo"), of("/content"));
+        final NodeState overlappingRules2 = wrap("/", rootNodeState, 
of("/content/foo"), of("/content"), null);
         assertMissingChildNodeName(overlappingRules2, "content");
         assertMissingChildNodeName(overlappingRules2.getChildNode("content"), 
"foo");
 
@@ -249,7 +249,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldRespectPathBoundariesForIncludes() {
-        final NodeState decorated = wrap("/", rootNodeState, 
of("/content/foo"), null);
+        final NodeState decorated = wrap("/", rootNodeState, 
of("/content/foo"), null, null);
 
         assertExistingChildNodeName(decorated, "content");
         assertExistingChildNodeName(decorated.getChildNode("content"), "foo");
@@ -258,7 +258,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldRespectPathBoundariesForExcludes() {
-        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo"));
+        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo"), null);
 
         assertExistingChildNodeName(decorated, "content");
         assertMissingChildNodeName(decorated.getChildNode("content"), "foo");
@@ -267,7 +267,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldDelegatePropertyCount() {
-        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo/de"));
+        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo/de"), null);
 
         assertEquals(1, getNodeState(decorated, 
"/content").getPropertyCount());
         assertEquals(0, getNodeState(decorated, 
"/content/foo").getPropertyCount());
@@ -276,7 +276,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldDelegateGetProperty() {
-        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo"));
+        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo"), null);
         final NodeState content = getNodeState(decorated, "/content");
 
         assertNotNull(content.getProperty(OAK_CHILD_ORDER));
@@ -286,7 +286,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void shouldDelegateHasProperty() {
-        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo/de"));
+        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo/de"), null);
 
         assertTrue(getNodeState(decorated, 
"/content").hasProperty(OAK_CHILD_ORDER));
         assertFalse(getNodeState(decorated, "/content").hasProperty("foo"));
@@ -295,7 +295,7 @@ public class FilteringNodeStateTest {
 
     @Test
     public void exists() {
-        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo"));
+        final NodeState decorated = wrap("/", rootNodeState, null, 
of("/content/foo"), null);
         assertTrue("/content should exist and be visible", 
getNodeState(decorated, "/content").exists());
         assertFalse("/content/foo should be hidden", getNodeState(decorated, 
"/content/foo").exists());
         assertFalse("/nonexisting should not exist", getNodeState(decorated, 
"/nonexisting").exists());


Reply via email to