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.CharTokenizer;
21 import org.apache.lucene.analysis.SimpleAnalyzer;
22 import org.apache.lucene.analysis.TokenStream;
23 import org.apache.lucene.document.DateField;
24 import org.apache.lucene.document.Document;
25 import org.apache.lucene.document.Field;
26 import org.apache.maven.artifact.Artifact;
27 import org.apache.maven.artifact.repository.ArtifactRepository;
28 import org.apache.maven.repository.digest.Digester;
29 import org.codehaus.plexus.util.FileUtils;
30 import org.codehaus.plexus.util.IOUtil;
33 import java.io.FileInputStream;
34 import java.io.FileNotFoundException;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.io.Reader;
38 import java.security.NoSuchAlgorithmException;
39 import java.util.Enumeration;
40 import java.util.zip.ZipEntry;
41 import java.util.zip.ZipException;
42 import java.util.zip.ZipFile;
43 import java.util.zip.ZipOutputStream;
46 * @author Edwin Punzalan
48 public class EclipseRepositoryIndex
49 extends AbstractRepositoryIndex
51 private static final String JAR_NAME = "j";
53 private static final String JAR_SIZE = "s";
55 private static final String JAR_DATE = "d";
57 private static final String NAMES = "c";
59 private static final String MD5 = "m";
61 private Digester digester;
67 * @param indexPath the path where the lucene index will be created/updated.
68 * @param repository the repository where the indexed artifacts are located
69 * @param digester the digester object to generate the checksum strings
71 public EclipseRepositoryIndex( File indexPath, ArtifactRepository repository, Digester digester )
73 super( indexPath, repository );
75 this.digester = digester;
79 * @see AbstractRepositoryIndex#getAnalyzer()
81 public Analyzer getAnalyzer()
83 return new EclipseIndexAnalyzer( new SimpleAnalyzer() );
87 * Method to index a given artifact for use with the eclipse plugin
89 * @param artifact the Artifact object to be indexed
90 * @throws RepositoryIndexException
92 public void indexArtifact( Artifact artifact )
93 throws RepositoryIndexException
95 File artifactFile = artifact.getFile();
96 if ( artifactFile != null && artifactFile.getName().endsWith( ".jar" ) && artifactFile.exists() )
101 md5 = digester.createChecksum( artifactFile, "MD5" );
103 catch ( FileNotFoundException e )
105 throw new RepositoryIndexException( "Unable to compute checksum.", e );
107 catch ( NoSuchAlgorithmException e )
109 throw new RepositoryIndexException( "Unable to compute checksum.", e );
111 catch ( IOException e )
113 throw new RepositoryIndexException( "Unable to compute checksum.", e );
116 StringBuffer classes;
120 classes = new StringBuffer();
121 if ( "jar".equals( artifact.getType() ) )
123 ZipFile jar = new ZipFile( artifact.getFile() );
125 for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
127 ZipEntry entry = (ZipEntry) entries.nextElement();
128 addIfClassEntry( entry, classes );
132 catch ( ZipException e )
134 throw new RepositoryIndexException( "Error reading from artifact file: " + artifact.getFile(), e );
136 catch ( IOException e )
138 throw new RepositoryIndexException( "Error reading from artifact file", e );
141 Document doc = new Document();
142 doc.add( Field.Text( MD5, md5 ) );
143 doc.add( Field.Text( JAR_NAME, artifactFile.getName() ) );
144 doc.add( Field.Text( JAR_DATE, DateField.timeToString( artifactFile.lastModified() ) ) );
145 doc.add( Field.Text( JAR_SIZE, Long.toString( artifactFile.length() ) ) );
146 doc.add( Field.Text( NAMES, classes.toString() ) );
154 getIndexWriter().addDocument( doc );
156 catch ( IOException e )
158 throw new RepositoryIndexException( "Error opening index.", e );
164 * method to create an archived copy of the index contents
166 * @return File object to the archive
167 * @throws IOException
169 public File getCompressedCopy()
172 File indexPath = getIndexPath();
173 String name = indexPath.getName();
175 File outputFile = new File( indexPath.getParent(), name + ".zip" );
176 FileUtils.fileDelete( outputFile.getAbsolutePath() );
178 ZipOutputStream zos = new ZipOutputStream( new FileOutputStream( outputFile ) );
181 File[] files = indexPath.listFiles();
184 for ( int i = 0; i < files.length; i++ )
186 writeFile( zos, files[i] );
197 private static void writeFile( ZipOutputStream zos, File file )
200 ZipEntry e = new ZipEntry( file.getName() );
201 zos.putNextEntry( e );
203 FileInputStream is = new FileInputStream( file );
206 IOUtil.copy( is, zos );
218 * @see AbstractRepositoryIndex#deleteIfIndexed(Object)
220 public void deleteIfIndexed( Object object )
221 throws RepositoryIndexException, IOException
223 if ( object instanceof Artifact )
225 Artifact artifact = (Artifact) object;
228 validateIndex( FIELDS );
233 md5 = digester.createChecksum( artifact.getFile(), "MD5" );
235 catch ( FileNotFoundException e )
237 throw new RepositoryIndexException( "Unable to create index.", e );
239 catch ( NoSuchAlgorithmException e )
241 throw new RepositoryIndexException( "Unable to create index.", e );
243 catch ( IOException e )
245 throw new RepositoryIndexException( "Unable to create index.", e );
248 deleteDocument( MD5, md5 );
253 throw new RepositoryIndexException( "Object is not of type artifact." );
258 * Class used to analyze the lucene index
260 private static class EclipseIndexAnalyzer
263 private Analyzer defaultAnalyzer;
266 * constructor to for this analyzer
268 * @param defaultAnalyzer the analyzer to use as default for the general fields of the artifact indeces
270 EclipseIndexAnalyzer( Analyzer defaultAnalyzer )
272 this.defaultAnalyzer = defaultAnalyzer;
276 * Method called by lucence during indexing operations
278 * @param fieldName the field name that the lucene object is currently processing
279 * @param reader a Reader object to the index stream
280 * @return an analyzer to specific to the field name or the default analyzer if none is present
282 public TokenStream tokenStream( String fieldName, Reader reader )
284 TokenStream tokenStream;
286 if ( "s".equals( fieldName ) )
288 tokenStream = new EclipseIndexTokenizer( reader );
292 tokenStream = defaultAnalyzer.tokenStream( fieldName, reader );
300 * Class used to tokenize the eclipse index
302 private static class EclipseIndexTokenizer
303 extends CharTokenizer
306 * Constructor with the required reader to the index stream
308 * @param reader the Reader object of the index stream
310 EclipseIndexTokenizer( Reader reader )
316 * method that lucene calls to check tokenization of a stream character
318 * @param character char currently being processed
319 * @return true if the char is a token, false if the char is a stop char
321 protected boolean isTokenChar( char character )