You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2011/07/04 12:37:53 UTC
svn commit: r1142612 - in /jackrabbit/sandbox/microkernel/src:
main/java/org/apache/jackrabbit/mk/util/PathUtils.java
test/java/org/apache/jackrabbit/mk/PathTest.java
Author: thomasm
Date: Mon Jul 4 10:37:53 2011
New Revision: 1142612
URL: http://svn.apache.org/viewvc?rev=1142612&view=rev
Log:
Improve PathUtils.
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/PathUtils.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/PathTest.java
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/PathUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/PathUtils.java?rev=1142612&r1=1142611&r2=1142612&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/PathUtils.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/PathUtils.java Mon Jul 4 10:37:53 2011
@@ -27,19 +27,43 @@ public class PathUtils {
// utility class
}
+ /**
+ * Whether the path is the root path ("/").
+ *
+ * @param path the path
+ * @return whether this is the root
+ */
public static boolean denotesRoot(String path) {
return "/".equals(path);
}
+ /**
+ * Whether the path is absolute (starts with a slash) or not.
+ *
+ * @param path the path
+ * @return true if it starts with a slash
+ */
public static boolean isAbsolute(String path) {
return path.startsWith("/");
}
+ /**
+ * Get the parent of a path. The parent of the root path ("/") is the root
+ * path. Only minimal validation takes place within this function, so when
+ * the parameter is an illegal path, the the result of this method is
+ * undefined.
+ *
+ * @param path the path
+ * @return the parent path
+ */
public static String getParentPath(String path) {
- int end = path.length() - 1;
- while (end >= 0 && path.charAt(end) == '/') {
- end--;
+ if (path.equals("/") || path.length() == 0) {
+ return path;
+ }
+ if (path.endsWith("/")) {
+ throw new IllegalArgumentException(path + " (ends with '/')");
}
+ int end = path.length() - 1;
int pos = getPreviousSlash(path, end);
if (pos > 0) {
return path.substring(0, pos);
@@ -50,19 +74,20 @@ public class PathUtils {
}
/**
- * Get the last element of the path
+ * Get the last element of the (absolute or relative) path. The name of the
+ * root node ("/") and the name of the empty path ("") is the empty path.
*
* @param path the complete path
* @return the last element
*/
public static String getName(String path) {
- int end = path.length() - 1;
- while (end >= 0 && path.charAt(end) == '/') {
- end--;
- if (end < 0) {
- return "";
- }
+ if (path.equals("/") || path.length() == 0) {
+ return "";
}
+ if (path.endsWith("/")) {
+ throw new IllegalArgumentException(path + " (ends with '/')");
+ }
+ int end = path.length() - 1;
int pos = getPreviousSlash(path, end);
if (pos != -1) {
return path.substring(pos + 1, end + 1);
@@ -70,18 +95,28 @@ public class PathUtils {
return path;
}
+ /**
+ * Calculate the number of elements in the path.
+ * The root path has zero elements.
+ *
+ * @param path the path
+ * @return the number of elements
+ */
public static int getDepth(String path) {
- if (PathUtils.denotesRoot(path)) {
- return 0;
- }
- int count = 0, i = 0;
+ int count = 1, i = 0;
if (path.startsWith("/")) {
+ if (PathUtils.denotesRoot(path)) {
+ return 0;
+ }
i++;
}
- for (; i > 0; i = getNextSlash(path, i) + 1) {
+ while (true) {
+ i = getNextSlash(path, i) + 1;
+ if (i == 0) {
+ return count;
+ }
count++;
}
- return count;
}
public static String[] split(String path) {
@@ -113,18 +148,20 @@ public class PathUtils {
return array;
}
- public static String concat(String parentPath, String nameOrRelativePath) {
- if (nameOrRelativePath.startsWith("/")) {
+ public static String concat(String parentPath, String relativePath) {
+ if (relativePath.startsWith("/")) {
throw new IllegalArgumentException("can't append absolute path");
+ } else if (relativePath.length() == 0) {
+ return parentPath;
}
int parentLen = parentPath.length();
StringBuilder buff = new StringBuilder(
- parentLen + 1 + nameOrRelativePath.length());
+ parentLen + 1 + relativePath.length());
buff.append(parentPath);
if (parentLen > 0 && !parentPath.endsWith("/")) {
buff.append('/');
}
- buff.append(nameOrRelativePath);
+ buff.append(relativePath);
return buff.toString();
}
@@ -196,4 +233,49 @@ public class PathUtils {
return index;
}
+ /**
+ * Check if the path is valid, and throw an IllegalArgumentException if not.
+ * A valid path is absolute (starts with a '/') or relative (doesn't start
+ * with '/'), and contain one or more elements. A path may not end with '/',
+ * except for the root path. Elements itself must be at least one character
+ * long. Within an element, there may be one or more section starting with
+ * '{' and ending with '}' that can contain any character (including '/',
+ * but not '{' or '}').
+ *
+ * @param path the path
+ */
+ public static void validate(String path) {
+ if ("/".equals(path) || path.length() == 0) {
+ return;
+ } else if (path.endsWith("/")) {
+ throw new IllegalArgumentException(path + " (ends with '/')");
+ }
+ char last = 0;
+ for (int index = 0, len = path.length(); index < len; index++) {
+ char c = path.charAt(index);
+ if (c == '/') {
+ if (last == '/') {
+ throw new IllegalArgumentException(path + " (contains '//')");
+ }
+ }
+ if (c == '{') {
+ while (true) {
+ index++;
+ if (index >= len) {
+ throw new IllegalArgumentException(path + " (missing '{')");
+ }
+ char x = path.charAt(index);
+ if (x == '{') {
+ throw new IllegalArgumentException(path +" (unmatched '{')");
+ } if (x == '}') {
+ break;
+ }
+ }
+ } else if (c == '}') {
+ throw new IllegalArgumentException(path + " (missing '{')");
+ }
+ last = c;
+ }
+ }
+
}
Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/PathTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/PathTest.java?rev=1142612&r1=1142611&r2=1142612&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/PathTest.java (original)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/PathTest.java Mon Jul 4 10:37:53 2011
@@ -37,6 +37,20 @@ public class PathTest extends TestCase {
// expected
}
+ try {
+ PathUtils.getParentPath("invalid/path/");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ PathUtils.getName("invalid/path/");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
test("parent", "child");
test("{/}parent", "child");
@@ -48,20 +62,53 @@ public class PathTest extends TestCase {
test("parent", "{x/y}child");
}
+ public void testValidate() {
+ for (String invalid : new String[] {
+ "//",
+ "//test",
+ "/test/",
+ "test/",
+ "/test//",
+ "/test//test",
+ "{{}",
+ "{}}",
+ "{test",
+ "}test"
+ }) {
+ try {
+ PathUtils.validate(invalid);
+ fail(invalid);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+ for (String valid : new String[] {
+ "",
+ "/",
+ "test",
+ "test/test",
+ "/test",
+ "/test/test",
+ "{}",
+ "{}/{}",
+ "/{}",
+ "/{}/{}",
+ "/{/}",
+ }) {
+ PathUtils.validate(valid);
+ }
+ }
+
public void testMore() {
String[] paths = {
"",
"/",
- "/foo",
- "/foo/",
- "/foo//",
- "/foo///",
"foo",
"/foo",
+ "foo/bar",
"/foo/bar",
- "/foo/bar/",
- "/foo/bar//",
- "foo//bar"
+ "foo/bar/baz",
+ "/foo/bar/baz",
};
for (String path : paths) {
@@ -69,12 +116,9 @@ public class PathTest extends TestCase {
String name = PathUtils.getName(path);
String concat = PathUtils.concat(parent, name);
- System.out.println("(" + path + ")(" + parent + "," + name + ")(" + concat + ")");
-
- while (path.endsWith("/") && path.length() > 1) {
- path = path.substring(0, path.length() - 1);
- }
- assertEquals(path, concat);
+ assertEquals("original: " + path + " parent: " + parent +
+ " name: " + name + " concat: " + concat,
+ path, concat);
}
}
@@ -111,6 +155,8 @@ public class PathTest extends TestCase {
assertEquals(0, PathUtils.getDepth("/"));
assertEquals(1, PathUtils.getDepth("/" + parent));
assertEquals(2, PathUtils.getDepth("/" + parent + "/" + child));
+ assertEquals(1, PathUtils.getDepth(parent));
+ assertEquals(2, PathUtils.getDepth(parent + "/" + child));
// getName
assertEquals("", PathUtils.getName("/"));