]> source.dussan.org Git - archiva.git/blob
11d288ec585b854935f4009437ffe8cbf687e566
[archiva.git] /
1 package org.apache.maven.repository.indexing;
2
3 /*
4  * Copyright 2005-2006 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  * 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.
17  */
18
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;
25
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;
33
34
35 /**
36  * Class used to index Artifact objects in a specified repository
37  *
38  * @author Edwin Punzalan
39  * @plexus.component role="org.apache.maven.repository.indexing.RepositoryIndex" role-hint="artifact" instantiation-strategy="per-lookup"
40  */
41 public class ArtifactRepositoryIndex
42     extends AbstractRepositoryIndex
43 {
44     private static final String NAME = "name";
45
46     private static final String GROUPID = "groupId";
47
48     private static final String ARTIFACTID = "artifactId";
49
50     private static final String VERSION = "version";
51
52     private static final String SHA1 = "sha1";
53
54     private static final String MD5 = "md5";
55
56     private static final String CLASSES = "classes";
57
58     private static final String PACKAGES = "packages";
59
60     private static final String FILES = "files";
61
62     private static final String[] FIELDS = {NAME, GROUPID, ARTIFACTID, VERSION, SHA1, MD5, CLASSES, PACKAGES, FILES};
63
64     private Analyzer analyzer;
65
66     /** @plexus.requirement */
67     private Digester digester;
68
69     /**
70      * method to get the Analyzer used to create indices
71      *
72      * @return the Analyzer object used to create the artifact indices
73      */
74     public Analyzer getAnalyzer()
75     {
76         if ( analyzer == null )
77         {
78             analyzer = new ArtifactRepositoryIndexAnalyzer( new SimpleAnalyzer() );
79         }
80
81         return analyzer;
82     }
83
84     /**
85      * method for collecting the available index fields usable for searching
86      *
87      * @return index field names
88      */
89     public String[] getIndexFields()
90     {
91         return FIELDS;
92     }
93
94     /**
95      * generic method for indexing
96      *
97      * @param obj the object to be indexed by this indexer
98      */
99     public void index( Object obj )
100         throws RepositoryIndexException
101     {
102         if ( obj instanceof Artifact )
103         {
104             indexArtifact( (Artifact) obj );
105         }
106         else
107         {
108             throw new RepositoryIndexException(
109                 "This instance of indexer cannot index instances of " + obj.getClass().getName() );
110         }
111     }
112
113     /**
114      * method to index a given artifact
115      *
116      * @param artifact the Artifact object to be indexed
117      */
118     public void indexArtifact( Artifact artifact )
119         throws RepositoryIndexException
120     {
121         if ( !isOpen() )
122         {
123             throw new RepositoryIndexException( "Unable to add artifact index on a closed index" );
124         }
125
126         StringBuffer classes = new StringBuffer();
127         StringBuffer packages = new StringBuffer();
128         StringBuffer files = new StringBuffer();
129
130         String sha1sum;
131         String md5sum;
132         ZipFile jar;
133         try
134         {
135             sha1sum = digester.createChecksum( artifact.getFile(), Digester.SHA1 );
136             md5sum = digester.createChecksum( artifact.getFile(), Digester.MD5 );
137             jar = new ZipFile( artifact.getFile() );
138         }
139         catch ( NoSuchAlgorithmException e )
140         {
141             throw new RepositoryIndexException( "Unable to create a checksum", e );
142         }
143         catch ( FileNotFoundException e )
144         {
145             throw new RepositoryIndexException( "Error reading from artifact file", e );
146         }
147         catch ( ZipException e )
148         {
149             throw new RepositoryIndexException( "Error reading from artifact file", e );
150         }
151         catch ( IOException e )
152         {
153             throw new RepositoryIndexException( "Error reading from artifact file", e );
154         }
155
156         for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
157         {
158             ZipEntry entry = (ZipEntry) entries.nextElement();
159             if ( addIfClassEntry( entry, classes ) )
160             {
161                 addClassPackage( entry.getName(), packages );
162             }
163             addFile( entry, files );
164         }
165
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() ) );
177
178         try
179         {
180             getIndexWriter().addDocument( doc );
181         }
182         catch ( IOException e )
183         {
184             throw new RepositoryIndexException( "Error opening index", e );
185         }
186     }
187
188     private boolean addIfClassEntry( ZipEntry entry, StringBuffer classes )
189     {
190         boolean isAdded = false;
191
192         String name = entry.getName();
193         if ( name.endsWith( ".class" ) )
194         {
195             // TODO verify if class is public or protected
196             if ( name.lastIndexOf( "$" ) == -1 )
197             {
198                 int idx = name.lastIndexOf( '/' );
199                 if ( idx < 0 )
200                 {
201                     idx = 0;
202                 }
203                 String classname = name.substring( idx, name.length() - 6 );
204                 classes.append( classname ).append( "\n" );
205                 isAdded = true;
206             }
207         }
208
209         return isAdded;
210     }
211
212     private boolean addClassPackage( String name, StringBuffer packages )
213     {
214         boolean isAdded = false;
215
216         int idx = name.lastIndexOf( '/' );
217         if ( idx > 0 )
218         {
219             String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
220             if ( packages.indexOf( packageName ) < 0 )
221             {
222                 packages.append( packageName ).append( "\n" );
223             }
224             isAdded = true;
225         }
226
227         return isAdded;
228     }
229
230     private boolean addFile( ZipEntry entry, StringBuffer files )
231     {
232         String name = entry.getName();
233         int idx = name.lastIndexOf( '/' );
234         if ( idx >= 0 )
235         {
236             name = name.substring( idx + 1 );
237         }
238
239         boolean isAdded = false;
240
241         if ( files.indexOf( name + "\n" ) < 0 )
242         {
243             files.append( name ).append( "\n" );
244             isAdded = true;
245         }
246
247         return isAdded;
248     }
249 }