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