EmbeddedFunctions { protected static boolean matchesFullText(String fulltext, String query) { if (fulltext == null || query == null) { return false; } Set<String> words = split(query.toLowerCase(), ' '); Set<String> filtered = new HashSet<String>(); for (String word : words) { if (!wordPattern.matcher(word).matches()) { filtered.add(word); } } words = filtered; if (words.isEmpty()) { return false; } Set<String> fulltextWords = split(fulltext.toLowerCase(), ' '); for (String word : words) { if (word.endsWith("*") || word.endsWith("%")) { String prefix = word.substring(0, word.length() - 2); boolean match = false; for (String candidate : fulltextWords) { if (candidate.startsWith(prefix)) { match = true; break; } } if (!match) { return false; } } else { if (!fulltextWords.contains(word)) { return false; } } } return true; }  static boolean isInTree(Serializable id, Serializable baseId); static boolean isInTree(Connection conn, Serializable id,
            Serializable baseId); static boolean isAccessAllowed(Serializable id,
            Set<String> principals, Set<String> permissions); static boolean isAccessAllowed(Connection conn, Serializable id,
            Set<String> principals, Set<String> permissions); static String parseFullText(String string1, String string2); static final String parseWord(String string); static Set<String> split(String string); static Set<String> split(String string, char sep);  }
@Test public void testMatchesFulltext() { checkMatchesFullText(false, "abc def", "ghi"); checkMatchesFullText(true, "abc", "abc"); checkMatchesFullText(true, "abc", "ABC"); checkMatchesFullText(true, "ABC", "abc"); checkMatchesFullText(true, "ABC", "ABC"); checkMatchesFullText(true, "abc def", "abc"); checkMatchesFullText(true, "abcdef", "abc*"); checkMatchesFullText(true, "abcdef", "abc%"); }