]> source.dussan.org Git - archiva.git/blob
3233a870e4c5aec0ca8f15f446445c6bd3217722
[archiva.git] /
1 package org.apache.maven.archiva.scheduled.executors;
2
3 /*
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
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.List;
25
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;
48
49 /**
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.
53  * 
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"
57  */
58 public class ArchivaIndexingTaskExecutor
59     implements TaskExecutor, Initializable
60 {
61     private Logger log = LoggerFactory.getLogger( ArchivaIndexingTaskExecutor.class );
62
63     /**
64      * @plexus.requirement
65      */
66     private IndexerEngine indexerEngine;
67
68     /**
69      * @plexus.requirement
70      */
71     private IndexPacker indexPacker;
72
73     private ArtifactContextProducer artifactContextProducer;
74
75     public void executeTask( Task task )
76         throws TaskExecutionException
77     {
78         synchronized ( indexerEngine )
79         {
80             ArtifactIndexingTask indexingTask = (ArtifactIndexingTask) task;
81
82             ManagedRepositoryConfiguration repository = indexingTask.getRepository();
83             IndexingContext context = indexingTask.getContext();
84
85             if ( ArtifactIndexingTask.Action.FINISH.equals( indexingTask.getAction() )
86                 && indexingTask.isExecuteOnEntireRepo() )
87             {
88                 log.debug( "Finishing indexing task on repo: " + repository.getId() );
89                 finishIndexingTask( indexingTask, repository, context );
90             }
91             else
92             {
93                 // create context if not a repo scan request
94                 if( !indexingTask.isExecuteOnEntireRepo() )
95                 {
96                     try
97                     {
98                         log.debug( "Creating indexing context on resource: " + indexingTask.getResourceFile().getPath() );
99                         context = TaskCreator.createContext( repository );
100                     }
101                     catch( IOException e )
102                     {
103                         log.error( "Error occurred while creating context: " + e.getMessage() );
104                         throw new TaskExecutionException( "Error occurred while creating context: " + e.getMessage() );
105                     }
106                     catch( UnsupportedExistingLuceneIndexException e )
107                     {
108                         log.error( "Error occurred while creating context: " + e.getMessage() );
109                         throw new TaskExecutionException( "Error occurred while creating context: " + e.getMessage() );    
110                     }
111                 }
112
113                 if ( context == null || context.getIndexDirectory() == null )
114                 {
115                     throw new TaskExecutionException( "Trying to index an artifact but the context is already closed" );
116                 }
117                 
118                 try
119                 {
120                     File artifactFile = indexingTask.getResourceFile();
121                     ArtifactContext ac = artifactContextProducer.getArtifactContext( context, artifactFile );
122
123                     if ( ac != null )
124                     {
125                         if ( indexingTask.getAction().equals( ArtifactIndexingTask.Action.ADD ) )
126                         {
127                             boolean add = true;
128                             IndexReader r = context.getIndexReader();
129                             for ( int i = 0; i < r.numDocs(); i++ )
130                             {
131                                 if ( !r.isDeleted( i ) )
132                                 {
133                                     Document d = r.document( i );
134                                     String uinfo = d.get( ArtifactInfo.UINFO );
135                                     if ( ac.getArtifactInfo().getUinfo().equals( uinfo ) )
136                                     {
137                                         add = false;
138                                         break;
139                                     }
140                                 }
141                             }
142
143                             if ( add )
144                             {
145                                 log.debug( "Adding artifact '" + ac.getArtifactInfo() + "' to index.." );
146                                 indexerEngine.index( context, ac );
147                                 context.getIndexWriter().commit();
148                             }
149                             else
150                             {
151                                 log.debug( "Updating artifact '" + ac.getArtifactInfo() + "' in index.." );
152                                 indexerEngine.update( context, ac );
153                                 context.getIndexWriter().commit();
154                             }
155
156                             // close the context if not a repo scan request
157                             if( !indexingTask.isExecuteOnEntireRepo() )
158                             {
159                                 log.debug( "Finishing indexing task on resource file : " + indexingTask.getResourceFile().getPath() );
160                                 finishIndexingTask( indexingTask, repository, context );   
161                             }
162                         }
163                         else
164                         {
165                             log.debug( "Removing artifact '" + ac.getArtifactInfo() + "' from index.." );
166                             indexerEngine.remove( context, ac );
167                             context.getIndexWriter().commit();
168                         }
169                     }
170                 }
171                 catch ( IOException e )
172                 {
173                     log.error( "Error occurred while executing indexing task '" + indexingTask + "': " + e.getMessage() );
174                     throw new TaskExecutionException( "Error occurred while executing indexing task '" + indexingTask
175                         + "'", e );
176                 }
177             }
178         }
179     }
180
181     private void finishIndexingTask( ArtifactIndexingTask indexingTask, ManagedRepositoryConfiguration repository,
182                                      IndexingContext context )
183         throws TaskExecutionException
184     {
185         try
186         {
187             context.optimize();
188
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 );
193
194             log.debug( "Index file packaged at '" + indexLocation.getPath() + "'." );
195         }
196         catch ( IOException e )
197         {
198             log.error( "Error occurred while executing indexing task '" + indexingTask + "': " + e.getMessage() );
199             throw new TaskExecutionException( "Error occurred while executing indexing task '" + indexingTask
200                 + "'", e );
201         }
202         finally
203         {
204             if ( context != null )
205             {
206                 try
207                 {
208                     context.close( false );
209                 }
210                 catch ( IOException e )
211                 {
212                     log.error( "Error occurred while closing context: " + e.getMessage() );
213                     throw new TaskExecutionException( "Error occurred while closing context: " + e.getMessage() );
214                 }
215             }
216         }
217     }
218
219     public void initialize()
220         throws InitializationException
221     {
222         log.info( "Initialized " + this.getClass().getName() );
223
224         artifactContextProducer = new DefaultArtifactContextProducer();
225     }
226
227     public void setIndexerEngine( IndexerEngine indexerEngine )
228     {
229         this.indexerEngine = indexerEngine;
230     }
231
232     public void setIndexPacker( IndexPacker indexPacker )
233     {
234         this.indexPacker = indexPacker;
235     }
236 }