Author: chetanm
Date: Wed Oct 19 15:06:11 2016
New Revision: 1765616

URL: http://svn.apache.org/viewvc?rev=1765616&view=rev
Log:
OAK-1312 -  [bundling] Bundle nodes into a document

Switch to matcher based approach to match the child nodes. The matchers 
maintain the state of where they are in given pattern and avoid repeated path 
comparison logic

Added:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcher.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeAllMatcher.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcher.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Matcher.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcherTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcherTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/MatcherTest.java
   (with props)
Removed:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingRoot.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingRootTest.java
Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Include.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlorTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java?rev=1765616&r1=1765615&r2=1765616&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
 Wed Oct 19 15:06:11 2016
@@ -33,26 +33,26 @@ import static org.apache.jackrabbit.oak.
 public class BundlingHandler {
     private final BundledTypesRegistry registry;
     private final String path;
-    private final BundlingRoot root;
+    private final BundlingContext ctx;
     private final Set<PropertyState> metaProps;
 
     public BundlingHandler(BundledTypesRegistry registry) {
-        this(registry, new BundlingRoot(), ROOT_PATH, 
Collections.<PropertyState>emptySet());
+        this(registry, BundlingContext.NULL, ROOT_PATH, 
Collections.<PropertyState>emptySet());
     }
 
-    private BundlingHandler(BundledTypesRegistry registry, BundlingRoot root, 
String path) {
-        this(registry, root, path, Collections.<PropertyState>emptySet());
+    private BundlingHandler(BundledTypesRegistry registry, BundlingContext 
ctx, String path) {
+        this(registry, ctx, path, Collections.<PropertyState>emptySet());
     }
 
-    private BundlingHandler(BundledTypesRegistry registry, BundlingRoot root, 
String path, Set<PropertyState> metaProps) {
+    private BundlingHandler(BundledTypesRegistry registry, BundlingContext 
ctx, String path, Set<PropertyState> metaProps) {
         this.registry = registry;
         this.path = path;
-        this.root = root;
+        this.ctx = ctx;
         this.metaProps = metaProps;
     }
 
     public String getPropertyPath(String propertyName) {
-        return root.getPropertyPath(path, propertyName);
+        return ctx.isBundling() ? ctx.getPropertyPath(propertyName) : 
propertyName;
     }
 
     public Set<PropertyState> getMetaProps() {
@@ -60,67 +60,101 @@ public class BundlingHandler {
     }
 
     public String getRootBundlePath() {
-        return root.bundlingEnabled() ? root.getPath() : path;
+        return ctx.isBundling() ? ctx.bundlingPath : path;
     }
 
     public BundlingHandler childAdded(String name, NodeState state){
         String childPath = childPath(name);
-        BundlingRoot childRoot;
+        BundlingContext childContext;
         Set<PropertyState> metaProps = Collections.emptySet();
-        if (root.isBundled(childPath)) {
+        Matcher childMatcher = ctx.matcher.next(name);
+        if (childMatcher.isMatch()) {
             //TODO Add meta prop for bundled child node
-            childRoot = root;
+            childContext = createChildContext(childMatcher);
         } else {
             DocumentBundlor bundlor = registry.getBundlor(state);
             if (bundlor != null){
                 PropertyState bundlorConfig = bundlor.asPropertyState();
                 metaProps = Collections.singleton(bundlorConfig);
+                childContext = new BundlingContext(childPath, 
bundlor.createMatcher());
+            } else {
+                childContext = BundlingContext.NULL;
             }
-            childRoot = new BundlingRoot(childPath, bundlor);
         }
-
-        return new BundlingHandler(registry, childRoot, childPath, metaProps);
+        return new BundlingHandler(registry, childContext, childPath, 
metaProps);
     }
 
     public BundlingHandler childDeleted(String name, NodeState state){
         String childPath = childPath(name);
-        BundlingRoot childRoot;
-        if (root.isBundled(childPath)) {
+        BundlingContext childContext;
+        Matcher childMatcher = ctx.matcher.next(name);
+        if (childMatcher.isMatch()) {
             //TODO Add meta prop for bundled child node
-            childRoot = root;
+            childContext = createChildContext(childMatcher);
         } else {
-            childRoot = new BundlingRoot(childPath, 
getBundlorFromEmbeddedConfig(state));
+            childContext = getBundlorContext(childPath, state);
         }
-        return new BundlingHandler(registry, childRoot, childPath);
+        return new BundlingHandler(registry, childContext, childPath);
     }
 
     public BundlingHandler childChanged(String name, NodeState state){
         String childPath = childPath(name);
-        BundlingRoot childRoot;
-        if (root.isBundled(childPath)) {
-            childRoot = root;
+        BundlingContext childContext;
+        Matcher childMatcher = ctx.matcher.next(name);
+        if (childMatcher.isMatch()) {
+            childContext = createChildContext(childMatcher);
         } else {
-            childRoot = new BundlingRoot(childPath, 
getBundlorFromEmbeddedConfig(state));
+            childContext = getBundlorContext(childPath, state);
         }
 
-        return new BundlingHandler(registry, childRoot,  childPath);
+        return new BundlingHandler(registry, childContext,  childPath);
     }
 
     public boolean isBundlingRoot() {
-        return root.getPath().equals(path);
+        if (ctx.isBundling()){
+            return ctx.bundlingPath.equals(path);
+        }
+        return true;
     }
 
     private String childPath(String name){
         return PathUtils.concat(path, name);
     }
 
-    @CheckForNull
-    private static DocumentBundlor getBundlorFromEmbeddedConfig(NodeState 
state) {
+    private BundlingContext createChildContext(Matcher childMatcher) {
+        return ctx.child(childMatcher);
+    }
+
+    private static BundlingContext getBundlorContext(String path, NodeState 
state) {
+        BundlingContext result = BundlingContext.NULL;
         PropertyState bundlorConfig = 
state.getProperty(DocumentBundlor.META_PROP_PATTERN);
-        DocumentBundlor bundlor = null;
         if (bundlorConfig != null){
-            bundlor = DocumentBundlor.from(bundlorConfig);
+            DocumentBundlor bundlor = DocumentBundlor.from(bundlorConfig);
+            result = new BundlingContext(path, bundlor.createMatcher());
+        }
+        return result;
+    }
+
+    private static class BundlingContext {
+        static final BundlingContext NULL = new BundlingContext("", 
Matcher.FAILED);
+        final String bundlingPath;
+        final Matcher matcher;
+
+        public BundlingContext(String bundlingPath, Matcher matcher) {
+            this.bundlingPath = bundlingPath;
+            this.matcher = matcher;
+        }
+
+        public BundlingContext child(Matcher matcher){
+            return new BundlingContext(bundlingPath, matcher);
+        }
+
+        public boolean isBundling(){
+            return matcher.isMatch();
+        }
+
+        public String getPropertyPath(String propertyName) {
+            return PathUtils.concat(matcher.getMatchedPath(), propertyName);
         }
-        return bundlor;
     }
 }

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcher.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcher.java?rev=1765616&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcher.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcher.java
 Wed Oct 19 15:06:11 2016
@@ -0,0 +1,76 @@
+/*
+ * 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.oak.plugins.document.bundlor;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+class CompositeMatcher implements Matcher {
+    private final List<Matcher> matchers;
+
+    public static Matcher compose(List<Matcher> matchers){
+        switch (matchers.size()) {
+            case 0:
+                return Matcher.FAILED;
+            case 1:
+                return matchers.get(0);
+            default:
+                return new CompositeMatcher(matchers);
+        }
+    }
+
+    /**
+     * A CompositeMatcher must only be constructed when all passed
+     * matchers are matching
+     */
+    private CompositeMatcher(List<Matcher> matchers) {
+        for (Matcher m : matchers){
+            checkArgument(m.isMatch(), "Non matching matcher found in [%s]", 
matchers);
+        }
+        this.matchers = matchers;
+    }
+
+    @Override
+    public Matcher next(String name) {
+        List<Matcher> nextSet = 
Lists.newArrayListWithCapacity(matchers.size());
+        for (Matcher current : matchers){
+            Matcher next = current.next(name);
+            if (next.isMatch()){
+                nextSet.add(next);
+            }
+        }
+        return compose(nextSet);
+    }
+
+    @Override
+    public boolean isMatch() {
+        return true;
+    }
+
+    @Override
+    public String getMatchedPath() {
+        //All matchers would have traversed same path. So use any one to
+        //determine the matching path
+        return matchers.get(0).getMatchedPath();
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java?rev=1765616&r1=1765615&r2=1765616&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
 Wed Oct 19 15:06:11 2016
@@ -27,6 +27,7 @@ import com.google.common.collect.Immutab
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
@@ -61,17 +62,15 @@ public class DocumentBundlor {
     }
 
     private DocumentBundlor(List<Include> includes) {
-        //TODO Have assertion for that all intermediate paths are included
         this.includes = ImmutableList.copyOf(includes);
     }
 
     public boolean isBundled(String relativePath) {
-        for (Include include : includes){
-            if (include.match(relativePath)){
-                return true;
-            }
+        Matcher m = createMatcher();
+        for (String e : PathUtils.elements(relativePath)){
+            m = m.next(e);
         }
-        return false;
+        return m.isMatch();
     }
 
     public PropertyState asPropertyState(){
@@ -82,8 +81,17 @@ public class DocumentBundlor {
         return createProperty(META_PROP_PATTERN, includePatterns, STRINGS);
     }
 
+    public Matcher createMatcher(){
+        List<Matcher> matchers = 
Lists.newArrayListWithCapacity(includes.size());
+        for(Include include : includes){
+            matchers.add(include.createMatcher());
+        }
+        return CompositeMatcher.compose(matchers);
+    }
+
     @Override
     public String toString() {
         return includes.toString();
     }
+
 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Include.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Include.java?rev=1765616&r1=1765615&r2=1765616&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Include.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Include.java
 Wed Oct 19 15:06:11 2016
@@ -19,13 +19,15 @@
 
 package org.apache.jackrabbit.oak.plugins.document.bundlor;
 
-import java.util.Arrays;
 import java.util.List;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 
+import static com.google.common.base.Preconditions.checkElementIndex;
+import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+
 /**
  * Include represents a single path pattern which captures the path which
  * needs to be included in bundling. Path patterns can be like below.
@@ -71,29 +73,11 @@ public class Include {
     }
 
     public boolean match(String relativePath) {
-        int targetDepth = 0;
+        Matcher m = createMatcher();
         for (String e : PathUtils.elements(relativePath)){
-            if (targetDepth == elements.length){
-                //TODO exception when leaf but have extra elements
-                if (directive == Directive.ALL){
-                    return true;
-                }
-                return false;
-            }
-
-            String pe = elements[targetDepth++];
-            if ("*".equals(pe) || pe.equals(e)){
-                continue;
-            }
-
-            return false;
-        }
-
-        //Number of elements in target < pattern then match not possible
-        if (targetDepth < elements.length){
-            return false;
+            m = m.next(e);
         }
-        return true;
+        return m.isMatch();
     }
 
     public String getPattern() {
@@ -105,7 +89,22 @@ public class Include {
         return pattern;
     }
 
+    public Matcher createMatcher() {
+        return new IncludeMatcher(this);
+    }
+
     Directive getDirective() {
         return directive;
     }
+
+    public boolean match(String nodeName, int depth) {
+        checkElementIndex(depth, elements.length);
+        String e = elements[depth];
+        return "*".equals(e) || nodeName.equals(e);
+    }
+
+    public int size() {
+        return elements.length;
+    }
+
 }

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeAllMatcher.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeAllMatcher.java?rev=1765616&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeAllMatcher.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeAllMatcher.java
 Wed Oct 19 15:06:11 2016
@@ -0,0 +1,48 @@
+/*
+ * 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.oak.plugins.document.bundlor;
+
+import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+
+/**
+ * Matcher which matches all child nodes
+ */
+class IncludeAllMatcher implements Matcher {
+    private final String matchingPath;
+
+    IncludeAllMatcher(String matchingPath) {
+        this.matchingPath = matchingPath;
+    }
+
+    @Override
+    public Matcher next(String name) {
+        return new IncludeAllMatcher(concat(matchingPath, name));
+    }
+
+    @Override
+    public boolean isMatch() {
+        return true;
+    }
+
+    @Override
+    public String getMatchedPath() {
+        return matchingPath;
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeAllMatcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcher.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcher.java?rev=1765616&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcher.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcher.java
 Wed Oct 19 15:06:11 2016
@@ -0,0 +1,82 @@
+/*
+ * 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.oak.plugins.document.bundlor;
+
+import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_NAME;
+import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+
+class IncludeMatcher implements Matcher {
+    private final Include include;
+    private final int depth;
+    private final String matchedPath;
+
+    public IncludeMatcher(Include include) {
+        this(include, 0, ROOT_NAME);
+    }
+
+    private IncludeMatcher(Include include, int depth, String matchedPath) {
+        this.include = include;
+        this.depth = depth;
+        this.matchedPath = matchedPath;
+    }
+
+    @Override
+    public Matcher next(String name) {
+        if (hasMore()) {
+            if (include.match(name, depth)) {
+                String nextPath = concat(matchedPath, name);
+                if (lastEntry() && include.getDirective() == 
Include.Directive.ALL) {
+                    return new IncludeAllMatcher(nextPath);
+                }
+                return new IncludeMatcher(include, depth + 1, nextPath);
+            } else {
+                return Matcher.FAILED;
+            }
+        }
+        return Matcher.FAILED;
+    }
+
+    @Override
+    public boolean isMatch() {
+        return true;
+    }
+
+    @Override
+    public String getMatchedPath() {
+        return matchedPath;
+    }
+
+    @Override
+    public String toString() {
+        return "IncludeMatcher{" +
+                "include=" + include +
+                ", depth=" + depth +
+                ", matchedPath='" + matchedPath + '\'' +
+                '}';
+    }
+
+    private boolean hasMore() {
+        return depth < include.size();
+    }
+
+    private boolean lastEntry() {
+        return depth == include.size() - 1;
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Matcher.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Matcher.java?rev=1765616&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Matcher.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Matcher.java
 Wed Oct 19 15:06:11 2016
@@ -0,0 +1,58 @@
+/*
+ * 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.oak.plugins.document.bundlor;
+
+public interface Matcher {
+    Matcher FAILED = new Matcher() {
+        @Override
+        public Matcher next(String name) {
+            return FAILED;
+        }
+
+        @Override
+        public boolean isMatch() {
+            return false;
+        }
+
+        @Override
+        public String getMatchedPath() {
+            throw new IllegalStateException("No matching path for non matching 
matcher");
+        }
+    };
+
+    /**
+     * Returns a matcher for given child node name based on current state
+     *
+     * @param name child node name
+     * @return child matcher
+     */
+    Matcher next(String name);
+
+    /**
+     * Returns true if there was a match wrt current child node path
+     */
+    boolean isMatch();
+
+    /**
+     * Relative node path from the bundling root if
+     * there was a match
+     */
+    String getMatchedPath();
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/Matcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcherTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcherTest.java?rev=1765616&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcherTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcherTest.java
 Wed Oct 19 15:06:11 2016
@@ -0,0 +1,63 @@
+/*
+ * 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.oak.plugins.document.bundlor;
+
+import java.util.Collections;
+
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.*;
+
+public class CompositeMatcherTest {
+
+    @Test
+    public void empty() throws Exception{
+        Matcher m = CompositeMatcher.compose(Collections.<Matcher>emptyList());
+        assertFalse(m.isMatch());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void multiWithFailing() throws Exception{
+        CompositeMatcher.compose(asList(new Include("x").createMatcher(), 
Matcher.FAILED));
+    }
+
+    @Test
+    public void multi() throws Exception{
+        Matcher m = CompositeMatcher.compose(asList(
+                new Include("x/z").createMatcher(),
+                new Include("x/y").createMatcher())
+        );
+
+        Matcher m2 = m.next("x");
+        assertTrue(m2.isMatch());
+        assertEquals("x", m2.getMatchedPath());
+
+        assertFalse(m.next("a").isMatch());
+
+        Matcher m3 = m2.next("y");
+        assertTrue(m3.isMatch());
+        assertEquals("x/y", m3.getMatchedPath());
+
+        Matcher m4 = m3.next("a");
+        assertFalse(m4.isMatch());
+    }
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/CompositeMatcherTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlorTest.java?rev=1765616&r1=1765615&r2=1765616&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlorTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlorTest.java
 Wed Oct 19 15:06:11 2016
@@ -20,6 +20,7 @@
 package org.apache.jackrabbit.oak.plugins.document.bundlor;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.junit.Test;
 

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcherTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcherTest.java?rev=1765616&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcherTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcherTest.java
 Wed Oct 19 15:06:11 2016
@@ -0,0 +1,55 @@
+/*
+ * 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.oak.plugins.document.bundlor;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class IncludeMatcherTest {
+
+    @Test
+    public void singleLevel() throws Exception{
+        Matcher m = new Include("x").createMatcher();
+        assertTrue(m.isMatch());
+        assertTrue(m.next("x").isMatch());
+        assertEquals("x", m.next("x").getMatchedPath());
+
+        //Next level does not match
+        assertFalse(m.next("x").next("x").isMatch());
+
+        //Same level different path element name does not match
+        assertFalse(m.next("y").isMatch());
+    }
+
+    @Test
+    public void includeAll() throws Exception{
+        Matcher m = new Include("x/*;all").createMatcher();
+
+        assertTrue(m.isMatch());
+        assertTrue(m.next("x").isMatch());
+        assertTrue(m.next("x").next("x").isMatch());
+        assertTrue(m.next("x").next("y").isMatch());
+        assertTrue(m.next("x").next("y").next("z").isMatch());
+
+        assertEquals("x/y/z", 
m.next("x").next("y").next("z").getMatchedPath());
+    }
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeMatcherTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeTest.java?rev=1765616&r1=1765615&r2=1765616&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/IncludeTest.java
 Wed Oct 19 15:06:11 2016
@@ -19,6 +19,7 @@
 
 package org.apache.jackrabbit.oak.plugins.document.bundlor;
 
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -40,7 +41,8 @@ public class IncludeTest {
         assertTrue(new Include("x").match("x"));
         assertFalse(new Include("x").match("y"));
 
-        assertFalse(new Include("x/y").match("x"));
+        assertTrue(new Include("x/y").match("x"));
+        assertFalse(new Include("x/y").match("y"));
         assertTrue(new Include("x/y").match("x/y"));
     }
 
@@ -71,4 +73,12 @@ public class IncludeTest {
         assertTrue(i2.match("x/y/z/x"));
     }
 
+    private boolean match(Include i, String path){
+        Matcher m = i.createMatcher();
+        for (String e : PathUtils.elements(path)){
+            m = m.next(e);
+        }
+        return m.isMatch();
+    }
+
 }
\ No newline at end of file

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/MatcherTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/MatcherTest.java?rev=1765616&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/MatcherTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/MatcherTest.java
 Wed Oct 19 15:06:11 2016
@@ -0,0 +1,50 @@
+/*
+ * 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.oak.plugins.document.bundlor;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class MatcherTest {
+
+    @Test
+    public void failingMatcher() throws Exception{
+        assertFalse(Matcher.FAILED.isMatch());
+        assertFalse(Matcher.FAILED.next("x").isMatch());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void failingMatcherInvalidPath() throws Exception{
+        Matcher.FAILED.getMatchedPath();
+    }
+
+    @Test
+    public void includeAll() throws Exception{
+        Matcher m = new IncludeAllMatcher("x");
+        assertTrue(m.isMatch());
+        assertEquals("x", m.getMatchedPath());
+
+        assertTrue(m.next("y").isMatch());
+        assertEquals("x/y", m.next("y").getMatchedPath());
+    }
+
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/MatcherTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to