--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.diagram.symbollibrary.ui;\r
+\r
+import java.nio.CharBuffer;\r
+\r
+/**\r
+ * Default implementation of IFilterStrategy.\r
+ * \r
+ * <p>\r
+ * It implements simple search semantics with only the special wildcard\r
+ * characters '*' ( 0 to n any characters) and '?' (any one character)\r
+ * recognized. In order to allow the filter to pass arbitrary prefixes, the\r
+ * client has to give a '*' prefix in the filter string. On the contrary, the\r
+ * client does not have to specify a '*' in order to pass arbitrary suffixes -\r
+ * arbitrary suffixes are allowed by default by this strategy.\r
+ * \r
+ * <p>\r
+ * This strategy forces the filter string to lowercase.\r
+ * \r
+ * 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
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+class DefaultFilterStrategy {\r
+\r
+ private static final boolean DEBUG = false;\r
+\r
+ private static StringBuilder addSearchWord(StringBuilder sb, String pattern) {\r
+ if (DEBUG)\r
+ System.out.println("addSearchWord(" + pattern + ") to '" + sb.toString() + "'");\r
+\r
+ if (pattern == null || pattern.isEmpty())\r
+ return sb;\r
+ if (sb.length() > 0)\r
+ sb.append('|');\r
+ sb.append('(');\r
+ sb.append(pattern);\r
+ sb.append(')');\r
+ return sb;\r
+ }\r
+\r
+ private static String toString(CharBuffer cb) {\r
+ cb.limit(cb.position());\r
+ cb.reset();\r
+ if (DEBUG)\r
+ System.out.println("toString(" + cb + ")");\r
+ String result = cb.toString();\r
+ cb.limit(cb.capacity());\r
+ return result;\r
+ }\r
+\r
+ public static String toSinglePatternString(String filter, boolean implicitPreAsterisk) {\r
+ if (!filter.isEmpty()) {\r
+ // Force searching in lowercase.\r
+ filter = filter.toLowerCase();\r
+\r
+ // Construct a regular expression from the specified text.\r
+ String regExFilter = filter\r
+ .replace("\\", "\\\\") // \ -> \\\r
+ .replace(".", "\\.") // . -> \.\r
+ .replace("*", ".*") // * -> Any 0..n characters\r
+ .replace("?", ".") // ? -> Any single character\r
+ .replace("+", "\\+") // + -> \+\r
+ .replace("(", "\\(") // ( -> \(\r
+ .replace(")", "\\)") // ) -> \)\r
+ .replace("[", "\\[") // [ -> \[\r
+ .replace("]", "\\]") // ] -> \]\r
+ .replace("{", "\\{") // { -> \{\r
+ .replace("}", "\\}") // } -> \}\r
+ .replace("^", "\\^") // ^ -> \^\r
+ .replace("$", "\\$") // $ -> \$\r
+ .replace("|", ".*|") // $ -> \$\r
+ //.replace("|", "\\|") // | -> \|\r
+ .replace("&&", "\\&&") // && -> \&&\r
+ ;\r
+\r
+ if (implicitPreAsterisk)\r
+ if (!regExFilter.startsWith(".*"))\r
+ regExFilter = ".*" + regExFilter ;\r
+ if (!regExFilter.endsWith(".*"))\r
+ regExFilter += ".*" ;\r
+\r
+ return regExFilter;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public static String defaultToPatternString(String filter, boolean implicitPreAsterisk) {\r
+ if (filter.isEmpty())\r
+ return null;\r
+\r
+ CharBuffer buf = CharBuffer.allocate(filter.length()*2);\r
+ buf.mark();\r
+ StringBuilder sb = new StringBuilder(filter.length()*2);\r
+ boolean inQuote = false;\r
+ int len = filter.length();\r
+ for (int i = 0; i < len;) {\r
+ char ch = filter.charAt(i);\r
+ if (DEBUG)\r
+ System.out.println("char[" + i + "]: '" + ch + "'");\r
+\r
+ if (ch == '"') {\r
+ if (!inQuote) {\r
+ if (DEBUG)\r
+ System.out.println("begin quoted text");\r
+ inQuote = true;\r
+ } else {\r
+ if (DEBUG)\r
+ System.out.println("end quoted text");\r
+ inQuote = false;\r
+ addSearchWord(sb, toSinglePatternString( toString(buf), implicitPreAsterisk ));\r
+ }\r
+ ++i;\r
+ continue;\r
+ } else if (ch == '\\') {\r
+ // Next character is escaped, i.e. taken as is.\r
+ ++i;\r
+ if (i >= len)\r
+ // Unexpected end-of-string\r
+ break;\r
+\r
+ ch = filter.charAt(i);\r
+ if (DEBUG)\r
+ System.out.println("append escaped character '" + ch + "'");\r
+\r
+ buf.append(ch);\r
+ ++i;\r
+ break;\r
+ } else if (ch == ' ') {\r
+ if (inQuote) {\r
+ if (DEBUG)\r
+ System.out.println("append char '" + ch + "'");\r
+ buf.append(ch);\r
+ ++i;\r
+ } else {\r
+ if (buf.position() > 0) {\r
+ addSearchWord(sb, toSinglePatternString( toString(buf), implicitPreAsterisk ));\r
+ }\r
+ ++i;\r
+ }\r
+ } else {\r
+ if (DEBUG)\r
+ System.out.println("append char '" + ch + "'");\r
+ buf.append(ch);\r
+ ++i;\r
+ }\r
+ }\r
+ if (buf.position() > 0) {\r
+ addSearchWord(sb, toSinglePatternString( toString(buf), implicitPreAsterisk ));\r
+ }\r
+\r
+ //sb.append(".*");\r
+\r
+ return sb.toString();\r
+ }\r
+\r
+}\r