1 package org.apache.maven.repository.indexing;
\r
4 * Copyright 2005-2006 The Apache Software Foundation.
\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
10 * http://www.apache.org/licenses/LICENSE-2.0
\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
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
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
50 * Implementation Class for searching through the index
\r
52 public class DefaultRepositoryIndexSearcher
\r
53 extends AbstractLogEnabled
\r
54 implements RepositoryIndexSearcher
\r
56 protected RepositoryIndex index;
\r
58 private ArtifactFactory factory;
\r
60 private List artifactList;
\r
65 * @param index the index object
\r
67 protected DefaultRepositoryIndexSearcher( RepositoryIndex index, ArtifactFactory factory )
\r
70 this.factory = factory;
\r
74 * @see RepositoryIndexSearcher#search(org.apache.maven.repository.indexing.query.Query)
\r
76 public List search( Query query )
\r
77 throws RepositoryIndexSearchException
\r
79 artifactList = new ArrayList();
\r
80 org.apache.lucene.search.Query luceneQuery;
\r
83 luceneQuery = createLuceneQuery( query );
\r
85 catch ( ParseException e )
\r
87 throw new RepositoryIndexSearchException( "Unable to construct query: " + e.getMessage(), e );
\r
90 IndexSearcher searcher;
\r
93 searcher = new IndexSearcher( index.getIndexPath() );
\r
95 catch ( IOException e )
\r
97 throw new RepositoryIndexSearchException( "Unable to open index: " + e.getMessage(), e );
\r
103 Hits hits = searcher.search( luceneQuery );
\r
104 docs = buildList( hits );
\r
106 catch ( MalformedURLException e )
\r
108 throw new RepositoryIndexSearchException( "Unable to search index: " + e.getMessage(), e );
\r
110 catch ( IOException e )
\r
112 throw new RepositoryIndexSearchException( "Unable to search index: " + e.getMessage(), e );
\r
114 catch ( XmlPullParserException xe )
\r
116 throw new RepositoryIndexSearchException( "Unable to parse metadata file: " + xe.getMessage(), xe );
\r
125 catch ( IOException e )
\r
127 getLogger().error( "Unable to close index searcher", e );
\r
135 * Method to create a lucene Query object by converting a prepared Query object
\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
141 private org.apache.lucene.search.Query createLuceneQuery( Query query )
\r
142 throws ParseException
\r
144 return query.createLuceneQuery( index );
\r
148 * Create a list of artifact objects from the result set.
\r
150 * @param hits the search result set
\r
152 * @throws IOException
\r
154 private List buildList( Hits hits )
\r
155 throws MalformedURLException, IOException, XmlPullParserException
\r
157 for ( int i = 0; i < hits.length(); i++ )
\r
159 Document doc = hits.doc( i );
\r
160 artifactList.add( createSearchedObjectFromIndexDocument( doc ) );
\r
163 return artifactList;
\r
167 * Method for creating the object to be returned for the search
\r
169 * @param doc the index document where the object field values will be retrieved from
\r
172 protected RepositoryIndexSearchHit createSearchedObjectFromIndexDocument( Document doc )
\r
173 throws MalformedURLException, IOException, XmlPullParserException
\r
175 RepositoryIndexSearchHit searchHit = null;
\r
177 // the document is of type artifact
\r
178 if ( doc.get( RepositoryIndex.FLD_DOCTYPE ).equals( RepositoryIndex.ARTIFACT ) )
\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
187 new File( index.getRepository().getBasedir(), index.getRepository().pathOf( artifact ) ) );
\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
198 searchHit = new RepositoryIndexSearchHit( true, false, false );
\r
199 searchHit.setObject( map );
\r
201 // the document is of type model
\r
202 else if ( doc.get( RepositoryIndex.FLD_DOCTYPE ).equals( RepositoryIndex.POM ) )
\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
210 searchHit = new RepositoryIndexSearchHit( false, false, true );
\r
211 searchHit.setObject( reader.read( new InputStreamReader( is ) ) );
\r
214 // the document is of type metadata
\r
215 else if ( doc.get( RepositoryIndex.FLD_DOCTYPE ).equals( RepositoryIndex.METADATA ) )
\r
217 List pathParts = new ArrayList();
\r
218 StringTokenizer st = new StringTokenizer( doc.get( RepositoryIndex.FLD_NAME ), "/\\" );
\r
219 while ( st.hasMoreTokens() )
\r
221 pathParts.add( st.nextToken() );
\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
229 String metadataType;
\r
230 if ( tmpDir.equals( doc.get( RepositoryIndex.FLD_VERSION ) ) )
\r
232 metadataType = MetadataRepositoryIndex.SNAPSHOT_METADATA;
\r
234 else if ( tmpDir.equals( doc.get( RepositoryIndex.FLD_ARTIFACTID ) ) )
\r
236 metadataType = MetadataRepositoryIndex.ARTIFACT_METADATA;
\r
240 metadataType = MetadataRepositoryIndex.GROUP_METADATA;
\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
247 searchHit = new RepositoryIndexSearchHit( false, true, false );
\r
248 searchHit.setObject( repoMetadata );
\r
255 * Create RepositoryMetadata object.
\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
266 private RepositoryMetadata getMetadata( String groupId, String artifactId, String version, String filename,
\r
267 String metadataType )
\r
268 throws IOException, XmlPullParserException
\r
270 RepositoryMetadata repoMetadata = null;
\r
272 // TODO! file handles left open
\r
274 MetadataXpp3Reader metadataReader = new MetadataXpp3Reader();
\r
277 if ( metadataType.equals( MetadataRepositoryIndex.GROUP_METADATA ) )
\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
285 //artifact metadata
\r
286 else if ( metadataType.equals( MetadataRepositoryIndex.ARTIFACT_METADATA ) )
\r
288 // TODO! use pathOfMetadata
\r
289 is = new FileInputStream( new File( index.getRepository().getBasedir() + groupId.replace( '.', '/' ) + "/" +
\r
290 artifactId + "/" + filename ) );
\r
292 new ArtifactRepositoryMetadata( factory.createBuildArtifact( groupId, artifactId, version, "jar" ) );
\r
293 repoMetadata.setMetadata( metadataReader.read( new InputStreamReader( is ) ) );
\r
295 //snapshot/version metadata
\r
296 else if ( metadataType.equals( MetadataRepositoryIndex.SNAPSHOT_METADATA ) )
\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
306 return repoMetadata;
\r