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