]> source.dussan.org Git - archiva.git/blob
c8382945a9a0d777c75aea198673ebea9ea97e19
[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.File;
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;
32
33 import org.apache.lucene.document.Document;
34 import org.apache.lucene.document.Field;
35
36 import org.apache.maven.artifact.Artifact;
37 import org.apache.maven.artifact.repository.ArtifactRepository;
38
39 /**
40  *
41  * @author Edwin Punzalan
42  */
43 public class ArtifactRepositoryIndexer
44     extends AbstractRepositoryIndexer
45 {
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";
55     
56     private static final String[] FIELDS = { NAME, GROUPID, ARTIFACTID, VERSION, SHA1, MD5,
57                                                CLASSES, PACKAGES, FILES };
58     
59     private ArtifactRepository repository;
60
61     private StringBuffer classes;
62     private StringBuffer packages;
63     private StringBuffer files;
64     
65     public ArtifactRepositoryIndexer( ArtifactRepository repository, String path )
66         throws RepositoryIndexerException
67     {
68         this.repository = repository;
69         indexPath = path;
70         validateIndex();
71     }
72     
73     public String[] getIndexFields()
74     {
75         return FIELDS;
76     }
77
78     public void addObjectIndex(Object obj) 
79         throws RepositoryIndexerException
80     {
81         if ( obj instanceof Artifact )
82         {
83             addArtifactIndex( (Artifact) obj );
84         }
85         else
86         {
87             throw new RepositoryIndexerException( "This instance of indexer cannot index instances of " + 
88                     obj.getClass().getName() );
89         }
90     }
91
92     public void addArtifactIndex( Artifact artifact )
93         throws RepositoryIndexerException
94     {
95         if ( !isOpen() )
96         {
97             throw new RepositoryIndexerException( "Unable to add artifact index on a closed index" );
98         }
99
100         try
101         {
102             getIndexWriter();
103
104             initBuffers();
105             processArtifactContents( artifact.getFile() );
106             
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 );
119
120             removeBuffers();
121         }
122         catch( Exception e )
123         {
124             throw new RepositoryIndexerException( e );
125         }
126     }
127
128     private String getSha1( Artifact artifact )
129         throws FileNotFoundException, IOException, NoSuchAlgorithmException
130     {
131         FileInputStream fIn = new FileInputStream( artifact.getFile() );
132         return new String( getChecksum( fIn, "SHA-1" ) );
133     }
134     
135     private String getMd5( Artifact artifact )
136         throws FileNotFoundException, IOException, NoSuchAlgorithmException
137     {
138         FileInputStream fIn = new FileInputStream( artifact.getFile() );
139         return new String( getChecksum( fIn, "MD5" ) );
140     }
141
142     private byte[] getChecksum( InputStream inStream, String algorithm )
143         throws IOException, NoSuchAlgorithmException
144     {
145         byte[] buffer = new byte[ 256 ];
146         MessageDigest complete = MessageDigest.getInstance( algorithm );
147         int numRead;
148         do
149         {
150             numRead = inStream.read( buffer );
151             if ( numRead > 0 )
152             {
153                 complete.update( buffer, 0, numRead );
154             }
155         }
156         while ( numRead != -1 );
157         inStream.close();
158
159         return complete.digest();
160     }
161
162     private void initBuffers()
163     {
164         classes = new StringBuffer();
165         packages = new StringBuffer();
166         files = new StringBuffer();
167     }
168
169     private void removeBuffers()
170     {
171         classes = null;
172         packages = null;
173         files = null;
174     }
175
176     private void processArtifactContents( File artifact )
177         throws IOException, ZipException
178     {
179         ZipFile jar = new ZipFile( artifact );
180         for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
181         {
182             ZipEntry entry = (ZipEntry) entries.nextElement();
183             System.out.println( entry.getName() );
184             if ( addIfClassEntry( entry ) )
185             {
186                 addClassPackage( entry.getName() );
187             }
188             addFile( entry );
189         }
190     }
191
192     private boolean addIfClassEntry( ZipEntry entry )
193     {
194         boolean isAdded = false;
195         
196         String name = entry.getName();
197         if( name.endsWith( ".class") )
198         {
199             // TODO verify if class is public or protected
200             if( name.lastIndexOf( "$" ) == -1)
201             {
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" );
206                 isAdded = true;
207             }
208         }
209         
210         return isAdded;
211     }
212
213     private boolean addClassPackage( String name )
214     {
215         boolean isAdded = false;
216
217         int idx = name.lastIndexOf( '/' );
218         if ( idx > 0 )
219         {
220             String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
221             if ( packages.indexOf( packageName ) < 0 )
222             {
223                 packages.append( packageName ).append( "\n" );
224             }
225             isAdded = true;
226         }
227         
228         return isAdded;
229     }
230
231     private boolean addFile( ZipEntry entry )
232     {
233         boolean isAdded = false;
234
235         String name = entry.getName();
236         int idx = name.lastIndexOf( '/' );
237         if ( idx >= 0 )
238         {
239             name = name.substring( idx + 1 );
240         }
241
242         if ( files.indexOf( name + "\n" ) < 0 )
243         {
244             files.append( name ).append( "\n" );
245             isAdded = true;
246         }
247         
248         return isAdded;
249     }
250 }