001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.javadoc.search;
043:
044: import java.util.NoSuchElementException;
045: import java.util.StringTokenizer;
046: import java.io.BufferedReader;
047: import java.io.InputStreamReader;
048: import java.io.Reader;
049: import java.net.URL;
050:
051: import javax.swing.text.html.parser.ParserDelegator;
052: import javax.swing.text.html.HTMLEditorKit;
053: import javax.swing.text.html.HTML;
054: import javax.swing.text.MutableAttributeSet;
055:
056: import org.openide.ErrorManager;
057: import org.openide.util.NbBundle;
058: import org.openide.filesystems.FileObject;
059:
060: /** This class implements the index search through documenation
061: * generated by Jdk 1.2 standard doclet
062: */
063:
064: class SearchThreadJdk12_japan extends IndexSearchThread {
065:
066: private Reader in;
067: private URL contextURL;
068:
069: private boolean stopSearch = false;
070:
071: private boolean splitedIndex = false;
072: private int currentIndexNumber;
073: private FileObject folder = null;
074: private String JapanEncoding;
075: private final Object LOCK = new Object();
076:
077: public SearchThreadJdk12_japan(String toFind, FileObject fo,
078: IndexSearchThread.DocIndexItemConsumer diiConsumer,
079: boolean caseSensitive, String JapanEncoding) {
080:
081: super (toFind, fo, diiConsumer, caseSensitive);
082: this .JapanEncoding = JapanEncoding;
083:
084: if (fo.isFolder()) {
085: // Documentation uses splited index - resolve the right file
086:
087: // This is just a try in most cases the fileNumber should be
088: // the right one but when some index files are missing we have
089: // to find the right one
090: folder = fo;
091: currentIndexNumber = (int) (Character.toUpperCase(lastField
092: .charAt(0))) - 'A' + 1;//toFind.charAt(0) )) - 'A' + 1;
093:
094: if (currentIndexNumber < 1) {
095: currentIndexNumber = 1;
096: } else if (currentIndexNumber > 26) {
097: currentIndexNumber = 27;
098: }
099:
100: /*
101: if ( currentIndexNumber < 1 || currentIndexNumber > 26 ) {
102: currentIndexNumber = 27;
103: }
104: */
105: findFileObject(0);
106:
107: splitedIndex = true;
108: } else {
109: try {
110: contextURL = this .indexRoot.getURL();
111: //contextURL = this.fo.getParent().getURL();
112: } catch (org.openide.filesystems.FileStateInvalidException e) {
113: throw new InternalError(
114: "Can't create documentation folder URL - file state invalid"); // NOI18N
115: }
116:
117: splitedIndex = false;
118: }
119: }
120:
121: public void stopSearch() {
122: Reader br;
123: synchronized (LOCK) {
124: stopSearch = true;
125: br = in;
126: }
127:
128: try {
129: if (br != null)
130: br.close();
131: } catch (java.io.IOException e) {
132: ErrorManager.getDefault().notify(e);
133: }
134: }
135:
136: public void run() {
137:
138: ParserDelegator pd = new ParserDelegator();
139:
140: if (indexRoot == null || lastField == null
141: || lastField.length() == 0) {
142: taskFinished();
143: return;
144: }
145:
146: SearchCallbackJdk12_japan sc = null;
147:
148: int theDirection = 0;
149:
150: do {
151: if (sc != null) {
152:
153: if (sc.badFile != theDirection) {
154: break;
155: }
156:
157: findFileObject(sc.badFile);
158: if (indexRoot == null) {
159: // No other file to search
160: break;
161: }
162: }
163:
164: try {
165: synchronized (LOCK) {
166: if (stopSearch) {
167: break;
168: }
169: in = new BufferedReader(new InputStreamReader(
170: indexRoot.getInputStream(), JapanEncoding));
171: }
172: // System.out.println("Encoding: " + JapanEncoding);
173: pd.parse(in, sc = new SearchCallbackJdk12_japan(
174: splitedIndex, caseSensitive), true);
175: } catch (java.io.IOException e) {
176: // Do nothing
177: }
178:
179: if (sc.badFile != 0 && theDirection == 0) {
180: theDirection = sc.badFile;
181: }
182: } while (sc.badFile != 0);
183:
184: try {
185: if (in != null) {
186: in.close();
187: }
188: } catch (java.io.IOException e) {
189: // Do nothing
190: }
191: //is.searchEnded();
192: taskFinished();
193: }
194:
195: void findFileObject(int direction) {
196:
197: if (direction < 0) {
198: currentIndexNumber--;
199: } else if (direction > 0) {
200: currentIndexNumber++;
201: }
202:
203: do {
204:
205: // Assure the only one direction of looking for Files
206: if (currentIndexNumber < 0 || currentIndexNumber > 27) {
207: indexRoot = null;
208: return;
209: }
210:
211: String fileName = "index-" + currentIndexNumber; // NOI18N
212:
213: if (folder == null) {
214: indexRoot = null;
215: return;
216: }
217:
218: indexRoot = folder.getFileObject(fileName, "html"); // NOI18N
219:
220: if (indexRoot != null) {
221: try {
222: contextURL = this .indexRoot.getURL();
223: } catch (org.openide.filesystems.FileStateInvalidException e) {
224: throw new InternalError(
225: "Can't create documentation folder URL - file state invalid"); // NOI18N
226: }
227: } else {
228:
229: currentIndexNumber += direction > 0 ? 1 : -1;
230: }
231: } while (indexRoot == null);
232:
233: }
234:
235: // Inner classes ------------------------------------------------------------------------------------
236:
237: /* These are constants for the inner class */
238:
239: static private final String STR_CLASS = NbBundle.getMessage(
240: SearchThreadJdk12_japan.class, "JDK12_CLASS"); //NOI18N
241: static private final String STR_INTERFACE = NbBundle.getMessage(
242: SearchThreadJdk12_japan.class, "JDK12_INTERFACE"); //NOI18N
243: static private final String STR_EXCEPTION = NbBundle.getMessage(
244: SearchThreadJdk12_japan.class, "JDK12_EXCEPTION"); //NOI18N
245: static private final String STR_CONSTRUCTOR = NbBundle.getMessage(
246: SearchThreadJdk12_japan.class, "JDK12_CONSTRUCTOR"); //NOI18N
247: static private final String STR_METHOD = NbBundle.getMessage(
248: SearchThreadJdk12_japan.class, "JDK12_METHOD"); //NOI18N
249: static private final String STR_ERROR = NbBundle.getMessage(
250: SearchThreadJdk12_japan.class, "JDK12_ERROR"); //NOI18N
251: static private final String STR_VARIABLE = NbBundle.getMessage(
252: SearchThreadJdk12_japan.class, "JDK12_VARIABLE"); //NOI18N
253: static private final String STR_STATIC = NbBundle.getMessage(
254: SearchThreadJdk12_japan.class, "JDK12_STATIC"); //NOI18N
255: static private final String STR_DASH = NbBundle.getMessage(
256: SearchThreadJdk12_japan.class, "JDK12_DASH"); //NOI18N
257: static private final String STR_PACKAGE = NbBundle.getMessage(
258: SearchThreadJdk12_japan.class, "JDK12_PACKAGE"); //NOI18N
259: private static final String STR_ENUM = NbBundle.getMessage(
260: SearchThreadJdk12_japan.class, "JDK15_ENUM"); //NOI18N
261: private static final String STR_ANNTYPE = NbBundle.getMessage(
262: SearchThreadJdk12_japan.class, "JDK15_ANNOTATION_TYPE"); //NOI18N
263:
264: /* Same translations from JDK javadoc */
265: static private final String STR_CLASS_LOC = "\u30AF\u30E9\u30B9"; //NOI18N
266: static private final String STR_INTERFACE_LOC = "\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9"; //NOI18N
267: static private final String STR_EXCEPTION_LOC = "\u4F8B\u5916"; //NOI18N
268: static private final String STR_CONSTRUCTOR_LOC = "\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF"; //NOI18N
269: static private final String STR_METHOD_LOC = "\u30E1\u30BD\u30C3\u30C9"; //NOI18N
270: static private final String STR_ERROR_LOC = "\u30A8\u30E9\u30FC"; //NOI18N
271: static private final String STR_VARIABLE_LOC = "\u5909\u6570"; //NOI18N
272: static private final String STR_STATIC_LOC = "static"; //NOI18N
273: static private final String STR_DASH_LOC = "-"; //NOI18N
274: static private final String STR_PACKAGE_LOC = "\u30D1\u30C3\u30B1\u30FC\u30B8"; //NOI18N
275: private static final String STR_ENUM_LOC = "\u5217\u6319\u578B"; //NOI18N
276: private static final String STR_ANNTYPE_LOC = "\u6CE8\u91C8\u578B"; //NOI18N
277:
278: static private final int IN_BALAST = 0;
279: static private final int IN_DT = 1;
280: static private final int IN_AREF = 2;
281: // static private final int IN_B = 3;
282: static private final int IN_DESCRIPTION = 4;
283: static private final int IN_DESCRIPTION_SUFFIX = 5;
284:
285: /** This inner class parses the JDK 1.2 Documentation index and returns
286: * found indexItems.
287: */
288:
289: private class SearchCallbackJdk12_japan extends
290: HTMLEditorKit.ParserCallback {
291:
292: private String hrefVal;
293: private DocIndexItem currentDii = null;
294: private int where = IN_BALAST;
295:
296: private boolean splited;
297: private boolean stopOnNext = false;
298:
299: private int badFile = 0;
300:
301: int printText = 0;
302:
303: SearchCallbackJdk12_japan(boolean splited, boolean caseSensitive) {
304: super ();
305: this .splited = splited;
306: }
307:
308: public void handleStartTag(HTML.Tag t, MutableAttributeSet a,
309: int pos) {
310:
311: if (t == HTML.Tag.DT) {
312: where = IN_DT;
313: currentDii = null;
314: } else if (t == HTML.Tag.A && where == IN_DT) {
315: where = IN_AREF;
316: Object val = a.getAttribute(HTML.Attribute.HREF);
317: if (val != null) {
318: hrefVal = (String) val.toString();
319: currentDii = new DocIndexItem(null, null,
320: contextURL, hrefVal);
321: }
322: } else if (t == HTML.Tag.A
323: && (where == IN_DESCRIPTION_SUFFIX || where == IN_DESCRIPTION)) {
324: ; // Just ignore
325: } else if (t == HTML.Tag.B && where == IN_AREF) {
326: where = IN_AREF;
327: } else {
328: where = IN_BALAST;
329: }
330: }
331:
332: public void handleEndTag(HTML.Tag t, int pos) {
333: if (t == HTML.Tag.DT && where != IN_BALAST) {
334: where = IN_BALAST;
335: }
336: }
337:
338: public void handleText(char[] data, int pos) {
339:
340: if (where == IN_AREF) {
341:
342: if (stopOnNext) {
343: try {
344: in.close();
345: where = IN_BALAST;
346: return;
347: } catch (java.io.IOException e) {
348: ErrorManager.getDefault().notify(e);
349: }
350: }
351:
352: String text = new String(data);
353:
354: if (splited) {
355: // it is possible that we search wrong file
356: char first = Character.toUpperCase(lastField
357: .charAt(0));
358: char curr = Character.toUpperCase(data[0]);
359: if (first != curr) {
360:
361: badFile = first < curr ? -1 : 1;
362: try {
363: in.close();
364: where = IN_BALAST;
365: return;
366: } catch (java.io.IOException e) {
367: ErrorManager.getDefault().notify(e);
368: }
369: }
370:
371: }
372: currentDii.setField(text.trim());
373: where = IN_DESCRIPTION;
374: } else if (where == IN_DESCRIPTION) {
375: String text = new String(data);
376: /*
377: // Stop suffering if we are behind the searched words
378: if ( text.substring( 0, Math.min(toFind.length(), text.length()) ).compareTo( toFind ) > 0 ) {
379: try {
380: System.out.println("Stoping suffering");
381: in.close();
382: }
383: catch ( java.io.IOException e ) {
384: ErrorManager.getDefault().notify(e);
385: }
386: }
387: */
388:
389: //text = text.toUpperCase();
390: int dashIdx = text.indexOf(STR_DASH);
391: if (dashIdx < 0) {
392: return;
393: }
394: text = text.substring(dashIdx - 1);
395: currentDii.setRemark(text);
396:
397: StringTokenizer st = new StringTokenizer(text);
398: String token;
399:
400: boolean isStatic = false;
401: try {
402: token = st.nextToken();
403: if (token.equals(STR_DASH))
404: token = st.nextToken();
405:
406: if (token.equalsIgnoreCase(STR_STATIC)) {
407: isStatic = true;
408: token = st.nextToken();
409: }
410: } catch (NoSuchElementException ex) { // see #71978
411: where = IN_DESCRIPTION_SUFFIX;
412: return;
413: }
414:
415: if (token.equalsIgnoreCase(STR_CLASS))
416: currentDii.setIconIndex(DocSearchIcons.ICON_CLASS);
417: else if (token.equalsIgnoreCase(STR_INTERFACE))
418: currentDii
419: .setIconIndex(DocSearchIcons.ICON_INTERFACE);
420: else if (token.equalsIgnoreCase(STR_ENUM))
421: currentDii.setIconIndex(DocSearchIcons.ICON_ENUM);
422: else if (token.equalsIgnoreCase(STR_ANNTYPE))
423: currentDii
424: .setIconIndex(DocSearchIcons.ICON_ANNTYPE);
425: else if (token.equalsIgnoreCase(STR_EXCEPTION))
426: currentDii
427: .setIconIndex(DocSearchIcons.ICON_EXCEPTION);
428: else if (token.equalsIgnoreCase(STR_ERROR))
429: currentDii.setIconIndex(DocSearchIcons.ICON_ERROR);
430: else if (token.equalsIgnoreCase(STR_PACKAGE))
431: currentDii
432: .setIconIndex(DocSearchIcons.ICON_PACKAGE);
433: else if (token.equalsIgnoreCase(STR_CONSTRUCTOR))
434: currentDii
435: .setIconIndex(DocSearchIcons.ICON_CONSTRUCTOR);
436: else if (token.equalsIgnoreCase(STR_METHOD))
437: currentDii
438: .setIconIndex(isStatic ? DocSearchIcons.ICON_METHOD_ST
439: : DocSearchIcons.ICON_METHOD);
440: else if (token.equalsIgnoreCase(STR_VARIABLE))
441: currentDii
442: .setIconIndex(isStatic ? DocSearchIcons.ICON_VARIABLE_ST
443: : DocSearchIcons.ICON_VARIABLE);
444:
445: // Add the item when all information is available
446: //insertDocIndexItem( currentDii );
447:
448: if (currentDii.getPackage() != null) {
449: where = IN_DESCRIPTION_SUFFIX;
450: } else if (text.endsWith(".")) { // NOI18N
451: where = IN_DESCRIPTION_SUFFIX;
452: currentDii.setPackage(text.substring(
453: text.lastIndexOf(' ')).trim());
454: } else
455: where = IN_BALAST;
456: } else if (where == IN_DESCRIPTION_SUFFIX) {
457: boolean isStatic = false;
458: String remark = String.valueOf(data);
459:
460: if (remark.contains(STR_STATIC_LOC)) {
461: isStatic = true;
462: }
463:
464: if (remark.contains(STR_CLASS_LOC))
465: currentDii.setIconIndex(DocSearchIcons.ICON_CLASS);
466: else if (remark.contains(STR_INTERFACE_LOC))
467: currentDii
468: .setIconIndex(DocSearchIcons.ICON_INTERFACE);
469: else if (remark.contains(STR_ENUM_LOC))
470: currentDii.setIconIndex(DocSearchIcons.ICON_ENUM);
471: else if (remark.contains(STR_ANNTYPE_LOC))
472: currentDii
473: .setIconIndex(DocSearchIcons.ICON_ANNTYPE);
474: else if (remark.contains(STR_EXCEPTION_LOC))
475: currentDii
476: .setIconIndex(DocSearchIcons.ICON_EXCEPTION);
477: else if (remark.contains(STR_ERROR_LOC))
478: currentDii.setIconIndex(DocSearchIcons.ICON_ERROR);
479: else if (remark.contains(STR_PACKAGE_LOC))
480: currentDii
481: .setIconIndex(DocSearchIcons.ICON_PACKAGE);
482: else if (remark.contains(STR_CONSTRUCTOR_LOC))
483: currentDii
484: .setIconIndex(DocSearchIcons.ICON_CONSTRUCTOR);
485: else if (remark.contains(STR_METHOD_LOC))
486: currentDii
487: .setIconIndex(isStatic ? DocSearchIcons.ICON_METHOD_ST
488: : DocSearchIcons.ICON_METHOD);
489: else if (remark.contains(STR_VARIABLE_LOC))
490: currentDii
491: .setIconIndex(isStatic ? DocSearchIcons.ICON_VARIABLE_ST
492: : DocSearchIcons.ICON_VARIABLE);
493:
494: currentDii.setRemark(currentDii.getRemark() + remark);
495: String declaringClass = remark.trim();
496: if (!(".".equals(declaringClass))) { //NOI18N
497: if (currentDii.getDeclaringClass() == null) {
498: currentDii.setDeclaringClass(declaringClass);
499: insertDocIndexItem(currentDii);
500: }
501: }
502: } else
503: where = IN_BALAST;
504:
505: }
506:
507: }
508:
509: }
|