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.
21 import java.io.FileInputStream;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.security.MessageDigest;
26 import java.security.NoSuchAlgorithmException;
27 import java.util.Collection;
28 import java.util.Enumeration;
29 import java.util.zip.ZipEntry;
30 import java.util.zip.ZipException;
31 import java.util.zip.ZipFile;
33 import org.apache.lucene.document.Document;
34 import org.apache.lucene.document.Field;
36 import org.apache.maven.artifact.Artifact;
37 import org.apache.maven.artifact.repository.ArtifactRepository;
41 * @author Edwin Punzalan
43 public class ArtifactRepositoryIndexer
44 extends AbstractRepositoryIndexer
46 private static final String NAME = "name";
47 private static final String GROUPID = "groupId";
48 private static final String ARTIFACTID = "artifactId";
49 private static final String VERSION = "version";
50 private static final String SHA1 = "sha1";
51 private static final String MD5 = "md5";
52 private static final String CLASSES = "classes";
53 private static final String PACKAGES = "packages";
54 private static final String FILES = "files";
56 private static final String[] FIELDS = { NAME, GROUPID, ARTIFACTID, VERSION, SHA1, MD5,
57 CLASSES, PACKAGES, FILES };
59 private ArtifactRepository repository;
61 private StringBuffer classes;
62 private StringBuffer packages;
63 private StringBuffer files;
65 public ArtifactRepositoryIndexer( ArtifactRepository repository, String path )
66 throws RepositoryIndexerException
68 this.repository = repository;
73 public String[] getIndexFields()
78 public void addObjectIndex(Object obj)
79 throws RepositoryIndexerException
81 if ( obj instanceof Artifact )
83 addArtifactIndex( (Artifact) obj );
87 throw new RepositoryIndexerException( "This instance of indexer cannot index instances of " +
88 obj.getClass().getName() );
92 public void addArtifactIndex( Artifact artifact )
93 throws RepositoryIndexerException
97 throw new RepositoryIndexerException( "Unable to add artifact index on a closed index" );
105 processArtifactContents( artifact.getFile() );
107 //@todo should some of these fields be Keyword instead of Text ?
108 Document doc = new Document();
109 doc.add( Field.Text( NAME, repository.pathOf( artifact ) ) );
110 doc.add( Field.Text( GROUPID, artifact.getGroupId() ) );
111 doc.add( Field.Text( ARTIFACTID, artifact.getArtifactId() ) );
112 doc.add( Field.Text( VERSION, artifact.getVersion() ) );
113 doc.add( Field.Text( SHA1, getSha1( artifact ) ) );
114 doc.add( Field.Text( MD5, getMd5( artifact ) ) );
115 doc.add( Field.Text( CLASSES, classes.toString() ) );
116 doc.add( Field.Text( PACKAGES, packages.toString() ) );
117 doc.add( Field.Text( FILES, files.toString() ) );
118 indexWriter.addDocument( doc );
124 throw new RepositoryIndexerException( e );
128 private String getSha1( Artifact artifact )
129 throws FileNotFoundException, IOException, NoSuchAlgorithmException
131 FileInputStream fIn = new FileInputStream( artifact.getFile() );
132 return new String( getChecksum( fIn, "SHA-1" ) );
135 private String getMd5( Artifact artifact )
136 throws FileNotFoundException, IOException, NoSuchAlgorithmException
138 FileInputStream fIn = new FileInputStream( artifact.getFile() );
139 return new String( getChecksum( fIn, "MD5" ) );
142 private byte[] getChecksum( InputStream inStream, String algorithm )
143 throws IOException, NoSuchAlgorithmException
145 byte[] buffer = new byte[ 256 ];
146 MessageDigest complete = MessageDigest.getInstance( algorithm );
150 numRead = inStream.read( buffer );
153 complete.update( buffer, 0, numRead );
156 while ( numRead != -1 );
159 return complete.digest();
162 private void initBuffers()
164 classes = new StringBuffer();
165 packages = new StringBuffer();
166 files = new StringBuffer();
169 private void removeBuffers()
176 private void processArtifactContents( File artifact )
177 throws IOException, ZipException
179 ZipFile jar = new ZipFile( artifact );
180 for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
182 ZipEntry entry = (ZipEntry) entries.nextElement();
183 System.out.println( entry.getName() );
184 if ( addIfClassEntry( entry ) )
186 addClassPackage( entry.getName() );
192 private boolean addIfClassEntry( ZipEntry entry )
194 boolean isAdded = false;
196 String name = entry.getName();
197 if( name.endsWith( ".class") )
199 // TODO verify if class is public or protected
200 if( name.lastIndexOf( "$" ) == -1)
202 int idx = name.lastIndexOf( '/' );
203 if ( idx < 0 ) idx = 0;
204 String classname = name.substring( idx, name.length() - 6 );
205 classes.append( classname ).append( "\n" );
213 private boolean addClassPackage( String name )
215 boolean isAdded = false;
217 int idx = name.lastIndexOf( '/' );
220 String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
221 if ( packages.indexOf( packageName ) < 0 )
223 packages.append( packageName ).append( "\n" );
231 private boolean addFile( ZipEntry entry )
233 boolean isAdded = false;
235 String name = entry.getName();
236 int idx = name.lastIndexOf( '/' );
239 name = name.substring( idx + 1 );
242 if ( files.indexOf( name + "\n" ) < 0 )
244 files.append( name ).append( "\n" );