1 package org.apache.maven.archiva.scheduled.executors;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
23 import java.io.IOException;
24 import java.util.List;
26 import org.apache.lucene.document.Document;
27 import org.apache.lucene.index.IndexReader;
28 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
29 import org.apache.maven.archiva.scheduled.tasks.ArtifactIndexingTask;
30 import org.apache.maven.archiva.scheduled.tasks.TaskCreator;
31 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
32 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
33 import org.codehaus.plexus.taskqueue.Task;
34 import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
35 import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.sonatype.nexus.index.ArtifactContext;
39 import org.sonatype.nexus.index.ArtifactContextProducer;
40 import org.sonatype.nexus.index.ArtifactInfo;
41 import org.sonatype.nexus.index.DefaultArtifactContextProducer;
42 import org.sonatype.nexus.index.IndexerEngine;
43 import org.sonatype.nexus.index.context.IndexCreator;
44 import org.sonatype.nexus.index.context.IndexingContext;
45 import org.sonatype.nexus.index.context.UnsupportedExistingLuceneIndexException;
46 import org.sonatype.nexus.index.packer.IndexPacker;
47 import org.sonatype.nexus.index.packer.IndexPackingRequest;
50 * ArchivaIndexingTaskExecutor Executes all indexing tasks. Adding, updating and removing artifacts from the index are
51 * all performed by this executor. Add and update artifact in index tasks are added in the indexing task queue by the
52 * NexusIndexerConsumer while remove artifact from index tasks are added by the LuceneCleanupRemoveIndexedConsumer.
54 * @todo Nexus specifics shouldn't be in the archiva-scheduled module
55 * @plexus.component role="org.codehaus.plexus.taskqueue.execution.TaskExecutor" role-hint="indexing"
56 * instantiation-strategy="singleton"
58 public class ArchivaIndexingTaskExecutor
59 implements TaskExecutor, Initializable
61 private Logger log = LoggerFactory.getLogger( ArchivaIndexingTaskExecutor.class );
66 private IndexerEngine indexerEngine;
71 private IndexPacker indexPacker;
73 private ArtifactContextProducer artifactContextProducer;
75 public void executeTask( Task task )
76 throws TaskExecutionException
78 synchronized ( indexerEngine )
80 ArtifactIndexingTask indexingTask = (ArtifactIndexingTask) task;
82 ManagedRepositoryConfiguration repository = indexingTask.getRepository();
83 IndexingContext context = indexingTask.getContext();
85 if ( ArtifactIndexingTask.Action.FINISH.equals( indexingTask.getAction() )
86 && indexingTask.isExecuteOnEntireRepo() )
88 log.debug( "Finishing indexing task on repo: " + repository.getId() );
89 finishIndexingTask( indexingTask, repository, context );
93 // create context if not a repo scan request
94 if( !indexingTask.isExecuteOnEntireRepo() )
98 log.debug( "Creating indexing context on resource: " + indexingTask.getResourceFile().getPath() );
99 context = TaskCreator.createContext( repository );
101 catch( IOException e )
103 log.error( "Error occurred while creating context: " + e.getMessage() );
104 throw new TaskExecutionException( "Error occurred while creating context: " + e.getMessage() );
106 catch( UnsupportedExistingLuceneIndexException e )
108 log.error( "Error occurred while creating context: " + e.getMessage() );
109 throw new TaskExecutionException( "Error occurred while creating context: " + e.getMessage() );
113 if ( context == null || context.getIndexDirectory() == null )
115 throw new TaskExecutionException( "Trying to index an artifact but the context is already closed" );
120 File artifactFile = indexingTask.getResourceFile();
121 ArtifactContext ac = artifactContextProducer.getArtifactContext( context, artifactFile );
125 if ( indexingTask.getAction().equals( ArtifactIndexingTask.Action.ADD ) )
128 IndexReader r = context.getIndexReader();
129 for ( int i = 0; i < r.numDocs(); i++ )
131 if ( !r.isDeleted( i ) )
133 Document d = r.document( i );
134 String uinfo = d.get( ArtifactInfo.UINFO );
135 if ( ac.getArtifactInfo().getUinfo().equals( uinfo ) )
145 log.debug( "Adding artifact '" + ac.getArtifactInfo() + "' to index.." );
146 indexerEngine.index( context, ac );
147 context.getIndexWriter().commit();
151 log.debug( "Updating artifact '" + ac.getArtifactInfo() + "' in index.." );
152 indexerEngine.update( context, ac );
153 context.getIndexWriter().commit();
156 // close the context if not a repo scan request
157 if( !indexingTask.isExecuteOnEntireRepo() )
159 log.debug( "Finishing indexing task on resource file : " + indexingTask.getResourceFile().getPath() );
160 finishIndexingTask( indexingTask, repository, context );
165 log.debug( "Removing artifact '" + ac.getArtifactInfo() + "' from index.." );
166 indexerEngine.remove( context, ac );
167 context.getIndexWriter().commit();
171 catch ( IOException e )
173 log.error( "Error occurred while executing indexing task '" + indexingTask + "': " + e.getMessage() );
174 throw new TaskExecutionException( "Error occurred while executing indexing task '" + indexingTask
181 private void finishIndexingTask( ArtifactIndexingTask indexingTask, ManagedRepositoryConfiguration repository,
182 IndexingContext context )
183 throws TaskExecutionException
189 File managedRepository = new File( repository.getLocation() );
190 final File indexLocation = new File( managedRepository, ".index" );
191 IndexPackingRequest request = new IndexPackingRequest( context, indexLocation );
192 indexPacker.packIndex( request );
194 log.debug( "Index file packaged at '" + indexLocation.getPath() + "'." );
196 catch ( IOException e )
198 log.error( "Error occurred while executing indexing task '" + indexingTask + "': " + e.getMessage() );
199 throw new TaskExecutionException( "Error occurred while executing indexing task '" + indexingTask
204 if ( context != null )
208 context.close( false );
210 catch ( IOException e )
212 log.error( "Error occurred while closing context: " + e.getMessage() );
213 throw new TaskExecutionException( "Error occurred while closing context: " + e.getMessage() );
219 public void initialize()
220 throws InitializationException
222 log.info( "Initialized " + this.getClass().getName() );
224 artifactContextProducer = new DefaultArtifactContextProducer();
227 public void setIndexerEngine( IndexerEngine indexerEngine )
229 this.indexerEngine = indexerEngine;
232 public void setIndexPacker( IndexPacker indexPacker )
234 this.indexPacker = indexPacker;