]> source.dussan.org Git - archiva.git/blob
ec55ad6e575ff39fce9d8665f535e9c85fb09a1a
[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
216         String version = metadata.getBaseVersion().replace( Artifact.SNAPSHOT_VERSION,
217                                                             snapshot.getTimestamp() + "-" + snapshot.getBuildNumber() );
218         Artifact artifact =
219             artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(), version );
220         artifact.isSnapshot(); // trigger baseVersion correction
221
222         if ( !repositoryQueryLayer.containsArtifact( artifact ) )
223         {
224             reporter.addFailure( metadata, "Snapshot artifact " + version + " does not exist." );
225             hasFailures = true;
226         }
227
228         return hasFailures;
229     }
230
231     /**
232      * Method for validating the versions declared inside an ArtifactRepositoryMetadata
233      *
234      * @param metadata   the metadata to be processed.
235      * @param repository the repository where the metadata was encountered
236      * @param reporter   the ArtifactReporter to receive processing results
237      */
238     private boolean checkMetadataVersions( RepositoryMetadata metadata, ArtifactRepository repository,
239                                            ArtifactReporter reporter )
240     {
241         RepositoryQueryLayer repositoryQueryLayer =
242             repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
243
244         boolean hasFailures = false;
245         Versioning versioning = metadata.getMetadata().getVersioning();
246         for ( Iterator versions = versioning.getVersions().iterator(); versions.hasNext(); )
247         {
248             String version = (String) versions.next();
249
250             Artifact artifact =
251                 artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(), version );
252
253             if ( !repositoryQueryLayer.containsArtifact( artifact ) )
254             {
255                 reporter.addFailure( metadata, "Artifact version " + version + " is present in metadata but " +
256                     "missing in the repository." );
257                 hasFailures = true;
258             }
259         }
260         return hasFailures;
261     }
262
263     /**
264      * Searches the artifact repository directory for all versions and verifies that all of them are listed in the
265      * ArtifactRepositoryMetadata
266      *
267      * @param metadata   the metadata to be processed.
268      * @param repository the repository where the metadata was encountered
269      * @param reporter   the ArtifactReporter to receive processing results
270      */
271     private boolean checkRepositoryVersions( RepositoryMetadata metadata, ArtifactRepository repository,
272                                              ArtifactReporter reporter )
273         throws IOException
274     {
275         boolean hasFailures = false;
276         Versioning versioning = metadata.getMetadata().getVersioning();
277         File versionsDir =
278             new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
279         List versions = FileUtils.getFileNames( versionsDir, "*/*.pom", null, false );
280         for ( Iterator i = versions.iterator(); i.hasNext(); )
281         {
282             File path = new File( (String) i.next() );
283             String version = path.getParentFile().getName();
284             if ( !versioning.getVersions().contains( version ) )
285             {
286                 reporter.addFailure( metadata, "Artifact version " + version + " found in the repository but " +
287                     "missing in the metadata." );
288                 hasFailures = true;
289             }
290         }
291         return hasFailures;
292     }
293
294     /**
295      * Used to gather artifactIds from a groupId directory.
296      *
297      * @param groupIdDir the directory of the group
298      * @return the list of artifact ID File objects for each directory
299      * @throws IOException if there was a failure to read the directories
300      */
301     private List getArtifactIdFiles( File groupIdDir )
302         throws IOException
303     {
304         List artifactIdFiles = new ArrayList();
305
306         List fileArray = new ArrayList( Arrays.asList( groupIdDir.listFiles() ) );
307         for ( Iterator files = fileArray.iterator(); files.hasNext(); )
308         {
309             File artifactDir = (File) files.next();
310
311             if ( artifactDir.isDirectory() )
312             {
313                 List versions = FileUtils.getFileNames( artifactDir, "*/*.pom", null, false );
314                 if ( versions.size() > 0 )
315                 {
316                     artifactIdFiles.add( artifactDir );
317                 }
318             }
319         }
320
321         return artifactIdFiles;
322     }
323 }