]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/store/PathPattern.java
Check statement collisions
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / store / PathPattern.java
1 package org.simantics.graph.store;\r
2 \r
3 import gnu.trove.set.hash.THashSet;\r
4 \r
5 import java.util.regex.Pattern;\r
6 \r
7 import org.simantics.graph.query.Path;\r
8 import org.simantics.graph.query.PathChild;\r
9 import org.simantics.graph.query.Paths;\r
10 \r
11 public class PathPattern {\r
12         \r
13         private static PathPattern EMPTY_PATTERN = new PathPattern(null, null);\r
14         \r
15         Path prefix;\r
16         Pattern suffix;\r
17         \r
18         private PathPattern(Path prefix, Pattern suffix) {\r
19                 this.prefix = prefix;\r
20                 this.suffix = suffix;\r
21         }\r
22 \r
23         public static PathPattern compile(String pattern) {\r
24                 pattern = stripPatternPrefix(pattern);\r
25                 if(pattern == null)\r
26                         return EMPTY_PATTERN;\r
27                 String[] parts = pattern.split("/");\r
28                 \r
29                 Path path = Paths.Root;\r
30                 for(int i=0;i<parts.length;++i) {\r
31                         String part = parts[i];\r
32                         if(containsWildcards(part)) {\r
33                                 StringBuilder b = new StringBuilder(pattern.length());\r
34                                 for(;i<parts.length;++i) {\r
35                                         b.append('/');\r
36                                         b.append(parts[i]);\r
37                                 }\r
38                                 return new PathPattern(path, compileGlobPattern(b.toString()));\r
39                         }\r
40                         else\r
41                                 path = new PathChild(part, path);\r
42                 }\r
43                 \r
44                 return new PathPattern(path, null);\r
45         }\r
46         \r
47         private static String patternStart = "http://";\r
48         private static String stripPatternPrefix(String pattern) {\r
49                 for(int i=0;i<patternStart.length();++i) {\r
50                         if(pattern.length() <= i)\r
51                                 return null;\r
52                         char c = pattern.charAt(i);\r
53                         if(c == '*')\r
54                                 return pattern.substring(i);\r
55                         if(c != patternStart.charAt(i) && c != '?')\r
56                                 return null;\r
57                 }\r
58                 return pattern.substring(patternStart.length());\r
59         }\r
60         \r
61         private static boolean containsWildcards(String pattern) {\r
62                 return pattern.contains("*") || pattern.contains("?");\r
63         }\r
64         \r
65         private static Pattern compileGlobPattern(String pattern) {\r
66                 int length = pattern.length();\r
67                 StringBuilder b = new StringBuilder(2*length);\r
68                 b.append("\\Q");\r
69                 for(int i=0;i<length;++i) {\r
70                         char c = pattern.charAt(i);\r
71                         switch(c) {\r
72                         case '*':\r
73                                 b.append("\\E.*\\Q");\r
74                                 break;\r
75                         case '?':\r
76                                 b.append("\\E.\\Q");\r
77                                 break;\r
78                         case '\\':\r
79                                 ++i;\r
80                                 if(i < length) {\r
81                                         c = pattern.charAt(i);\r
82                                         if(c == '\\' && i+1 < length && pattern.charAt(i+1) == 'E') {\r
83                                                 ++i;\r
84                                                 b.append("\\E\\\\E\\Q");\r
85                                         }\r
86                                         else if(c == '*' || c == '?')\r
87                                                 b.append(c);\r
88                                         else {\r
89                                                 b.append('\\');\r
90                                                 b.append(c);\r
91                                         }\r
92                                 }\r
93                                 break;\r
94                         default:\r
95                                 b.append(c);\r
96                         }\r
97                 }\r
98                 b.append("\\E");\r
99                 return Pattern.compile(b.toString());\r
100         }\r
101         \r
102         @Override\r
103         public String toString() {\r
104                 return "(" + prefix + ", " + suffix + ")";\r
105         }\r
106         \r
107         public void search(IdentityStore store, THashSet<Path> result) {\r
108                 int id = store.pathToId(prefix);\r
109                 if(id == -1)\r
110                         return;\r
111                 store.findChildren(id, prefix, "", suffix, result);\r
112         }\r
113         \r
114         public static void main(String[] args) {\r
115                 System.out.println(compile("http://www.simantics.org/*/foo"));\r
116         }\r
117 }\r