]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph/src/org/simantics/graph/store/PathPattern.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / store / PathPattern.java
diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/store/PathPattern.java b/bundles/org.simantics.graph/src/org/simantics/graph/store/PathPattern.java
new file mode 100644 (file)
index 0000000..347b42b
--- /dev/null
@@ -0,0 +1,117 @@
+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