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"
40 * @todo I think we should merge with Abstract*. Don't see that there'd be multiple implementations based on this
41 * @todo I think we should instantiate this based on a repository from a factory instead of making it a component of its own
43 public class ArtifactRepositoryIndex
44 extends AbstractRepositoryIndex
46 private static final String NAME = "name";
48 private static final String GROUPID = "groupId";
50 private static final String ARTIFACTID = "artifactId";
52 private static final String VERSION = "version";
54 private static final String SHA1 = "sha1";
56 private static final String MD5 = "md5";
58 private static final String CLASSES = "classes";
60 private static final String PACKAGES = "packages";
62 private static final String FILES = "files";
64 private static final String[] FIELDS = {NAME, GROUPID, ARTIFACTID, VERSION, SHA1, MD5, CLASSES, PACKAGES, FILES};
66 private Analyzer analyzer;
68 /** @plexus.requirement */
69 private Digester digester;
72 * method to get the Analyzer used to create indices
74 * @return the Analyzer object used to create the artifact indices
76 public Analyzer getAnalyzer()
78 if ( analyzer == null )
80 analyzer = new ArtifactRepositoryIndexAnalyzer( new SimpleAnalyzer() );
87 * method for collecting the available index fields usable for searching
89 * @return index field names
91 public String[] getIndexFields()
97 * generic method for indexing
99 * @param obj the object to be indexed by this indexer
101 public void index( Object obj )
102 throws RepositoryIndexException
104 if ( obj instanceof Artifact )
106 indexArtifact( (Artifact) obj );
110 throw new RepositoryIndexException(
111 "This instance of indexer cannot index instances of " + obj.getClass().getName() );
116 * method to index a given artifact
118 * @param artifact the Artifact object to be indexed
120 public void indexArtifact( Artifact artifact )
121 throws RepositoryIndexException
125 throw new RepositoryIndexException( "Unable to add artifact index on a closed index" );
128 StringBuffer classes = new StringBuffer();
129 StringBuffer packages = new StringBuffer();
130 StringBuffer files = new StringBuffer();
137 sha1sum = digester.createChecksum( artifact.getFile(), Digester.SHA1 );
138 md5sum = digester.createChecksum( artifact.getFile(), Digester.MD5 );
139 jar = new ZipFile( artifact.getFile() );
141 catch ( NoSuchAlgorithmException e )
143 throw new RepositoryIndexException( "Unable to create a checksum", e );
145 catch ( FileNotFoundException e )
147 throw new RepositoryIndexException( "Error reading from artifact file", e );
149 catch ( ZipException e )
151 throw new RepositoryIndexException( "Error reading from artifact file", e );
153 catch ( IOException e )
155 throw new RepositoryIndexException( "Error reading from artifact file", e );
158 for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
160 ZipEntry entry = (ZipEntry) entries.nextElement();
161 if ( addIfClassEntry( entry, classes ) )
163 addClassPackage( entry.getName(), packages );
165 addFile( entry, files );
168 //@todo should some of these fields be Keyword instead of Text ?
169 Document doc = new Document();
170 doc.add( Field.Text( NAME, artifact.getFile().getName() ) );
171 doc.add( Field.Text( GROUPID, artifact.getGroupId() ) );
172 doc.add( Field.Text( ARTIFACTID, artifact.getArtifactId() ) );
173 doc.add( Field.Text( VERSION, artifact.getVersion() ) );
174 doc.add( Field.Text( SHA1, sha1sum ) );
175 doc.add( Field.Text( MD5, md5sum ) );
176 doc.add( Field.Text( CLASSES, classes.toString() ) );
177 doc.add( Field.Text( PACKAGES, packages.toString() ) );
178 doc.add( Field.Text( FILES, files.toString() ) );
182 getIndexWriter().addDocument( doc );
184 catch ( IOException e )
186 throw new RepositoryIndexException( "Error opening index", e );
190 private boolean addIfClassEntry( ZipEntry entry, StringBuffer classes )
192 boolean isAdded = false;
194 String name = entry.getName();
195 if ( name.endsWith( ".class" ) )
197 // TODO verify if class is public or protected
198 if ( name.lastIndexOf( "$" ) == -1 )
200 int idx = name.lastIndexOf( '/' );
205 String classname = name.substring( idx, name.length() - 6 );
206 classes.append( classname ).append( "\n" );
214 private boolean addClassPackage( String name, StringBuffer packages )
216 boolean isAdded = false;
218 int idx = name.lastIndexOf( '/' );
221 String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
222 if ( packages.indexOf( packageName ) < 0 )
224 packages.append( packageName ).append( "\n" );
232 private boolean addFile( ZipEntry entry, StringBuffer files )
234 String name = entry.getName();
235 int idx = name.lastIndexOf( '/' );
238 name = name.substring( idx + 1 );
241 boolean isAdded = false;
243 if ( files.indexOf( name + "\n" ) < 0 )
245 files.append( name ).append( "\n" );