OSDN Git Service

uni-gramで日本語全文検索できるように変更。ノートコンテンツとタイトルが対象。日本語全文検索時に日本語がハイライトされない問題を修正。
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / xml / XMLInsertHilight.java
1 /*\r
2  * This file is part of NixNote/NeighborNote \r
3  * Copyright 2009 Randy Baumgarte\r
4  * \r
5  * This file may be licensed under the terms of of the\r
6  * GNU General Public License Version 2 (the ``GPL'').\r
7  *\r
8  * Software distributed under the License is distributed\r
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
10  * express or implied. See the GPL for the specific language\r
11  * governing rights and limitations.\r
12  *\r
13  * You should have received a copy of the GPL along with this\r
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
15  * or write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
17  *\r
18 */\r
19 \r
20 \r
21 package cx.fbn.nevernote.xml;\r
22 \r
23 import java.util.ArrayList;\r
24 import java.util.List;\r
25 import java.util.regex.Matcher;\r
26 import java.util.regex.Pattern;\r
27 \r
28 import com.trolltech.qt.xml.QDomDocument;\r
29 import com.trolltech.qt.xml.QDomDocumentFragment;\r
30 import com.trolltech.qt.xml.QDomElement;\r
31 import com.trolltech.qt.xml.QDomNode;\r
32 import com.trolltech.qt.xml.QDomNodeList;\r
33 import com.trolltech.qt.xml.QDomText;\r
34 \r
35 public class XMLInsertHilight {\r
36         private final QDomDocument doc;\r
37         List<String> terms;\r
38         List<QDomNode> oldNodes;\r
39         List<QDomNode> newNodes;\r
40         \r
41         public XMLInsertHilight(QDomDocument d, List<String> t) {\r
42                 doc = d;\r
43                 terms = t;\r
44                 oldNodes = new ArrayList<QDomNode>();\r
45                 newNodes = new ArrayList<QDomNode>();\r
46                 scanTags();\r
47         }\r
48         public QDomDocument getDoc() {\r
49                 for (int i=0; i<oldNodes.size(); i++) {\r
50                         oldNodes.get(i).parentNode().replaceChild(newNodes.get(i), oldNodes.get(i));\r
51                 }\r
52                 return doc;\r
53         }\r
54         // Start looking through the tree.\r
55         private void scanTags() {\r
56 //              QDomElement element = doc.firstChildElement();\r
57 //              parseChildren(element.firstChild());\r
58                 if (doc.hasChildNodes())\r
59                         parseNodes(doc.childNodes());\r
60                 return;\r
61         }\r
62         \r
63         private void parseNodes(QDomNodeList nodes) {\r
64                 for (int i=0; i<nodes.size(); i++) {\r
65                         QDomNode node = nodes.at(i);\r
66                         if (node.hasChildNodes()) {\r
67                                 parseNodes(node.childNodes());\r
68                         }\r
69                         scanWords(node);\r
70                 }\r
71 }\r
72         \r
73         \r
74         // Parse through individual nodes\r
75         public void parseChildren(QDomNode node) {\r
76                 for(; !node.isNull(); node = node.nextSibling()) {\r
77                         if (node.hasChildNodes()) {\r
78                                 QDomNodeList l = node.childNodes();\r
79                                 for (int i=0; i<l.size(); i++)\r
80                                         parseChildren(l.at(i));\r
81                         }\r
82                         if (node.isText()) {\r
83                                 scanWords(node);\r
84                         }\r
85                 }\r
86         }\r
87         \r
88         // We found a text node, so we need to search for things to hilight\r
89         private void scanWords(QDomNode node) { \r
90                 String value = node.nodeValue();\r
91                 \r
92                 QDomDocumentFragment fragment = doc.createDocumentFragment();\r
93                 boolean matchFound = false;\r
94                 int previousPosition = 0;\r
95                 String valueEnd = "";\r
96         \r
97                 String regex = buildRegex();\r
98                         \r
99                 Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);\r
100                 Matcher matcher = pattern.matcher(value);\r
101                         \r
102                 while (matcher.find()) {\r
103                         matchFound = true;\r
104                         String valueStart = "";\r
105                         int start = matcher.start();\r
106                         int end = matcher.end();\r
107                         if (value.substring(start).startsWith(" "))\r
108                                         start++;\r
109                                 if (value.substring(start, end).endsWith(" "))\r
110                                         end--;\r
111                         \r
112                         if (matcher.start() > 0) {\r
113                                 valueStart = value.substring(previousPosition,start); \r
114                         } \r
115                         String valueMiddle = value.substring(start, end);\r
116                         valueEnd = "";\r
117                         if (matcher.end() < value.length()) {\r
118                                 valueEnd = value.substring(end);\r
119                         }\r
120                         \r
121                         previousPosition = end;\r
122                         if (!valueStart.equals("")) {\r
123                                 QDomText startText = doc.createTextNode(valueStart);\r
124                                 fragment.appendChild(startText);\r
125                         }\r
126                         \r
127                         QDomElement hilight = doc.createElement("en-hilight");\r
128                         hilight.appendChild(doc.createTextNode(valueMiddle));\r
129                         fragment.appendChild(hilight);\r
130                 }\r
131                 if (matchFound) {\r
132                         if (previousPosition != value.length()) {\r
133                                 QDomText endText = doc.createTextNode(valueEnd);\r
134                                 fragment.appendChild(endText);\r
135                         }\r
136                         newNodes.add(fragment);\r
137                         oldNodes.add(node);\r
138                 }\r
139         }\r
140         \r
141         \r
142         private String buildRegex() {\r
143                 StringBuffer regex = new StringBuffer();\r
144                 \r
145                 // Remove any empty terms of it screws things up later\r
146                 for (int j=terms.size()-1; j>=0; j--) {\r
147                         if (terms.get(j).trim().equals(""))\r
148                                 terms.remove(j);\r
149                 }\r
150                 \r
151                 for (int i=0; i<terms.size(); i++) {\r
152                         String term = terms.get(i);\r
153                         if (term.indexOf("*") > -1) {\r
154                                 term = term.replace("*", "");\r
155                         }/* else {\r
156                                 term = "\\b"+term+"\\b";\r
157                         }*/\r
158                         regex.append(term);\r
159                         if (i<terms.size()-1)\r
160                                 regex.append("|"); \r
161                 }\r
162                 \r
163                 return regex.toString();\r
164         }\r
165         \r
166 \r
167 }\r