KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openidex > search > SimpleSearchIterator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 2004 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.openidex.search;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.NoSuchElementException JavaDoc;
27 import org.openide.filesystems.FileObject;
28 import org.openide.loaders.DataFolder;
29 import org.openide.loaders.DataObject;
30
31 /**
32  *
33  * @author Marian Petras
34  */

35 class SimpleSearchIterator implements Iterator JavaDoc {
36
37     /** current enumeration of children */
38     private Enumeration JavaDoc childrenEnum;
39     /**
40      * filters to be applied on the current enumeration of children
41      * ({@link #childrenEnum})
42      */

43     private List JavaDoc filters;
44     /**
45      * contains either an equal copy of {@link #filters} or <code>null</code>
46      */

47     private List JavaDoc filtersCopy;
48     /** */
49     private final boolean recursive;
50     /** stack of the ancestor folders' children enumerations */
51     private final ArrayList JavaDoc enums = new ArrayList JavaDoc(); //unsynced stack
52
/**
53      * stack of filter lists to be applied on children of the ancestor folders
54      * ({@link #enums})
55      */

56     private final ArrayList JavaDoc filterLists = new ArrayList JavaDoc(); //unsynced stack
57
/** whether value of {@link #nextObject} is up-to-date */
58     private boolean upToDate = false;
59     /**
60      * <code>DataObject</code> to be returned the next time method
61      * {@link #next()} is called
62      */

63     private DataObject nextObject;
64
65     /**
66      */

67     SimpleSearchIterator(DataFolder folder,
68                          boolean recursive,
69                          List JavaDoc filters) {
70         this.childrenEnum = folder.children(false);
71         this.recursive = recursive;
72         this.filters = (filters != null) ? new ArrayList JavaDoc(filters)
73                                          : null;
74     }
75
76     /**
77      */

78     public boolean hasNext() {
79         if (!upToDate) {
80             update();
81         }
82         return nextObject != null;
83     }
84
85     /**
86      */

87     public Object JavaDoc next() {
88         if (!hasNext()) {
89             throw new NoSuchElementException JavaDoc();
90         }
91
92         upToDate = false;
93         return nextObject;
94     }
95
96     /**
97      */

98     private void update() {
99         assert upToDate == false;
100         assert childrenEnum != null;
101         do {
102             if (childrenEnum.hasMoreElements()) {
103                 Object JavaDoc next = childrenEnum.nextElement();
104                 DataObject dataObject = (DataObject) next;
105                 FileObject file = dataObject.getPrimaryFile();
106                 if (file.isFolder()) {
107                     if (!recursive) {
108                         continue;
109                     }
110                     
111                     if (filters != null) {
112                         final List JavaDoc subfolderFilters = checkFolderFilters(file);
113                         if (subfolderFilters == null) {
114                             continue;
115                         }
116                         
117                         filterLists.add(filters);
118                         if (subfolderFilters.size() != filters.size()) {
119                             filters = (!subfolderFilters.isEmpty())
120                                       ? subfolderFilters
121                                       : null;
122                         }
123                     } else {
124                         filterLists.add(null);
125                     }
126                     enums.add(childrenEnum);
127                     childrenEnum = ((DataFolder) dataObject).children(false);
128                 } else {
129                     if ((filters != null) && !checkFileFilters(file)) {
130                         continue;
131                     }
132                     
133                     nextObject = (DataObject) dataObject;
134                     break;
135                 }
136             } else {
137                 assert enums.isEmpty() == filterLists.isEmpty();
138                 
139                 nextObject = null;
140                 
141                 if (enums.isEmpty()) {
142                     childrenEnum = null;
143                     continue;
144                 }
145                 
146                 /* pop an element from the stack of children enumerations: */
147                 childrenEnum = (Enumeration JavaDoc) enums.remove(enums.size() - 1);
148                 
149                 /* pop an element from the stack of FileObjectFilters: */
150                 filters = (List JavaDoc) filterLists.remove(filterLists.size() - 1);
151                 if ((filtersCopy != null)
152                         && (filtersCopy.size() != filters.size())) {
153                     filtersCopy = null;
154                 }
155             }
156         } while (childrenEnum != null);
157         
158         upToDate = true;
159     }
160     
161     /**
162      * Computes a list of filters to be applied on the folder's children.
163      * The current list of filters is used as a base and then each filter
164      * is checked with the folder as a parameter.
165      * <p>
166      * If any of the filters returns <code>DO_NOT_TRAVERSE</code>,
167      * <code>the method returns <code>null</code> and no further filters
168      * are checked.
169      * If a filter returns <code>TRAVERSE_ALL_SUBFOLDERS</code>,
170      * the filter is removed from the base as it needs not be applied
171      * on the folder's children. The remaining list of filters is returned
172      * as a result.
173      *
174      * @param folder folder to compute children filters for
175      * @return list of filters to be applied on the folder's children;
176      * or <code>null</code> if the folder should not be traversed
177      */

178     private List JavaDoc checkFolderFilters(final FileObject folder) {
179         assert folder.isFolder();
180         assert filters != null;
181         
182         if (filtersCopy == null) {
183             filtersCopy = new ArrayList JavaDoc(filters);
184         }
185         
186         List JavaDoc result = filtersCopy;
187         cycle:
188         for (Iterator JavaDoc i = result.iterator(); i.hasNext(); ) {
189             FileObjectFilter filter = (FileObjectFilter) i.next();
190             final int traverseCommand = filter.traverseFolder(folder);
191             switch (traverseCommand) {
192                 case FileObjectFilter.TRAVERSE:
193                     break;
194                 case FileObjectFilter.DO_NOT_TRAVERSE:
195                     result = null;
196                     break cycle;
197                 case FileObjectFilter.TRAVERSE_ALL_SUBFOLDERS:
198                     i.remove();
199                     filtersCopy = null;
200                     break;
201                 default:
202                     assert false;
203                     break;
204             }
205         }
206         
207         return result;
208     }
209     
210     /**
211      * Checks whether the file passes all of the current
212      * {@link #filters}.
213      *
214      * @param file file to be checked
215      * @return <code>true</code> if the file passed all of the filters,
216      * <code>false</code> otherwise
217      */

218     private boolean checkFileFilters(FileObject file) {
219         assert file.isFolder() == false;
220         assert filters != null;
221         
222         for (Iterator JavaDoc i = filters.iterator(); i.hasNext(); ) {
223             FileObjectFilter filter = (FileObjectFilter) i.next();
224             if (!filter.searchFile(file)) {
225                 return false;
226             }
227         }
228         
229         return true;
230     }
231
232     /**
233      */

234     public void remove() {
235         throw new UnsupportedOperationException JavaDoc();
236     }
237     
238 }
239
Popular Tags