OSDN Git Service

uni-gramで日本語全文検索できるように変更。ノートコンテンツとタイトルが対象。日本語全文検索時に日本語がハイライトされない問題を修正。
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / sql / REnSearch.java
index 1da5abe..4ee21b7 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * This file is part of NeverNote \r
+ * This file is part of NixNote/NeighborNote \r
  * Copyright 2009 Randy Baumgarte\r
  * \r
  * This file may be licensed under the terms of of the\r
@@ -27,12 +27,13 @@ import java.util.GregorianCalendar;
 import java.util.List;\r
 import java.util.regex.Pattern;\r
 \r
-import org.apache.commons.lang.StringEscapeUtils;\r
+import org.apache.commons.lang3.StringEscapeUtils;\r
 \r
 import com.evernote.edam.type.Note;\r
 import com.evernote.edam.type.Notebook;\r
 import com.evernote.edam.type.Tag;\r
 \r
+import cx.fbn.nevernote.Global;\r
 import cx.fbn.nevernote.sql.driver.NSqlQuery;\r
 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
 \r
@@ -115,8 +116,7 @@ public class REnSearch {
        public List<String> getStack() { return stack; }\r
 \r
        // match tag names\r
-       private boolean matchTagsAll(List<String> tagNames) {\r
-               List<String> list = getTags();\r
+       private boolean matchTagsAll(List<String> tagNames, List<String> list) {\r
                                \r
                for (int j=0; j<list.size(); j++) {\r
                        boolean negative = false;\r
@@ -129,32 +129,28 @@ public class REnSearch {
                        \r
                        if (tagNames.size() == 0 && !negative)\r
                                return false;\r
-                       if (tagNames.size() == 0 && negative)\r
-                               return true;\r
                        \r
-                       boolean good = false;\r
-                       for (int i=0; i<tagNames.size() && !good; i++) {                \r
+                       boolean matchFound = false;\r
+                       for (int i=0; i<tagNames.size(); i++) { \r
                                boolean matches = Pattern.matches(filterName.toLowerCase(),tagNames.get(i).toLowerCase());\r
-                               if (matches && !negative)\r
-                                       good = true;\r
-                               if (!matches && negative)\r
-                                       good = true;\r
+                               if (matches)\r
+                                       matchFound = true;\r
                        }\r
-                       if (!good)\r
+                       if (negative) \r
+                               matchFound = !matchFound;\r
+                       if (!matchFound) \r
                                return false;\r
                }\r
                return true;\r
        }\r
        \r
        // match tag names\r
-       private boolean matchTagsAny(List<String> tagNames) {\r
-               List<String> list = getTags();\r
+       private boolean matchTagsAny(List<String> tagNames, List<String> list) {\r
                if (list.size() == 0)\r
                        return true;\r
                \r
                boolean negative = false;               \r
-               boolean found = false;\r
-               \r
+\r
                for (int j=0; j<list.size(); j++) {\r
                        negative = false;\r
                        if (list.get(j).startsWith("-"))\r
@@ -163,21 +159,19 @@ public class REnSearch {
                        String filterName = cleanupWord(list.get(j).substring(pos+1));\r
                        filterName = filterName.replace("*", ".*");   // setup for regular expression pattern match\r
                        \r
-                       if (tagNames.size() == 0)\r
-                               found = false;\r
+                       if (tagNames.size() == 0 && !negative)\r
+                               return false;\r
 \r
                        for (int i=0; i<tagNames.size(); i++) {         \r
                                boolean matches = Pattern.matches(filterName.toLowerCase(),tagNames.get(i).toLowerCase());\r
-                               if (matches)\r
-                                       found = true;\r
+                               if (!matches && !negative)\r
+                                       return false;\r
                        }\r
                }\r
-               if (negative)\r
-                       return !found;\r
-               else\r
-                       return found;\r
+               return true;\r
        }\r
        \r
+       \r
        // Match notebooks in search terms against notes\r
        private boolean matchNotebook(String guid) {\r
                if (getNotebooks().size() == 0)\r
@@ -250,7 +244,7 @@ public class REnSearch {
                n = conn.getNoteTable().getNote(n.getGuid(), true, true, false, false, false);\r
 \r
                // Check for search phrases\r
-               String text = StringEscapeUtils.unescapeHtml(n.getContent().replaceAll("\\<.*?\\>", "")).toLowerCase();\r
+               String text = StringEscapeUtils.unescapeHtml4(n.getContent().replaceAll("\\<.*?\\>", "")).toLowerCase();\r
                boolean negative = false;\r
                for (int i=0; i<searchPhrases.size(); i++) {\r
                        String phrase = searchPhrases.get(i);\r
@@ -386,6 +380,7 @@ public class REnSearch {
        private void parseTerms(List<String> words) {\r
                for (int i=0; i<words.size(); i++) {\r
                        String word = words.get(i);\r
+                       System.out.println("word = " + word);\r
                        int pos = word.indexOf(":");\r
                        if (word.startsWith("any:")) {\r
                                any = true;\r
@@ -397,10 +392,19 @@ public class REnSearch {
                                searchPhrase=true;\r
                                searchPhrases.add(word.toLowerCase());\r
                        }\r
-                       if (!searchPhrase && pos < 0) \r
-                               if (word != null && word.length() > 0)\r
+                       if (!searchPhrase && pos < 0) {\r
+                               if (word != null && word.length() > 0 && !Global.automaticWildcardSearches())\r
                                        getWords().add(word); \r
+                               if (word != null && word.length() > 0 && Global.automaticWildcardSearches()) {\r
+                                       String wildcardWord = word;\r
+                                       if (!wildcardWord.startsWith("*"))\r
+                                               wildcardWord = "*"+wildcardWord;\r
+                                       if (!wildcardWord.endsWith("*"))\r
+                                               wildcardWord = wildcardWord+"*";\r
+                                       getWords().add(wildcardWord); \r
+                               }\r
 //                             getWords().add("*"+word+"*");           //// WILDCARD\r
+                       }\r
                        if (word.startsWith("intitle:")) \r
                                intitle.add("*"+word+"*");\r
                        if (word.startsWith("-intitle:")) \r
@@ -498,22 +502,10 @@ public class REnSearch {
                if (todo.size() == 0 && resource.size() == 0 && searchPhrases.size() == 0)\r
                        return true;\r
                \r
-               boolean returnTodo = false;\r
-               boolean returnResource = false;\r
-               boolean returnPhrase = false;\r
-               \r
-               if (todo.size() == 0)\r
-                       returnTodo = true;\r
-               if (resource.size() == 0)\r
-                       returnResource = true;\r
-               if (searchPhrases.size() == 0)\r
-                       returnPhrase = true;\r
-               \r
-               \r
                n = conn.getNoteTable().getNote(n.getGuid(), true, true, false, false, false);\r
                \r
                // Check for search phrases\r
-               String text = StringEscapeUtils.unescapeHtml(n.getContent().replaceAll("\\<.*?\\>", "")).toLowerCase();\r
+               String text = StringEscapeUtils.unescapeHtml4(n.getContent().replaceAll("\\<.*?\\>", "")).toLowerCase();\r
                boolean negative = false;\r
                for (int i=0; i<searchPhrases.size(); i++) {\r
                        String phrase = searchPhrases.get(i);\r
@@ -524,12 +516,11 @@ public class REnSearch {
                                negative = false;\r
                        phrase = phrase.substring(1);\r
                        phrase = phrase.substring(0,phrase.length()-1);\r
-                       if (text.indexOf(phrase)>=0) {\r
-                               if (!negative)\r
-                                       returnPhrase = true;\r
-                       }\r
-                       if (text.indexOf(phrase)<0 && negative)\r
-                               returnPhrase = true;\r
+                       if (text.indexOf(phrase)>=0 && negative) {\r
+                               return false;\r
+                       } \r
+                       if (text.indexOf(phrase) < 0 && !negative)\r
+                               return false;\r
                }\r
 \r
                \r
@@ -546,27 +537,30 @@ public class REnSearch {
                        if (value.startsWith("-"))\r
                                desiredState = !desiredState;\r
                        int pos = n.getContent().indexOf("<en-todo");\r
-                       if (pos == -1 && value.startsWith("-") && (value.endsWith("*") || value.endsWith(":")))\r
-                               return true;\r
+                       if (pos == -1 && !value.startsWith("-"))\r
+                               return false;\r
                        if (pos > -1 && value.startsWith("-") && (value.endsWith("*") || value.endsWith(":")))\r
                                return false;\r
-                       if (pos == -1) \r
+                       if (pos == -1 && !value.startsWith("-")\r
                                return false;\r
-                       if (value.endsWith("*"))\r
-                               returnTodo = true;\r
+                       boolean returnTodo = false;\r
                        while (pos > -1) {\r
-                               int endPos = n.getContent().indexOf("/>", pos);\r
+                               int endPos = n.getContent().indexOf(">", pos);\r
                                String segment = n.getContent().substring(pos, endPos);\r
                                boolean currentState;\r
                                if (segment.toLowerCase().indexOf("checked=\"true\"") == -1)\r
                                        currentState = false;\r
                                else\r
                                        currentState = true;\r
-                               if (desiredState == currentState)\r
+                               if (desiredState == currentState) \r
+                                       returnTodo = true;\r
+                               if (value.endsWith("*") || value.endsWith(":"))\r
                                        returnTodo = true;\r
                                \r
                                pos = n.getContent().indexOf("<en-todo", pos+1);\r
                        }\r
+                       if (!returnTodo)\r
+                               return false;\r
                }\r
                \r
                // Check resources\r
@@ -581,13 +575,14 @@ public class REnSearch {
                                return false;\r
                        for (int j=0; j<n.getResourcesSize(); j++) {\r
                                boolean match = stringMatch(n.getResources().get(j).getMime(), resourceString, negative);\r
-                               if (!match)\r
+                               if (!match && !negative)\r
+                                       return false;\r
+                               if (match && negative) \r
                                        return false;\r
-                               returnResource = true;\r
                        }\r
                }\r
                \r
-               return returnResource && returnTodo && returnPhrase;\r
+               return true;\r
        }\r
        \r
        private boolean stringMatch(String content, String text, boolean negative) {\r
@@ -708,28 +703,33 @@ public class REnSearch {
                }\r
 \r
                NSqlQuery insertQuery = new NSqlQuery(conn.getConnection());\r
-               NSqlQuery indexQuery = new NSqlQuery(conn.getIndexConnection());\r
+//             NSqlQuery indexQuery = new NSqlQuery(conn.getIndexConnection());\r
                NSqlQuery mergeQuery = new NSqlQuery(conn.getConnection());\r
                NSqlQuery deleteQuery = new NSqlQuery(conn.getConnection());\r
+               NSqlQuery ftlQuery = new NSqlQuery(conn.getConnection());\r
+               ftlQuery.prepare("SELECT N.GUID AS GUID FROM FTL_SEARCH_DATA(:text, 0, 0) FT, NOTE N WHERE FT.TABLE='NOTE' AND N.GUID=FT.KEYS[0]");\r
                \r
                insertQuery.prepare("Insert into SEARCH_RESULTS (guid) values (:guid)");\r
                mergeQuery.prepare("Insert into SEARCH_RESULTS_MERGE (guid) values (:guid)");\r
                \r
                if (subSelect) {\r
                        for (int i=0; i<getWords().size(); i++) {\r
-                               if (getWords().get(i).indexOf("*") == 0) {\r
-                                       indexQuery.prepare("Select distinct guid from words where weight >= " +minimumRecognitionWeight +\r
-                                                       " and word=:word");\r
-                                       indexQuery.bindValue(":word", getWords().get(i));\r
-                               } else {\r
-                                       indexQuery.prepare("Select distinct guid from words where weight >= " +minimumRecognitionWeight +\r
-                                               " and word like :word");\r
-                                       indexQuery.bindValue(":word", getWords().get(i).replace("*", "%"));\r
-                               }\r
-                               indexQuery.exec();\r
+//                             if (getWords().get(i).indexOf("*") == -1) {\r
+//                                     indexQuery.prepare("Select distinct guid from words where weight >= " +minimumRecognitionWeight +\r
+//                                                     " and word=:word");\r
+//                                     indexQuery.bindValue(":word", getWords().get(i));\r
+//                             } else {\r
+//                                     indexQuery.prepare("Select distinct guid from words where weight >= " +minimumRecognitionWeight +\r
+//                                             " and word like :word");\r
+//                                     indexQuery.bindValue(":word", getWords().get(i).replace("*", "%"));\r
+//                             }\r
+                               \r
+                               ftlQuery.bindValue(":text", getWords().get(i));\r
+                               ftlQuery.exec();\r
+                               \r
                                String guid = null;\r
-                               while(indexQuery.next()) {\r
-                                       guid = indexQuery.valueString(0);\r
+                               while(ftlQuery.next()) {\r
+                                       guid = ftlQuery.valueString(0);\r
                                        if (i==0 || any) {\r
                                                insertQuery.bindValue(":guid", guid);\r
                                                insertQuery.exec();\r
@@ -764,7 +764,7 @@ public class REnSearch {
                                                \r
                        // Start matching special stuff, like tags & notebooks\r
                        if (any) {\r
-                               if (good && !matchTagsAny(n.getTagNames()))\r
+                               if (good && !matchTagsAny(n.getTagNames(), getTags()))\r
                                        good = false;\r
                                if (good && !matchNotebook(n.getNotebookGuid()))\r
                                        good = false;\r
@@ -787,7 +787,7 @@ public class REnSearch {
                                if (good && n.getAttributes() != null && !matchDatesAny(getSubjectDate(), n.getAttributes().getSubjectDate()))\r
                                        good = false;\r
                        } else {\r
-                               if (good && !matchTagsAll(n.getTagNames()))\r
+                               if (good && !matchTagsAll(n.getTagNames(), getTags()))\r
                                        good = false;\r
                                if (good && !matchNotebook(n.getNotebookGuid()))\r
                                        good = false;\r