You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2015/10/30 07:58:19 UTC

svn commit: r1711407 - in /sling/trunk/bundles/api/src: main/java/org/apache/sling/api/resource/ test/java/org/apache/sling/api/resource/

Author: cziegeler
Date: Fri Oct 30 06:58:19 2015
New Revision: 1711407

URL: http://svn.apache.org/viewvc?rev=1711407&view=rev
Log:
SLING-5220 : Add Path and PathSet

Added:
    sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Path.java   (with props)
    sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/PathSet.java   (with props)
    sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathSetTest.java   (with props)
    sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathTest.java   (with props)

Added: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Path.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Path.java?rev=1711407&view=auto
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Path.java (added)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Path.java Fri Oct 30 06:58:19 2015
@@ -0,0 +1,83 @@
+/*
+ * 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.sling.api.resource;
+
+/**
+ * Simple helper class for path matching.
+ *
+ * @since 2.9.0 (Sling API Bundle 2.10.0)
+ */
+public class Path implements Comparable<Path> {
+
+    private final String path;
+
+    private final String prefix;
+
+    /**
+     * Create a new path object.
+     * @param path The resource path.
+     */
+    public Path(final String path) {
+        this.path = path;
+        this.prefix = path.equals("/") ? "/" : path.concat("/");
+    }
+
+    /**
+     * Check whether the provided path is equal to this path or a sub path
+     * of it.
+     * @param otherPath Path to check
+     * @return {@code true} If other path is within the sub tree of this path.
+     */
+    public boolean matches(final String otherPath) {
+        if ( this.path.equals(otherPath) || otherPath.startsWith(this.prefix) ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Return the path.
+     * @return The path.
+     */
+    public String getPath() {
+        return this.path;
+    }
+
+    @Override
+    public int compareTo(final Path o) {
+        return this.getPath().compareTo(o.getPath());
+    }
+
+    @Override
+    public int hashCode() {
+        return this.getPath().hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || !(obj instanceof Path)) {
+            return false;
+        }
+        return this.getPath().equals(((Path)obj).getPath());
+    }
+
+}
\ No newline at end of file

Propchange: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Path.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Path.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/PathSet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/PathSet.java?rev=1711407&view=auto
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/PathSet.java (added)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/PathSet.java Fri Oct 30 06:58:19 2015
@@ -0,0 +1,187 @@
+/*
+ * 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.sling.api.resource;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Simple helper class for path matching against a set of paths.
+ *
+ * @since 2.9.0 (Sling API Bundle 2.10.0)
+ */
+public class PathSet implements Iterable<Path> {
+
+    /**
+     * Create a path set from a collection of path objects
+     * @param paths The collection of path objects
+     * @return The path set
+     */
+    public static PathSet fromPathSet(final Collection<Path> paths) {
+        final Set<Path> set = new HashSet<Path>();
+        for(final Path p : paths) {
+            set.add(p);
+        }
+        optimize(set);
+        return new PathSet(set);
+    }
+
+    /**
+     * Create a path set from a collection of path objects
+     * @param paths The collection of path objects
+     * @return The path set
+     */
+    public static PathSet fromPaths(final Path...paths) {
+        final Set<Path> set = new HashSet<Path>();
+        for(final Path p : paths) {
+            set.add(p);
+        }
+        optimize(set);
+        return new PathSet(set);
+    }
+
+    /**
+     * Create a path set from a collection of strings
+     * @param paths The collection of strings
+     * @return The path set
+     */
+    public static PathSet fromStringSet(final Collection<String> paths) {
+        final Set<Path> set = new HashSet<Path>();
+        for(final String p : paths) {
+            set.add(new Path(p));
+        }
+        optimize(set);
+        return new PathSet(set);
+    }
+
+    /**
+     * Create a path set from a collection of strings
+     * @param paths The collection of strings
+     * @return The path set
+     */
+    public static PathSet fromStrings(final String...strings) {
+        final Set<Path> set = new HashSet<Path>();
+        for(final String p : strings) {
+            set.add(new Path(p));
+        }
+        optimize(set);
+        return new PathSet(set);
+    }
+
+    /**
+     * Optimize the set by filtering out paths which are a sub path
+     * of another path in the set.
+     * @param set The path set
+     */
+    private static void optimize(final Set<Path> set) {
+        final Iterator<Path> i = set.iterator();
+        while ( i.hasNext() ) {
+            final Path next = i.next();
+            boolean found = false;
+            for(final Path p : set) {
+                if ( p != next && p.matches(next.getPath()) ) {
+                    found = true;
+                    break;
+                }
+            }
+            if ( found ) {
+                i.remove();
+            }
+        }
+    }
+
+    private final Set<Path> paths;
+
+    /**
+     * Create a path set from a set of paths
+     * @param paths A set of paths
+     */
+    private PathSet(final Set<Path> paths) {
+        this.paths = paths;
+    }
+
+    /**
+     * Check whether the provided path is in the sub tree of any
+     * of the paths in this set.
+     * @param otherPath
+     * @return The path which matches the provided path, {@code null} otherwise.
+     * @see {@link Path#matches(String)}
+     */
+    public Path matches(final String otherPath) {
+         for(final Path p : this.paths) {
+             if ( p.matches(otherPath) ) {
+                 return p;
+             }
+         }
+         return null;
+    }
+
+    /**
+     * Generate a path set of paths from this set which
+     * are in the sub tree of the provided path
+     * @param path The base path
+     * @return Path set
+     */
+    public PathSet getSubset(final String path) {
+        return getSubset(new Path(path));
+    }
+
+    /**
+     * Generate a path set of paths from this set which
+     * are in the sub tree of the provided path
+     * @param path The base path
+     * @return Path set
+     */
+    public PathSet getSubset(final Path path) {
+        final Set<Path> result = new HashSet<Path>();
+        for(final Path p : this.paths) {
+            if ( path.matches(p.getPath()) ) {
+                result.add(p);
+            }
+        }
+        return new PathSet(result);
+    }
+
+    /**
+     * Return an unmodifiable iterator for the paths.
+     */
+    @Override
+    public Iterator<Path> iterator() {
+        return Collections.unmodifiableSet(this.paths).iterator();
+    }
+
+    @Override
+    public int hashCode() {
+        return paths.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || !(obj instanceof PathSet)) {
+            return false;
+        }
+        return this.paths.equals(((PathSet)obj).paths);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/PathSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/PathSet.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathSetTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathSetTest.java?rev=1711407&view=auto
==============================================================================
--- sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathSetTest.java (added)
+++ sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathSetTest.java Fri Oct 30 06:58:19 2015
@@ -0,0 +1,108 @@
+/*
+ * 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.sling.api.resource;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+
+public class PathSetTest {
+
+    private void assertEqualSets(final PathSet set, final String...paths) {
+        final Set<String> stringSet = new HashSet<String>();
+        for(final String p : paths) {
+            stringSet.add(p);
+        }
+        final Set<Path> pathSet = new HashSet<Path>();
+        for(final Path p : set) {
+            pathSet.add(p);
+        }
+        assertEquals(stringSet.size(), pathSet.size());
+        for(final Path p : pathSet) {
+            assertTrue(stringSet.contains(p.getPath()));
+        }
+    }
+
+    @Test public void testStringSet() {
+        final Set<String> strings = new HashSet<String>();
+        strings.add("/a");
+        strings.add("/x/y");
+        strings.add("/z");
+        final PathSet set = PathSet.fromStringSet(strings);
+        assertNotNull(set);
+        assertEqualSets(set, "/a", "/x/y", "/z");
+    }
+
+    @Test public void testStrings() {
+        final PathSet set = PathSet.fromStrings("/z", "/x/y", "/a");
+        assertNotNull(set);
+        assertEqualSets(set, "/a", "/x/y", "/z");
+    }
+
+    @Test public void testPathSet() {
+        final Set<Path> paths = new HashSet<Path>();
+        paths.add(new Path("/a"));
+        paths.add(new Path("/x/y"));
+        paths.add(new Path("/z"));
+        final PathSet set = PathSet.fromPathSet(paths);
+        assertNotNull(set);
+        assertEqualSets(set, "/a", "/x/y", "/z");
+    }
+
+    @Test public void testPaths() {
+        final PathSet set = PathSet.fromPaths(new Path("/z"), new Path("/x/y"), new Path("/a"));
+        assertNotNull(set);
+        assertEqualSets(set, "/a", "/x/y", "/z");
+    }
+
+    @Test public void testOptimize() {
+        final PathSet set1 = PathSet.fromStrings("/", "/a", "/z", "/x/y");
+        assertEqualSets(set1, "/");
+
+        final PathSet set2 = PathSet.fromStrings("/a", "/a/x/y", "/z", "/x/y", "/a2");
+        assertEqualSets(set2, "/a", "/z", "/a2", "/x/y");
+    }
+
+    @Test public void testMatching() {
+        final PathSet set = PathSet.fromStrings("/a", "/x/y");
+        assertNull(set.matches("/"));
+
+        assertEquals(new Path("/a"), set.matches("/a"));
+        assertEquals(new Path("/a"), set.matches("/a/b"));
+        assertEquals(new Path("/a"), set.matches("/a/b/c"));
+
+        assertNull(set.matches("/a2"));
+
+        assertNull(set.matches("/c"));
+        assertNull(set.matches("/d/g"));
+
+        assertNull(set.matches("/x"));
+        assertNull(set.matches("/x/y2"));
+
+        assertEquals(new Path("/x/y"), set.matches("/x/y"));
+        assertEquals(new Path("/x/y"), set.matches("/x/y/1"));
+        assertEquals(new Path("/x/y"), set.matches("/x/y/g/e"));
+    }
+}

Propchange: sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathSetTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathSetTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathTest.java?rev=1711407&view=auto
==============================================================================
--- sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathTest.java (added)
+++ sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathTest.java Fri Oct 30 06:58:19 2015
@@ -0,0 +1,49 @@
+/*
+ * 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.sling.api.resource;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class PathTest {
+
+    @Test public void testRootMatching() {
+        final Path path = new Path("/");
+
+        assertTrue(path.matches("/"));
+        assertTrue(path.matches("/foo"));
+        assertTrue(path.matches("/foo/bar"));
+    }
+
+    @Test public void testPathMatching() {
+        final Path path = new Path("/content");
+
+        assertFalse(path.matches("/"));
+        assertFalse(path.matches("/foo"));
+        assertFalse(path.matches("/foo/bar"));
+
+        assertTrue(path.matches("/content"));
+        assertTrue(path.matches("/content/a"));
+        assertTrue(path.matches("/content/a/b"));
+
+        assertFalse(path.matches("/content1"));
+    }
+}

Propchange: sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/api/src/test/java/org/apache/sling/api/resource/PathTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url