]> source.dussan.org Git - archiva.git/blob
c38004841dae06e517ff7f8d156644c10a2da02e
[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.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;
24
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;
32
33
34 /**
35  * Class used to index Artifact objects in a specific repository
36  *
37  * @author Edwin Punzalan
38  */
39 public class ArtifactRepositoryIndex
40     extends AbstractRepositoryIndex
41 {
42     private Digester digester;
43
44     /**
45      * Class constructor
46      *
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
51      */
52     public ArtifactRepositoryIndex( String indexPath, ArtifactRepository repository, Digester digester )
53         throws RepositoryIndexException
54     {
55         super( indexPath, repository );
56         this.digester = digester;
57     }
58
59     /**
60      * @see AbstractRepositoryIndex#isIndexed(Object)
61      */
62     public void isIndexed( Object object )
63         throws RepositoryIndexException, IOException
64     {
65         if ( object instanceof Artifact )
66         {
67             Artifact artifact = (Artifact) object;
68             checkIfIndexExists();
69             if ( indexExists )
70             {
71                 validateIndex( FIELDS );
72                 deleteDocument( FLD_ID, ARTIFACT + ":" + artifact.getId() );
73             }
74         }
75         else
76         {
77             throw new RepositoryIndexException( "Object is not of type artifact." );
78         }
79     }
80
81     /**
82      * Method to index a given artifact
83      *
84      * @param artifact the Artifact object to be indexed
85      * @throws RepositoryIndexException
86      */
87     public void indexArtifact( Artifact artifact )
88         throws RepositoryIndexException
89     {
90         StringBuffer classes = new StringBuffer();
91         StringBuffer packages = new StringBuffer();
92         StringBuffer files = new StringBuffer();
93
94         String sha1sum;
95         String md5sum;
96         try
97         {
98             sha1sum = digester.createChecksum( artifact.getFile(), Digester.SHA1 );
99             md5sum = digester.createChecksum( artifact.getFile(), Digester.MD5 );
100         }
101         catch ( NoSuchAlgorithmException e )
102         {
103             throw new RepositoryIndexException( "Unable to create a checksum", e );
104         }
105         catch ( FileNotFoundException e )
106         {
107             throw new RepositoryIndexException( "Error reading from artifact file", e );
108         }
109         catch ( IOException e )
110         {
111             throw new RepositoryIndexException( "Error reading from artifact file", e );
112         }
113
114         try
115         {
116             // TODO: improve
117             if ( "jar".equals( artifact.getType() ) )
118             {
119                 ZipFile jar = new ZipFile( artifact.getFile() );
120
121                 for ( Enumeration entries = jar.entries(); entries.hasMoreElements(); )
122                 {
123                     ZipEntry entry = (ZipEntry) entries.nextElement();
124                     if ( addIfClassEntry( entry, classes ) )
125                     {
126                         addClassPackage( entry.getName(), packages );
127                     }
128                     addFile( entry, files );
129                 }
130             }
131         }
132         catch ( ZipException e )
133         {
134             throw new RepositoryIndexException( "Error reading from artifact file: " + artifact.getFile(), e );
135         }
136         catch ( IOException e )
137         {
138             throw new RepositoryIndexException( "Error reading from artifact file", e );
139         }
140
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 ) ) );
162
163         try
164         {
165             isIndexed( artifact );
166             if ( !isOpen() )
167             {
168                 open();
169             }
170             getIndexWriter().addDocument( doc );
171         }
172         catch ( IOException e )
173         {
174             throw new RepositoryIndexException( "Error opening index", e );
175         }
176     }
177
178     /**
179      * Method to test a zip entry if it is a java class, and adds it to the classes buffer
180      *
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
184      */
185     private boolean addIfClassEntry( ZipEntry entry, StringBuffer classes )
186     {
187         boolean isAdded = false;
188
189         String name = entry.getName();
190         if ( name.endsWith( ".class" ) )
191         {
192             // TODO verify if class is public or protected
193             if ( name.lastIndexOf( "$" ) == -1 )
194             {
195                 int idx = name.lastIndexOf( '/' );
196                 if ( idx < 0 )
197                 {
198                     idx = 0;
199                 }
200                 String classname = name.substring( idx, name.length() - 6 );
201                 classes.append( classname ).append( "\n" );
202                 isAdded = true;
203             }
204         }
205
206         return isAdded;
207     }
208
209     /**
210      * Method to add a class package to the buffer of packages
211      *
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
215      */
216     private boolean addClassPackage( String name, StringBuffer packages )
217     {
218         boolean isAdded = false;
219
220         int idx = name.lastIndexOf( '/' );
221         if ( idx > 0 )
222         {
223             String packageName = name.substring( 0, idx ).replace( '/', '.' ) + "\n";
224             if ( packages.indexOf( packageName ) < 0 )
225             {
226                 packages.append( packageName ).append( "\n" );
227             }
228             isAdded = true;
229         }
230
231         return isAdded;
232     }
233
234     /**
235      * Method to add the zip entry as a file list
236      *
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
240      */
241     private boolean addFile( ZipEntry entry, StringBuffer files )
242     {
243         String name = entry.getName();
244         int idx = name.lastIndexOf( '/' );
245         if ( idx >= 0 )
246         {
247             name = name.substring( idx + 1 );
248         }
249
250         boolean isAdded = false;
251
252         if ( files.indexOf( name + "\n" ) < 0 )
253         {
254             files.append( name ).append( "\n" );
255             isAdded = true;
256         }
257
258         return isAdded;
259     }
260 }