1 package org.apache.maven.repository.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.artifact.Artifact;
20 import org.apache.maven.artifact.factory.ArtifactFactory;
21 import org.apache.maven.artifact.repository.ArtifactRepository;
22 import org.apache.maven.artifact.repository.metadata.Plugin;
23 import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
24 import org.apache.maven.artifact.repository.metadata.Snapshot;
25 import org.apache.maven.artifact.repository.metadata.Versioning;
26 import org.codehaus.plexus.util.FileUtils;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.List;
38 * This class will report on bad metadata files. These include invalid version declarations and incomplete version
39 * information inside the metadata file. Plugin metadata will be checked for validity of the latest plugin artifacts.
41 public class BadMetadataReportProcessor
42 implements MetadataReportProcessor
45 private ArtifactFactory artifactFactory;
47 private RepositoryQueryLayerFactory repositoryQueryLayerFactory;
51 * Process the metadata encountered in the repository and report all errors found, if any.
53 * @param metadata the metadata to be processed.
54 * @param repository the repository where the metadata was encountered
55 * @param reporter the ArtifactReporter to receive processing results
56 * @throws ReportProcessorException if an error was occurred while processing the metadata
58 public void processMetadata( RepositoryMetadata metadata, ArtifactRepository repository, ArtifactReporter reporter )
59 throws ReportProcessorException
61 boolean hasFailures = false;
63 if ( metadata.storedInGroupDirectory() )
67 checkPluginMetadata( metadata, repository, reporter );
69 catch ( IOException e )
71 throw new ReportProcessorException( "Error getting plugin artifact directories versions", e );
76 String lastUpdated = metadata.getMetadata().getVersioning().getLastUpdated();
77 if ( lastUpdated == null || lastUpdated.length() == 0 )
79 reporter.addFailure( metadata, "Missing lastUpdated element inside the metadata." );
83 if ( metadata.storedInArtifactVersionDirectory() )
85 checkSnapshotMetadata( metadata, repository, reporter );
89 if ( !checkMetadataVersions( metadata, repository, reporter ) )
96 if ( checkRepositoryVersions( metadata, repository, reporter ) )
101 catch ( IOException e )
103 throw new ReportProcessorException( "Error getting versions", e );
110 reporter.addSuccess( metadata );
115 * Method for processing a GroupRepositoryMetadata
117 * @param metadata the metadata to be processed.
118 * @param repository the repository where the metadata was encountered
119 * @param reporter the ArtifactReporter to receive processing results
121 protected boolean checkPluginMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
122 ArtifactReporter reporter )
125 boolean hasFailures = false;
128 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
129 List pluginDirs = getArtifactIdFiles( metadataDir );
131 HashMap prefixes = new HashMap();
132 for ( Iterator plugins = metadata.getMetadata().getPlugins().iterator(); plugins.hasNext(); )
134 Plugin plugin = (Plugin) plugins.next();
136 String artifactId = plugin.getArtifactId();
137 if ( artifactId == null || artifactId.length() == 0 )
139 reporter.addFailure( metadata, "Missing or empty artifactId in group metadata." );
143 String prefix = plugin.getPrefix();
144 if ( prefix == null || prefix.length() == 0 )
146 reporter.addFailure( metadata, "Missing or empty plugin prefix for artifactId " + artifactId + "." );
151 if ( prefixes.containsKey( prefix ) )
153 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" );
172 pluginDirs.remove( pluginDir );
177 if ( pluginDirs.size() > 0 )
179 for ( Iterator plugins = pluginDirs.iterator(); plugins.hasNext(); )
181 File plugin = (File) plugins.next();
182 reporter.addFailure( metadata, "Plugin " + plugin.getName() + " is present in the repository but " +
183 "missing in the metadata." );
192 * Method for processing a SnapshotArtifactRepository
194 * @param metadata the metadata to be processed.
195 * @param repository the repository where the metadata was encountered
196 * @param reporter the ArtifactReporter to receive processing results
198 protected boolean checkSnapshotMetadata( RepositoryMetadata metadata, ArtifactRepository repository,
199 ArtifactReporter reporter )
201 RepositoryQueryLayer repositoryQueryLayer =
202 repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
204 boolean hasFailures = false;
206 Snapshot snapshot = metadata.getMetadata().getVersioning().getSnapshot();
207 String timestamp = snapshot.getTimestamp();
208 String buildNumber = String.valueOf( snapshot.getBuildNumber() );
210 Artifact artifact = createArtifact( metadata );
211 if ( !repositoryQueryLayer.containsArtifact( artifact, snapshot ) )
213 reporter.addFailure( metadata, "Snapshot artifact " + timestamp + "-" + buildNumber + " does not exist." );
221 * Method for validating the versions declared inside an ArtifactRepositoryMetadata
223 * @param metadata the metadata to be processed.
224 * @param repository the repository where the metadata was encountered
225 * @param reporter the ArtifactReporter to receive processing results
227 protected boolean checkMetadataVersions( RepositoryMetadata metadata, ArtifactRepository repository,
228 ArtifactReporter reporter )
230 RepositoryQueryLayer repositoryQueryLayer =
231 repositoryQueryLayerFactory.createRepositoryQueryLayer( repository );
233 boolean hasFailures = false;
234 Versioning versioning = metadata.getMetadata().getVersioning();
235 for ( Iterator versions = versioning.getVersions().iterator(); versions.hasNext(); )
237 String version = (String) versions.next();
239 Artifact artifact = createArtifact( metadata, version );
241 if ( !repositoryQueryLayer.containsArtifact( artifact ) )
243 reporter.addFailure( metadata, "Artifact version " + version + " is present in metadata but " +
244 "missing in the repository." );
252 * Searches the artifact repository directory for all versions and verifies that all of them are listed in the
253 * ArtifactRepositoryMetadata
255 * @param metadata the metadata to be processed.
256 * @param repository the repository where the metadata was encountered
257 * @param reporter the ArtifactReporter to receive processing results
259 protected boolean checkRepositoryVersions( RepositoryMetadata metadata, ArtifactRepository repository,
260 ArtifactReporter reporter )
263 boolean hasFailures = false;
264 Versioning versioning = metadata.getMetadata().getVersioning();
265 // TODO: change this to look for repository artifacts. It needs to centre around that I think, currently this is hardwired to the default layout
267 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( metadata ) ).getParentFile();
268 List versions = FileUtils.getFileNames( versionsDir, "*/*.pom", null, false );
269 for ( Iterator i = versions.iterator(); i.hasNext(); )
271 File path = new File( (String) i.next() );
272 String version = path.getParentFile().getName();
273 if ( !versioning.getVersions().contains( version ) )
275 reporter.addFailure( metadata, "Artifact version " + version + " found in the repository but " +
276 "missing in the metadata." );
284 * Used to create an artifact object from a metadata base version
286 private Artifact createArtifact( RepositoryMetadata metadata )
288 return artifactFactory.createBuildArtifact( metadata.getGroupId(), metadata.getArtifactId(),
289 metadata.getBaseVersion(), "pom" );
293 * Used to create an artifact object with a specified version
295 private Artifact createArtifact( RepositoryMetadata metadata, String version )
297 return artifactFactory.createBuildArtifact( metadata.getGroupId(), metadata.getArtifactId(), version, "pom" );
301 * Used to gather artifactIds from a groupId directory
303 private List getArtifactIdFiles( File groupIdDir )
306 List artifactIdFiles = new ArrayList();
308 List fileArray = new ArrayList( Arrays.asList( groupIdDir.listFiles() ) );
309 for ( Iterator files = fileArray.iterator(); files.hasNext(); )
311 File artifactDir = (File) files.next();
313 if ( artifactDir.isDirectory() )
315 List versions = FileUtils.getFileNames( artifactDir, "*/*.pom", null, false );
316 if ( versions.size() > 0 )
318 artifactIdFiles.add( artifactDir );
323 return artifactIdFiles;