1 package org.apache.maven.repository.indexing;
4 * Copyright 2005-2006 The Apache Software Foundation.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 import org.apache.lucene.analysis.Analyzer;
20 import org.apache.lucene.analysis.SimpleAnalyzer;
21 import org.apache.lucene.analysis.TokenStream;
22 import org.apache.lucene.analysis.CharTokenizer;
23 import org.apache.lucene.index.IndexReader;
24 import org.apache.lucene.index.IndexWriter;
25 import org.apache.lucene.index.Term;
26 import org.apache.maven.artifact.repository.ArtifactRepository;
29 import java.io.IOException;
30 import java.io.Reader;
31 import java.util.Collection;
34 * Abstract class for RepositoryIndexers
36 * @author Edwin Punzalan
38 public abstract class AbstractRepositoryIndex
39 implements RepositoryIndex
41 private String indexPath;
43 private boolean indexOpen;
45 private IndexWriter indexWriter;
47 protected ArtifactRepository repository;
49 private Analyzer analyzer;
56 * @throws RepositoryIndexException
58 protected AbstractRepositoryIndex( String indexPath, ArtifactRepository repository )
59 throws RepositoryIndexException
61 this.repository = repository;
62 this.indexPath = indexPath;
66 * Method to open the IndexWriter
68 * @throws RepositoryIndexException
71 throws RepositoryIndexException
77 indexWriter = new IndexWriter( indexPath, getAnalyzer(), false );
81 indexWriter = new IndexWriter( indexPath, getAnalyzer(), true );
84 catch ( IOException ie )
86 throw new RepositoryIndexException( ie );
92 * @see org.apache.maven.repository.indexing.RepositoryIndex#optimize()
94 public void optimize()
95 throws RepositoryIndexException
99 throw new RepositoryIndexException( "Unable to optimize index on a closed index" );
104 indexWriter.optimize();
106 catch ( IOException ioe )
108 throw new RepositoryIndexException( "Failed to optimize index", ioe );
113 * @see org.apache.maven.repository.indexing.RepositoryIndex#isOpen()
115 public boolean isOpen()
121 * @see org.apache.maven.repository.indexing.RepositoryIndex#close()
124 throws RepositoryIndexException
128 if ( indexWriter != null )
136 catch ( IOException e )
138 throw new RepositoryIndexException( e.getMessage(), e );
143 * @see org.apache.maven.repository.indexing.RepositoryIndex#getIndexPath()
145 public String getIndexPath()
151 * Method to retrieve the lucene IndexWriter used in creating/updating the index
153 * @return the lucene IndexWriter object used to update the index
154 * @throws IOException
156 protected IndexWriter getIndexWriter()
159 if ( indexWriter == null )
161 indexWriter = new IndexWriter( indexPath, getAnalyzer(), false );
167 * method for validating an index directory
170 * @throws RepositoryIndexException if the given indexPath is not valid for this type of RepositoryIndex
172 protected void validateIndex( String[] indexFields )
173 throws RepositoryIndexException, IOException
175 IndexReader indexReader = IndexReader.open( indexPath );
178 if ( indexReader.numDocs() > 0 )
180 Collection fields = indexReader.getFieldNames();
181 for ( int idx = 0; idx < indexFields.length; idx++ )
183 if ( !fields.contains( indexFields[idx] ) )
185 throw new RepositoryIndexException(
186 "The Field " + indexFields[idx] + " does not exist in index " + indexPath + "." );
198 * @see org.apache.maven.repository.indexing.RepositoryIndex#getRepository()
200 public ArtifactRepository getRepository()
206 * Delete the document(s) that contains the specified value on the specified field.
210 * @throws RepositoryIndexException
211 * @throws IOException
213 protected void deleteDocument( String field, String value )
214 throws RepositoryIndexException, IOException
216 IndexReader indexReader = null;
219 indexReader = IndexReader.open( indexPath );
220 indexReader.delete( new Term( field, value ) );
222 catch ( IOException ie )
224 throw new RepositoryIndexException( indexPath + "is not a valid directory." );
228 if ( indexReader != null )
236 * Check if the index already exists.
238 * @return true if the index already exists
239 * @throws IOException
240 * @throws RepositoryIndexException
242 protected boolean indexExists()
243 throws IOException, RepositoryIndexException
245 File indexDir = new File( indexPath );
247 if ( IndexReader.indexExists( indexDir ) )
251 else if ( !indexDir.exists() )
255 else if ( indexDir.isDirectory() )
257 throw new RepositoryIndexException( indexPath + " is not a valid index directory." );
261 throw new RepositoryIndexException( indexPath + " is not a directory." );
266 * Checks if the object has already been indexed and deletes it if it is.
268 * @param object the object to be indexed.
269 * @throws RepositoryIndexException
270 * @throws IOException
272 abstract void deleteIfIndexed( Object object )
273 throws RepositoryIndexException, IOException;
276 * @see org.apache.maven.repository.indexing.RepositoryIndex#getAnalyzer()
278 public Analyzer getAnalyzer()
280 if ( analyzer == null )
282 analyzer = new ArtifactRepositoryIndexAnalyzer( new SimpleAnalyzer() );
289 * @see RepositoryIndex#isKeywordField(String)
291 public boolean isKeywordField( String field )
293 return KEYWORD_FIELDS.contains( field );
296 private class ArtifactRepositoryIndexAnalyzer
299 private Analyzer defaultAnalyzer;
302 * constructor to for this analyzer
304 * @param defaultAnalyzer the analyzer to use as default for the general fields of the artifact indeces
306 public ArtifactRepositoryIndexAnalyzer( Analyzer defaultAnalyzer )
308 this.defaultAnalyzer = defaultAnalyzer;
312 * Method called by lucence during indexing operations
314 * @param fieldName the field name that the lucene object is currently processing
315 * @param reader a Reader object to the index stream
316 * @return an analyzer to specific to the field name or the default analyzer if none is present
318 public TokenStream tokenStream( String fieldName, Reader reader )
320 TokenStream tokenStream;
322 if ( RepositoryIndex.FLD_VERSION.equals( fieldName ) || RepositoryIndex.FLD_LASTUPDATE.equals( fieldName ) )
324 tokenStream = new VersionTokenizer( reader );
328 tokenStream = defaultAnalyzer.tokenStream( fieldName, reader );
335 * Class used to tokenize an artifact's version.
337 private class VersionTokenizer
338 extends CharTokenizer
341 * Constructor with the required reader to the index stream
343 * @param reader the Reader object of the index stream
345 VersionTokenizer( Reader reader )
351 * method that lucene calls to check tokenization of a stream character
353 * @param character char currently being processed
354 * @return true if the char is a token, false if the char is a stop char
356 protected boolean isTokenChar( char character )
358 return character != '.' && character != '-';