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.document.Document;
20 import org.apache.lucene.document.Field;
21 import org.apache.maven.artifact.Artifact;
22 import org.apache.maven.artifact.repository.ArtifactRepository;
23 import org.apache.maven.repository.digest.Digester;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.security.NoSuchAlgorithmException;
28 import java.util.Enumeration;
29 import java.util.zip.ZipEntry;
30 import java.util.zip.ZipException;
31 import java.util.zip.ZipFile;
35 * Class used to index Artifact objects in a specific repository
37 * @author Edwin Punzalan
39 public class ArtifactRepositoryIndex
40 extends AbstractRepositoryIndex
42 private Digester digester;
47 * @param indexPath the path where the lucene index will be created/updated.
48 * @param repository the repository where the indexed artifacts are located
49 * @param digester the digester object to generate the checksum strings
50 * @throws RepositoryIndexException
52 public ArtifactRepositoryIndex( String indexPath, ArtifactRepository repository, Digester digester )
53 throws RepositoryIndexException
55 super( indexPath, repository );
56 this.digester = digester;
60 * @see AbstractRepositoryIndex#isIndexed(Object)
62 public void isIndexed( Object object )
63 throws RepositoryIndexException, IOException
65 if ( object instanceof Artifact )
67 Artifact artifact = (Artifact) object;
71 validateIndex( FIELDS );
72 deleteDocument( FLD_ID, ARTIFACT + ":" + artifact.getId() );
77 throw new RepositoryIndexException( "Object is not of type artifact." );
82 * Method to index a given artifact
84 * @param artifact the Artifact object to be indexed
85 * @throws RepositoryIndexException
87 public void indexArtifact( Artifact artifact )
88 throws RepositoryIndexException
90 StringBuffer classes = new StringBuffer();
91 StringBuffer packages = new StringBuffer();
92 StringBuffer files = new StringBuffer();
98 sha1sum = digester.createChecksum( artifact.getFile(), Digester.SHA1 );
99 md5sum = digester.createChecksum( artifact.getFile(), Digester.MD5 );
101 catch ( NoSuchAlgorithmException e )
103 throw new RepositoryIndexException( "Unable to create a checksum", e );
105 catch ( FileNotFoundException e )
107 throw new RepositoryIndexException( "Error reading from artifact file", e );
109 catch ( IOException e )
111 throw new RepositoryIndexException( "Error reading from artifact file", e );
117 if ( "jar".equals( artifact.getType() ) )
119 ZipFile jar = new ZipFile( artifact.getFile() );
121 for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
123 ZipEntry entry = (ZipEntry) entries.nextElement();
124 if ( addIfClassEntry( entry, classes ) )
126 addClassPackage( entry.getName(), packages );
128 addFile( entry, files );
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.Keyword( FLD_ID, ARTIFACT + ":" + artifact.getId() ) );
143 doc.add( Field.Text( FLD_NAME, artifact.getFile().getName() ) );
144 doc.add( Field.Text( FLD_GROUPID, artifact.getGroupId() ) );
145 doc.add( Field.Text( FLD_ARTIFACTID, artifact.getArtifactId() ) );
146 doc.add( Field.Text( FLD_VERSION, artifact.getVersion() ) );
147 doc.add( Field.Text( FLD_SHA1, sha1sum ) );
148 doc.add( Field.Text( FLD_MD5, md5sum ) );
149 doc.add( Field.Text( FLD_CLASSES, classes.toString() ) );
150 doc.add( Field.Text( FLD_PACKAGES, packages.toString() ) );
151 doc.add( Field.Text( FLD_FILES, files.toString() ) );
152 doc.add( Field.UnIndexed( FLD_DOCTYPE, ARTIFACT ) );
153 doc.add( Field.Text( FLD_LASTUPDATE, "" ) );
154 doc.add( Field.Text( FLD_PLUGINPREFIX, "" ) );
155 doc.add( Field.Keyword( FLD_LICENSE_URLS, "" ) );
156 doc.add( Field.Keyword( FLD_DEPENDENCIES, "" ) );
157 doc.add( Field.Keyword( FLD_PLUGINS_REPORT, "" ) );
158 doc.add( Field.Keyword( FLD_PLUGINS_BUILD, "" ) );
159 doc.add( Field.Keyword( FLD_PLUGINS_ALL, "" ) );
160 int i = artifact.getFile().getName().lastIndexOf( '.' );
161 doc.add( Field.Text( FLD_PACKAGING, artifact.getFile().getName().substring( i + 1 ) ) );
165 isIndexed( artifact );
170 getIndexWriter().addDocument( doc );
172 catch ( IOException e )
174 throw new RepositoryIndexException( "Error opening index", e );
179 * Method to test a zip entry if it is a java class, and adds it to the classes buffer
181 * @param entry the zip entry to test for java class
182 * @param classes the String buffer to add the java class if the test result as true
183 * @return true if the zip entry is a java class and was successfully added to the buffer
185 private boolean addIfClassEntry( ZipEntry entry, StringBuffer classes )
187 boolean isAdded = false;
189 String name = entry.getName();
190 if ( name.endsWith( ".class" ) )
192 // TODO verify if class is public or protected
193 if ( name.lastIndexOf( "$" ) == -1 )
195 int idx = name.lastIndexOf( '/' );
200 String classname = name.substring( idx, name.length() - 6 );
201 classes.append( classname ).append( "\n" );
210 * Method to add a class package to the buffer of packages
212 * @param name the complete path name of the class
213 * @param packages the packages buffer
214 * @return true if the package is successfully added
216 private boolean addClassPackage( String name, StringBuffer packages )
218 boolean isAdded = false;
220 int idx = name.lastIndexOf( '/' );
223 String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
224 if ( packages.indexOf( packageName ) < 0 )
226 packages.append( packageName ).append( "\n" );
235 * Method to add the zip entry as a file list
237 * @param entry the zip entry to be added
238 * @param files the buffer of files to update
239 * @return true if the file was successfully added
241 private boolean addFile( ZipEntry entry, StringBuffer files )
243 String name = entry.getName();
244 int idx = name.lastIndexOf( '/' );
247 name = name.substring( idx + 1 );
250 boolean isAdded = false;
252 if ( files.indexOf( name + "\n" ) < 0 )
254 files.append( name ).append( "\n" );