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;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
40 * This class will report on bad metadata files. These include invalid version declarations and incomplete version
41 * information inside the metadata file. Plugin metadata will be checked for validity of the latest plugin artifacts.
43 * @plexus.component role="org.apache.maven.archiva.reporting.MetadataReportProcessor" role-hint="bad-metadata"
45 public class BadMetadataReportProcessor
46 implements MetadataReportProcessor
51 private ArtifactFactory artifactFactory;
56 private RepositoryQueryLayerFactory repositoryQueryLayerFactory;
59 * Process the metadata encountered in the repository and report all errors found, if any.
61 * @param metadata the metadata to be processed.
62 * @param repository the repository where the metadata was encountered
63 * @param reporter the ArtifactReporter to receive processing results
64 * @throws ReportProcessorException if an error was occurred while processing the metadata
66 public void processMetadata( RepositoryMetadata metadata, ArtifactRepository repository, ArtifactReporter reporter )
67 throws ReportProcessorException
69 boolean hasFailures = false;
71 if ( metadata.storedInGroupDirectory() )
75 hasFailures = checkPluginMetadata( metadata, repository, reporter );
77 catch ( IOException e )
79 throw new ReportProcessorException( "Error getting plugin artifact directories versions", e );
84 String lastUpdated = metadata.getMetadata().getVersioning().getLastUpdated();
85 if ( lastUpdated == null || lastUpdated.length() == 0 )
87 reporter.addFailure( metadata, "Missing lastUpdated element inside the metadata." );
91 if ( metadata.storedInArtifactVersionDirectory() )
93 hasFailures |= checkSnapshotMetadata( metadata, repository, reporter );
97 if ( !checkMetadataVersions( metadata, repository, reporter ) )
104 if ( checkRepositoryVersions( metadata, repository, reporter ) )
109 catch ( IOException e )
111 throw new ReportProcessorException( "Error getting versions", e );
118 reporter.addSuccess( metadata );
123 * Method for processing a GroupRepositoryMetadata
125 * @param metadata the metadata to be processed.
126 * @param repository the repository where the metadata was encountered
127 * @param reporter the ArtifactReporter to receive processing results
129 private boolean checkPluginMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
130 ArtifactReporter reporter )
133 boolean hasFailures = false;
136 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
137 List pluginDirs = getArtifactIdFiles( metadataDir );
139 Map prefixes = new HashMap();
140 for ( Iterator plugins = metadata.getMetadata().getPlugins().iterator(); plugins.hasNext(); )
142 Plugin plugin = (Plugin) plugins.next();
144 String artifactId = plugin.getArtifactId();
145 if ( artifactId == null || artifactId.length() == 0 )
147 reporter.addFailure( metadata, "Missing or empty artifactId in group metadata." );
151 String prefix = plugin.getPrefix();
152 if ( prefix == null || prefix.length() == 0 )
154 reporter.addFailure( metadata, "Missing or empty plugin prefix for artifactId " + artifactId + "." );
159 if ( prefixes.containsKey( prefix ) )
161 reporter.addFailure( metadata, "Duplicate plugin prefix found: " + prefix + "." );
166 prefixes.put( prefix, plugin );
170 if ( artifactId != null && artifactId.length() > 0 )
172 File pluginDir = new File( metadataDir, artifactId );
173 if ( !pluginDirs.contains( pluginDir ) )
175 reporter.addFailure( metadata, "Metadata plugin " + artifactId + " not found in the repository" );
180 pluginDirs.remove( pluginDir );
185 if ( pluginDirs.size() > 0 )
187 for ( Iterator plugins = pluginDirs.iterator(); plugins.hasNext(); )
189 File plugin = (File) plugins.next();
190 reporter.addFailure( metadata, "Plugin " + plugin.getName() + " is present in the repository but " +
191 "missing in the metadata." );
200 * Method for processing a SnapshotArtifactRepository
202 * @param metadata the metadata to be processed.
203 * @param repository the repository where the metadata was encountered
204 * @param reporter the ArtifactReporter to receive processing results
206 private boolean checkSnapshotMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
207 ArtifactReporter reporter )
209 RepositoryQueryLayer repositoryQueryLayer =
210 repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
212 boolean hasFailures = false;
214 Snapshot snapshot = metadata.getMetadata().getVersioning().getSnapshot();
215 String timestamp = snapshot.getTimestamp();
216 String buildNumber = String.valueOf( snapshot.getBuildNumber() );
218 Artifact artifact = createArtifact( metadata );
219 if ( !repositoryQueryLayer.containsArtifact( artifact, snapshot ) )
221 reporter.addFailure( metadata, "Snapshot artifact " + timestamp + "-" + buildNumber + " does not exist." );
229 * Method for validating the versions declared inside an ArtifactRepositoryMetadata
231 * @param metadata the metadata to be processed.
232 * @param repository the repository where the metadata was encountered
233 * @param reporter the ArtifactReporter to receive processing results
235 private boolean checkMetadataVersions( RepositoryMetadata metadata, ArtifactRepository repository,
236 ArtifactReporter reporter )
238 RepositoryQueryLayer repositoryQueryLayer =
239 repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
241 boolean hasFailures = false;
242 Versioning versioning = metadata.getMetadata().getVersioning();
243 for ( Iterator versions = versioning.getVersions().iterator(); versions.hasNext(); )
245 String version = (String) versions.next();
247 Artifact artifact = createArtifact( metadata, version );
249 if ( !repositoryQueryLayer.containsArtifact( artifact ) )
251 reporter.addFailure( metadata, "Artifact version " + version + " is present in metadata but " +
252 "missing in the repository." );
260 * Searches the artifact repository directory for all versions and verifies that all of them are listed in the
261 * ArtifactRepositoryMetadata
263 * @param metadata the metadata to be processed.
264 * @param repository the repository where the metadata was encountered
265 * @param reporter the ArtifactReporter to receive processing results
267 private boolean checkRepositoryVersions( RepositoryMetadata metadata, ArtifactRepository repository,
268 ArtifactReporter reporter )
271 boolean hasFailures = false;
272 Versioning versioning = metadata.getMetadata().getVersioning();
274 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
275 List versions = FileUtils.getFileNames( versionsDir, "*/*.pom", null, false );
276 for ( Iterator i = versions.iterator(); i.hasNext(); )
278 File path = new File( (String) i.next() );
279 String version = path.getParentFile().getName();
280 if ( !versioning.getVersions().contains( version ) )
282 reporter.addFailure( metadata, "Artifact version " + version + " found in the repository but " +
283 "missing in the metadata." );
291 * Used to create an artifact object from a metadata base version
293 private Artifact createArtifact( RepositoryMetadata metadata )
295 return artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(),
296 metadata.getBaseVersion() );
300 * Used to create an artifact object with a specified version
302 private Artifact createArtifact( RepositoryMetadata metadata, String version )
304 return artifactFactory.createProjectArtifact( metadata.getGroupId(), metadata.getArtifactId(), version );
308 * Used to gather artifactIds from a groupId directory
310 private List getArtifactIdFiles( File groupIdDir )
313 List artifactIdFiles = new ArrayList();
315 List fileArray = new ArrayList( Arrays.asList( groupIdDir.listFiles() ) );
316 for ( Iterator files = fileArray.iterator(); files.hasNext(); )
318 File artifactDir = (File) files.next();
320 if ( artifactDir.isDirectory() )
322 List versions = FileUtils.getFileNames( artifactDir, "*/*.pom", null, false );
323 if ( versions.size() > 0 )
325 artifactIdFiles.add( artifactDir );
330 return artifactIdFiles;