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