]> source.dussan.org Git - archiva.git/blob
fabe952bdd22a7ff483350370eb2391b8495ab05
[archiva.git] /
1 package org.apache.maven.repository.indexing;\r
2 \r
3 /*\r
4  * Copyright 2005-2006 The Apache Software Foundation.\r
5  *\r
6  * Licensed under the Apache License, Version 2.0 (the "License");\r
7  * you may not use this file except in compliance with the License.\r
8  * You may obtain a copy of the License at\r
9  *\r
10  *      http://www.apache.org/licenses/LICENSE-2.0\r
11  *\r
12  * Unless required by applicable law or agreed to in writing, software\r
13  * distributed under the License is distributed on an "AS IS" BASIS,\r
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
15  * See the License for the specific language governing permissions and\r
16  * limitations under the License.\r
17  */\r
18 \r
19 import org.apache.lucene.document.Document;\r
20 import org.apache.lucene.queryParser.ParseException;\r
21 import org.apache.lucene.search.Hits;\r
22 import org.apache.lucene.search.IndexSearcher;\r
23 import org.apache.maven.artifact.Artifact;\r
24 import org.apache.maven.artifact.factory.ArtifactFactory;\r
25 import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;\r
26 import org.apache.maven.artifact.repository.metadata.GroupRepositoryMetadata;\r
27 import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;\r
28 import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;\r
29 import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;\r
30 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;\r
31 import org.apache.maven.repository.indexing.query.Query;\r
32 import org.codehaus.plexus.logging.AbstractLogEnabled;\r
33 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;\r
34 \r
35 import java.io.File;\r
36 import java.io.FileInputStream;\r
37 import java.io.IOException;\r
38 import java.io.InputStream;\r
39 import java.io.InputStreamReader;\r
40 import java.net.MalformedURLException;\r
41 import java.util.ArrayList;\r
42 import java.util.Collections;\r
43 import java.util.HashMap;\r
44 import java.util.Iterator;\r
45 import java.util.List;\r
46 import java.util.Map;\r
47 import java.util.StringTokenizer;\r
48 \r
49 /**\r
50  * Implementation Class for searching through the index\r
51  */\r
52 public class DefaultRepositoryIndexSearcher\r
53     extends AbstractLogEnabled\r
54     implements RepositoryIndexSearcher\r
55 {\r
56     protected RepositoryIndex index;\r
57 \r
58     private ArtifactFactory factory;\r
59 \r
60     private List artifactList;\r
61 \r
62     /**\r
63      * Constructor\r
64      *\r
65      * @param index the index object\r
66      */\r
67     protected DefaultRepositoryIndexSearcher( RepositoryIndex index, ArtifactFactory factory )\r
68     {\r
69         this.index = index;\r
70         this.factory = factory;\r
71     }\r
72 \r
73     /**\r
74      * @see RepositoryIndexSearcher#search(org.apache.maven.repository.indexing.query.Query)\r
75      */\r
76     public List search( Query query )\r
77         throws RepositoryIndexSearchException\r
78     {\r
79         artifactList = new ArrayList();\r
80         org.apache.lucene.search.Query luceneQuery;\r
81         try\r
82         {\r
83             luceneQuery = createLuceneQuery( query );\r
84         }\r
85         catch ( ParseException e )\r
86         {\r
87             throw new RepositoryIndexSearchException( "Unable to construct query: " + e.getMessage(), e );\r
88         }\r
89 \r
90         IndexSearcher searcher;\r
91         try\r
92         {\r
93             searcher = new IndexSearcher( index.getIndexPath() );\r
94         }\r
95         catch ( IOException e )\r
96         {\r
97             throw new RepositoryIndexSearchException( "Unable to open index: " + e.getMessage(), e );\r
98         }\r
99 \r
100         List docs;\r
101         try\r
102         {\r
103             Hits hits = searcher.search( luceneQuery );\r
104             docs = buildList( hits );\r
105         }\r
106         catch ( MalformedURLException e )\r
107         {\r
108             throw new RepositoryIndexSearchException( "Unable to search index: " + e.getMessage(), e );\r
109         }\r
110         catch ( IOException e )\r
111         {\r
112             throw new RepositoryIndexSearchException( "Unable to search index: " + e.getMessage(), e );\r
113         }\r
114         catch ( XmlPullParserException xe )\r
115         {\r
116             throw new RepositoryIndexSearchException( "Unable to parse metadata file: " + xe.getMessage(), xe );\r
117         }\r
118 \r
119         finally\r
120         {\r
121             try\r
122             {\r
123                 searcher.close();\r
124             }\r
125             catch ( IOException e )\r
126             {\r
127                 getLogger().error( "Unable to close index searcher", e );\r
128             }\r
129         }\r
130 \r
131         return docs;\r
132     }\r
133 \r
134     /**\r
135      * Method to create a lucene Query object by converting a prepared Query object\r
136      *\r
137      * @param query the prepared Query object to be converted into a lucene Query object\r
138      * @return a lucene Query object to represent the passed Query object\r
139      * @throws ParseException\r
140      */\r
141     private org.apache.lucene.search.Query createLuceneQuery( Query query )\r
142         throws ParseException\r
143     {\r
144         return query.createLuceneQuery( index );\r
145     }\r
146 \r
147     /**\r
148      * Create a list of artifact objects from the result set.\r
149      *\r
150      * @param hits the search result set\r
151      * @return List\r
152      * @throws IOException\r
153      */\r
154     private List buildList( Hits hits )\r
155         throws MalformedURLException, IOException, XmlPullParserException\r
156     {\r
157         for ( int i = 0; i < hits.length(); i++ )\r
158         {\r
159             Document doc = hits.doc( i );\r
160             artifactList.add( createSearchedObjectFromIndexDocument( doc ) );\r
161         }\r
162 \r
163         return artifactList;\r
164     }\r
165 \r
166     /**\r
167      * Method for creating the object to be returned for the search\r
168      *\r
169      * @param doc the index document where the object field values will be retrieved from\r
170      * @return Object\r
171      */\r
172     protected RepositoryIndexSearchHit createSearchedObjectFromIndexDocument( Document doc )\r
173         throws MalformedURLException, IOException, XmlPullParserException\r
174     {\r
175         RepositoryIndexSearchHit searchHit = null;\r
176 \r
177         // the document is of type artifact\r
178         if ( doc.get( RepositoryIndex.FLD_DOCTYPE ).equals( RepositoryIndex.ARTIFACT ) )\r
179         {\r
180             String groupId = doc.get( RepositoryIndex.FLD_GROUPID );\r
181             String artifactId = doc.get( RepositoryIndex.FLD_ARTIFACTID );\r
182             String version = doc.get( RepositoryIndex.FLD_VERSION );\r
183             String packaging = doc.get( RepositoryIndex.FLD_PACKAGING );\r
184             Artifact artifact = factory.createBuildArtifact( groupId, artifactId, version, packaging );\r
185 \r
186             artifact.setFile(\r
187                 new File( index.getRepository().getBasedir(), index.getRepository().pathOf( artifact ) ) );\r
188 \r
189             Map map = new HashMap();\r
190             map.put( RepositoryIndex.ARTIFACT, artifact );\r
191             map.put( RepositoryIndex.FLD_CLASSES, doc.get( RepositoryIndex.FLD_CLASSES ) );\r
192             map.put( RepositoryIndex.FLD_PACKAGES, doc.get( RepositoryIndex.FLD_PACKAGES ) );\r
193             map.put( RepositoryIndex.FLD_FILES, doc.get( RepositoryIndex.FLD_FILES ) );\r
194             map.put( RepositoryIndex.FLD_MD5, doc.get( RepositoryIndex.FLD_MD5 ) );\r
195             map.put( RepositoryIndex.FLD_SHA1, doc.get( RepositoryIndex.FLD_SHA1 ) );\r
196             map.put( RepositoryIndex.FLD_PACKAGING, doc.get( RepositoryIndex.FLD_PACKAGING ) );\r
197 \r
198             searchHit = new RepositoryIndexSearchHit( true, false, false );\r
199             searchHit.setObject( map );\r
200         }\r
201         // the document is of type model\r
202         else if ( doc.get( RepositoryIndex.FLD_DOCTYPE ).equals( RepositoryIndex.POM ) )\r
203         {\r
204             InputStream is = new FileInputStream( new File( index.getRepository().getBasedir() +\r
205                 doc.get( RepositoryIndex.FLD_GROUPID ).replace( '.', '/' ) + "/" +\r
206                 doc.get( RepositoryIndex.FLD_ARTIFACTID ) + "/" + doc.get( RepositoryIndex.FLD_VERSION ) + "/" +\r
207                 doc.get( RepositoryIndex.FLD_ARTIFACTID ) + "-" + doc.get( RepositoryIndex.FLD_VERSION ) + ".pom" ) );\r
208             MavenXpp3Reader reader = new MavenXpp3Reader();\r
209 \r
210             searchHit = new RepositoryIndexSearchHit( false, false, true );\r
211             searchHit.setObject( reader.read( new InputStreamReader( is ) ) );\r
212 \r
213         }\r
214         // the document is of type metadata\r
215         else if ( doc.get( RepositoryIndex.FLD_DOCTYPE ).equals( RepositoryIndex.METADATA ) )\r
216         {\r
217             List pathParts = new ArrayList();\r
218             StringTokenizer st = new StringTokenizer( doc.get( RepositoryIndex.FLD_NAME ), "/\\" );\r
219             while ( st.hasMoreTokens() )\r
220             {\r
221                 pathParts.add( st.nextToken() );\r
222             }\r
223 \r
224             Collections.reverse( pathParts );\r
225             Iterator it = pathParts.iterator();\r
226             String metadataFile = (String) it.next();\r
227             String tmpDir = (String) it.next();\r
228 \r
229             String metadataType;\r
230             if ( tmpDir.equals( doc.get( RepositoryIndex.FLD_VERSION ) ) )\r
231             {\r
232                 metadataType = MetadataRepositoryIndex.SNAPSHOT_METADATA;\r
233             }\r
234             else if ( tmpDir.equals( doc.get( RepositoryIndex.FLD_ARTIFACTID ) ) )\r
235             {\r
236                 metadataType = MetadataRepositoryIndex.ARTIFACT_METADATA;\r
237             }\r
238             else\r
239             {\r
240                 metadataType = MetadataRepositoryIndex.GROUP_METADATA;\r
241             }\r
242 \r
243             RepositoryMetadata repoMetadata = getMetadata( doc.get( RepositoryIndex.FLD_GROUPID ),\r
244                                                            doc.get( RepositoryIndex.FLD_ARTIFACTID ),\r
245                                                            doc.get( RepositoryIndex.FLD_VERSION ), metadataFile,\r
246                                                            metadataType );\r
247             searchHit = new RepositoryIndexSearchHit( false, true, false );\r
248             searchHit.setObject( repoMetadata );\r
249         }\r
250 \r
251         return searchHit;\r
252     }\r
253 \r
254     /**\r
255      * Create RepositoryMetadata object.\r
256      *\r
257      * @param groupId      the groupId to be set\r
258      * @param artifactId   the artifactId to be set\r
259      * @param version      the version to be set\r
260      * @param filename     the name of the metadata file\r
261      * @param metadataType the type of RepositoryMetadata object to be created (GROUP, ARTIFACT or SNAPSHOT)\r
262      * @return RepositoryMetadata\r
263      * @throws IOException\r
264      * @throws XmlPullParserException\r
265      */\r
266     private RepositoryMetadata getMetadata( String groupId, String artifactId, String version, String filename,\r
267                                             String metadataType )\r
268         throws IOException, XmlPullParserException\r
269     {\r
270         RepositoryMetadata repoMetadata = null;\r
271 \r
272         // TODO! file handles left open\r
273         InputStream is;\r
274         MetadataXpp3Reader metadataReader = new MetadataXpp3Reader();\r
275 \r
276         //group metadata\r
277         if ( metadataType.equals( MetadataRepositoryIndex.GROUP_METADATA ) )\r
278         {\r
279             // TODO! use pathOfMetadata\r
280             is = new FileInputStream(\r
281                 new File( index.getRepository().getBasedir() + groupId.replace( '.', '/' ) + "/" + filename ) );\r
282             repoMetadata = new GroupRepositoryMetadata( groupId );\r
283             repoMetadata.setMetadata( metadataReader.read( new InputStreamReader( is ) ) );\r
284         }\r
285         //artifact metadata\r
286         else if ( metadataType.equals( MetadataRepositoryIndex.ARTIFACT_METADATA ) )\r
287         {\r
288             // TODO! use pathOfMetadata\r
289             is = new FileInputStream( new File( index.getRepository().getBasedir() + groupId.replace( '.', '/' ) + "/" +\r
290                 artifactId + "/" + filename ) );\r
291             repoMetadata =\r
292                 new ArtifactRepositoryMetadata( factory.createBuildArtifact( groupId, artifactId, version, "jar" ) );\r
293             repoMetadata.setMetadata( metadataReader.read( new InputStreamReader( is ) ) );\r
294         }\r
295         //snapshot/version metadata\r
296         else if ( metadataType.equals( MetadataRepositoryIndex.SNAPSHOT_METADATA ) )\r
297         {\r
298             // TODO! use pathOfMetadata\r
299             is = new FileInputStream( new File( index.getRepository().getBasedir() + groupId.replace( '.', '/' ) + "/" +\r
300                 artifactId + "/" + version + "/" + filename ) );\r
301             repoMetadata = new SnapshotArtifactRepositoryMetadata(\r
302                 factory.createBuildArtifact( groupId, artifactId, version, "jar" ) );\r
303             repoMetadata.setMetadata( metadataReader.read( new InputStreamReader( is ) ) );\r
304         }\r
305 \r
306         return repoMetadata;\r
307     }\r
308 \r
309 }\r