]> source.dussan.org Git - archiva.git/blob
e1b6009f22ad70940f1bda60ea6b622aa6ca4992
[archiva.git] /
1 package org.apache.archiva.consumers.core;
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 org.apache.archiva.admin.model.beans.ManagedRepository;
23 import org.apache.archiva.configuration.ArchivaConfiguration;
24 import org.apache.archiva.configuration.ConfigurationNames;
25 import org.apache.archiva.configuration.FileTypes;
26 import org.apache.archiva.consumers.AbstractMonitoredConsumer;
27 import org.apache.archiva.consumers.ConsumerException;
28 import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
29 import org.apache.archiva.model.ArtifactReference;
30 import org.apache.archiva.model.ProjectReference;
31 import org.apache.archiva.model.VersionedReference;
32 import org.apache.archiva.repository.ContentNotFoundException;
33 import org.apache.archiva.repository.ManagedRepositoryContent;
34 import org.apache.archiva.repository.RepositoryContentFactory;
35 import org.apache.archiva.repository.RepositoryException;
36 import org.apache.archiva.repository.RepositoryNotFoundException;
37 import org.apache.archiva.repository.layout.LayoutException;
38 import org.apache.archiva.repository.metadata.MetadataTools;
39 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
40 import org.apache.archiva.redback.components.registry.Registry;
41 import org.apache.archiva.redback.components.registry.RegistryListener;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.context.annotation.Scope;
45 import org.springframework.stereotype.Service;
46
47 import javax.annotation.PostConstruct;
48 import javax.inject.Inject;
49 import java.io.File;
50 import java.io.IOException;
51 import java.util.ArrayList;
52 import java.util.Date;
53 import java.util.List;
54
55 /**
56  * MetadataUpdaterConsumer will create and update the metadata present within the repository.
57  *
58  *
59  */
60 @Service( "knownRepositoryContentConsumer#metadata-updater" )
61 @Scope( "prototype" )
62 public class MetadataUpdaterConsumer
63     extends AbstractMonitoredConsumer
64     implements KnownRepositoryContentConsumer, RegistryListener
65 {
66     private Logger log = LoggerFactory.getLogger( MetadataUpdaterConsumer.class );
67
68     /**
69      * default-value="metadata-updater"
70      */
71     private String id = "metadata-updater";
72
73     /**
74      * default-value="Update / Create maven-metadata.xml files"
75      */
76     private String description = "Update / Create maven-metadata.xml files";
77
78     /**
79      *
80      */
81     @Inject
82     private RepositoryContentFactory repositoryFactory;
83
84     /**
85      *
86      */
87     @Inject
88     private MetadataTools metadataTools;
89
90     /**
91      *
92      */
93     @Inject
94     private ArchivaConfiguration configuration;
95
96     /**
97      *
98      */
99     @Inject
100     private FileTypes filetypes;
101
102     private static final String TYPE_METADATA_BAD_INTERNAL_REF = "metadata-bad-internal-ref";
103
104     private static final String TYPE_METADATA_WRITE_FAILURE = "metadata-write-failure";
105
106     private static final String TYPE_METADATA_IO = "metadata-io-warning";
107
108     private ManagedRepositoryContent repository;
109
110     private File repositoryDir;
111
112     private List<String> includes = new ArrayList<>( 0 );
113
114     private long scanStartTimestamp = 0;
115
116     @Override
117     public String getDescription()
118     {
119         return description;
120     }
121
122     @Override
123     public String getId()
124     {
125         return id;
126     }
127
128     public void setIncludes( List<String> includes )
129     {
130         this.includes = includes;
131     }
132
133     @Override
134     public void beginScan( ManagedRepository repoConfig, Date whenGathered )
135         throws ConsumerException
136     {
137         try
138         {
139             this.repository = repositoryFactory.getManagedRepositoryContent( repoConfig.getId() );
140             this.repositoryDir = new File( repository.getRepoRoot() );
141             this.scanStartTimestamp = System.currentTimeMillis();
142         }
143         catch ( RepositoryNotFoundException e )
144         {
145             throw new ConsumerException( e.getMessage(), e );
146         }
147         catch ( RepositoryException e )
148         {
149             throw new ConsumerException( e.getMessage(), e );
150         }
151     }
152
153     @Override
154     public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo )
155         throws ConsumerException
156     {
157         beginScan( repository, whenGathered );
158     }
159
160     @Override
161     public void completeScan()
162     {
163         /* do nothing here */
164     }
165
166     @Override
167     public void completeScan( boolean executeOnEntireRepo )
168     {
169         completeScan();
170     }
171
172     @Override
173     public List<String> getExcludes()
174     {
175         return getDefaultArtifactExclusions();
176     }
177
178     @Override
179     public List<String> getIncludes()
180     {
181         return this.includes;
182     }
183
184     @Override
185     public void processFile( String path )
186         throws ConsumerException
187     {
188         // Ignore paths like .index etc
189         if ( !path.startsWith( "." ) )
190         {
191             try
192             {
193                 ArtifactReference artifact = repository.toArtifactReference( path );
194                 updateVersionMetadata( artifact, path );
195                 updateProjectMetadata( artifact, path );
196             }
197             catch ( LayoutException e )
198             {
199                 log.info( "Not processing path that is not an artifact: {} ({})", path, e.getMessage() );
200             }
201         }
202     }
203
204     @Override
205     public void processFile( String path, boolean executeOnEntireRepo )
206         throws Exception
207     {
208         processFile( path );
209     }
210
211     private void updateProjectMetadata( ArtifactReference artifact, String path )
212     {
213         ProjectReference projectRef = new ProjectReference();
214         projectRef.setGroupId( artifact.getGroupId() );
215         projectRef.setArtifactId( artifact.getArtifactId() );
216
217         try
218         {
219             String metadataPath = this.metadataTools.toPath( projectRef );
220
221             File projectMetadata = new File( this.repositoryDir, metadataPath );
222
223             if ( projectMetadata.exists() && ( projectMetadata.lastModified() >= this.scanStartTimestamp ) )
224             {
225                 // This metadata is up to date. skip it.
226                 log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( projectRef ) );
227                 return;
228             }
229
230             metadataTools.updateMetadata( this.repository, projectRef );
231             log.debug( "Updated metadata: {}", this.metadataTools.toPath( projectRef ) );
232         }
233         catch ( LayoutException e )
234         {
235             triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
236                                     "Unable to convert path [" + path + "] to an internal project reference: "
237                                         + e.getMessage() );
238         }
239         catch ( RepositoryMetadataException e )
240         {
241             triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
242                                   "Unable to write project metadata for artifact [" + path + "]: " + e.getMessage() );
243         }
244         catch ( IOException e )
245         {
246             triggerConsumerWarning( TYPE_METADATA_IO,
247                                     "Project metadata not written due to IO warning: " + e.getMessage() );
248         }
249         catch ( ContentNotFoundException e )
250         {
251             triggerConsumerWarning( TYPE_METADATA_IO,
252                                     "Project metadata not written because no versions were found to update: "
253                                         + e.getMessage() );
254         }
255     }
256
257     private void updateVersionMetadata( ArtifactReference artifact, String path )
258     {
259         VersionedReference versionRef = new VersionedReference();
260         versionRef.setGroupId( artifact.getGroupId() );
261         versionRef.setArtifactId( artifact.getArtifactId() );
262         versionRef.setVersion( artifact.getVersion() );
263
264         try
265         {
266             String metadataPath = this.metadataTools.toPath( versionRef );
267
268             File projectMetadata = new File( this.repositoryDir, metadataPath );
269
270             if ( projectMetadata.exists() && ( projectMetadata.lastModified() >= this.scanStartTimestamp ) )
271             {
272                 // This metadata is up to date. skip it.
273                 log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( versionRef ) );
274                 return;
275             }
276
277             metadataTools.updateMetadata( this.repository, versionRef );
278             log.debug( "Updated metadata: {}", this.metadataTools.toPath( versionRef ) );
279         }
280         catch ( LayoutException e )
281         {
282             triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
283                                     "Unable to convert path [" + path + "] to an internal version reference: "
284                                         + e.getMessage() );
285         }
286         catch ( RepositoryMetadataException e )
287         {
288             triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
289                                   "Unable to write version metadata for artifact [" + path + "]: " + e.getMessage() );
290         }
291         catch ( IOException e )
292         {
293             triggerConsumerWarning( TYPE_METADATA_IO,
294                                     "Version metadata not written due to IO warning: " + e.getMessage() );
295         }
296         catch ( ContentNotFoundException e )
297         {
298             triggerConsumerWarning( TYPE_METADATA_IO,
299                                     "Version metadata not written because no versions were found to update: "
300                                         + e.getMessage() );
301         }
302     }
303
304     @Override
305     public boolean isPermanent()
306     {
307         return false;
308     }
309
310     @Override
311     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
312     {
313         if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
314         {
315             initIncludes();
316         }
317     }
318
319     @Override
320     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
321     {
322         /* do nothing here */
323     }
324
325     private void initIncludes()
326     {
327         includes = new ArrayList<String>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
328     }
329
330     @PostConstruct
331     public void initialize()
332     {
333         configuration.addChangeListener( this );
334
335         initIncludes();
336     }
337 }