]> source.dussan.org Git - archiva.git/blob
2200b12f54270df58d6a043b6aab792d4fee7429
[archiva.git] /
1 package org.apache.maven.repository.indexing;
2
3 /*
4  * Copyright 2001-2005 The Apache Software Foundation.
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  
12  *
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.
18  */
19
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;
31
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;
37
38 import org.apache.maven.artifact.Artifact;
39 import org.apache.maven.artifact.repository.ArtifactRepository;
40
41 /**
42  *
43  * @author Edwin Punzalan
44  */
45 public class ArtifactRepositoryIndexer
46     extends AbstractRepositoryIndexer
47 {
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";
56     
57     private static final String[] FIELDS = { NAME, GROUPID, ARTIFACTID, VERSION, SHA1, MD5, CLASSES, PACKAGES };
58     
59     ArtifactRepository repository;
60     
61     public ArtifactRepositoryIndexer( ArtifactRepository repository, String path )
62         throws RepositoryIndexerException
63     {
64         this.repository = repository;
65         indexPath = path;
66         validateIndex();
67     }
68
69     public void addArtifactIndex( Artifact artifact )
70         throws RepositoryIndexerException
71     {
72         try
73         {
74             getIndexWriter();
75
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 );
86         }
87         catch( Exception e )
88         {
89             throw new RepositoryIndexerException( e );
90         }
91     }
92
93     public void optimize()
94         throws RepositoryIndexerException
95     {
96         try
97         {
98             indexWriter.optimize();
99         }
100         catch ( IOException ioe )
101         {
102             throw new RepositoryIndexerException( "Failed to optimize index", ioe );
103         }
104     }
105
106     private String getSha1( Artifact artifact )
107         throws FileNotFoundException, IOException, NoSuchAlgorithmException
108     {
109         FileInputStream fIn = new FileInputStream( artifact.getFile() );
110         return new String( getChecksum( fIn, "SHA-1" ) );
111     }
112     
113     private String getMd5( Artifact artifact )
114         throws FileNotFoundException, IOException, NoSuchAlgorithmException
115     {
116         FileInputStream fIn = new FileInputStream( artifact.getFile() );
117         return new String( getChecksum( fIn, "MD5" ) );
118     }
119
120     private byte[] getChecksum( InputStream inStream, String algorithm )
121         throws IOException, NoSuchAlgorithmException
122     {
123         byte[] buffer = new byte[ 256 ];
124         MessageDigest complete = MessageDigest.getInstance( algorithm );
125         int numRead;
126         do
127         {
128             numRead = inStream.read( buffer );
129             if ( numRead > 0 )
130             {
131                 complete.update( buffer, 0, numRead );
132             }
133         }
134         while ( numRead != -1 );
135         inStream.close();
136
137         return complete.digest();
138     }
139
140     private String getClasses( Artifact artifact )
141         throws IOException, ZipException
142     {
143         StringBuffer sb = new StringBuffer();
144
145         ZipFile jar = new ZipFile( artifact.getFile() );
146         for( Enumeration en = jar.entries(); en.hasMoreElements(); )
147         {
148             ZipEntry e = ( ZipEntry ) en.nextElement();
149             String name = e.getName();
150             if( name.endsWith( ".class") )
151             {
152                 // TODO verify if class is public or protected
153                 // TODO skipp all inner classes for now
154                 if( name.lastIndexOf( "$" ) == -1)
155                 {
156                     int idx = name.lastIndexOf( '/' );
157                     if ( idx < 0 ) idx = 0;
158                     sb.append( name.substring( idx, name.length() - 6 ) ).append( "\n" );
159                 }
160             }
161         }
162
163         return sb.toString();
164     }
165
166     private String getPackages( Artifact artifact )
167         throws IOException, ZipException
168     {
169         StringBuffer sb = new StringBuffer();
170
171         ZipFile jar = new ZipFile( artifact.getFile() );
172         for( Enumeration en = jar.entries(); en.hasMoreElements(); )
173         {
174             ZipEntry e = ( ZipEntry ) en.nextElement();
175             String name = e.getName();
176             //only include packages with accompanying classes
177             if ( name.endsWith( ".class" ) )
178             {
179                 int idx = name.lastIndexOf( '/' );
180                 if ( idx > 0 )
181                 {
182                     String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
183                     if ( sb.indexOf( packageName ) < 0 )
184                     {
185                         sb.append( packageName ).append( "\n" );
186                     }
187                 }
188             }
189         }
190
191         return sb.toString();
192     }
193
194     private void validateIndex()
195         throws RepositoryIndexerException
196     {
197         try
198         {
199             getIndexReader();
200             Collection fields = indexReader.getFieldNames();
201             for( int idx=0; idx<FIELDS.length; idx++ )
202             {
203                 if ( !fields.contains( FIELDS[ idx ] ) )
204                 {
205                     throw new RepositoryIndexerException( "The Field " + FIELDS[ idx ] + " does not exist in index path " +
206                             indexPath + "." );
207                 }
208             }
209         }
210         catch ( IOException e )
211         {
212             throw new RepositoryIndexerException( e );
213         }
214     }
215 }