Index: archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveArtifactConsumer.java =================================================================== --- archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveArtifactConsumer.java (revision 627380) +++ archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveArtifactConsumer.java (working copy) @@ -22,9 +22,13 @@ import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer; import org.apache.maven.archiva.consumers.ConsumerException; import org.apache.maven.archiva.consumers.DatabaseCleanupConsumer; +import org.apache.maven.archiva.database.Constraint; +import org.apache.maven.archiva.database.RepositoryProblemDAO; +import org.apache.maven.archiva.database.constraints.RepositoryProblemByArtifactConstraint; import org.apache.maven.archiva.model.ArchivaArtifact; import org.apache.maven.archiva.database.ArtifactDAO; import org.apache.maven.archiva.database.ArchivaDatabaseException; +import org.apache.maven.archiva.model.RepositoryProblem; import org.apache.maven.archiva.repository.ManagedRepositoryContent; import org.apache.maven.archiva.repository.RepositoryContentFactory; import org.apache.maven.archiva.repository.RepositoryException; @@ -61,8 +65,13 @@ * @plexus.requirement role-hint="jdo" */ private ArtifactDAO artifactDAO; - + /** + * @plexus.requirement role-hint="jdo" + */ + private RepositoryProblemDAO repositoryProblemDAO; + + /** * @plexus.requirement */ private RepositoryContentFactory repositoryFactory; @@ -80,34 +89,47 @@ public List getIncludedTypes() { - return null; + return null; } public void processArchivaArtifact( ArchivaArtifact artifact ) throws ConsumerException - { - try - { - ManagedRepositoryContent repositoryContent = - repositoryFactory.getManagedRepositoryContent( artifact.getModel().getRepositoryId() ); - - File file = new File( repositoryContent.getRepoRoot(), repositoryContent.toPath( artifact ) ); - - if( !file.exists() ) - { - artifactDAO.deleteArtifact( artifact ); - } - } - catch ( RepositoryException re ) - { - throw new ConsumerException( "Can't run database cleanup remove artifact consumer: " + - re.getMessage() ); - } - catch ( ArchivaDatabaseException e ) + { + try { + ManagedRepositoryContent repositoryContent = + repositoryFactory.getManagedRepositoryContent( artifact.getModel().getRepositoryId() ); + + File file = new File( repositoryContent.getRepoRoot(), repositoryContent.toPath( artifact ) ); + + if( !file.exists() ) + { + artifactDAO.deleteArtifact( artifact ); + + // Remove all repository problems related to this artifact + Constraint artifactConstraint = new RepositoryProblemByArtifactConstraint( artifact ); + List repositoryProblems = + repositoryProblemDAO.queryRepositoryProblems( artifactConstraint ); + + if ( repositoryProblems != null ) + { + for ( RepositoryProblem repositoryProblem : repositoryProblems ) + { + repositoryProblemDAO.deleteRepositoryProblem( repositoryProblem ); + } + } + } + } + catch ( RepositoryException re ) + { + throw new ConsumerException( "Can't run database cleanup remove artifact consumer: " + + re.getMessage() ); + } + catch ( ArchivaDatabaseException e ) + { throw new ConsumerException( e.getMessage() ); } - } + } public String getDescription() { @@ -128,9 +150,14 @@ { this.artifactDAO = artifactDAO; } - + + public void setRepositoryProblemDAO( RepositoryProblemDAO repositoryProblemDAO ) + { + this.repositoryProblemDAO = repositoryProblemDAO; + } + public void setRepositoryFactory( RepositoryContentFactory repositoryFactory ) { this.repositoryFactory = repositoryFactory; - } + } } Index: archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveProjectConsumer.java =================================================================== --- archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveProjectConsumer.java (revision 627380) +++ archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveProjectConsumer.java (working copy) @@ -23,13 +23,20 @@ import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer; import org.apache.maven.archiva.consumers.ConsumerException; import org.apache.maven.archiva.consumers.DatabaseCleanupConsumer; +import org.apache.maven.archiva.database.ArtifactDAO; +import org.apache.maven.archiva.database.Constraint; +import org.apache.maven.archiva.database.RepositoryProblemDAO; +import org.apache.maven.archiva.database.constraints.RepositoryProblemByArtifactConstraint; import org.apache.maven.archiva.model.ArchivaArtifact; +import org.apache.maven.archiva.model.ArchivaArtifactModel; import org.apache.maven.archiva.model.ArchivaProjectModel; +import org.apache.maven.archiva.model.RepositoryProblem; import org.apache.maven.archiva.repository.ManagedRepositoryContent; import org.apache.maven.archiva.repository.RepositoryContentFactory; import org.apache.maven.archiva.repository.RepositoryException; import org.apache.maven.archiva.database.ProjectModelDAO; import org.apache.maven.archiva.database.ArchivaDatabaseException; +import org.codehaus.plexus.cache.Cache; import java.util.List; import java.io.File; @@ -64,12 +71,27 @@ * @plexus.requirement role-hint="jdo" */ private ProjectModelDAO projectModelDAO; + + /** + * @plexus.requirement role-hint="jdo" + */ + private ArtifactDAO artifactDAO; + + /** + * @plexus.requirement role-hint="jdo" + */ + private RepositoryProblemDAO repositoryProblemDAO; /** * @plexus.requirement */ private RepositoryContentFactory repositoryFactory; + /** + * @plexus.requirement role-hint="effective-project-cache" + */ + private Cache effectiveProjectCache; + public void beginScan() { // TODO Auto-generated method stub @@ -81,44 +103,88 @@ } public List getIncludedTypes() - { - return null; + { + return null; } public void processArchivaArtifact( ArchivaArtifact artifact ) throws ConsumerException - { - if ( !StringUtils.equals( "pom", artifact.getType() ) ) + { + if ( !StringUtils.equals( "pom", artifact.getType() ) ) { - // Not a pom. Skip it. + // Not a pom. Skip it. return; } - - try - { - ManagedRepositoryContent repositoryContent = - repositoryFactory.getManagedRepositoryContent( artifact.getModel().getRepositoryId() ); - - File file = new File( repositoryContent.getRepoRoot(), repositoryContent.toPath( artifact ) ); - - if( !file.exists() ) - { - ArchivaProjectModel projectModel = projectModelDAO.getProjectModel( - artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() ); - - projectModelDAO.deleteProjectModel( projectModel ); - } - } - catch ( RepositoryException re ) - { - throw new ConsumerException( "Can't run database cleanup remove artifact consumer: " + - re.getMessage() ); - } - catch ( ArchivaDatabaseException e ) - { + + try + { + ManagedRepositoryContent repositoryContent = + repositoryFactory.getManagedRepositoryContent( artifact.getModel().getRepositoryId() ); + + File file = new File( repositoryContent.getRepoRoot(), repositoryContent.toPath( artifact ) ); + + if( !file.exists() ) + { + ArchivaProjectModel projectModel = projectModelDAO.getProjectModel( + artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() ); + + projectModelDAO.deleteProjectModel( projectModel ); + } + else + { + ArchivaArtifactModel artifactModel = artifact.getModel(); + + // Force artifact update if it has been modified since + // last time it was processed + if ( artifactModel.getWhenProcessed() != null && + artifactModel.getWhenProcessed().before( artifactModel.getLastModified() ) ) + { + // Set artifact to unprocessed and save it to database + artifactModel.setWhenProcessed( null ); + artifactDAO.saveArtifact( artifact ); + + // Remove current project model so it can be re-created + // once artifact gets processed again + ArchivaProjectModel projectModel = + projectModelDAO.getProjectModel( artifact.getGroupId(), artifact.getArtifactId(), + artifact.getVersion() ); + projectModelDAO.deleteProjectModel( projectModel ); + + // Force removal of project model from effective cache + String projectKey = toProjectKey( projectModel ); + synchronized ( effectiveProjectCache ) + { + if ( effectiveProjectCache.hasKey( projectKey ) ) + { + effectiveProjectCache.remove( projectKey ); + } + } + } + + // Remove all repository problems related to this artifact + Constraint artifactConstraint = new RepositoryProblemByArtifactConstraint( artifact ); + List repositoryProblems = + repositoryProblemDAO.queryRepositoryProblems( artifactConstraint ); + + if ( repositoryProblems != null ) + { + for ( RepositoryProblem repositoryProblem : repositoryProblems ) + { + repositoryProblemDAO.deleteRepositoryProblem( repositoryProblem ); + } + } + } + } + catch ( RepositoryException re ) + { + throw new ConsumerException( "Can't run database cleanup remove artifact consumer: " + + re.getMessage() ); + } + catch ( ArchivaDatabaseException e ) + { throw new ConsumerException( e.getMessage() ); - } - + } + } public String getDescription() @@ -134,16 +200,31 @@ public boolean isPermanent() { return false; - } - + } + public void setProjectModelDAO( ProjectModelDAO projectModelDAO ) { this.projectModelDAO = projectModelDAO; } + + public void setRepositoryProblemDAO( RepositoryProblemDAO repositoryProblemDAO ) + { + this.repositoryProblemDAO = repositoryProblemDAO; + } public void setRepositoryFactory( RepositoryContentFactory repositoryFactory ) { this.repositoryFactory = repositoryFactory; } - + + private String toProjectKey( ArchivaProjectModel project ) + { + StringBuilder key = new StringBuilder(); + + key.append( project.getGroupId() ).append( ":" ); + key.append( project.getArtifactId() ).append( ":" ); + key.append( project.getVersion() ); + + return key.toString(); + } } Index: archiva-base/archiva-consumers/archiva-database-consumers/src/test/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveArtifactConsumerTest.java =================================================================== --- archiva-base/archiva-consumers/archiva-database-consumers/src/test/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveArtifactConsumerTest.java (revision 627380) +++ archiva-base/archiva-consumers/archiva-database-consumers/src/test/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveArtifactConsumerTest.java (working copy) @@ -22,10 +22,11 @@ import org.easymock.MockControl; import org.apache.maven.archiva.model.ArchivaArtifact; import org.apache.maven.archiva.database.ArtifactDAO; +import org.apache.maven.archiva.database.RepositoryProblemDAO; /** * Test for DatabaseCleanupRemoveArtifactConsumerTest - * + * * @author Maria Odea Ching */ public class DatabaseCleanupRemoveArtifactConsumerTest @@ -35,6 +36,10 @@ private ArtifactDAO artifactDAOMock; + private MockControl repositoryProblemDAOControl; + + private RepositoryProblemDAO repositoryProblemDAOMock; + private DatabaseCleanupRemoveArtifactConsumer dbCleanupRemoveArtifactConsumer; public void setUp() @@ -48,8 +53,14 @@ artifactDAOMock = (ArtifactDAO) artifactDAOControl.getMock(); + repositoryProblemDAOControl = MockControl.createControl( RepositoryProblemDAO.class ); + + repositoryProblemDAOMock = (RepositoryProblemDAO) repositoryProblemDAOControl.getMock(); + dbCleanupRemoveArtifactConsumer.setArtifactDAO( artifactDAOMock ); - + + dbCleanupRemoveArtifactConsumer.setRepositoryProblemDAO( repositoryProblemDAOMock ); + dbCleanupRemoveArtifactConsumer.setRepositoryFactory( repositoryFactory ); } @@ -60,9 +71,13 @@ artifactDAOControl.replay(); + repositoryProblemDAOControl.replay(); + dbCleanupRemoveArtifactConsumer.processArchivaArtifact( artifact ); artifactDAOControl.verify(); + + repositoryProblemDAOControl.verify(); } public void testIfArtifactWasDeleted() @@ -73,10 +88,10 @@ artifactDAOMock.deleteArtifact( artifact ); artifactDAOControl.replay(); - + dbCleanupRemoveArtifactConsumer.processArchivaArtifact( artifact ); - artifactDAOControl.verify(); + artifactDAOControl.verify(); } } Index: archiva-base/archiva-consumers/archiva-database-consumers/src/test/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveProjectConsumerTest.java =================================================================== --- archiva-base/archiva-consumers/archiva-database-consumers/src/test/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveProjectConsumerTest.java (revision 627380) +++ archiva-base/archiva-consumers/archiva-database-consumers/src/test/java/org/apache/maven/archiva/consumers/database/DatabaseCleanupRemoveProjectConsumerTest.java (working copy) @@ -21,6 +21,7 @@ import org.easymock.MockControl; import org.apache.maven.archiva.database.ProjectModelDAO; +import org.apache.maven.archiva.database.RepositoryProblemDAO; import org.apache.maven.archiva.model.ArchivaArtifact; import org.apache.maven.archiva.model.ArchivaProjectModel; @@ -36,6 +37,10 @@ private ProjectModelDAO projectModelDAOMock; + private MockControl repositoryProblemDAOControl; + + private RepositoryProblemDAO repositoryProblemDAOMock; + private DatabaseCleanupRemoveProjectConsumer dbCleanupRemoveProjectConsumer; public void setUp() @@ -49,8 +54,14 @@ projectModelDAOMock = (ProjectModelDAO) projectModelDAOControl.getMock(); + repositoryProblemDAOControl = MockControl.createControl( RepositoryProblemDAO.class ); + + repositoryProblemDAOMock = (RepositoryProblemDAO) repositoryProblemDAOControl.getMock(); + dbCleanupRemoveProjectConsumer.setProjectModelDAO( projectModelDAOMock ); + dbCleanupRemoveProjectConsumer.setRepositoryProblemDAO( repositoryProblemDAOMock ); + dbCleanupRemoveProjectConsumer.setRepositoryFactory( repositoryFactory ); } @@ -60,10 +71,10 @@ ArchivaArtifact artifact = createArtifact( TEST_GROUP_ID, "do-not-cleanup-artifact-test", TEST_VERSION, "pom" ); projectModelDAOControl.replay(); - + dbCleanupRemoveProjectConsumer.processArchivaArtifact( artifact ); - projectModelDAOControl.verify(); + projectModelDAOControl.verify(); } public void testIfArtifactWasDeleted() Index: archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/RepositoryProblemByArtifactConstraint.java =================================================================== --- archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/RepositoryProblemByArtifactConstraint.java (revision 0) +++ archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/RepositoryProblemByArtifactConstraint.java (revision 0) @@ -0,0 +1,57 @@ +package org.apache.maven.archiva.database.constraints; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.archiva.database.Constraint; +import org.apache.maven.archiva.model.ArchivaArtifact; + +/** + * RepositoryProblemByArtifactConstraint + */ +public class RepositoryProblemByArtifactConstraint + extends AbstractDeclarativeConstraint + implements Constraint +{ + private String whereClause; + + private void createWhereClause( ArchivaArtifact artifact ) + { + whereClause = + "groupId.like(desiredGroupId) && artifactId.like(desiredArtifactId) && version.like(desiredVersion)"; + declParams = new String[] { "String desiredGroupId" , "String desiredArtifactId" , "String desiredVersion"}; + params = new Object[] { artifact.getGroupId() + "%" , artifact.getArtifactId() + "%", artifact.getVersion() + "%"}; + } + + public RepositoryProblemByArtifactConstraint( ArchivaArtifact desiredArtifact ) + { + super(); + createWhereClause( desiredArtifact ); + } + + public String getSortColumn() + { + return "artifactId"; + } + + public String getWhereCondition() + { + return whereClause; + } +}