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