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