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.document.Document;
22 import org.apache.lucene.document.Field;
23 import org.apache.maven.artifact.Artifact;
24 import org.apache.maven.repository.digest.Digester;
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.security.NoSuchAlgorithmException;
29 import java.util.Enumeration;
30 import java.util.zip.ZipEntry;
31 import java.util.zip.ZipException;
32 import java.util.zip.ZipFile;
36 * Class used to index Artifact objects in a specified repository
38 * @author Edwin Punzalan
39 * @plexus.component role="org.apache.maven.repository.indexing.RepositoryIndex" role-hint="artifact" instantiation-strategy="per-lookup"
41 public class ArtifactRepositoryIndex
42 extends AbstractRepositoryIndex
44 private static final String NAME = "name";
46 private static final String GROUPID = "groupId";
48 private static final String ARTIFACTID = "artifactId";
50 private static final String VERSION = "version";
52 private static final String SHA1 = "sha1";
54 private static final String MD5 = "md5";
56 private static final String CLASSES = "classes";
58 private static final String PACKAGES = "packages";
60 private static final String FILES = "files";
62 private static final String[] FIELDS = {NAME, GROUPID, ARTIFACTID, VERSION, SHA1, MD5, CLASSES, PACKAGES, FILES};
64 private Analyzer analyzer;
66 /** @plexus.requirement */
67 private Digester digester;
70 * method to get the Analyzer used to create indices
72 * @return the Analyzer object used to create the artifact indices
74 public Analyzer getAnalyzer()
76 if ( analyzer == null )
78 analyzer = new ArtifactRepositoryIndexAnalyzer( new SimpleAnalyzer() );
85 * method for collecting the available index fields usable for searching
87 * @return index field names
89 public String[] getIndexFields()
95 * generic method for indexing
97 * @param obj the object to be indexed by this indexer
99 public void index( Object obj )
100 throws RepositoryIndexException
102 if ( obj instanceof Artifact )
104 indexArtifact( (Artifact) obj );
108 throw new RepositoryIndexException(
109 "This instance of indexer cannot index instances of " + obj.getClass().getName() );
114 * method to index a given artifact
116 * @param artifact the Artifact object to be indexed
118 public void indexArtifact( Artifact artifact )
119 throws RepositoryIndexException
123 throw new RepositoryIndexException( "Unable to add artifact index on a closed index" );
126 StringBuffer classes = new StringBuffer();
127 StringBuffer packages = new StringBuffer();
128 StringBuffer files = new StringBuffer();
135 sha1sum = digester.createChecksum( artifact.getFile(), Digester.SHA1 );
136 md5sum = digester.createChecksum( artifact.getFile(), Digester.MD5 );
137 jar = new ZipFile( artifact.getFile() );
139 catch ( NoSuchAlgorithmException e )
141 throw new RepositoryIndexException( "Unable to create a checksum", e );
143 catch ( FileNotFoundException e )
145 throw new RepositoryIndexException( "Error reading from artifact file", e );
147 catch ( ZipException e )
149 throw new RepositoryIndexException( "Error reading from artifact file", e );
151 catch ( IOException e )
153 throw new RepositoryIndexException( "Error reading from artifact file", e );
156 for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
158 ZipEntry entry = (ZipEntry) entries.nextElement();
159 if ( addIfClassEntry( entry, classes ) )
161 addClassPackage( entry.getName(), packages );
163 addFile( entry, files );
166 //@todo should some of these fields be Keyword instead of Text ?
167 Document doc = new Document();
168 doc.add( Field.Text( NAME, artifact.getFile().getName() ) );
169 doc.add( Field.Text( GROUPID, artifact.getGroupId() ) );
170 doc.add( Field.Text( ARTIFACTID, artifact.getArtifactId() ) );
171 doc.add( Field.Text( VERSION, artifact.getVersion() ) );
172 doc.add( Field.Text( SHA1, sha1sum ) );
173 doc.add( Field.Text( MD5, md5sum ) );
174 doc.add( Field.Text( CLASSES, classes.toString() ) );
175 doc.add( Field.Text( PACKAGES, packages.toString() ) );
176 doc.add( Field.Text( FILES, files.toString() ) );
180 getIndexWriter().addDocument( doc );
182 catch ( IOException e )
184 throw new RepositoryIndexException( "Error opening index", e );
188 private boolean addIfClassEntry( ZipEntry entry, StringBuffer classes )
190 boolean isAdded = false;
192 String name = entry.getName();
193 if ( name.endsWith( ".class" ) )
195 // TODO verify if class is public or protected
196 if ( name.lastIndexOf( "$" ) == -1 )
198 int idx = name.lastIndexOf( '/' );
203 String classname = name.substring( idx, name.length() - 6 );
204 classes.append( classname ).append( "\n" );
212 private boolean addClassPackage( String name, StringBuffer packages )
214 boolean isAdded = false;
216 int idx = name.lastIndexOf( '/' );
219 String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
220 if ( packages.indexOf( packageName ) < 0 )
222 packages.append( packageName ).append( "\n" );
230 private boolean addFile( ZipEntry entry, StringBuffer files )
232 String name = entry.getName();
233 int idx = name.lastIndexOf( '/' );
236 name = name.substring( idx + 1 );
239 boolean isAdded = false;
241 if ( files.indexOf( name + "\n" ) < 0 )
243 files.append( name ).append( "\n" );