KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > source > usages > LuceneIndex


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 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.java.source.usages;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.text.ParseException JavaDoc;
25 import java.util.Comparator JavaDoc;
26 import java.util.EnumSet JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.LinkedList JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Set JavaDoc;
33 import java.util.TreeSet JavaDoc;
34 import java.util.concurrent.atomic.AtomicBoolean JavaDoc;
35 import java.util.logging.Logger JavaDoc;
36 import java.util.regex.Matcher JavaDoc;
37 import java.util.regex.Pattern JavaDoc;
38 import javax.lang.model.element.ElementKind;
39 import org.apache.lucene.analysis.KeywordAnalyzer;
40 import org.apache.lucene.document.Document;
41 import org.apache.lucene.index.IndexReader;
42 import org.apache.lucene.index.IndexWriter;
43 import org.apache.lucene.index.Term;
44 import org.apache.lucene.index.TermDocs;
45 import org.apache.lucene.index.TermEnum;
46 import org.apache.lucene.search.BooleanClause.Occur;
47 import org.apache.lucene.search.BooleanQuery;
48 import org.apache.lucene.search.BooleanQuery;
49 import org.apache.lucene.search.Hit;
50 import org.apache.lucene.search.Hits;
51 import org.apache.lucene.search.IndexSearcher;
52 import org.apache.lucene.search.Searcher;
53 import org.apache.lucene.search.Query;
54 import org.apache.lucene.search.TermQuery;
55 import org.apache.lucene.search.WildcardQuery;
56 import org.apache.lucene.store.Directory;
57 import org.apache.lucene.store.FSDirectory;
58 import org.apache.lucene.store.RAMDirectory;
59 import org.netbeans.api.java.source.ClassIndex;
60 import org.netbeans.modules.java.source.usages.LuceneIndexMBeanImpl;
61 import org.netbeans.modules.java.source.util.LowMemoryEvent;
62 import org.netbeans.modules.java.source.util.LowMemoryListener;
63 import org.netbeans.modules.java.source.util.LowMemoryNotifier;
64
65 /**
66  *
67  * @author Tomas Zezula
68  */

69 class LuceneIndex extends Index {
70     
71     private static final boolean debugIndexMerging = Boolean.getBoolean("LuceneIndex.debugIndexMerge"); // NOI18N
72
private static final String JavaDoc REFERENCES = "refs"; // NOI18N
73

74     private static final Logger JavaDoc LOGGER = Logger.getLogger(LuceneIndex.class.getName());
75     
76     private final Directory directory;
77     private Long JavaDoc rootTimeStamp;
78     
79     private IndexReader reader; //Cache, do not use this dirrectly, use getReader
80
private IndexWriter writer; //Cache, do not use this dirrectly, use getWriter
81
private Set JavaDoc<String JavaDoc> rootPkgCache; //Cache, do not use this dirrectly
82

83     public static Index create (final File JavaDoc cacheRoot) throws IOException JavaDoc {
84         assert cacheRoot != null && cacheRoot.exists() && cacheRoot.canRead() && cacheRoot.canWrite();
85         return new LuceneIndex (getReferencesCacheFolder(cacheRoot));
86     }
87     
88     /** Creates a new instance of LuceneIndex */
89     private LuceneIndex (final File JavaDoc refCacheRoot) throws IOException JavaDoc {
90         assert refCacheRoot != null;
91         this.directory = FSDirectory.getDirectory(refCacheRoot, false);
92     }
93
94     @SuppressWarnings JavaDoc("unchecked") // NOI18N, unchecked - lucene has source 1.4
95
public List JavaDoc<String JavaDoc> getUsagesData(final String JavaDoc resourceName, Set JavaDoc<ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException JavaDoc {
96         if (!isValid(false)) {
97             return null;
98         }
99         final Searcher searcher = new IndexSearcher (this.getReader());
100         try {
101             final List JavaDoc<String JavaDoc> result = new LinkedList JavaDoc<String JavaDoc> ();
102             Query query = null;
103             if (mask == null) {
104                 query = new WildcardQuery(DocumentUtil.referencesTerm (resourceName,null));
105             }
106             else {
107                 assert operator != null;
108                 switch (operator) {
109                     case AND:
110                         query = new WildcardQuery(DocumentUtil.referencesTerm (resourceName, mask));
111                         break;
112                     case OR:
113                         BooleanQuery booleanQuery = new BooleanQuery ();
114                         for (ClassIndexImpl.UsageType ut : mask) {
115                             final Query subQuery = new WildcardQuery(DocumentUtil.referencesTerm (resourceName, EnumSet.of(ut)));
116                             booleanQuery.add(subQuery, Occur.SHOULD);
117                         }
118                         query = booleanQuery;
119                         break;
120                     default:
121                         throw new IllegalArgumentException JavaDoc (operator.toString());
122                 }
123             }
124             assert query != null;
125             final Hits hits = searcher.search (query);
126             for (Iterator JavaDoc<Hit> it = (Iterator JavaDoc<Hit>) hits.iterator(); it.hasNext();) {
127                 final Hit hit = it.next ();
128                 final Document doc = hit.getDocument();
129                 final String JavaDoc user = DocumentUtil.getBinaryName(doc);
130                 final String JavaDoc map = DocumentUtil.getRefereneType(doc,resourceName);
131                 if (map != null) {
132                     result.add (DocumentUtil.encodeUsage(user,map));
133                 }
134             }
135             return result;
136         } finally {
137             searcher.close();
138         }
139     }
140
141     @SuppressWarnings JavaDoc ("unchecked") // NOI18N, unchecked - lucene has source 1.4
142
public List JavaDoc<String JavaDoc> getUsagesFQN(final String JavaDoc resourceName, final Set JavaDoc<ClassIndexImpl.UsageType>mask, final BooleanOperator operator) throws IOException JavaDoc {
143         if (!isValid(false)) {
144             return null;
145         }
146         assert resourceName != null;
147         assert mask != null;
148         assert operator != null;
149         final Searcher searcher = new IndexSearcher (this.getReader());
150         Query query;
151         try {
152             final List JavaDoc<String JavaDoc> result = new LinkedList JavaDoc<String JavaDoc> ();
153             switch (operator) {
154                 case AND:
155                     query = new WildcardQuery(DocumentUtil.referencesTerm (resourceName, mask));
156                     break;
157                 case OR:
158                     BooleanQuery booleanQuery = new BooleanQuery ();
159                     for (ClassIndexImpl.UsageType ut : mask) {
160                         final Query subQuery = new WildcardQuery(DocumentUtil.referencesTerm (resourceName, EnumSet.of(ut)));
161                         booleanQuery.add(subQuery, Occur.SHOULD);
162                     }
163                     query = booleanQuery;
164                     break;
165                 default:
166                     throw new IllegalArgumentException JavaDoc (operator.toString());
167             }
168             final Hits hits = searcher.search (query);
169             for (Iterator JavaDoc<Hit> it = (Iterator JavaDoc<Hit>) hits.iterator(); it.hasNext();) {
170                 final Hit hit = it.next ();
171                 final Document doc = hit.getDocument();
172                 final String JavaDoc user = DocumentUtil.getBinaryName(doc);
173                 result.add (user);
174             }
175             return result;
176         } finally {
177             searcher.close();
178         }
179     }
180
181     public List JavaDoc<String JavaDoc> getReferencesData(final String JavaDoc resourceName) throws IOException JavaDoc {
182         if (!isValid(false)) {
183             return null;
184         }
185         Searcher searcher = new IndexSearcher (this.getReader());
186         try {
187             Hits hits = searcher.search(DocumentUtil.binaryNameQuery(resourceName));
188             assert hits.length() <= 1;
189             if (hits.length() == 0) {
190                 return null;
191             }
192             else {
193                 Hit hit = (Hit) hits.iterator().next();
194                 return DocumentUtil.getReferences(hit.getDocument());
195             }
196         }
197         finally {
198             searcher.close();
199         }
200     }
201         
202     @SuppressWarnings JavaDoc ("unchecked") // NOI18N, unchecked - lucene has source 1.4
203
public <T> void getDeclaredTypes (final String JavaDoc name, final ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set JavaDoc<? super T> result) throws IOException JavaDoc {
204         if (!isValid(false)) {
205             LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
206             return;
207         }
208         assert name != null;
209         final Set JavaDoc<Term> toSearch = new TreeSet JavaDoc<Term> (new Comparator JavaDoc<Term>(){
210             public int compare (Term t1, Term t2) {
211                 int ret = t1.field().compareTo(t2.field());
212                 if (ret == 0) {
213                     ret = t1.text().compareTo(t2.text());
214                 }
215                 return ret;
216             }
217         });
218         final IndexReader in = getReader();
219         switch (kind) {
220             case SIMPLE_NAME:
221                 {
222                     toSearch.add(DocumentUtil.simpleNameTerm(name));
223                     break;
224                 }
225             case PREFIX:
226                 if (name.length() == 0) {
227                     //Special case (all) handle in different way
228
emptyPrefixSearch(in, convertor, result);
229                     return;
230                 }
231                 else {
232                     final Term nameTerm = DocumentUtil.simpleNameTerm(name);
233                     prefixSearh(nameTerm, in, toSearch);
234                     break;
235                 }
236             case CASE_INSENSITIVE_PREFIX:
237                 if (name.length() == 0) {
238                     //Special case (all) handle in different way
239
emptyPrefixSearch(in, convertor, result);
240                     return;
241                 }
242                 else {
243                     final Term nameTerm = DocumentUtil.caseInsensitiveNameTerm(name.toLowerCase()); //XXX: I18N, Locale
244
prefixSearh(nameTerm, in, toSearch);
245                     break;
246                 }
247             case CAMEL_CASE:
248                 if (name.length() == 0) {
249                     throw new IllegalArgumentException JavaDoc ();
250                 }
251                 {
252                 final StringBuilder JavaDoc patternString = new StringBuilder JavaDoc ();
253                 char startChar = 0;
254                 for (int i=0; i<name.length(); i++) {
255                     char c = name.charAt(i);
256                     //todo: maybe check for upper case, I18N????
257
if (i == 0) {
258                         startChar = c;
259                     }
260                     patternString.append(c);
261                     if (i == name.length()-1) {
262                         patternString.append("\\w*"); // NOI18N
263
}
264                     else {
265                         patternString.append("[\\p{Lower}\\p{Digit}]*"); // NOI18N
266
}
267                 }
268                 final Pattern JavaDoc pattern = Pattern.compile(patternString.toString());
269                 regExpSearch(pattern,DocumentUtil.simpleNameTerm(Character.toString(startChar)),in,toSearch);
270                 break;
271                 }
272             case CASE_INSENSITIVE_REGEXP:
273                 if (name.length() == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) {
274                     throw new IllegalArgumentException JavaDoc ();
275                 }
276                 {
277                     final Pattern JavaDoc pattern = Pattern.compile(name,Pattern.CASE_INSENSITIVE);
278                     regExpSearch(pattern, DocumentUtil.caseInsensitiveNameTerm(name.toLowerCase()), in, toSearch); //XXX: Locale
279
break;
280                 }
281             case REGEXP:
282                 if (name.length() == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) {
283                     throw new IllegalArgumentException JavaDoc ();
284                 }
285                 {
286                     final Pattern JavaDoc pattern = Pattern.compile(name);
287                     regExpSearch(pattern, DocumentUtil.simpleNameTerm(name), in, toSearch);
288                     break;
289                 }
290             default:
291                 throw new UnsupportedOperationException JavaDoc (kind.toString());
292         }
293         TermDocs tds = in.termDocs();
294         LOGGER.fine(String.format("LuceneIndex.getDeclaredTypes[%s] returned %d elements\n",this.toString(), toSearch.size()));
295         final Iterator JavaDoc<Term> it = toSearch.iterator();
296         final ElementKind[] kindHolder = new ElementKind[1];
297         Set JavaDoc<Integer JavaDoc> docNums = new TreeSet JavaDoc<Integer JavaDoc>();
298         while (it.hasNext()) {
299             tds.seek(it.next());
300             while (tds.next()) {
301                 docNums.add (tds.doc());
302             }
303         }
304         for (Integer JavaDoc docNum : docNums) {
305             final Document doc = in.document(docNum);
306             final String JavaDoc binaryName = DocumentUtil.getBinaryName(doc, kindHolder);
307             result.add (convertor.convert(kindHolder[0],binaryName));
308         }
309     }
310     
311     private void regExpSearch (final Pattern JavaDoc pattern, final Term startTerm, final IndexReader in, final Set JavaDoc<Term> toSearch) throws IOException JavaDoc {
312         final String JavaDoc startText = startTerm.text();
313         final StringBuilder JavaDoc startBuilder = new StringBuilder JavaDoc ();
314         startBuilder.append(startText.charAt(0));
315         for (int i=1; i<startText.length(); i++) {
316             char c = startText.charAt(i);
317             if (!Character.isJavaIdentifierPart(c)) {
318                 break;
319             }
320             startBuilder.append(c);
321         }
322         final String JavaDoc startPrefix = startBuilder.toString();
323         final String JavaDoc camelField = startTerm.field();
324         final TermEnum en = in.terms(startTerm);
325         try {
326             do {
327                 Term term = en.term();
328                 if (term != null && camelField == term.field() && term.text().startsWith(startPrefix)) {
329                     final Matcher JavaDoc m = pattern.matcher(term.text());
330                     if (m.matches()) {
331                         toSearch.add (term);
332                     }
333                 }
334                 else {
335                     break;
336                 }
337             } while (en.next());
338         } finally {
339             en.close();
340         }
341     }
342     
343     private <T> void emptyPrefixSearch (final IndexReader in, final ResultConvertor<T> convertor, final Set JavaDoc<? super T> result) throws IOException JavaDoc {
344         final int bound = in.maxDoc();
345         final ElementKind[] kindHolder = new ElementKind[1];
346         for (int i=0; i<bound; i++) {
347             if (!in.isDeleted(i)) {
348                 final Document doc = in.document(i);
349                 if (doc != null) {
350                     String JavaDoc binaryName = DocumentUtil.getBinaryName (doc, kindHolder);
351                     if (binaryName == null) {
352                         //Root timestamp document
353
continue;
354                     }
355                     else {
356                         result.add (convertor.convert(kindHolder[0],binaryName));
357                     }
358                 }
359             }
360         }
361     }
362     
363     private void prefixSearh (Term nameTerm, final IndexReader in, final Set JavaDoc<Term> toSearch) throws IOException JavaDoc {
364         final String JavaDoc prefixField = nameTerm.field();
365         final String JavaDoc name = nameTerm.text();
366         final TermEnum en = in.terms(nameTerm);
367         try {
368             do {
369                 Term term = en.term();
370                 if (term != null && prefixField == term.field() && term.text().startsWith(name)) {
371                     toSearch.add (term);
372                 }
373                 else {
374                     break;
375                 }
376             } while (en.next());
377         } finally {
378             en.close();
379         }
380     }
381     
382     
383     public void getPackageNames (final String JavaDoc prefix, final boolean directOnly, final Set JavaDoc<String JavaDoc> result) throws IOException JavaDoc {
384         if (!isValid(false)) {
385             return;
386         }
387         final IndexReader in = getReader();
388         final Term pkgTerm = DocumentUtil.packageNameTerm (prefix);
389         final String JavaDoc prefixField = pkgTerm.field();
390         if (prefix.length() == 0) {
391             if (directOnly && this.rootPkgCache != null) {
392                 result.addAll(this.rootPkgCache);
393             }
394             else {
395                 if (directOnly) {
396                     this.rootPkgCache = new HashSet JavaDoc<String JavaDoc>();
397                 }
398                 final TermEnum terms = in.terms ();
399                 try {
400                     do {
401                         final Term currentTerm = terms.term();
402                         if (currentTerm != null && prefixField == currentTerm.field()) {
403                             String JavaDoc pkgName = currentTerm.text();
404                             if (directOnly) {
405                                 int index = pkgName.indexOf('.',prefix.length());
406                                 if (index>0) {
407                                     pkgName = pkgName.substring(0,index);
408                                 }
409                                 this.rootPkgCache.add(pkgName);
410                             }
411                             result.add(pkgName);
412                         }
413                     } while (terms.next());
414                 } finally {
415                     terms.close();
416                 }
417             }
418         }
419         else {
420             final TermEnum terms = in.terms (pkgTerm);
421             try {
422                 do {
423                     final Term currentTerm = terms.term();
424                     if (currentTerm != null && prefixField == currentTerm.field() && currentTerm.text().startsWith(prefix)) {
425                         String JavaDoc pkgName = currentTerm.text();
426                         if (directOnly) {
427                             int index = pkgName.indexOf('.',prefix.length());
428                             if (index>0) {
429                                 pkgName = pkgName.substring(0,index);
430                             }
431                         }
432                         result.add(pkgName);
433                     }
434                     else {
435                         break;
436                     }
437                 } while (terms.next());
438             } finally {
439                 terms.close();
440             }
441         }
442     }
443
444     public boolean isUpToDate(String JavaDoc resourceName, long timeStamp) throws IOException JavaDoc {
445         if (!isValid(false)) {
446             return false;
447         }
448         try {
449             Searcher searcher = new IndexSearcher (this.getReader());
450             try {
451                 Hits hits;
452                 if (resourceName == null) {
453                     synchronized (this) {
454                         if (this.rootTimeStamp != null) {
455                             return rootTimeStamp.longValue() >= timeStamp;
456                         }
457                     }
458                     hits = searcher.search(new TermQuery(DocumentUtil.rootDocumentTerm()));
459                 }
460                 else {
461                     hits = searcher.search(DocumentUtil.binaryNameQuery(resourceName));
462                 }
463
464                 assert hits.length() <= 1;
465                 if (hits.length() == 0) {
466                     return false;
467                 }
468                 else {
469                     try {
470                         Hit hit = (Hit) hits.iterator().next();
471                         long cacheTime = DocumentUtil.getTimeStamp(hit.getDocument());
472                         if (resourceName == null) {
473                             synchronized (this) {
474                                 this.rootTimeStamp = new Long JavaDoc (cacheTime);
475                             }
476                         }
477                         return cacheTime >= timeStamp;
478                     } catch (ParseException JavaDoc pe) {
479                         throw new IOException JavaDoc ();
480                     }
481                 }
482             } finally {
483                 searcher.close();
484             }
485         } catch (java.io.FileNotFoundException JavaDoc fnf) {
486             this.clear();
487             return false;
488         }
489     }
490     
491     public void store (final Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>> refs, final List JavaDoc<String JavaDoc> topLevels) throws IOException JavaDoc {
492         this.rootPkgCache = null;
493         boolean create = !isValid (false);
494         long timeStamp = System.currentTimeMillis();
495         if (!create) {
496             IndexReader in = getReader();
497             final Searcher searcher = new IndexSearcher (in);
498             try {
499                 for (String JavaDoc topLevel : topLevels) {
500                     Hits hits = searcher.search(DocumentUtil.binaryContentNameQuery(topLevel));
501                     for (int i=0; i<hits.length(); i++) {
502                         in.deleteDocument (hits.id(i));
503                     }
504                 }
505                 in.deleteDocuments (DocumentUtil.rootDocumentTerm());
506             } finally {
507                 searcher.close();
508             }
509         }
510         storeData(refs, create, timeStamp);
511     }
512
513     public void store(final Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>> refs, final Set JavaDoc<String JavaDoc> toDelete) throws IOException JavaDoc {
514         this.rootPkgCache = null;
515         boolean create = !isValid (false);
516         long timeStamp = System.currentTimeMillis();
517         if (!create) {
518             IndexReader in = getReader();
519             final Searcher searcher = new IndexSearcher (in);
520             try {
521                 for (String JavaDoc toDeleteItem : toDelete) {
522                     Hits hits = searcher.search(DocumentUtil.binaryNameQuery(toDeleteItem));
523 // Disabled assertion until the signature file links are integrated
524
// assert hits.length() <=1 : "Multiple index entries for binaryName: " + toDeleteItem; //NOI18N
525
if (hits.length()>1) {
526                         java.util.logging.Logger.getLogger("global").warning("Multiple index entries for binaryName: " + toDeleteItem); //NOI18N
527
}
528                     for (int i=0; i<hits.length(); i++) {
529                         in.deleteDocument (hits.id(i));
530                     }
531                 }
532                 in.deleteDocuments (DocumentUtil.rootDocumentTerm());
533             } finally {
534                 searcher.close();
535             }
536         }
537         storeData(refs, create, timeStamp);
538     }
539     
540     private void storeData (final Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>> refs, final boolean create, final long timeStamp) throws IOException JavaDoc {
541         IndexWriter out = getWriter(create);
542         if (debugIndexMerging) {
543             out.setInfoStream (System.err);
544         }
545         final LuceneIndexMBean indexSettings = LuceneIndexMBeanImpl.getDefault();
546         if (indexSettings != null) {
547             out.setMergeFactor(indexSettings.getMergeFactor());
548             out.setMaxMergeDocs(indexSettings.getMaxMergeDocs());
549             out.setMaxBufferedDocs(indexSettings.getMaxBufferedDocs());
550         }
551         LowMemoryNotifier lm = LowMemoryNotifier.getDefault();
552         LMListener lmListener = new LMListener ();
553         lm.addLowMemoryListener (lmListener);
554         Directory memDir = null;
555         IndexWriter activeOut = null;
556         if (lmListener.lowMemory.getAndSet(false)) {
557             activeOut = out;
558         }
559         else {
560             memDir = new RAMDirectory ();
561             activeOut = new IndexWriter (memDir,new KeywordAnalyzer(), true);
562         }
563         try {
564             activeOut.addDocument (DocumentUtil.createRootTimeStampDocument (timeStamp));
565             for (Iterator JavaDoc<Map.Entry JavaDoc<String JavaDoc,List JavaDoc<String JavaDoc>>> it = refs.entrySet().iterator(); it.hasNext();) {
566                 Map.Entry JavaDoc<String JavaDoc,List JavaDoc<String JavaDoc>> refsEntry = it.next();
567                 it.remove();
568                 String JavaDoc cn = refsEntry.getKey();
569                 List JavaDoc<String JavaDoc> cr = refsEntry.getValue();
570                 Document newDoc = DocumentUtil.createDocument(cn,timeStamp,cr);
571                 activeOut.addDocument(newDoc);
572                 if (memDir != null && lmListener.lowMemory.getAndSet(false)) {
573                     activeOut.close();
574                     out.addIndexes(new Directory[] {memDir});
575                     memDir = new RAMDirectory ();
576                     activeOut = new IndexWriter (memDir,new KeywordAnalyzer(), true);
577                 }
578             }
579             if (memDir != null) {
580                 activeOut.close();
581                 out.addIndexes(new Directory[] {memDir});
582                 activeOut = null;
583                 memDir = null;
584             }
585             synchronized (this) {
586                 this.rootTimeStamp = new Long JavaDoc (timeStamp);
587             }
588         } finally {
589             lm.removeLowMemoryListener (lmListener);
590         }
591     }
592
593     public boolean isValid (boolean tryOpen) throws IOException JavaDoc {
594         boolean res = IndexReader.indexExists(this.directory);
595         if (res && tryOpen) {
596             try {
597                 getReader();
598             } catch (java.io.FileNotFoundException JavaDoc e) {
599                 res = false;
600                 clear();
601             }
602         }
603         return res;
604     }
605     
606     public synchronized void clear () throws IOException JavaDoc {
607         this.close ();
608         final String JavaDoc[] content = this.directory.list();
609         for (String JavaDoc file : content) {
610             directory.deleteFile(file);
611         }
612     }
613     
614     public synchronized void close () throws IOException JavaDoc {
615         if (this.reader != null) {
616             this.reader.close();
617             this.reader = null;
618         }
619         if (this.writer != null) {
620             this.writer.close();
621             this.writer = null;
622         }
623     }
624     
625     public @Override JavaDoc String JavaDoc toString () {
626         return this.directory.toString();
627     }
628     
629     private synchronized IndexReader getReader () throws IOException JavaDoc {
630         if (this.reader == null) {
631             if (this.writer != null) {
632                 this.writer.close();
633                 this.writer = null;
634             }
635             this.reader = IndexReader.open(this.directory);
636         }
637         return this.reader;
638     }
639     
640     private synchronized IndexWriter getWriter (final boolean create) throws IOException JavaDoc {
641         if (this.writer == null) {
642             if (this.reader != null) {
643                 this.reader.close();
644                 this.reader = null;
645             }
646             this.writer = new IndexWriter (this.directory,new KeywordAnalyzer(), create);
647         }
648         return this.writer;
649     }
650     
651     
652     private static File JavaDoc getReferencesCacheFolder (final File JavaDoc cacheRoot) throws IOException JavaDoc {
653         File JavaDoc refRoot = new File JavaDoc (cacheRoot,REFERENCES);
654         if (!refRoot.exists()) {
655             refRoot.mkdir();
656         }
657         return refRoot;
658     }
659     
660     private static class LMListener implements LowMemoryListener {
661         
662         private AtomicBoolean JavaDoc lowMemory = new AtomicBoolean JavaDoc (false);
663         
664         public void lowMemory(LowMemoryEvent event) {
665             lowMemory.set(true);
666         }
667     }
668     
669 }
670
Popular Tags