| package org.apache.maven.index; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import javax.inject.Named; |
| import javax.inject.Singleton; |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.Field; |
| import org.apache.lucene.index.IndexWriter; |
| import org.apache.lucene.index.IndexableField; |
| import org.apache.lucene.index.Term; |
| import org.apache.lucene.search.IndexSearcher; |
| import org.apache.lucene.search.TermQuery; |
| import org.apache.lucene.search.TopDocs; |
| import org.apache.maven.index.context.IndexingContext; |
| import org.apache.maven.index.creator.MinimalArtifactInfoIndexCreator; |
| |
| /** |
| * A default {@link IndexerEngine} implementation. |
| * |
| * @author Tamas Cservenak |
| */ |
| @Singleton |
| @Named |
| public class DefaultIndexerEngine |
| implements IndexerEngine |
| { |
| |
| public void index( IndexingContext context, ArtifactContext ac ) |
| throws IOException |
| { |
| // skip artifacts not obeying repository layout (whether m1 or m2) |
| if ( ac != null && ac.getGav() != null ) |
| { |
| Document d = ac.createDocument( context ); |
| |
| if ( d != null ) |
| { |
| context.getIndexWriter().addDocument( d ); |
| |
| context.updateTimestamp(); |
| } |
| } |
| } |
| |
| public void update( IndexingContext context, ArtifactContext ac ) |
| throws IOException |
| { |
| if ( ac != null && ac.getGav() != null ) |
| { |
| Document d = ac.createDocument( context ); |
| |
| if ( d != null ) |
| { |
| Document old = getOldDocument( context, ac ); |
| |
| if ( !equals( d, old ) ) |
| { |
| IndexWriter w = context.getIndexWriter(); |
| |
| w.updateDocument( new Term( ArtifactInfo.UINFO, ac.getArtifactInfo().getUinfo() ), d ); |
| |
| updateGroups( context, ac ); |
| |
| context.updateTimestamp(); |
| } |
| } |
| } |
| } |
| |
| public void remove( IndexingContext context, ArtifactContext ac ) |
| throws IOException |
| { |
| if ( ac != null ) |
| { |
| final String uinfo = ac.getArtifactInfo().getUinfo(); |
| |
| // add artifact deletion marker |
| final Document doc = new Document(); |
| |
| doc.add( new Field( ArtifactInfo.DELETED, uinfo, Field.Store.YES, Field.Index.NO ) ); |
| doc.add( new Field( ArtifactInfo.LAST_MODIFIED, // |
| Long.toString( System.currentTimeMillis() ), Field.Store.YES, Field.Index.NO ) ); |
| |
| IndexWriter w = context.getIndexWriter(); |
| w.addDocument( doc ); |
| w.deleteDocuments( new Term( ArtifactInfo.UINFO, uinfo ) ); |
| context.updateTimestamp(); |
| } |
| } |
| |
| // == |
| |
| private boolean equals( final Document d1, final Document d2 ) |
| { |
| if ( d1 == null && d2 == null ) |
| { |
| return true; |
| } |
| if ( d1 == null || d2 == null ) |
| { |
| return false; |
| } |
| |
| final Map<String, String> m1 = toMap( d1 ); |
| final Map<String, String> m2 = toMap( d2 ); |
| |
| m1.remove( MinimalArtifactInfoIndexCreator.FLD_LAST_MODIFIED.getKey() ); |
| m2.remove( MinimalArtifactInfoIndexCreator.FLD_LAST_MODIFIED.getKey() ); |
| |
| return m1.equals( m2 ); |
| } |
| |
| private Map<String, String> toMap( Document d ) |
| { |
| final HashMap<String, String> result = new HashMap<String, String>(); |
| |
| for ( Object o : d.getFields() ) |
| { |
| IndexableField f = (IndexableField) o; |
| if ( f.fieldType().stored() ) |
| { |
| result.put( f.name(), f.stringValue() ); |
| } |
| } |
| |
| return result; |
| } |
| |
| private Document getOldDocument( IndexingContext context, ArtifactContext ac ) |
| { |
| try |
| { |
| final IndexSearcher indexSearcher = context.acquireIndexSearcher(); |
| try |
| { |
| TopDocs result = |
| indexSearcher.search( |
| new TermQuery( new Term( ArtifactInfo.UINFO, ac.getArtifactInfo().getUinfo() ) ), 2 ); |
| |
| if ( result.totalHits == 1 ) |
| { |
| return indexSearcher.doc( result.scoreDocs[0].doc ); |
| } |
| } |
| finally |
| { |
| context.releaseIndexSearcher( indexSearcher ); |
| } |
| } |
| catch ( IOException e ) |
| { |
| // huh? |
| throw new IllegalStateException( e ); |
| } |
| return null; |
| } |
| |
| private void updateGroups( IndexingContext context, ArtifactContext ac ) |
| throws IOException |
| { |
| String rootGroup = ac.getArtifactInfo().getRootGroup(); |
| Set<String> rootGroups = context.getRootGroups(); |
| if ( !rootGroups.contains( rootGroup ) ) |
| { |
| rootGroups.add( rootGroup ); |
| context.setRootGroups( rootGroups ); |
| } |
| |
| Set<String> allGroups = context.getAllGroups(); |
| if ( !allGroups.contains( ac.getArtifactInfo().getGroupId() ) ) |
| { |
| allGroups.add( ac.getArtifactInfo().getGroupId() ); |
| context.setAllGroups( allGroups ); |
| } |
| } |
| } |