]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/symbollibrary/ui/DefaultFilterStrategy.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / symbollibrary / ui / DefaultFilterStrategy.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.diagram.symbollibrary.ui;\r
13 \r
14 import java.nio.CharBuffer;\r
15 \r
16 /**\r
17  * Default implementation of IFilterStrategy.\r
18  * \r
19  * <p>\r
20  * It implements simple search semantics with only the special wildcard\r
21  * characters '*' ( 0 to n any characters) and '?' (any one character)\r
22  * recognized. In order to allow the filter to pass arbitrary prefixes, the\r
23  * client has to give a '*' prefix in the filter string. On the contrary, the\r
24  * client does not have to specify a '*' in order to pass arbitrary suffixes -\r
25  * arbitrary suffixes are allowed by default by this strategy.\r
26  * \r
27  * <p>\r
28  * This strategy forces the filter string to lowercase.\r
29  * \r
30  * TODO: this code is duplicated from org.simantics.browsing.ui.common.views since there was no good way of getting this same. Remove code duplication.\r
31  * \r
32  * @author Tuukka Lehtonen\r
33  */\r
34 class DefaultFilterStrategy {\r
35 \r
36     private static final boolean DEBUG = false;\r
37 \r
38     private static StringBuilder addSearchWord(StringBuilder sb, String pattern) {\r
39         if (DEBUG)\r
40             System.out.println("addSearchWord(" + pattern + ") to '" + sb.toString() + "'");\r
41 \r
42         if (pattern == null || pattern.isEmpty())\r
43             return sb;\r
44         if (sb.length() > 0)\r
45             sb.append('|');\r
46         sb.append('(');\r
47         sb.append(pattern);\r
48         sb.append(')');\r
49         return sb;\r
50     }\r
51 \r
52     private static String toString(CharBuffer cb) {\r
53         cb.limit(cb.position());\r
54         cb.reset();\r
55         if (DEBUG)\r
56             System.out.println("toString(" + cb + ")");\r
57         String result = cb.toString();\r
58         cb.limit(cb.capacity());\r
59         return result;\r
60     }\r
61 \r
62     public static String toSinglePatternString(String filter, boolean implicitPreAsterisk) {\r
63         if (!filter.isEmpty()) {\r
64             // Force searching in lowercase.\r
65             filter = filter.toLowerCase();\r
66 \r
67             // Construct a regular expression from the specified text.\r
68             String regExFilter = filter\r
69             .replace("\\", "\\\\")   // \ -> \\\r
70             .replace(".", "\\.")     // . -> \.\r
71             .replace("*", ".*")      // * -> Any 0..n characters\r
72             .replace("?", ".")       // ? -> Any single character\r
73             .replace("+", "\\+")     // + -> \+\r
74             .replace("(", "\\(")     // ( -> \(\r
75             .replace(")", "\\)")     // ) -> \)\r
76             .replace("[", "\\[")     // [ -> \[\r
77             .replace("]", "\\]")     // ] -> \]\r
78             .replace("{", "\\{")     // { -> \{\r
79             .replace("}", "\\}")     // } -> \}\r
80             .replace("^", "\\^")     // ^ -> \^\r
81             .replace("$", "\\$")     // $ -> \$\r
82             .replace("|", ".*|")     // $ -> \$\r
83             //.replace("|", "\\|")     // | -> \|\r
84             .replace("&&", "\\&&")   // && -> \&&\r
85             ;\r
86 \r
87             if (implicitPreAsterisk)\r
88                 if (!regExFilter.startsWith(".*"))\r
89                     regExFilter = ".*" + regExFilter ;\r
90             if (!regExFilter.endsWith(".*"))\r
91                 regExFilter += ".*" ;\r
92 \r
93             return regExFilter;\r
94         }\r
95         return null;\r
96     }\r
97 \r
98     public static String defaultToPatternString(String filter, boolean implicitPreAsterisk) {\r
99         if (filter.isEmpty())\r
100             return null;\r
101 \r
102         CharBuffer buf = CharBuffer.allocate(filter.length()*2);\r
103         buf.mark();\r
104         StringBuilder sb = new StringBuilder(filter.length()*2);\r
105         boolean inQuote = false;\r
106         int len = filter.length();\r
107         for (int i = 0; i < len;) {\r
108             char ch = filter.charAt(i);\r
109             if (DEBUG)\r
110                 System.out.println("char[" + i + "]: '" + ch + "'");\r
111 \r
112             if (ch == '"') {\r
113                 if (!inQuote) {\r
114                     if (DEBUG)\r
115                         System.out.println("begin quoted text");\r
116                     inQuote = true;\r
117                 } else {\r
118                     if (DEBUG)\r
119                         System.out.println("end quoted text");\r
120                     inQuote = false;\r
121                     addSearchWord(sb, toSinglePatternString( toString(buf), implicitPreAsterisk ));\r
122                 }\r
123                 ++i;\r
124                 continue;\r
125             } else if (ch == '\\') {\r
126                 // Next character is escaped, i.e. taken as is.\r
127                 ++i;\r
128                 if (i >= len)\r
129                     // Unexpected end-of-string\r
130                     break;\r
131 \r
132                 ch = filter.charAt(i);\r
133                 if (DEBUG)\r
134                     System.out.println("append escaped character '" + ch + "'");\r
135 \r
136                 buf.append(ch);\r
137                 ++i;\r
138                 break;\r
139             } else if (ch == ' ') {\r
140                 if (inQuote) {\r
141                     if (DEBUG)\r
142                         System.out.println("append char '" + ch + "'");\r
143                     buf.append(ch);\r
144                     ++i;\r
145                 } else {\r
146                     if (buf.position() > 0) {\r
147                         addSearchWord(sb, toSinglePatternString( toString(buf), implicitPreAsterisk ));\r
148                     }\r
149                     ++i;\r
150                 }\r
151             } else {\r
152                 if (DEBUG)\r
153                     System.out.println("append char '" + ch + "'");\r
154                 buf.append(ch);\r
155                 ++i;\r
156             }\r
157         }\r
158         if (buf.position() > 0) {\r
159             addSearchWord(sb, toSinglePatternString( toString(buf), implicitPreAsterisk ));\r
160         }\r
161 \r
162         //sb.append(".*");\r
163 \r
164         return sb.toString();\r
165     }\r
166 \r
167 }\r