summaryrefslogtreecommitdiffstats
path: root/archiva-reporting/archiva-artifact-reports/src/main
diff options
context:
space:
mode:
authorJoakim Erdfelt <joakime@apache.org>2007-04-19 12:25:11 +0000
committerJoakim Erdfelt <joakime@apache.org>2007-04-19 12:25:11 +0000
commit8b0319bf628d8ba366d2c12791db67c340dc0076 (patch)
tree06240146f2f875508c60b11908f5d7c4fdc597c4 /archiva-reporting/archiva-artifact-reports/src/main
parent346583093493614302e3761b3de1c2d8ff67a806 (diff)
downloadarchiva-8b0319bf628d8ba366d2c12791db67c340dc0076.tar.gz
archiva-8b0319bf628d8ba366d2c12791db67c340dc0076.zip
Refactoring of reporting. One step closer to an end-to-end compile.
git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/branches/archiva-jpox-database-refactor@530395 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'archiva-reporting/archiva-artifact-reports/src/main')
-rw-r--r--archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactReport.java80
-rw-r--r--archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactsConsumer.java228
-rw-r--r--archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsConsumer.java366
-rw-r--r--archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsReport.java81
-rw-r--r--archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldArtifactReport.java76
-rw-r--r--archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldSnapshotArtifactReport.java76
6 files changed, 907 insertions, 0 deletions
diff --git a/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactReport.java b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactReport.java
new file mode 100644
index 000000000..f4e82152d
--- /dev/null
+++ b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactReport.java
@@ -0,0 +1,80 @@
+package org.apache.maven.archiva.reporting.artifact;
+
+/*
+ * 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.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.Constraint;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.constraints.RepositoryProblemByTypeConstraint;
+import org.apache.maven.archiva.reporting.DataLimits;
+import org.apache.maven.archiva.reporting.DynamicReportSource;
+
+import java.util.List;
+
+/**
+ * DuplicateArtifactReport
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.reporting.DynamicReportSource"
+ * role-hint="duplicate-artifacts"
+ */
+public class DuplicateArtifactReport
+ implements DynamicReportSource
+{
+ public static final String PROBLEM_TYPE_DUPLICATE_ARTIFACTS = "duplicate-artifacts";
+
+ /**
+ * @plexus.configuration default-value="Duplicate Artifact Report"
+ */
+ private String name;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaDAO dao;
+
+ private Constraint constraint;
+
+ public DuplicateArtifactReport()
+ {
+ constraint = new RepositoryProblemByTypeConstraint( PROBLEM_TYPE_DUPLICATE_ARTIFACTS );
+ }
+
+ public List getData()
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ return dao.getRepositoryProblemDAO().queryRepositoryProblems( constraint );
+ }
+
+ public List getData( DataLimits limits )
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ // TODO: implement limits.
+ return dao.getRepositoryProblemDAO().queryRepositoryProblems( constraint );
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+}
diff --git a/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactsConsumer.java b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactsConsumer.java
new file mode 100644
index 000000000..ad6bb675f
--- /dev/null
+++ b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/DuplicateArtifactsConsumer.java
@@ -0,0 +1,228 @@
+package org.apache.maven.archiva.reporting.artifact;
+
+/*
+ * 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.commons.collections.CollectionUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.ConfigurationNames;
+import org.apache.maven.archiva.configuration.FileType;
+import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer;
+import org.apache.maven.archiva.consumers.ArchivaArtifactConsumer;
+import org.apache.maven.archiva.consumers.ConsumerException;
+import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.constraints.ArtifactsBySha1ChecksumConstraint;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+import org.apache.maven.archiva.model.RepositoryProblem;
+import org.apache.maven.archiva.reporting.artifact.DuplicateArtifactReport;
+import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
+import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayoutFactory;
+import org.apache.maven.archiva.repository.layout.LayoutException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.registry.Registry;
+import org.codehaus.plexus.registry.RegistryListener;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Search the database of known SHA1 Checksums for potential duplicate artifacts.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.consumers.ArchivaArtifactConsumer"
+ * role-hint="duplicate-artifacts"
+ */
+public class DuplicateArtifactsConsumer
+ extends AbstractMonitoredConsumer
+ implements ArchivaArtifactConsumer, RegistryListener, Initializable
+{
+ /**
+ * @plexus.configuration default-value="duplicate-artifacts"
+ */
+ private String id;
+
+ /**
+ * @plexus.configuration default-value="Check for Duplicate Artifacts via SHA1 Checksums"
+ */
+ private String description;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration configuration;
+
+ /**
+ * @plexus.requirement role-hint="jdo"
+ */
+ private ArchivaDAO dao;
+
+ /**
+ * @plexus.requirement
+ */
+ private BidirectionalRepositoryLayoutFactory layoutFactory;
+
+ private List includes = new ArrayList();
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public boolean isPermanent()
+ {
+ return false;
+ }
+
+ public void beginScan()
+ {
+ /* do nothing */
+ }
+
+ public void completeScan()
+ {
+ /* do nothing */
+ }
+
+ public List getIncludedTypes()
+ {
+ return null;
+ }
+
+ public void processArchivaArtifact( ArchivaArtifact artifact )
+ throws ConsumerException
+ {
+ String checksumSha1 = artifact.getModel().getChecksumSHA1();
+
+ List results = null;
+ try
+ {
+ results = dao.getArtifactDAO().queryArtifacts( new ArtifactsBySha1ChecksumConstraint( checksumSha1 ) );
+ }
+ catch ( ObjectNotFoundException e )
+ {
+ getLogger().debug( "No duplicates for artifact: " + artifact );
+ return;
+ }
+ catch ( ArchivaDatabaseException e )
+ {
+ getLogger().warn( "Unable to query DB for potential duplicates with : " + artifact );
+ return;
+ }
+
+ if ( CollectionUtils.isNotEmpty( results ) )
+ {
+ if ( results.size() <= 1 )
+ {
+ // No duplicates detected.
+ getLogger().debug( "Found no duplicate artifact results on: " + artifact );
+ return;
+ }
+
+ Iterator it = results.iterator();
+ while ( it.hasNext() )
+ {
+ ArchivaArtifact dupArtifact = (ArchivaArtifact) it.next();
+
+ if( dupArtifact.equals( artifact ) )
+ {
+ // Skip reference to itself.
+ continue;
+ }
+
+ RepositoryProblem problem = new RepositoryProblem();
+ problem.setRepositoryId( dupArtifact.getModel().getRepositoryId() );
+ problem.setPath( toPath( dupArtifact ) );
+ problem.setGroupId( artifact.getGroupId() );
+ problem.setArtifactId( artifact.getArtifactId() );
+ problem.setVersion( artifact.getVersion() );
+ problem.setType( DuplicateArtifactReport.PROBLEM_TYPE_DUPLICATE_ARTIFACTS );
+ problem.setOrigin( getId() );
+ problem.setMessage( "Duplicate Artifact Detected: " + artifact + " <--> " + dupArtifact );
+
+ try
+ {
+ getLogger().debug( "Found duplicate artifact: " + problem );
+ dao.getRepositoryProblemDAO().saveRepositoryProblem( problem );
+ }
+ catch ( ArchivaDatabaseException e )
+ {
+ String emsg = "Unable to save problem with duplicate artifact to DB: " + e.getMessage();
+ getLogger().warn( emsg, e );
+ throw new ConsumerException( emsg, e );
+ }
+ }
+ }
+ }
+
+ private String toPath( ArchivaArtifact artifact )
+ {
+ try
+ {
+ BidirectionalRepositoryLayout layout = layoutFactory.getLayout( artifact );
+ return layout.toPath( artifact );
+ }
+ catch ( LayoutException e )
+ {
+ getLogger().warn( "Unable to calculate path for artifact: " + artifact );
+ return "";
+ }
+ }
+
+ public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+ {
+ if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
+ {
+ initIncludes();
+ }
+ }
+
+ public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+ {
+ /* do nothing */
+ }
+
+ private void initIncludes()
+ {
+ includes.clear();
+
+ FileType artifactTypes = configuration.getConfiguration().getRepositoryScanning().getFileTypeById( "artifacts" );
+ if ( artifactTypes != null )
+ {
+ includes.addAll( artifactTypes.getPatterns() );
+ }
+ }
+
+ public void initialize()
+ throws InitializationException
+ {
+ initIncludes();
+ configuration.addChangeListener( this );
+ }
+}
diff --git a/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsConsumer.java b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsConsumer.java
new file mode 100644
index 000000000..3a350f54f
--- /dev/null
+++ b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsConsumer.java
@@ -0,0 +1,366 @@
+package org.apache.maven.archiva.reporting.artifact;
+
+/*
+ * 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.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.ConfigurationNames;
+import org.apache.maven.archiva.configuration.FileType;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer;
+import org.apache.maven.archiva.consumers.ArchivaArtifactConsumer;
+import org.apache.maven.archiva.consumers.ConsumerException;
+import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+import org.apache.maven.archiva.model.ArchivaProjectModel;
+import org.apache.maven.archiva.model.ArchivaRepository;
+import org.apache.maven.archiva.model.RepositoryProblem;
+import org.apache.maven.archiva.repository.ArchivaConfigurationAdaptor;
+import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
+import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayoutFactory;
+import org.apache.maven.archiva.repository.layout.LayoutException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.registry.Registry;
+import org.codehaus.plexus.registry.RegistryListener;
+import org.codehaus.plexus.util.SelectorUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Validate the location of the artifact based on the values indicated
+ * in its pom (both the pom packaged with the artifact & the pom in the
+ * file system).
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.consumers.ArchivaArtifactConsumer"
+ * role-hint="validate-artifacts-location"
+ */
+public class LocationArtifactsConsumer
+ extends AbstractMonitoredConsumer
+ implements ArchivaArtifactConsumer, RegistryListener, Initializable
+{
+ /**
+ * @plexus.configuration default-value="duplicate-artifacts"
+ */
+ private String id;
+
+ /**
+ * @plexus.configuration default-value="Check for Duplicate Artifacts via SHA1 Checksums"
+ */
+ private String description;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration configuration;
+
+ /**
+ * @plexus.requirement role-hint="jdo"
+ */
+ private ArchivaDAO dao;
+
+ /**
+ * @plexus.requirement
+ */
+ private BidirectionalRepositoryLayoutFactory layoutFactory;
+
+ private Map repositoryMap = new HashMap();
+
+ private List includes = new ArrayList();
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public boolean isPermanent()
+ {
+ return false;
+ }
+
+ public void beginScan()
+ {
+ /* do nothing */
+ }
+
+ public void completeScan()
+ {
+ /* do nothing */
+ }
+
+ public List getIncludedTypes()
+ {
+ return null;
+ }
+
+ /**
+ * Check whether the artifact is in its proper location. The location of the artifact
+ * is validated first against the groupId, artifactId and versionId in the specified model
+ * object (pom in the file system). Then unpack the artifact (jar file) and get the model (pom)
+ * included in the package. If a model exists inside the package, then check if the artifact's
+ * location is valid based on the location specified in the pom. Check if the both the location
+ * specified in the file system pom and in the pom included in the package is the same.
+ */
+ public void processArchivaArtifact( ArchivaArtifact artifact )
+ throws ConsumerException
+ {
+ ArchivaRepository repository = findRepository( artifact );
+ if ( !repository.isManaged() )
+ {
+ getLogger().warn( "Artifact Location Validation Cannot operate against a non-managed Repository." );
+ return;
+ }
+
+ File artifactFile = new File( repository.getUrl().toString(), toPath( artifact ) );
+ ArchivaProjectModel fsModel = readFilesystemModel( artifactFile );
+ ArchivaProjectModel embeddedModel = readEmbeddedModel( artifact, artifactFile );
+
+ validateAppropriateModel( "Filesystem", artifact, fsModel );
+ validateAppropriateModel( "Embedded", artifact, embeddedModel );
+ }
+
+ private void validateAppropriateModel( String location, ArchivaArtifact artifact, ArchivaProjectModel model )
+ throws ConsumerException
+ {
+ if ( model != null )
+ {
+ if ( !StringUtils.equals( model.getGroupId(), artifact.getGroupId() ) )
+ {
+ addProblem( artifact, "The groupId of the " + location
+ + " project model doesn't match with the artifact, expected <" + artifact.getGroupId()
+ + ">, but was actually <" + model.getGroupId() + ">" );
+ }
+
+ if ( !StringUtils.equals( model.getArtifactId(), artifact.getArtifactId() ) )
+ {
+ addProblem( artifact, "The artifactId of the " + location
+ + " project model doesn't match with the artifact, expected <" + artifact.getArtifactId()
+ + ">, but was actually <" + model.getArtifactId() + ">" );
+ }
+
+ if ( !StringUtils.equals( model.getVersion(), artifact.getVersion() ) )
+ {
+ addProblem( artifact, "The version of the " + location
+ + " project model doesn't match with the artifact, expected <" + artifact.getVersion()
+ + ">, but was actually <" + model.getVersion() + ">" );
+ }
+ }
+ }
+
+ private ArchivaProjectModel readEmbeddedModel( ArchivaArtifact artifact, File artifactFile )
+ throws ConsumerException
+ {
+ try
+ {
+ JarFile jar = new JarFile( artifactFile );
+
+ // Get the entry and its input stream.
+ JarEntry expectedEntry = jar.getJarEntry( "META-INF/maven/" + artifact.getGroupId() + "/"
+ + artifact.getArtifactId() + "/pom.xml" );
+
+ if ( expectedEntry != null )
+ {
+ // TODO: read and resolve model here.
+ return null;
+ }
+
+ /* Expected Entry not found, look for alternate that might
+ * indicate that the artifact is, indeed located in the wrong place.
+ */
+
+ List actualPomXmls = findJarEntryPattern( jar, "META-INF/maven/**/pom.xml" );
+ if ( actualPomXmls.isEmpty() )
+ {
+ // No check needed.
+
+ }
+
+ // TODO: test for invalid actual pom.xml
+ // TODO: test
+ }
+ catch ( IOException e )
+ {
+ // Not able to read from the file.
+ String emsg = "Unable to read file contents: " + e.getMessage();
+ addProblem( artifact, emsg );
+ }
+
+ return null;
+ }
+
+ private List findJarEntryPattern( JarFile jar, String pattern )
+ {
+ List hits = new ArrayList();
+
+ Enumeration entries = jar.entries();
+ while ( entries.hasMoreElements() )
+ {
+ JarEntry entry = (JarEntry) entries.nextElement();
+ if ( SelectorUtils.match( pattern, entry.getName() ) )
+ {
+ hits.add( entry );
+ }
+ }
+
+ return hits;
+ }
+
+ private void addProblem( ArchivaArtifact artifact, String msg )
+ throws ConsumerException
+ {
+ RepositoryProblem problem = new RepositoryProblem();
+ problem.setRepositoryId( artifact.getModel().getRepositoryId() );
+ problem.setPath( toPath( artifact ) );
+ problem.setGroupId( artifact.getGroupId() );
+ problem.setArtifactId( artifact.getArtifactId() );
+ problem.setVersion( artifact.getVersion() );
+ problem.setType( LocationArtifactsReport.PROBLEM_TYPE_BAD_ARTIFACT_LOCATION );
+ problem.setOrigin( getId() );
+ problem.setMessage( msg );
+
+ try
+ {
+ dao.getRepositoryProblemDAO().saveRepositoryProblem( problem );
+ }
+ catch ( ArchivaDatabaseException e )
+ {
+ String emsg = "Unable to save problem with artifact location to DB: " + e.getMessage();
+ getLogger().warn( emsg, e );
+ throw new ConsumerException( emsg, e );
+ }
+ }
+
+ private ArchivaProjectModel readFilesystemModel( File artifactFile )
+ {
+ File pomFile = createPomFileReference( artifactFile );
+
+ // TODO: read and resolve model here.
+
+ return null;
+ }
+
+ private File createPomFileReference( File artifactFile )
+ {
+ String pomFilename = artifactFile.getAbsolutePath();
+
+ int pos = pomFilename.lastIndexOf( '.' );
+ if ( pos <= 0 )
+ {
+ // Invalid filename.
+ return null;
+ }
+
+ pomFilename = pomFilename.substring( 0, pos ) + ".pom";
+ return new File( pomFilename );
+ }
+
+ private ArchivaRepository findRepository( ArchivaArtifact artifact )
+ {
+ return (ArchivaRepository) this.repositoryMap.get( artifact.getModel().getRepositoryId() );
+ }
+
+ private String toPath( ArchivaArtifact artifact )
+ {
+ try
+ {
+ BidirectionalRepositoryLayout layout = layoutFactory.getLayout( artifact );
+ return layout.toPath( artifact );
+ }
+ catch ( LayoutException e )
+ {
+ getLogger().warn( "Unable to calculate path for artifact: " + artifact );
+ return null;
+ }
+ }
+
+ public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+ {
+ if ( ConfigurationNames.isRepositories( propertyName ) )
+ {
+ initRepositoryMap();
+ }
+
+ if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
+ {
+ initIncludes();
+ }
+ }
+
+ public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+ {
+ /* do nothing */
+ }
+
+ private void initIncludes()
+ {
+ includes.clear();
+
+ FileType artifactTypes = configuration.getConfiguration().getRepositoryScanning().getFileTypeById( "artifacts" );
+ if ( artifactTypes != null )
+ {
+ includes.addAll( artifactTypes.getPatterns() );
+ }
+ }
+
+ private void initRepositoryMap()
+ {
+ synchronized ( this.repositoryMap )
+ {
+ this.repositoryMap.clear();
+
+ Iterator it = configuration.getConfiguration().createRepositoryMap().entrySet().iterator();
+ while ( it.hasNext() )
+ {
+ Map.Entry entry = (Entry) it.next();
+ String key = (String) entry.getKey();
+ RepositoryConfiguration repoConfig = (RepositoryConfiguration) entry.getValue();
+ ArchivaRepository repository = ArchivaConfigurationAdaptor.toArchivaRepository( repoConfig );
+ this.repositoryMap.put( key, repository );
+ }
+ }
+ }
+
+ public void initialize()
+ throws InitializationException
+ {
+ initRepositoryMap();
+ initIncludes();
+ configuration.addChangeListener( this );
+ }
+}
diff --git a/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsReport.java b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsReport.java
new file mode 100644
index 000000000..3cca3fa13
--- /dev/null
+++ b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/LocationArtifactsReport.java
@@ -0,0 +1,81 @@
+package org.apache.maven.archiva.reporting.artifact;
+
+/*
+ * 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.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.Constraint;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.constraints.RepositoryProblemByTypeConstraint;
+import org.apache.maven.archiva.reporting.DataLimits;
+import org.apache.maven.archiva.reporting.DynamicReportSource;
+
+import java.util.List;
+
+/**
+ * LocationArtifactsReport
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.reporting.DynamicReportSource"
+ * role-hint="artifact-location"
+ */
+public class LocationArtifactsReport
+ implements DynamicReportSource
+{
+ public static final String PROBLEM_TYPE_BAD_ARTIFACT_LOCATION = "bad-artifact-location";
+
+ /**
+ * @plexus.configuration default-value="Artifact Locations Report"
+ */
+ private String name;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaDAO dao;
+
+ private Constraint constraint;
+
+ public LocationArtifactsReport()
+ {
+ constraint = new RepositoryProblemByTypeConstraint( PROBLEM_TYPE_BAD_ARTIFACT_LOCATION );
+ }
+
+ public List getData()
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ return dao.getRepositoryProblemDAO().queryRepositoryProblems( constraint );
+ }
+
+ public List getData( DataLimits limits )
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ // TODO: implement limits.
+ return dao.getRepositoryProblemDAO().queryRepositoryProblems( constraint );
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+}
diff --git a/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldArtifactReport.java b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldArtifactReport.java
new file mode 100644
index 000000000..6691314e2
--- /dev/null
+++ b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldArtifactReport.java
@@ -0,0 +1,76 @@
+package org.apache.maven.archiva.reporting.artifact;
+
+/*
+ * 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.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.constraints.OlderArtifactsByAgeConstraint;
+import org.apache.maven.archiva.reporting.DataLimits;
+import org.apache.maven.archiva.reporting.DynamicReportSource;
+
+import java.util.List;
+
+/**
+ * OldArtifactReport
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.reporting.DynamicReportSource"
+ * role-hint="old-artifacts"
+ */
+public class OldArtifactReport
+ implements DynamicReportSource
+{
+ /**
+ * @plexus.configuration default-value="Old Artifacts Report"
+ */
+ private String name;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaDAO dao;
+
+ /**
+ * The maximum age of an artifact before it is reported old, specified in days. The default is 1 year.
+ *
+ * @plexus.configuration default-value="365"
+ */
+ private int cutoffDays;
+
+ public List getData()
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ return dao.getArtifactDAO().queryArtifacts( new OlderArtifactsByAgeConstraint( cutoffDays ) );
+ }
+
+ public List getData( DataLimits limits )
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ return dao.getArtifactDAO().queryArtifacts( new OlderArtifactsByAgeConstraint( cutoffDays ) );
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+}
diff --git a/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldSnapshotArtifactReport.java b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldSnapshotArtifactReport.java
new file mode 100644
index 000000000..e039f6048
--- /dev/null
+++ b/archiva-reporting/archiva-artifact-reports/src/main/java/org/apache/maven/archiva/reporting/artifact/OldSnapshotArtifactReport.java
@@ -0,0 +1,76 @@
+package org.apache.maven.archiva.reporting.artifact;
+
+/*
+ * 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.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.constraints.OlderSnapshotArtifactsByAgeConstraint;
+import org.apache.maven.archiva.reporting.DataLimits;
+import org.apache.maven.archiva.reporting.DynamicReportSource;
+
+import java.util.List;
+
+/**
+ * OldSnapshotArtifactReport
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.reporting.DynamicReportSource"
+ * role-hint="old-snapshots"
+ */
+public class OldSnapshotArtifactReport
+ implements DynamicReportSource
+{
+ /**
+ * @plexus.configuration default-value="Old Snapshots Report"
+ */
+ private String name;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaDAO dao;
+
+ /**
+ * The maximum age of a snapshot before it is reported old, specified in days. The default is 1 year.
+ *
+ * @plexus.configuration default-value="365"
+ */
+ private int cutoffDays;
+
+ public List getData()
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ return dao.getArtifactDAO().queryArtifacts( new OlderSnapshotArtifactsByAgeConstraint( cutoffDays ) );
+ }
+
+ public List getData( DataLimits limits )
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ return dao.getArtifactDAO().queryArtifacts( new OlderSnapshotArtifactsByAgeConstraint( cutoffDays ) );
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+}