1 package org.apache.maven.archiva.reporting.artifact;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.commons.collections.CollectionUtils;
23 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
24 import org.apache.maven.archiva.configuration.ConfigurationNames;
25 import org.apache.maven.archiva.configuration.FileTypes;
26 import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer;
27 import org.apache.maven.archiva.consumers.ArchivaArtifactConsumer;
28 import org.apache.maven.archiva.consumers.ConsumerException;
29 import org.apache.maven.archiva.database.ArchivaDAO;
30 import org.apache.maven.archiva.database.ArchivaDatabaseException;
31 import org.apache.maven.archiva.database.ObjectNotFoundException;
32 import org.apache.maven.archiva.database.constraints.ArtifactsByChecksumConstraint;
33 import org.apache.maven.archiva.model.ArchivaArtifact;
34 import org.apache.maven.archiva.model.RepositoryProblem;
35 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
36 import org.apache.maven.archiva.repository.RepositoryContentFactory;
37 import org.apache.maven.archiva.repository.RepositoryException;
38 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
39 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
40 import org.codehaus.plexus.registry.Registry;
41 import org.codehaus.plexus.registry.RegistryListener;
43 import java.util.ArrayList;
44 import java.util.List;
47 * Search the database of known SHA1 Checksums for potential duplicate artifacts.
49 * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
52 * @plexus.component role="org.apache.maven.archiva.consumers.ArchivaArtifactConsumer"
53 * role-hint="duplicate-artifacts"
55 public class DuplicateArtifactsConsumer
56 extends AbstractMonitoredConsumer
57 implements ArchivaArtifactConsumer, RegistryListener, Initializable
60 * @plexus.configuration default-value="duplicate-artifacts"
65 * @plexus.configuration default-value="Check for Duplicate Artifacts via SHA1 Checksums"
67 private String description;
72 private ArchivaConfiguration configuration;
77 private FileTypes filetypes;
80 * @plexus.requirement role-hint="jdo"
82 private ArchivaDAO dao;
87 private RepositoryContentFactory repositoryFactory;
89 private List<String> includes = new ArrayList<String>();
96 public String getDescription()
101 public boolean isPermanent()
106 public void beginScan()
111 public void completeScan()
116 public List<String> getIncludedTypes()
121 public void processArchivaArtifact( ArchivaArtifact artifact )
122 throws ConsumerException
124 String checksumSha1 = artifact.getModel().getChecksumSHA1();
126 List<ArchivaArtifact> results = null;
129 results = dao.getArtifactDAO().queryArtifacts( new ArtifactsByChecksumConstraint(
130 checksumSha1, ArtifactsByChecksumConstraint.SHA1 ) );
132 catch ( ObjectNotFoundException e )
134 getLogger().debug( "No duplicates for artifact: " + artifact );
137 catch ( ArchivaDatabaseException e )
139 getLogger().warn( "Unable to query DB for potential duplicates with : " + artifact );
143 if ( CollectionUtils.isNotEmpty( results ) )
145 if ( results.size() <= 1 )
147 // No duplicates detected.
148 getLogger().debug( "Found no duplicate artifact results on: " + artifact );
152 for ( ArchivaArtifact dupArtifact : results )
154 if ( dupArtifact.equals( artifact ) )
156 // Skip reference to itself.
160 RepositoryProblem problem = new RepositoryProblem();
161 problem.setRepositoryId( dupArtifact.getModel().getRepositoryId() );
162 problem.setPath( toPath( dupArtifact ) );
163 problem.setGroupId( artifact.getGroupId() );
164 problem.setArtifactId( artifact.getArtifactId() );
165 problem.setVersion( artifact.getVersion() );
166 problem.setType( DuplicateArtifactReport.PROBLEM_TYPE_DUPLICATE_ARTIFACTS );
167 problem.setOrigin( getId() );
168 problem.setMessage( "Duplicate Artifact Detected: " + artifact + " <--> " + dupArtifact );
172 getLogger().debug( "Found duplicate artifact: " + problem );
173 dao.getRepositoryProblemDAO().saveRepositoryProblem( problem );
175 catch ( ArchivaDatabaseException e )
177 String emsg = "Unable to save problem with duplicate artifact to DB: " + e.getMessage();
178 getLogger().warn( emsg, e );
179 throw new ConsumerException( emsg, e );
185 private String toPath( ArchivaArtifact artifact )
189 String repoId = artifact.getModel().getRepositoryId();
190 ManagedRepositoryContent repo = repositoryFactory.getManagedRepositoryContent( repoId );
191 return repo.toPath( artifact );
193 catch ( RepositoryException e )
195 getLogger().warn( "Unable to calculate path for artifact: " + artifact );
200 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
202 if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
208 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
213 private void initIncludes()
217 includes.addAll( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
220 public void initialize()
221 throws InitializationException
224 configuration.addChangeListener( this );