-package org.simantics.graph.store;\r
-\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-import java.util.regex.Pattern;\r
-\r
-import org.simantics.graph.query.Path;\r
-import org.simantics.graph.query.PathChild;\r
-import org.simantics.graph.query.Paths;\r
-\r
-public class PathPattern {\r
- \r
- private static PathPattern EMPTY_PATTERN = new PathPattern(null, null);\r
- \r
- Path prefix;\r
- Pattern suffix;\r
- \r
- private PathPattern(Path prefix, Pattern suffix) {\r
- this.prefix = prefix;\r
- this.suffix = suffix;\r
- }\r
-\r
- public static PathPattern compile(String pattern) {\r
- pattern = stripPatternPrefix(pattern);\r
- if(pattern == null)\r
- return EMPTY_PATTERN;\r
- String[] parts = pattern.split("/");\r
- \r
- Path path = Paths.Root;\r
- for(int i=0;i<parts.length;++i) {\r
- String part = parts[i];\r
- if(containsWildcards(part)) {\r
- StringBuilder b = new StringBuilder(pattern.length());\r
- for(;i<parts.length;++i) {\r
- b.append('/');\r
- b.append(parts[i]);\r
- }\r
- return new PathPattern(path, compileGlobPattern(b.toString()));\r
- }\r
- else\r
- path = new PathChild(part, path);\r
- }\r
- \r
- return new PathPattern(path, null);\r
- }\r
- \r
- private static String patternStart = "http://";\r
- private static String stripPatternPrefix(String pattern) {\r
- for(int i=0;i<patternStart.length();++i) {\r
- if(pattern.length() <= i)\r
- return null;\r
- char c = pattern.charAt(i);\r
- if(c == '*')\r
- return pattern.substring(i);\r
- if(c != patternStart.charAt(i) && c != '?')\r
- return null;\r
- }\r
- return pattern.substring(patternStart.length());\r
- }\r
- \r
- private static boolean containsWildcards(String pattern) {\r
- return pattern.contains("*") || pattern.contains("?");\r
- }\r
- \r
- private static Pattern compileGlobPattern(String pattern) {\r
- int length = pattern.length();\r
- StringBuilder b = new StringBuilder(2*length);\r
- b.append("\\Q");\r
- for(int i=0;i<length;++i) {\r
- char c = pattern.charAt(i);\r
- switch(c) {\r
- case '*':\r
- b.append("\\E.*\\Q");\r
- break;\r
- case '?':\r
- b.append("\\E.\\Q");\r
- break;\r
- case '\\':\r
- ++i;\r
- if(i < length) {\r
- c = pattern.charAt(i);\r
- if(c == '\\' && i+1 < length && pattern.charAt(i+1) == 'E') {\r
- ++i;\r
- b.append("\\E\\\\E\\Q");\r
- }\r
- else if(c == '*' || c == '?')\r
- b.append(c);\r
- else {\r
- b.append('\\');\r
- b.append(c);\r
- }\r
- }\r
- break;\r
- default:\r
- b.append(c);\r
- }\r
- }\r
- b.append("\\E");\r
- return Pattern.compile(b.toString());\r
- }\r
- \r
- @Override\r
- public String toString() {\r
- return "(" + prefix + ", " + suffix + ")";\r
- }\r
- \r
- public void search(IdentityStore store, THashSet<Path> result) {\r
- int id = store.pathToId(prefix);\r
- if(id == -1)\r
- return;\r
- store.findChildren(id, prefix, "", suffix, result);\r
- }\r
- \r
- public static void main(String[] args) {\r
- System.out.println(compile("http://www.simantics.org/*/foo"));\r
- }\r
-}\r
+package org.simantics.graph.store;
+
+import gnu.trove.set.hash.THashSet;
+
+import java.util.regex.Pattern;
+
+import org.simantics.graph.query.Path;
+import org.simantics.graph.query.PathChild;
+import org.simantics.graph.query.Paths;
+
+public class PathPattern {
+
+ private static PathPattern EMPTY_PATTERN = new PathPattern(null, null);
+
+ Path prefix;
+ Pattern suffix;
+
+ private PathPattern(Path prefix, Pattern suffix) {
+ this.prefix = prefix;
+ this.suffix = suffix;
+ }
+
+ public static PathPattern compile(String pattern) {
+ pattern = stripPatternPrefix(pattern);
+ if(pattern == null)
+ return EMPTY_PATTERN;
+ String[] parts = pattern.split("/");
+
+ Path path = Paths.Root;
+ for(int i=0;i<parts.length;++i) {
+ String part = parts[i];
+ if(containsWildcards(part)) {
+ StringBuilder b = new StringBuilder(pattern.length());
+ for(;i<parts.length;++i) {
+ b.append('/');
+ b.append(parts[i]);
+ }
+ return new PathPattern(path, compileGlobPattern(b.toString()));
+ }
+ else
+ path = new PathChild(part, path);
+ }
+
+ return new PathPattern(path, null);
+ }
+
+ private static String patternStart = "http://";
+ private static String stripPatternPrefix(String pattern) {
+ for(int i=0;i<patternStart.length();++i) {
+ if(pattern.length() <= i)
+ return null;
+ char c = pattern.charAt(i);
+ if(c == '*')
+ return pattern.substring(i);
+ if(c != patternStart.charAt(i) && c != '?')
+ return null;
+ }
+ return pattern.substring(patternStart.length());
+ }
+
+ private static boolean containsWildcards(String pattern) {
+ return pattern.contains("*") || pattern.contains("?");
+ }
+
+ private static Pattern compileGlobPattern(String pattern) {
+ int length = pattern.length();
+ StringBuilder b = new StringBuilder(2*length);
+ b.append("\\Q");
+ for(int i=0;i<length;++i) {
+ char c = pattern.charAt(i);
+ switch(c) {
+ case '*':
+ b.append("\\E.*\\Q");
+ break;
+ case '?':
+ b.append("\\E.\\Q");
+ break;
+ case '\\':
+ ++i;
+ if(i < length) {
+ c = pattern.charAt(i);
+ if(c == '\\' && i+1 < length && pattern.charAt(i+1) == 'E') {
+ ++i;
+ b.append("\\E\\\\E\\Q");
+ }
+ else if(c == '*' || c == '?')
+ b.append(c);
+ else {
+ b.append('\\');
+ b.append(c);
+ }
+ }
+ break;
+ default:
+ b.append(c);
+ }
+ }
+ b.append("\\E");
+ return Pattern.compile(b.toString());
+ }
+
+ @Override
+ public String toString() {
+ return "(" + prefix + ", " + suffix + ")";
+ }
+
+ public void search(IdentityStore store, THashSet<Path> result) {
+ int id = store.pathToId(prefix);
+ if(id == -1)
+ return;
+ store.findChildren(id, prefix, "", suffix, result);
+ }
+
+ public static void main(String[] args) {
+ System.out.println(compile("http://www.simantics.org/*/foo"));
+ }
+}