]> source.dussan.org Git - archiva.git/blob
73352400244227d4f5458dace01cb9adaa588e85
[archiva.git] /
1 package org.apache.maven.archiva.reporting;
2
3 /*
4  * Copyright 2005-2006 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import org.apache.maven.archiva.layer.RepositoryQueryLayer;
20 import org.apache.maven.archiva.layer.RepositoryQueryLayerFactory;
21 import org.apache.maven.artifact.Artifact;
22 import org.apache.maven.artifact.factory.ArtifactFactory;
23 import org.apache.maven.artifact.repository.ArtifactRepository;
24 import org.apache.maven.artifact.repository.metadata.Plugin;
25 import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
26 import org.apache.maven.artifact.repository.metadata.Snapshot;
27 import org.apache.maven.artifact.repository.metadata.Versioning;
28 import org.codehaus.plexus.util.FileUtils;
29
30 import java.io.File;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38
39 /**
40  * This class will report on bad metadata files.  These include invalid version declarations and incomplete version
41  * information inside the metadata file.  Plugin metadata will be checked for validity of the latest plugin artifacts.
42  *
43  * @plexus.component role="org.apache.maven.archiva.reporting.MetadataReportProcessor" role-hint="bad-metadata"
44  */
45 public class BadMetadataReportProcessor
46     implements MetadataReportProcessor
47 {
48     /**
49      * @plexus.requirement
50      */
51     private ArtifactFactory artifactFactory;
52
53     /**
54      * @plexus.requirement
55      */
56     private RepositoryQueryLayerFactory repositoryQueryLayerFactory;
57
58     /**
59      * Process the metadata encountered in the repository and report all errors found, if any.
60      *
61      * @param metadata   the metadata to be processed.
62      * @param repository the repository where the metadata was encountered
63      * @param reporter   the ArtifactReporter to receive processing results
64      * @throws ReportProcessorException if an error was occurred while processing the metadata
65      */
66     public void processMetadata( RepositoryMetadata metadata, ArtifactRepository repository, ArtifactReporter reporter )
67         throws ReportProcessorException
68     {
69         boolean hasFailures = false;
70
71         if ( metadata.storedInGroupDirectory() )
72         {
73             try
74             {
75                 hasFailures = checkPluginMetadata( metadata, repository, reporter );
76             }
77             catch ( IOException e )
78             {
79                 throw new ReportProcessorException( "Error getting plugin artifact directories versions", e );
80             }
81         }
82         else
83         {
84             String lastUpdated = metadata.getMetadata().getVersioning().getLastUpdated();
85             if ( lastUpdated == null || lastUpdated.length() == 0 )
86             {
87                 reporter.addFailure( metadata, "Missing lastUpdated element inside the metadata." );
88                 hasFailures = true;
89             }
90
91             if ( metadata.storedInArtifactVersionDirectory() )
92             {
93                 hasFailures |= checkSnapshotMetadata( metadata, repository, reporter );
94             }
95             else
96             {
97                 if ( !checkMetadataVersions( metadata, repository, reporter ) )
98                 {
99                     hasFailures = true;
100                 }
101
102                 try
103                 {
104                     if ( checkRepositoryVersions( metadata, repository, reporter ) )
105                     {
106                         hasFailures = true;
107                     }
108                 }
109                 catch ( IOException e )
110                 {
111                     throw new ReportProcessorException( "Error getting versions", e );
112                 }
113             }
114         }
115
116         if ( !hasFailures )
117         {
118             reporter.addSuccess( metadata );
119         }
120     }
121
122     /**
123      * Method for processing a GroupRepositoryMetadata
124      *
125      * @param metadata   the metadata to be processed.
126      * @param repository the repository where the metadata was encountered
127      * @param reporter   the ArtifactReporter to receive processing results
128      */
129     private boolean checkPluginMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
130                                          ArtifactReporter reporter )
131         throws IOException
132     {
133         boolean hasFailures = false;
134
135         File metadataDir =
136             new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
137         List pluginDirs = getArtifactIdFiles( metadataDir );
138
139         Map prefixes = new HashMap();
140         for ( Iterator plugins = metadata.getMetadata().getPlugins().iterator(); plugins.hasNext(); )
141         {
142             Plugin plugin = (Plugin) plugins.next();
143
144             String artifactId = plugin.getArtifactId();
145             if ( artifactId == null || artifactId.length() == 0 )
146             {
147                 reporter.addFailure( metadata, "Missing or empty artifactId in group metadata." );
148                 hasFailures = true;
149             }
150
151             String prefix = plugin.getPrefix();
152             if ( prefix == null || prefix.length() == 0 )
153             {
154                 reporter.addFailure( metadata, "Missing or empty plugin prefix for artifactId " + artifactId + "." );
155                 hasFailures = true;
156             }
157             else
158             {
159                 if ( prefixes.containsKey( prefix ) )
160                 {
161                     reporter.addFailure( metadata, "Duplicate plugin prefix found: " + prefix + "." );
162                     hasFailures = true;
163                 }
164                 else
165                 {
166                     prefixes.put( prefix, plugin );
167                 }
168             }
169
170             if ( artifactId != null && artifactId.length() > 0 )
171             {
172                 File pluginDir = new File( metadataDir, artifactId );
173                 if ( !pluginDirs.contains( pluginDir ) )
174                 {
175                     reporter.addFailure( metadata, "Metadata plugin " + artifactId + " not found in the repository" );
176                     hasFailures = true;
177                 }
178                 else
179                 {
180                     pluginDirs.remove( pluginDir );
181                 }
182             }
183         }
184
185         if ( pluginDirs.size() > 0 )
186         {
187             for ( Iterator plugins = pluginDirs.iterator(); plugins.hasNext(); )
188             {
189                 File plugin = (File) plugins.next();
190                 reporter.addFailure( metadata, "Plugin " + plugin.getName() + " is present in the repository but " +
191                     "missing in the metadata." );
192             }
193             hasFailures = true;
194         }
195
196         return hasFailures;
197     }
198
199     /**
200      * Method for processing a SnapshotArtifactRepository
201      *
202      * @param metadata   the metadata to be processed.
203      * @param repository the repository where the metadata was encountered
204      * @param reporter   the ArtifactReporter to receive processing results
205      */
206     private boolean checkSnapshotMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
207                                            ArtifactReporter reporter )
208     {
209         RepositoryQueryLayer repositoryQueryLayer =
210             repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
211
212         boolean hasFailures = false;
213
214         Snapshot snapshot = metadata.getMetadata().getVersioning().getSnapshot();
215         String timestamp = snapshot.getTimestamp();
216         String buildNumber = String.valueOf( snapshot.getBuildNumber() );
217
218         Artifact artifact = createArtifact( metadata );
219         if ( !repositoryQueryLayer.containsArtifact( artifact, snapshot ) )
220         {
221             reporter.addFailure( metadata, "Snapshot artifact " + timestamp + "-" + buildNumber + " does not exist." );
222             hasFailures = true;
223         }
224
225         return hasFailures;
226     }
227
228     /**
229      * Method for validating the versions declared inside an ArtifactRepositoryMetadata
230      *
231      * @param metadata   the metadata to be processed.
232      * @param repository the repository where the metadata was encountered
233      * @param reporter   the ArtifactReporter to receive processing results
234      */
235     private boolean checkMetadataVersions( RepositoryMetadata metadata, ArtifactRepository repository,
236                                            ArtifactReporter reporter )
237     {
238         RepositoryQueryLayer repositoryQueryLayer =
239             repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
240
241         boolean hasFailures = false;
242         Versioning versioning = metadata.getMetadata().getVersioning();
243         for ( Iterator versions = versioning.getVersions().iterator(); versions.hasNext(); )
244         {
245             String version = (String) versions.next();
246
247             Artifact artifact = createArtifact( metadata, version );
248
249             if ( !repositoryQueryLayer.containsArtifact( artifact ) )
250             {
251                 reporter.addFailure( metadata, "Artifact version " + version + " is present in metadata but " +
252                     "missing in the repository." );
253                 hasFailures = true;
254             }
255         }
256         return hasFailures;
257     }
258
259     /**
260      * Searches the artifact repository directory for all versions and verifies that all of them are listed in the
261      * ArtifactRepositoryMetadata
262      *
263      * @param metadata   the metadata to be processed.
264      * @param repository the repository where the metadata was encountered
265      * @param reporter   the ArtifactReporter to receive processing results
266      */
267     private boolean checkRepositoryVersions( RepositoryMetadata metadata, ArtifactRepository repository,
268                                              ArtifactReporter reporter )
269         throws IOException
270     {
271         boolean hasFailures = false;
272         Versioning versioning = metadata.getMetadata().getVersioning();
273         File versionsDir =
274             new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
275         List versions = FileUtils.getFileNames( versionsDir, "*/*.pom", null, false );
276         for ( Iterator i = versions.iterator(); i.hasNext(); )
277         {
278             File path = new File( (String) i.next() );
279             String version = path.getParentFile().getName();
280             if ( !versioning.getVersions().contains( version ) )
281             {
282                 reporter.addFailure( metadata, "Artifact version " + version + " found in the repository but " +
283                     "missing in the metadata." );
284                 hasFailures = true;
285             }
286         }
287         return hasFailures;
288     }
289
290     /**
291      * Used to create an artifact object from a metadata base version
292      */
293     private Artifact createArtifact( RepositoryMetadata metadata )
294     {
295         return artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(),
296                                                       metadata.getBaseVersion() );
297     }
298
299     /**
300      * Used to create an artifact object with a specified version
301      */
302     private Artifact createArtifact( RepositoryMetadata metadata, String version )
303     {
304         return artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(), version );
305     }
306
307     /**
308      * Used to gather artifactIds from a groupId directory
309      */
310     private List getArtifactIdFiles( File groupIdDir )
311         throws IOException
312     {
313         List artifactIdFiles = new ArrayList();
314
315         List fileArray = new ArrayList( Arrays.asList( groupIdDir.listFiles() ) );
316         for ( Iterator files = fileArray.iterator(); files.hasNext(); )
317         {
318             File artifactDir = (File) files.next();
319
320             if ( artifactDir.isDirectory() )
321             {
322                 List versions = FileUtils.getFileNames( artifactDir, "*/*.pom", null, false );
323                 if ( versions.size() > 0 )
324                 {
325                     artifactIdFiles.add( artifactDir );
326                 }
327             }
328         }
329
330         return artifactIdFiles;
331     }
332 }