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