1 package org.apache.maven.repository.indexing;
4 * Copyright 2001-2005 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
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.security.MessageDigest;
25 import java.security.NoSuchAlgorithmException;
26 import java.util.Collection;
27 import java.util.Enumeration;
28 import java.util.zip.ZipEntry;
29 import java.util.zip.ZipException;
30 import java.util.zip.ZipFile;
32 import org.apache.lucene.analysis.standard.StandardAnalyzer;
33 import org.apache.lucene.document.Document;
34 import org.apache.lucene.document.Field;
35 import org.apache.lucene.index.IndexReader;
36 import org.apache.lucene.index.IndexWriter;
38 import org.apache.maven.artifact.Artifact;
39 import org.apache.maven.artifact.repository.ArtifactRepository;
43 * @author Edwin Punzalan
45 public class ArtifactRepositoryIndexer
46 extends AbstractRepositoryIndexer
48 private static final String NAME = "name";
49 private static final String GROUPID = "groupId";
50 private static final String ARTIFACTID = "artifactId";
51 private static final String VERSION = "version";
52 private static final String SHA1 = "sha1";
53 private static final String MD5 = "md5";
54 private static final String CLASSES = "classes";
55 private static final String PACKAGES = "packages";
57 private static final String[] FIELDS = { NAME, GROUPID, ARTIFACTID, VERSION, SHA1, MD5, CLASSES, PACKAGES };
59 ArtifactRepository repository;
61 public ArtifactRepositoryIndexer( ArtifactRepository repository, String path )
62 throws RepositoryIndexerException
64 this.repository = repository;
69 public void addArtifactIndex( Artifact artifact )
70 throws RepositoryIndexerException
76 Document doc = new Document();
77 doc.add( Field.Text( NAME, repository.pathOf( artifact ) ) );
78 doc.add( Field.Text( GROUPID, artifact.getGroupId() ) );
79 doc.add( Field.Text( ARTIFACTID, artifact.getArtifactId() ) );
80 doc.add( Field.Text( VERSION, artifact.getVersion() ) );
81 doc.add( Field.Text( SHA1, getSha1( artifact ) ) );
82 doc.add( Field.Text( MD5, getMd5( artifact ) ) );
83 doc.add( Field.Text( CLASSES, getClasses( artifact ) ) );
84 doc.add( Field.Text( PACKAGES, getPackages( artifact ) ) );
85 indexWriter.addDocument( doc );
89 throw new RepositoryIndexerException( e );
93 public void optimize()
94 throws RepositoryIndexerException
98 indexWriter.optimize();
100 catch ( IOException ioe )
102 throw new RepositoryIndexerException( "Failed to optimize index", ioe );
106 private String getSha1( Artifact artifact )
107 throws FileNotFoundException, IOException, NoSuchAlgorithmException
109 FileInputStream fIn = new FileInputStream( artifact.getFile() );
110 return new String( getChecksum( fIn, "SHA-1" ) );
113 private String getMd5( Artifact artifact )
114 throws FileNotFoundException, IOException, NoSuchAlgorithmException
116 FileInputStream fIn = new FileInputStream( artifact.getFile() );
117 return new String( getChecksum( fIn, "MD5" ) );
120 private byte[] getChecksum( InputStream inStream, String algorithm )
121 throws IOException, NoSuchAlgorithmException
123 byte[] buffer = new byte[ 256 ];
124 MessageDigest complete = MessageDigest.getInstance( algorithm );
128 numRead = inStream.read( buffer );
131 complete.update( buffer, 0, numRead );
134 while ( numRead != -1 );
137 return complete.digest();
140 private String getClasses( Artifact artifact )
141 throws IOException, ZipException
143 StringBuffer sb = new StringBuffer();
145 ZipFile jar = new ZipFile( artifact.getFile() );
146 for( Enumeration en = jar.entries(); en.hasMoreElements(); )
148 ZipEntry e = ( ZipEntry ) en.nextElement();
149 String name = e.getName();
150 if( name.endsWith( ".class") )
152 // TODO verify if class is public or protected
153 // TODO skipp all inner classes for now
154 if( name.lastIndexOf( "$" ) == -1)
156 int idx = name.lastIndexOf( '/' );
157 if ( idx < 0 ) idx = 0;
158 sb.append( name.substring( idx, name.length() - 6 ) ).append( "\n" );
163 return sb.toString();
166 private String getPackages( Artifact artifact )
167 throws IOException, ZipException
169 StringBuffer sb = new StringBuffer();
171 ZipFile jar = new ZipFile( artifact.getFile() );
172 for( Enumeration en = jar.entries(); en.hasMoreElements(); )
174 ZipEntry e = ( ZipEntry ) en.nextElement();
175 String name = e.getName();
176 //only include packages with accompanying classes
177 if ( name.endsWith( ".class" ) )
179 int idx = name.lastIndexOf( '/' );
182 String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
183 if ( sb.indexOf( packageName ) < 0 )
185 sb.append( packageName ).append( "\n" );
191 return sb.toString();
194 private void validateIndex()
195 throws RepositoryIndexerException
200 Collection fields = indexReader.getFieldNames();
201 for( int idx=0; idx<FIELDS.length; idx++ )
203 if ( !fields.contains( FIELDS[ idx ] ) )
205 throw new RepositoryIndexerException( "The Field " + FIELDS[ idx ] + " does not exist in index path " +
210 catch ( IOException e )
212 throw new RepositoryIndexerException( e );