1 package org.apache.maven.archiva.reporting;
4 * Copyright 2005-2006 The Apache Software Foundation.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
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;
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.
45 * @plexus.component role="org.apache.maven.archiva.reporting.MetadataReportProcessor" role-hint="bad-metadata"
47 public class BadMetadataReportProcessor
48 implements MetadataReportProcessor
53 private ArtifactFactory artifactFactory;
58 private RepositoryQueryLayerFactory repositoryQueryLayerFactory;
61 * Process the metadata encountered in the repository and report all errors found, if any.
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
67 public void processMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
68 ReportingDatabase reporter )
70 if ( metadata.storedInGroupDirectory() )
74 checkPluginMetadata( metadata, repository, reporter );
76 catch ( IOException e )
78 reporter.addWarning( metadata, "Error getting plugin artifact directories versions: " + e );
83 Versioning versioning = metadata.getMetadata().getVersioning();
84 boolean found = false;
85 if ( versioning != null )
87 String lastUpdated = versioning.getLastUpdated();
88 if ( lastUpdated != null && lastUpdated.length() != 0 )
95 reporter.addFailure( metadata, "Missing lastUpdated element inside the metadata." );
98 if ( metadata.storedInArtifactVersionDirectory() )
100 checkSnapshotMetadata( metadata, repository, reporter );
104 checkMetadataVersions( metadata, repository, reporter );
108 checkRepositoryVersions( metadata, repository, reporter );
110 catch ( IOException e )
112 reporter.addWarning( metadata, "Error getting plugin artifact directories versions: " + e );
119 * Method for processing a GroupRepositoryMetadata
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
125 private void checkPluginMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
126 ReportingDatabase reporter )
130 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
131 List pluginDirs = getArtifactIdFiles( metadataDir );
133 Map prefixes = new HashMap();
134 for ( Iterator plugins = metadata.getMetadata().getPlugins().iterator(); plugins.hasNext(); )
136 Plugin plugin = (Plugin) plugins.next();
138 String artifactId = plugin.getArtifactId();
139 if ( artifactId == null || artifactId.length() == 0 )
141 reporter.addFailure( metadata,
142 "Missing or empty artifactId in group metadata for plugin " + plugin.getPrefix() );
145 String prefix = plugin.getPrefix();
146 if ( prefix == null || prefix.length() == 0 )
148 reporter.addFailure( metadata, "Missing or empty plugin prefix for artifactId " + artifactId + "." );
152 if ( prefixes.containsKey( prefix ) )
154 reporter.addFailure( metadata, "Duplicate plugin prefix found: " + prefix + "." );
158 prefixes.put( prefix, plugin );
162 if ( artifactId != null && artifactId.length() > 0 )
164 File pluginDir = new File( metadataDir, artifactId );
165 if ( !pluginDirs.contains( pluginDir ) )
167 reporter.addFailure( metadata, "Metadata plugin " + artifactId + " not found in the repository" );
171 pluginDirs.remove( pluginDir );
176 if ( pluginDirs.size() > 0 )
178 for ( Iterator plugins = pluginDirs.iterator(); plugins.hasNext(); )
180 File plugin = (File) plugins.next();
181 reporter.addFailure( metadata, "Plugin " + plugin.getName() + " is present in the repository but " +
182 "missing in the metadata." );
188 * Method for processing a SnapshotArtifactRepository
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
194 private void checkSnapshotMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
195 ReportingDatabase reporter )
197 RepositoryQueryLayer repositoryQueryLayer =
198 repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
200 Versioning versioning = metadata.getMetadata().getVersioning();
201 if ( versioning != null )
203 Snapshot snapshot = versioning.getSnapshot();
205 String version = StringUtils.replace( metadata.getBaseVersion(), Artifact.SNAPSHOT_VERSION,
206 snapshot.getTimestamp() + "-" + snapshot.getBuildNumber() );
208 artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(), version );
209 artifact.isSnapshot(); // trigger baseVersion correction
211 if ( !repositoryQueryLayer.containsArtifact( artifact ) )
213 reporter.addFailure( metadata, "Snapshot artifact " + version + " does not exist." );
219 * Method for validating the versions declared inside an ArtifactRepositoryMetadata
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
225 private void checkMetadataVersions( RepositoryMetadata metadata, ArtifactRepository repository,
226 ReportingDatabase reporter )
228 RepositoryQueryLayer repositoryQueryLayer =
229 repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
231 Versioning versioning = metadata.getMetadata().getVersioning();
232 if ( versioning != null )
234 for ( Iterator versions = versioning.getVersions().iterator(); versions.hasNext(); )
236 String version = (String) versions.next();
239 artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(), version );
241 if ( !repositoryQueryLayer.containsArtifact( artifact ) )
243 reporter.addFailure( metadata, "Artifact version " + version + " is present in metadata but " +
244 "missing in the repository." );
251 * Searches the artifact repository directory for all versions and verifies that all of them are listed in the
252 * ArtifactRepositoryMetadata
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
258 private void checkRepositoryVersions( RepositoryMetadata metadata, ArtifactRepository repository,
259 ReportingDatabase reporter )
262 Versioning versioning = metadata.getMetadata().getVersioning();
263 List metadataVersions = versioning != null ? versioning.getVersions() : Collections.EMPTY_LIST;
265 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
267 // TODO: I don't know how this condition can happen, but it was seen on the main repository.
268 // Avoid hard failure
269 if ( versionsDir.exists() )
271 List versions = FileUtils.getFileNames( versionsDir, "*/*.pom", null, false );
272 for ( Iterator i = versions.iterator(); i.hasNext(); )
274 File path = new File( (String) i.next() );
275 String version = path.getParentFile().getName();
276 if ( !metadataVersions.contains( version ) )
278 reporter.addFailure( metadata, "Artifact version " + version + " found in the repository but " +
279 "missing in the metadata." );
285 reporter.addFailure( metadata, "Metadata's directory did not exist: " + versionsDir );
290 * Used to gather artifactIds from a groupId directory.
292 * @param groupIdDir the directory of the group
293 * @return the list of artifact ID File objects for each directory
294 * @throws IOException if there was a failure to read the directories
296 private List getArtifactIdFiles( File groupIdDir )
299 List artifactIdFiles = new ArrayList();
301 File[] files = groupIdDir.listFiles();
304 for ( Iterator i = Arrays.asList( files ).iterator(); i.hasNext(); )
306 File artifactDir = (File) i.next();
308 if ( artifactDir.isDirectory() )
310 List versions = FileUtils.getFileNames( artifactDir, "*/*.pom", null, false );
311 if ( versions.size() > 0 )
313 artifactIdFiles.add( artifactDir );
319 return artifactIdFiles;