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-2006 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.StringTokenizer;
045:
046: import org.openide.util.RequestProcessor;
047: import org.openide.filesystems.FileObject;
048:
049: /** Abstract class for thread which searches for documentation
050: *
051: * @author Petr Hrebejk, Petr Suchomel
052: */
053:
054: public abstract class IndexSearchThread implements Runnable {
055:
056: // PENDING: Add some abstract methods
057:
058: //protected String toFind;
059:
060: // documentation index file (or foldee for splitted index)
061: protected FileObject indexRoot;
062: private DocIndexItemConsumer ddiConsumer;
063: RequestProcessor.Task rpTask = null;
064: protected boolean caseSensitive;
065:
066: protected String lastField = ""; //NOI18N
067: protected String middleField = ""; //NOI18N
068: protected String reminder = ""; //NOI18N
069: private int tokens = 0;
070:
071: private String lastAdd = ""; //NOI18N
072: private String lastDeclaring = ""; //NOI18N
073:
074: /** This method must terminate the process of searching */
075: abstract void stopSearch();
076:
077: public IndexSearchThread(String toFind, FileObject fo,
078: DocIndexItemConsumer ddiConsumer, boolean caseSensitive) {
079: this .ddiConsumer = ddiConsumer;
080: this .indexRoot = fo;
081: this .caseSensitive = caseSensitive;
082:
083: //this.toFind = toFind;
084: //rpTask = RequestProcessor.createRequest( this );
085:
086: StringTokenizer st = new StringTokenizer(toFind, "."); //NOI18N
087: tokens = st.countTokens();
088: //System.out.println(tokens);
089:
090: if (tokens > 1) {
091: if (tokens == 2) {
092: middleField = st.nextToken();
093: lastField = st.nextToken();
094: } else {
095: for (int i = 0; i < tokens - 2; i++) {
096: reminder += st.nextToken();
097: if (i + 1 < tokens - 2)
098: reminder += '.';
099: }
100: middleField = st.nextToken();
101: lastField = st.nextToken();
102: }
103: } else {
104: lastField = toFind;
105: }
106: if (!caseSensitive) {
107: reminder = reminder.toUpperCase();
108: middleField = middleField.toUpperCase();
109: lastField = lastField.toUpperCase();
110: }
111: //System.out.println("lastField" + lastField);
112: }
113:
114: protected synchronized void insertDocIndexItem(DocIndexItem dii) {
115: //no '.', can add directly
116: //System.out.println("Inserting");
117: /*
118: try{
119: PrintWriter pw = new PrintWriter( new FileWriter( "c:/javadoc.dump", true ));
120: pw.println("\"" + dii.getField() +"\""+ " " + "\""+dii.getDeclaringClass()+ "\"" + " " + "\""+ dii.getPackage()+ "\"");
121: pw.println("\"" + lastField + "\"" + " " + "\"" + middleField + "\"" + " " + "\"" + reminder + "\"");
122: pw.flush();
123: pw.close();
124: }
125: catch(IOException ioEx){ioEx.printStackTrace();}
126: */
127: String diiField = dii.getField();
128: String diiDeclaringClass = dii.getDeclaringClass();
129: String diiPackage = dii.getPackage();
130: if (!caseSensitive) {
131: diiField = diiField.toUpperCase();
132: diiDeclaringClass = diiDeclaringClass.toUpperCase();
133: diiPackage = diiPackage.toUpperCase();
134: }
135:
136: if (tokens < 2) {
137: if (diiField.startsWith(lastField)) {
138: //System.out.println("------");
139: //System.out.println("Field: " + diiField + " last field: " + lastAdd + " declaring " + diiDeclaringClass + " package " + diiPackage);
140: if (!lastAdd.equals(diiField)
141: || !lastDeclaring.equals(diiDeclaringClass)) {
142: //System.out.println("ADDED");
143: ddiConsumer.addDocIndexItem(dii);
144: lastAdd = diiField;
145: lastDeclaring = diiDeclaringClass;
146: }
147: //System.out.println("------");
148: } else if (diiDeclaringClass.startsWith(lastField)
149: && dii.getIconIndex() == DocSearchIcons.ICON_CLASS) {
150: if (!lastAdd.equals(diiDeclaringClass)) {
151: ddiConsumer.addDocIndexItem(dii);//System.out.println("Declaring class " + diiDeclaringClass + " icon " + dii.getIconIndex() + " remark " + dii.getRemark());
152: lastAdd = diiDeclaringClass;
153: }
154: } else if (diiPackage.startsWith(lastField + '.')
155: && dii.getIconIndex() == DocSearchIcons.ICON_PACKAGE) {
156: if (!lastAdd.equals(diiPackage)) {
157: ddiConsumer.addDocIndexItem(dii);//System.out.println("Package " + diiPackage + " icon " + dii.getIconIndex() + " remark " + dii.getRemark());
158: lastAdd = diiPackage;
159: }
160: }
161: } else {
162: if (tokens == 2) {
163: //class and field (method etc. are equals)
164: //System.out.println(dii.getField() + " " + lastField + " " + dii.getDeclaringClass() + " " + middleField);
165: if (diiField.startsWith(lastField)
166: && diiDeclaringClass.equals(middleField)) {
167: ddiConsumer.addDocIndexItem(dii);
168: } else if (diiPackage.startsWith(middleField)
169: && diiDeclaringClass.equals(lastField)) {
170: ddiConsumer.addDocIndexItem(dii);
171: } else if (diiPackage
172: .startsWith((middleField + '.' + lastField))
173: && dii.getIconIndex() == DocSearchIcons.ICON_PACKAGE) {
174: ddiConsumer.addDocIndexItem(dii);
175: }
176: } else {
177: //class and field (method etc. are equals)
178: if (diiField.startsWith(lastField)
179: && diiDeclaringClass.equals(middleField)
180: && diiPackage.startsWith(reminder)) {
181: ddiConsumer.addDocIndexItem(dii);
182: }
183: //else if( diiDeclaringClass.equals(lastField) && diiPackage.startsWith( (reminder + '.' + middleField).toUpperCase()) ){
184: else if (diiDeclaringClass.startsWith(lastField)
185: && diiPackage.equals((reminder + '.'
186: + middleField + '.'))) {
187: ddiConsumer.addDocIndexItem(dii);
188: } else if (diiPackage.startsWith((reminder + '.'
189: + middleField + '.' + lastField))
190: && dii.getIconIndex() == DocSearchIcons.ICON_PACKAGE) {
191: ddiConsumer.addDocIndexItem(dii);
192: }
193: }
194: }
195: }
196:
197: public void go() {
198: rpTask = RequestProcessor.getDefault().post(this , 0,
199: Thread.NORM_PRIORITY);
200: }
201:
202: public void finish() {
203: if (!rpTask.isFinished() && !rpTask.cancel())
204: stopSearch();
205: taskFinished();
206: }
207:
208: public void taskFinished() {
209: ddiConsumer.indexSearchThreadFinished(this );
210: }
211:
212: /** Class for callback. Used to feed some container with found
213: * index items;
214: */
215:
216: public static interface DocIndexItemConsumer {
217:
218: /** Called when an item is found */
219: public void addDocIndexItem(DocIndexItem dii);
220:
221: /** Called when a task finished. May be called more than once */
222: public void indexSearchThreadFinished(IndexSearchThread ist);
223:
224: }
225:
226: }
|