diff options
author | Maria Odea B. Ching <oching@apache.org> | 2008-10-01 10:27:16 +0000 |
---|---|---|
committer | Maria Odea B. Ching <oching@apache.org> | 2008-10-01 10:27:16 +0000 |
commit | 5cdf0b8fa4251ef40c94e9416ccb4843214bf2e2 (patch) | |
tree | 8c9e2c03db5c903456e1c7d02dfbad5724f88e50 | |
parent | 3a14379327bd67fd63ac28c0157701b02a4610ce (diff) | |
download | archiva-5cdf0b8fa4251ef40c94e9416ccb4843214bf2e2.tar.gz archiva-5cdf0b8fa4251ef40c94e9416ccb4843214bf2e2.zip |
[MRM-84]
-added statistics report in reports UI
-added statistics report generator with tests
-added new fields (totalProjectCount, totalGroupCount, totalArtifactCount and totalSize) to RepositoryContentStatistics table
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@700729 13f79535-47bb-0310-9956-ffa450edef68
23 files changed, 1594 insertions, 121 deletions
diff --git a/archiva-modules/archiva-base/archiva-model/src/main/mdo/archiva-base.xml b/archiva-modules/archiva-base/archiva-model/src/main/mdo/archiva-base.xml index 9bf4c2017..b7e03b5af 100644 --- a/archiva-modules/archiva-base/archiva-model/src/main/mdo/archiva-base.xml +++ b/archiva-modules/archiva-base/archiva-model/src/main/mdo/archiva-base.xml @@ -2346,6 +2346,46 @@ The number of new files discovered. </description> </field> + <field> + <name>totalProjectCount</name> + <version>1.0.0+</version> + <identifier>false</identifier> + <required>true</required> + <type>long</type> + <description> + The total number of unique projects in the repository. + </description> + </field> + <field> + <name>totalGroupCount</name> + <version>1.0.0+</version> + <identifier>false</identifier> + <required>true</required> + <type>long</type> + <description> + The total number of unique groups in the repository. + </description> + </field> + <field> + <name>totalArtifactCount</name> + <version>1.0.0+</version> + <identifier>false</identifier> + <required>true</required> + <type>long</type> + <description> + The total number of artifacts in the repository. + </description> + </field> + <field> + <name>totalSize</name> + <version>1.0.0+</version> + <identifier>false</identifier> + <required>true</required> + <type>long</type> + <description> + The total size in bytes of the repository. + </description> + </field> </fields> <codeSegments> <codeSegment> diff --git a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/AbstractDeclarativeConstraint.java b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/AbstractDeclarativeConstraint.java index fe3985a02..8559e035c 100644 --- a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/AbstractDeclarativeConstraint.java +++ b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/AbstractDeclarativeConstraint.java @@ -40,6 +40,8 @@ public abstract class AbstractDeclarativeConstraint protected Object[] params; protected int[] range; + + protected String sortDirection = Constraint.ASCENDING; public String getFilter() { @@ -68,7 +70,7 @@ public abstract class AbstractDeclarativeConstraint public String getSortDirection() { - return Constraint.ASCENDING; + return sortDirection; } public String[] getVariables() diff --git a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraint.java b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraint.java index 4506123a2..9b3afab0a 100644 --- a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraint.java +++ b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraint.java @@ -44,14 +44,26 @@ public class ArtifactsByRepositoryConstraint params = new Object[] { repoId }; } - public ArtifactsByRepositoryConstraint( String repoId, Date targetWhenGathered, String sortColumn ) + public ArtifactsByRepositoryConstraint( String repoId, Date targetWhenGathered, String sortColumn, boolean isBefore ) { + String condition = isBefore ? "<=" : ">="; + declImports = new String[] { "import java.util.Date" }; - whereClause = "this.repositoryId == repoId && this.whenGathered >= targetWhenGathered"; + whereClause = "this.repositoryId == repoId && this.whenGathered " + condition + " targetWhenGathered"; declParams = new String[] { "String repoId", "Date targetWhenGathered" }; params = new Object[] { repoId, targetWhenGathered }; this.sortColumn = sortColumn; } + + public ArtifactsByRepositoryConstraint( String repoId, String type, Date before, String sortColumn ) + { + declImports = new String[] { "import java.util.Date" }; + whereClause = + "this.repositoryId == repoId && this.type == type && this.whenGathered <= before"; + declParams = new String[] { "String repoId", "String type", "Date before" }; + params = new Object[] { repoId, type, before }; + this.sortColumn = sortColumn; + } public String getSortColumn() { diff --git a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraint.java b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraint.java index dc3990980..ac3aad061 100644 --- a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraint.java +++ b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraint.java @@ -1,5 +1,9 @@ package org.apache.maven.archiva.database.constraints; +import java.util.Date; + +import org.apache.maven.archiva.database.Constraint; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -36,6 +40,16 @@ public class RepositoryContentStatisticsByRepositoryConstraint declParams = new String[] { "String repoId" }; params = new Object[] { repoId }; } + + public RepositoryContentStatisticsByRepositoryConstraint( String repoId, Date startDate, Date endDate ) + { + declImports = new String[] { "import java.util.Date" }; + whereClause = "repositoryId == repoId && whenGathered >= startDate && whenGathered <= endDate"; + declParams = new String[] { "String repoId", "Date startDate", "Date endDate" }; + params = new Object[] { repoId, startDate, endDate }; + + sortDirection = Constraint.DESCENDING; + } public String getSortColumn() { diff --git a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraint.java b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraint.java index 47766b94e..d64382c7d 100644 --- a/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraint.java +++ b/archiva-modules/archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraint.java @@ -35,7 +35,9 @@ public class UniqueArtifactIdConstraint implements Constraint { private StringBuffer sql = new StringBuffer(); - + + private Class resultClass; + /** * Obtain a set of unique ArtifactIds for the specified groupId. * @@ -43,7 +45,7 @@ public class UniqueArtifactIdConstraint */ public UniqueArtifactIdConstraint( List<String> selectedRepositoryIds, String groupId ) { - appendSelect( sql ); + appendSelect( sql, false ); sql.append( " WHERE " ); SqlBuilder.appendWhereSelectedRepositories( sql, "repositoryId", selectedRepositoryIds ); sql.append( " && " ); @@ -60,17 +62,36 @@ public class UniqueArtifactIdConstraint */ public UniqueArtifactIdConstraint( String groupId ) { - appendSelect( sql ); + appendSelect( sql, false ); sql.append( " WHERE " ); appendWhereSelectedGroupId( sql ); appendGroupBy( sql ); super.params = new Object[] { groupId }; } + + /** + * Obtain a set of unique artifactIds with respect to their groups from the specified repository. + * + * @param repoId + * @param isUnique + */ + public UniqueArtifactIdConstraint( String repoId, boolean isUnique ) + { + appendSelect( sql, isUnique ); + sql.append( " WHERE repositoryId == \"" + repoId + "\"" ); + + resultClass = Object[].class; + } @SuppressWarnings("unchecked") public Class getResultClass() { + if( resultClass != null ) + { + return resultClass; + } + return String.class; } @@ -84,9 +105,16 @@ public class UniqueArtifactIdConstraint buf.append( " GROUP BY artifactId ORDER BY artifactId ASCENDING" ); } - private void appendSelect( StringBuffer buf ) + private void appendSelect( StringBuffer buf, boolean isUnique ) { - buf.append( "SELECT artifactId FROM " ).append( ArchivaArtifactModel.class.getName() ); + if( isUnique ) + { + buf.append( "SELECT DISTINCT groupId, artifactId FROM " ).append( ArchivaArtifactModel.class.getName() ); + } + else + { + buf.append( "SELECT artifactId FROM " ).append( ArchivaArtifactModel.class.getName() ); + } } private void appendWhereSelectedGroupId( StringBuffer buf ) diff --git a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraintTest.java b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraintTest.java index c503ffcfa..41516e7d5 100644 --- a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraintTest.java +++ b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/ArtifactsByRepositoryConstraintTest.java @@ -37,20 +37,20 @@ import org.apache.maven.archiva.model.ArchivaArtifact; public class ArtifactsByRepositoryConstraintTest extends AbstractArchivaDatabaseTestCase { - private ArtifactDAO artifactDao; + private ArtifactDAO artifactDao; public void setUp() throws Exception { - super.setUp(); + super.setUp(); ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" ); artifactDao = dao.getArtifactDAO(); } - private ArchivaArtifact createArtifact( String groupId, String artifactId, String version ) + private ArchivaArtifact createArtifact( String groupId, String artifactId, String version, String type ) { - ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, null, "jar" ); + ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, null, type ); artifact.getModel().setLastModified( new Date() ); artifact.getModel().setRepositoryId( "test-repo" ); @@ -63,19 +63,19 @@ public class ArtifactsByRepositoryConstraintTest Date whenGathered = Calendar.getInstance().getTime(); whenGathered.setTime( 123456789 ); - ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0" ); + ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0", "jar" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); - artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1" ); + artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1", "jar" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); - artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.0.2" ); + artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.0.2", "jar" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); - artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0" ); + artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0", "jar" ); artifact.getModel().setRepositoryId( "different-repo" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); @@ -88,19 +88,19 @@ public class ArtifactsByRepositoryConstraintTest { Date whenGathered = Calendar.getInstance().getTime(); - ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0" ); + ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0", "jar" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); - artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1" ); + artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1", "jar" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); - artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.2" ); + artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.2", "jar" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); - artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0" ); + artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0", "jar" ); artifact.getModel().setRepositoryId( "different-repo" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); @@ -108,18 +108,63 @@ public class ArtifactsByRepositoryConstraintTest Date olderWhenGathered = Calendar.getInstance().getTime(); olderWhenGathered.setTime( 123456789 ); - artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.1-SNAPSHOT" ); + artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.1-SNAPSHOT", "jar" ); artifact.getModel().setWhenGathered( olderWhenGathered ); artifactDao.saveArtifact( artifact ); - artifact = createArtifact( "org.apache.archiva", "artifact-three", "2.0-beta-1" ); + artifact = createArtifact( "org.apache.archiva", "artifact-three", "2.0-beta-1", "jar" ); artifact.getModel().setWhenGathered( whenGathered ); artifactDao.saveArtifact( artifact ); assertConstraint( "Artifacts By Repository and When Gathered", 4, - new ArtifactsByRepositoryConstraint( "test-repo", whenGathered, "repositoryId" ) ); + new ArtifactsByRepositoryConstraint( "test-repo", whenGathered, "repositoryId", false ) ); } + + public void testQueryArtifactsInRepoByType() + throws Exception + { + Calendar cal = Calendar.getInstance(); + cal.set( 2008, 9, 1 ); + Date whenGathered = cal.getTime(); + + ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0", "jar" ); + artifact.getModel().setWhenGathered( whenGathered ); + artifactDao.saveArtifact( artifact ); + + artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1", "jar" ); + artifact.getModel().setWhenGathered( whenGathered ); + artifactDao.saveArtifact( artifact ); + + artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.2", "jar" ); + artifact.getModel().setWhenGathered( whenGathered ); + artifactDao.saveArtifact( artifact ); + + artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.1-SNAPSHOT", "war" ); + artifact.getModel().setWhenGathered( whenGathered ); + artifactDao.saveArtifact( artifact ); + + artifact = createArtifact( "org.apache.archiva", "artifact-three", "2.0-beta-1", "war" ); + artifact.getModel().setWhenGathered( whenGathered ); + artifactDao.saveArtifact( artifact ); + Calendar cal2 = Calendar.getInstance(); + cal2.set( 2008, 12, 12 ); + Date diffWhenGathered = cal2.getTime(); + + artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0", "jar" ); + artifact.getModel().setWhenGathered( diffWhenGathered ); + artifactDao.saveArtifact( artifact ); + + cal2 = Calendar.getInstance(); + cal2.set( 2008, 10, 30 ); + Date before = cal2.getTime(); + + assertConstraint( "Artifacts of Type 'jar' By Repository and When Gathered", 3, + new ArtifactsByRepositoryConstraint( "test-repo", "jar", before, "whenGathered" ) ); + assertConstraint( "Artifacts of Type 'war' By Repository and When Gathered", 2, + new ArtifactsByRepositoryConstraint( "test-repo", "war", before, "whenGathered" ) ); + } + private void assertConstraint( String msg, int count, ArtifactsByRepositoryConstraint constraint ) throws Exception { diff --git a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraintTest.java b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraintTest.java index 3e036b554..4a6b4555c 100644 --- a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraintTest.java +++ b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/RepositoryContentStatisticsByRepositoryConstraintTest.java @@ -32,7 +32,7 @@ import org.apache.maven.archiva.model.RepositoryContentStatistics; * @version */ public class RepositoryContentStatisticsByRepositoryConstraintTest - extends AbstractArchivaDatabaseTestCase + extends AbstractArchivaDatabaseTestCase { private RepositoryContentStatistics createStats( String repoId, String timestamp, long duration, long totalfiles, long newfiles ) @@ -76,4 +76,27 @@ public class RepositoryContentStatisticsByRepositoryConstraintTest assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 2 ) ).getRepositoryId() ); assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 3 ) ).getRepositoryId() ); } + + public void testStatsWithDateRange() + throws Exception + { + Constraint constraint = + new RepositoryContentStatisticsByRepositoryConstraint( "internal", toDate( "2007/10/18 8:00:00" ), + toDate( "2007/10/20 8:00:00" ) ); + List results = dao.getRepositoryContentStatisticsDAO().queryRepositoryContentStatistics( constraint ); + assertNotNull( "Stats: results (not null)", results ); + assertEquals( "Stats: results.size", 3, results.size() ); + + assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 0 ) ).getRepositoryId() ); + assertEquals( toDate( "2007/10/20 8:00:00" ), + ( (RepositoryContentStatistics) results.get( 0 ) ).getWhenGathered() ); + + assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 1 ) ).getRepositoryId() ); + assertEquals( toDate( "2007/10/19 8:00:00" ), + ( (RepositoryContentStatistics) results.get( 1 ) ).getWhenGathered() ); + + assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 2 ) ).getRepositoryId() ); + assertEquals( toDate( "2007/10/18 8:00:00" ), + ( (RepositoryContentStatistics) results.get( 2 ) ).getWhenGathered() ); + } } diff --git a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraintTest.java b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraintTest.java index 45191ec3a..db9fc81bb 100644 --- a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraintTest.java +++ b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueArtifactIdConstraintTest.java @@ -22,6 +22,7 @@ package org.apache.maven.archiva.database.constraints; import org.apache.commons.lang.StringUtils; import org.apache.maven.archiva.database.AbstractArchivaDatabaseTestCase; import org.apache.maven.archiva.database.ArchivaDAO; +import org.apache.maven.archiva.database.ArchivaDatabaseException; import org.apache.maven.archiva.database.ArtifactDAO; import org.apache.maven.archiva.database.SimpleConstraint; import org.apache.maven.archiva.model.ArchivaArtifact; @@ -62,9 +63,31 @@ public class UniqueArtifactIdConstraintTest public void testConstraint() throws Exception { - ArchivaArtifact artifact; + setUpArtifacts(); - // Setup artifacts in fresh DB. + assertConstraint( new String[] {}, new UniqueArtifactIdConstraint( "org.apache" ) ); + assertConstraint( new String[] { "commons-lang" }, new UniqueArtifactIdConstraint( "commons-lang" ) ); + assertConstraint( new String[] { "test-one" }, new UniqueArtifactIdConstraint( "org.apache.maven.test" ) ); + assertConstraint( new String[] { "test-two", "test-bar" }, + new UniqueArtifactIdConstraint( "org.apache.maven.shared" ) ); + assertConstraint( new String[] { "modellong" }, new UniqueArtifactIdConstraint( "org.codehaus.modello" ) ); + } + + public void testConstraintDisregardGroupId() + throws Exception + { + setUpArtifacts(); + + assertConstraintWithMultipleResultTypes( new String[] { "commons-lang", "test-one", "test-two", "test-two", "test-bar", "modellong" }, + new UniqueArtifactIdConstraint( "testable_repo", true ) ); + } + + private void setUpArtifacts() + throws ArchivaDatabaseException + { + ArchivaArtifact artifact; + + // Setup artifacts in fresh DB. artifact = createArtifact( "commons-lang", "commons-lang", "2.0" ); artifactDao.saveArtifact( artifact ); @@ -88,26 +111,41 @@ public class UniqueArtifactIdConstraintTest artifact = createArtifact( "org.codehaus.modello", "modellong", "3.0" ); artifactDao.saveArtifact( artifact ); - - assertConstraint( new String[] {}, new UniqueArtifactIdConstraint( "org.apache" ) ); - assertConstraint( new String[] { "commons-lang" }, new UniqueArtifactIdConstraint( "commons-lang" ) ); - assertConstraint( new String[] { "test-one" }, new UniqueArtifactIdConstraint( "org.apache.maven.test" ) ); - assertConstraint( new String[] { "test-two", "test-bar" }, - new UniqueArtifactIdConstraint( "org.apache.maven.shared" ) ); - assertConstraint( new String[] { "modellong" }, new UniqueArtifactIdConstraint( "org.codehaus.modello" ) ); } - + + private void assertConstraintWithMultipleResultTypes( String[] artifactIds, SimpleConstraint constraint ) + throws Exception + { + String prefix = "Unique Artifact IDs: "; + + List<Object[]> results = dao.query( constraint ); + assertNotNull( prefix + "Not Null", results ); + assertEquals( prefix + "Results.size", artifactIds.length, results.size() ); + + List<String> expectedArtifactIds = Arrays.asList( artifactIds ); + + Iterator<Object[]> it = results.iterator(); + while ( it.hasNext() ) + { + Object[] actualArtifactIds = (Object[]) it.next(); + String actualArtifactId = ( String ) actualArtifactIds[1]; + assertTrue( prefix + "artifactId result should not be blank.", StringUtils.isNotBlank( actualArtifactId ) ); + assertTrue( prefix + " artifactId result <" + actualArtifactId + "> exists in expected artifactIds.", + expectedArtifactIds.contains( actualArtifactId ) ); + } + } + private void assertConstraint( String[] artifactIds, SimpleConstraint constraint ) { String prefix = "Unique Artifact IDs: "; - List results = dao.query( constraint ); + List<String> results = dao.query( constraint ); assertNotNull( prefix + "Not Null", results ); assertEquals( prefix + "Results.size", artifactIds.length, results.size() ); - List expectedArtifactIds = Arrays.asList( artifactIds ); + List<String> expectedArtifactIds = Arrays.asList( artifactIds ); - Iterator it = results.iterator(); + Iterator<String> it = results.iterator(); while ( it.hasNext() ) { String actualArtifactId = (String) it.next(); diff --git a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueGroupIdConstraintTest.java b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueGroupIdConstraintTest.java index b32ea06cf..eef212eb2 100644 --- a/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueGroupIdConstraintTest.java +++ b/archiva-modules/archiva-database/src/test/java/org/apache/maven/archiva/database/constraints/UniqueGroupIdConstraintTest.java @@ -230,8 +230,8 @@ public class UniqueGroupIdConstraintTest assertConstraint( new String[] { "org.codehaus.modello", "org.codehaus.mojo", "org.apache.archiva" }, new UniqueGroupIdConstraint( observableRepositories ) ); - } - + } + private void assertConstraint( String[] expectedGroupIds, SimpleConstraint constraint ) throws Exception { diff --git a/archiva-modules/archiva-reporting/archiva-report-manager/pom.xml b/archiva-modules/archiva-reporting/archiva-report-manager/pom.xml index 2220a81f1..cf94e84b8 100755 --- a/archiva-modules/archiva-reporting/archiva-report-manager/pom.xml +++ b/archiva-modules/archiva-reporting/archiva-report-manager/pom.xml @@ -48,6 +48,11 @@ <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-spring</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> </build> diff --git a/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/ArchivaReportException.java b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/ArchivaReportException.java new file mode 100644 index 000000000..3eca9bf21 --- /dev/null +++ b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/ArchivaReportException.java @@ -0,0 +1,40 @@ +package org.apache.maven.archiva.reporting; + +/* + * 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. + */ + +/** + * ArchivaReportException + * + * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a> + * @version $Id: ArchivaReportException.java + */ +public class ArchivaReportException + extends Exception +{ + public ArchivaReportException( String message, Throwable cause ) + { + super( message, cause ); + } + + public ArchivaReportException( String message ) + { + super( message ); + } +} diff --git a/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/RepositoryStatistics.java b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/RepositoryStatistics.java new file mode 100644 index 000000000..44d6d4a71 --- /dev/null +++ b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/RepositoryStatistics.java @@ -0,0 +1,234 @@ +package org.apache.maven.archiva.reporting; + +import java.util.Date; + +/* + * 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. + */ + +/** + * RepositoryStatistics + * + * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a> + */ +public class RepositoryStatistics +{ + private String repositoryId; + + private long fileCount = 0; + + private long totalSize = 0; + + private long projectCount = 0; + + private long groupCount = 0; + + private long artifactCount = 0; + + private long pluginCount = 0; + + private long archetypeCount = 0; + + private long jarCount = 0; + + private long warCount = 0; + + private long earCount = 0; + + private long dllCount = 0; + + private long exeCount = 0; + + private long pomCount = 0; + + private long deploymentCount = 0; + + private long downloadCount = 0; + + private Date dateOfScan; + + public String getRepositoryId() + { + return repositoryId; + } + + public void setRepositoryId( String repositoryId ) + { + this.repositoryId = repositoryId; + } + + public long getFileCount() + { + return fileCount; + } + + public void setFileCount( long fileCount ) + { + this.fileCount = fileCount; + } + + public long getTotalSize() + { + return totalSize; + } + + public void setTotalSize( long totalSize ) + { + this.totalSize = totalSize; + } + + public long getProjectCount() + { + return projectCount; + } + + public void setProjectCount( long projectCount ) + { + this.projectCount = projectCount; + } + + public long getGroupCount() + { + return groupCount; + } + + public void setGroupCount( long groupCount ) + { + this.groupCount = groupCount; + } + + public long getArtifactCount() + { + return artifactCount; + } + + public void setArtifactCount( long artifactCount ) + { + this.artifactCount = artifactCount; + } + + public long getPluginCount() + { + return pluginCount; + } + + public void setPluginCount( long pluginCount ) + { + this.pluginCount = pluginCount; + } + + public long getArchetypeCount() + { + return archetypeCount; + } + + public void setArchetypeCount( long archetypeCount ) + { + this.archetypeCount = archetypeCount; + } + + public long getJarCount() + { + return jarCount; + } + + public void setJarCount( long jarCount ) + { + this.jarCount = jarCount; + } + + public long getWarCount() + { + return warCount; + } + + public void setWarCount( long warCount ) + { + this.warCount = warCount; + } + + public long getEarCount() + { + return earCount; + } + + public void setEarCount( long earCount ) + { + this.earCount = earCount; + } + + public long getDllCount() + { + return dllCount; + } + + public void setDllCount( long dllCount ) + { + this.dllCount = dllCount; + } + + public long getExeCount() + { + return exeCount; + } + + public void setExeCount( long exeCount ) + { + this.exeCount = exeCount; + } + + public long getPomCount() + { + return pomCount; + } + + public void setPomCount( long pomCount ) + { + this.pomCount = pomCount; + } + + public long getDeploymentCount() + { + return deploymentCount; + } + + public void setDeploymentCount( long deploymentCount ) + { + this.deploymentCount = deploymentCount; + } + + public long getDownloadCount() + { + return downloadCount; + } + + public void setDownloadCount( long downloadCount ) + { + this.downloadCount = downloadCount; + } + + public Date getDateOfScan() + { + return dateOfScan; + } + + public void setDateOfScan( Date dateOfScan ) + { + this.dateOfScan = dateOfScan; + } +} diff --git a/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/RepositoryStatisticsReportGenerator.java b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/RepositoryStatisticsReportGenerator.java new file mode 100644 index 000000000..1b1e0aa78 --- /dev/null +++ b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/RepositoryStatisticsReportGenerator.java @@ -0,0 +1,50 @@ +package org.apache.maven.archiva.reporting; + +/* + * 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 java.util.Date; +import java.util.List; + +import org.apache.maven.archiva.model.RepositoryContentStatistics; + +/** + * RepositoryStatisticsReportGenerator + * + * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a> + * @version $Id: RepositoryStatisticsReportGenerator.java + */ +public interface RepositoryStatisticsReportGenerator +{ + public static final String JAR_TYPE = "jar"; + + public static final String WAR_TYPE = "war"; + + public static final String POM_TYPE = "pom"; + + public static final String MAVEN_PLUGIN = "maven-plugin"; + + public static final String ARCHETYPE = "archetype"; + + public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats, String repository, Date startDate, Date endDate, DataLimits limits ) + throws ArchivaReportException; + + public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats, String repository, Date startDate, Date endDate ) + throws ArchivaReportException; +} diff --git a/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/SimpleRepositoryStatisticsReportGenerator.java b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/SimpleRepositoryStatisticsReportGenerator.java new file mode 100644 index 000000000..8eb75864b --- /dev/null +++ b/archiva-modules/archiva-reporting/archiva-report-manager/src/main/java/org/apache/maven/archiva/reporting/SimpleRepositoryStatisticsReportGenerator.java @@ -0,0 +1,147 @@ +package org.apache.maven.archiva.reporting; + +/* + * 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 java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.maven.archiva.database.ArchivaDAO; +import org.apache.maven.archiva.database.ArchivaDatabaseException; +import org.apache.maven.archiva.database.ArtifactDAO; +import org.apache.maven.archiva.database.constraints.ArtifactsByRepositoryConstraint; +import org.apache.maven.archiva.model.RepositoryContentStatistics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SimpleRepositoryStatisticsReportGenerator + * + * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a> + * @version $Id: SimpleRepositoryStatisticsReportGenerator.java + * + * @plexus.component role="org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator" role-hint="simple" + */ +public class SimpleRepositoryStatisticsReportGenerator + implements RepositoryStatisticsReportGenerator +{ + private Logger log = LoggerFactory.getLogger( SimpleRepositoryStatisticsReportGenerator.class ); + + /** + * @plexus.requirement role-hint="jdo" + */ + private ArchivaDAO dao; + + /** + * {@inheritDoc} + * + * @see org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator#generateReport(java.util.List + * repoContentStats, java.util.String repository, java.util.Date startDate, java.util.Date endDate, + * org.apache.maven.archiva.reporting.DataLimits limits ) + */ + public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats, + String repository, Date startDate, Date endDate, DataLimits limits ) + throws ArchivaReportException + { + if( limits.getCurrentPage() > limits.getCountOfPages() ) + { + throw new ArchivaReportException( "The requested page exceeds the total number of pages." ); + } + + int start = ( limits.getPerPageCount() * limits.getCurrentPage() ) - limits.getPerPageCount(); + int end = ( start + limits.getPerPageCount() ) - 1; + + if( end > repoContentStats.size() ) + { + end = repoContentStats.size() - 1; + } + + return constructRepositoryStatistics( repoContentStats, repository, endDate, start, end ); + } + + /** + * {@inheritDoc} + * + * @see org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator#generateReport(java.util.List + * repoContentStats, java.util.String repository, java.util.Date startDate, java.util.Date endDate) + */ + public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats, String repository, Date startDate, Date endDate ) + throws ArchivaReportException + { + return constructRepositoryStatistics( repoContentStats, repository, endDate, 0, repoContentStats.size() - 1 ); + } + + private List<RepositoryStatistics> constructRepositoryStatistics( + List<RepositoryContentStatistics> repoContentStats, + String repository, Date endDate, + int start, int end ) + { + ArtifactDAO artifactDao = dao.getArtifactDAO(); + + List<RepositoryStatistics> repoStatisticsList = new ArrayList<RepositoryStatistics>(); + for( int i = start; i <= end; i++ ) + { + RepositoryContentStatistics repoContentStat = (RepositoryContentStatistics) repoContentStats.get( i ); + RepositoryStatistics repoStatistics = new RepositoryStatistics(); + repoStatistics.setRepositoryId( repository ); + + // get only the latest + repoStatistics.setArtifactCount( repoContentStat.getTotalArtifactCount() ); + repoStatistics.setGroupCount( repoContentStat.getTotalGroupCount() ); + repoStatistics.setProjectCount( repoContentStat.getTotalProjectCount() ); + repoStatistics.setTotalSize( repoContentStat.getTotalSize() ); + repoStatistics.setFileCount( repoContentStat.getTotalFileCount() ); + repoStatistics.setDateOfScan( repoContentStat.getWhenGathered() ); + + try + { + //TODO use the repo content stats whenGathered date instead of endDate for single repo reports + List types = artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( repository, JAR_TYPE, endDate, "whenGathered" ) ); + repoStatistics.setJarCount( types.size() ); + + types = artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( repository, WAR_TYPE, endDate, "whenGathered" ) ); + repoStatistics.setWarCount( types.size() ); + + types = artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( repository, MAVEN_PLUGIN, endDate, "whenGathered" ) ); + repoStatistics.setPluginCount( types.size() ); + + // TODO: must need to be able to track archetypes. possible way of identifying an + // archetype is by checking if archetype.xml exists in src/main/resources/META-INF/ + + } + catch( ArchivaDatabaseException e ) + { + log.error( "Error occurred while querying artifacts from the database.", e.getMessage() ); + } + + repoStatisticsList.add( repoStatistics ); + } + + return repoStatisticsList; + } + + public void setDao( ArchivaDAO dao ) + { + this.dao = dao; + } +} diff --git a/archiva-modules/archiva-reporting/archiva-report-manager/src/test/java/org/apache/maven/archiva/reporting/SimpleRepositoryStatisticsReportGeneratorTest.java b/archiva-modules/archiva-reporting/archiva-report-manager/src/test/java/org/apache/maven/archiva/reporting/SimpleRepositoryStatisticsReportGeneratorTest.java new file mode 100644 index 000000000..49828e0dc --- /dev/null +++ b/archiva-modules/archiva-reporting/archiva-report-manager/src/test/java/org/apache/maven/archiva/reporting/SimpleRepositoryStatisticsReportGeneratorTest.java @@ -0,0 +1,356 @@ +package org.apache.maven.archiva.reporting; + +/* + * 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 java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.apache.maven.archiva.database.ArchivaDAO; +import org.apache.maven.archiva.database.ArtifactDAO; +import org.apache.maven.archiva.database.constraints.ArtifactsByRepositoryConstraint; +import org.apache.maven.archiva.model.ArchivaArtifact; +import org.apache.maven.archiva.model.RepositoryContentStatistics; +import org.codehaus.plexus.spring.PlexusInSpringTestCase; +import org.easymock.MockControl; +import org.easymock.internal.AlwaysMatcher; + +/** + * SimpleRepositoryStatisticsReportGeneratorTest + * + * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a> + * @version $Id: SimpleRepositoryStatisticsReportGenerator.java + * + * @plexus.component role="org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator" role-hint="simple" + */ +public class SimpleRepositoryStatisticsReportGeneratorTest + extends PlexusInSpringTestCase +{ + private MockControl daoControl; + + private ArchivaDAO dao; + + private MockControl artifactDaoControl; + + private ArtifactDAO artifactDao; + + private SimpleRepositoryStatisticsReportGenerator generator; + + private static final String REPO = "test-repo"; + + public void setUp() + throws Exception + { + super.setUp(); + + daoControl = MockControl.createControl( ArchivaDAO.class ); + dao = ( ArchivaDAO ) daoControl.getMock(); + + generator = new SimpleRepositoryStatisticsReportGenerator(); + generator.setDao( dao ); + + artifactDaoControl = MockControl.createControl( ArtifactDAO.class ); + artifactDaoControl.setDefaultMatcher( new AlwaysMatcher() ); + artifactDao = ( ArtifactDAO ) artifactDaoControl.getMock(); + } + + private Date toDate( int year, int month, int date, int hour, int min, int sec ) + { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set( year, month, date, hour, min, sec ); + + return cal.getTime(); + } + + private List<ArchivaArtifact> createArtifacts( String type ) + { + List<ArchivaArtifact> artifacts = new ArrayList<ArchivaArtifact>(); + artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "1.0", type ) ); + artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "1.1", type ) ); + artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "1.2", type ) ); + artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "2.0", type ) ); + artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "3.0", type ) ); + + return artifacts; + } + + private ArchivaArtifact createArtifact( String repoId, String groupId, String artifactId, String version, String type ) + { + ArchivaArtifact artifact = new ArchivaArtifact( groupId, artifactId, version, null, type ); + artifact.getModel().setLastModified( new Date() ); + artifact.getModel().setRepositoryId( repoId ); + + return artifact; + } + + private RepositoryContentStatistics createRepositoryContentStatistics( Date startDate, String repositoryId ) + { + RepositoryContentStatistics repoContentStats = new RepositoryContentStatistics(); + repoContentStats.setRepositoryId( repositoryId ); + repoContentStats.setDuration( 10000 ); + repoContentStats.setNewFileCount( 100 ); + repoContentStats.setTotalArtifactCount( 200 ); + repoContentStats.setTotalFileCount( 250 ); + repoContentStats.setTotalGroupCount( 100 ); + repoContentStats.setTotalProjectCount( 180 ); + repoContentStats.setTotalSize( 200000 ); + repoContentStats.setWhenGathered( startDate ); + + return repoContentStats; + } + + private List<RepositoryContentStatistics> createStatisticsHistoryForSingleRepositoryTest( String repoId ) + { + List<RepositoryContentStatistics> repoContentStatsList = new ArrayList<RepositoryContentStatistics>(); + + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 11, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 10, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 10, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 9, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 9, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 8, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 8, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 7, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 7, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 6, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 6, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 5, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 5, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 4, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 4, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 3, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 3, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 2, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 2, 1, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 1, 16, 0, 0, 0 ), repoId ) ); + repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 1, 1, 0, 0, 0 ), repoId ) ); + + return repoContentStatsList; + } + + public void testSimpleReportWithPagination() + throws Exception + { + Date startDate = toDate( 2008, 1, 1, 0, 0, 0 ); + Date endDate = toDate( 2008, 11, 30, 0, 0, 0 ); + + DataLimits limits = new DataLimits(); + limits.setPerPageCount( 5 ); + limits.setCurrentPage( 1 ); + limits.setCountOfPages( 5 ); + limits.setTotalCount( 21 ); + + List<ArchivaArtifact> jarArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.JAR_TYPE ); + List<ArchivaArtifact> warArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.WAR_TYPE ); + List<ArchivaArtifact> mavenPlugins = createArtifacts( RepositoryStatisticsReportGenerator.MAVEN_PLUGIN ); + + List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO ); + + // get first page + daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts, 5 ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts, 5 ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins, 5 ); + + daoControl.replay(); + artifactDaoControl.replay(); + + List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits ); + + daoControl.verify(); + artifactDaoControl.verify(); + + assertEquals( 5, data.size() ); + + RepositoryStatistics stats = (RepositoryStatistics) data.get( 0 ); + assertEquals( REPO, stats.getRepositoryId() ); + assertEquals( 200, stats.getArtifactCount() ); + assertEquals( 5, stats.getJarCount() ); + assertEquals( 5, stats.getWarCount() ); + assertEquals( 5, stats.getPluginCount() ); + assertEquals( toDate( 2008, 11, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() ); + assertEquals( toDate( 2008, 9, 1, 0, 0, 0 ).getTime(), ( (RepositoryStatistics) data.get( 4 ) ).getDateOfScan().getTime() ); + + // get last page + limits.setCurrentPage( 5 ); + + daoControl.reset(); + artifactDaoControl.reset(); + + artifactDaoControl.setDefaultMatcher( new AlwaysMatcher() ); + + daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins ); + + daoControl.replay(); + artifactDaoControl.replay(); + + data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits ); + + daoControl.verify(); + artifactDaoControl.verify(); + + assertEquals( 1, data.size() ); + + stats = (RepositoryStatistics) data.get( 0 ); + assertEquals( REPO, stats.getRepositoryId() ); + assertEquals( 200, stats.getArtifactCount() ); + assertEquals( 5, stats.getJarCount() ); + assertEquals( 5, stats.getWarCount() ); + assertEquals( 5, stats.getPluginCount() ); + assertEquals( toDate( 2008, 1, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() ); + } + + public void testSimpleReportWithoutPagination() + throws Exception + { + Date startDate = toDate( 2008, 1, 1, 0, 0, 0 ); + Date endDate = toDate( 2008, 11, 30, 0, 0, 0 ); + + List<ArchivaArtifact> jarArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.JAR_TYPE ); + List<ArchivaArtifact> warArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.WAR_TYPE ); + List<ArchivaArtifact> mavenPlugins = createArtifacts( RepositoryStatisticsReportGenerator.MAVEN_PLUGIN ); + + List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO ); + + // get first page + daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts, 21 ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts, 21 ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins, 21 ); + + daoControl.replay(); + artifactDaoControl.replay(); + + List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate ); + + daoControl.verify(); + artifactDaoControl.verify(); + + assertEquals( 21, data.size() ); + + RepositoryStatistics stats = (RepositoryStatistics) data.get( 0 ); + assertEquals( REPO, stats.getRepositoryId() ); + assertEquals( 200, stats.getArtifactCount() ); + assertEquals( 5, stats.getJarCount() ); + assertEquals( 5, stats.getWarCount() ); + assertEquals( 5, stats.getPluginCount() ); + assertEquals( toDate( 2008, 11, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() ); + assertEquals( toDate( 2008, 1, 1, 0, 0, 0 ).getTime(), ( (RepositoryStatistics) data.get( 20 ) ).getDateOfScan().getTime() ); + } + + public void testSimpleReportNoArtifactCountStatisticsAvailable() + throws Exception + { + Date startDate = toDate( 2008, 1, 1, 0, 0, 0 ); + Date endDate = toDate( 2008, 11, 30, 0, 0, 0 ); + + DataLimits limits = new DataLimits(); + limits.setPerPageCount( 5 ); + limits.setCurrentPage( 1 ); + limits.setCountOfPages( 5 ); + limits.setTotalCount( 21 ); + + List<ArchivaArtifact> jarArtifacts = new ArrayList<ArchivaArtifact>(); + List<ArchivaArtifact> warArtifacts = new ArrayList<ArchivaArtifact>(); + List<ArchivaArtifact> mavenPlugins = new ArrayList<ArchivaArtifact>(); + + List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO ); + + daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts, 5 ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts, 5 ); + + artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts( + new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins, 5 ); + + daoControl.replay(); + artifactDaoControl.replay(); + + List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits ); + + daoControl.verify(); + artifactDaoControl.verify(); + + assertEquals( 5, data.size() ); + + RepositoryStatistics stats = (RepositoryStatistics) data.get( 0 ); + assertEquals( REPO, stats.getRepositoryId() ); + assertEquals( 200, stats.getArtifactCount() ); + assertEquals( 0, stats.getJarCount() ); + assertEquals( 0, stats.getWarCount() ); + assertEquals( 0, stats.getPluginCount() ); + assertEquals( toDate( 2008, 11, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() ); + assertEquals( toDate( 2008, 9, 1, 0, 0, 0 ).getTime(), ( (RepositoryStatistics) data.get( 4 ) ).getDateOfScan().getTime() ); + // no results found when ArtifactDAO was queried + } + + public void testSimpleReportWithPaginationInvalidRequestedPage() + throws Exception + { + Date startDate = toDate( 2008, 1, 1, 0, 0, 0 ); + Date endDate = toDate( 2008, 11, 30, 0, 0, 0 ); + + DataLimits limits = new DataLimits(); + limits.setPerPageCount( 5 ); + limits.setCurrentPage( 10 ); + limits.setCountOfPages( 5 ); + limits.setTotalCount( 21 ); + + List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO ); + + try + { + List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits ); + fail( "An ArchivaReportException should have been thrown." ); + } + catch ( ArchivaReportException a ) + { + + } + // requested page exceeds total number of pages + } +} diff --git a/archiva-modules/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/executors/ArchivaRepositoryScanningTaskExecutor.java b/archiva-modules/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/executors/ArchivaRepositoryScanningTaskExecutor.java index 527ee34fc..65393a164 100644 --- a/archiva-modules/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/executors/ArchivaRepositoryScanningTaskExecutor.java +++ b/archiva-modules/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/executors/ArchivaRepositoryScanningTaskExecutor.java @@ -20,10 +20,14 @@ package org.apache.maven.archiva.scheduled.executors; */ import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.apache.maven.archiva.configuration.ArchivaConfiguration; import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; 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.ArtifactsByRepositoryConstraint; import org.apache.maven.archiva.database.constraints.MostRecentRepositoryScanStatistics; import org.apache.maven.archiva.model.RepositoryContentStatistics; import org.apache.maven.archiva.repository.RepositoryException; @@ -38,6 +42,7 @@ import org.codehaus.plexus.taskqueue.execution.TaskExecutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; import java.util.List; /** @@ -112,19 +117,95 @@ public class ArchivaRepositoryScanningTaskExecutor log.info( "Finished repository task: " + stats.toDump( arepo ) ); - // I hate jpox and modello - RepositoryContentStatistics dbstats = new RepositoryContentStatistics(); - dbstats.setDuration( stats.getDuration() ); - dbstats.setNewFileCount( stats.getNewFileCount() ); - dbstats.setRepositoryId( stats.getRepositoryId() ); - dbstats.setTotalFileCount( stats.getTotalFileCount() ); - dbstats.setWhenGathered( stats.getWhenGathered() ); + RepositoryContentStatistics dbstats = constructRepositoryStatistics( arepo, sinceWhen, results, stats ); - dao.getRepositoryContentStatisticsDAO().saveRepositoryContentStatistics( dbstats ); + dao.getRepositoryContentStatisticsDAO().saveRepositoryContentStatistics( dbstats ); } catch ( RepositoryException e ) - { + { throw new TaskExecutionException( "Repository error when executing repository job.", e ); - } + } } + + private RepositoryContentStatistics constructRepositoryStatistics( ManagedRepositoryConfiguration arepo, + long sinceWhen, + List<RepositoryContentStatistics> results, + RepositoryScanStatistics stats ) + { + // I hate jpox and modello <-- and so do I + RepositoryContentStatistics dbstats = new RepositoryContentStatistics(); + dbstats.setDuration( stats.getDuration() ); + dbstats.setNewFileCount( stats.getNewFileCount() ); + dbstats.setRepositoryId( stats.getRepositoryId() ); + dbstats.setTotalFileCount( stats.getTotalFileCount() ); + dbstats.setWhenGathered( stats.getWhenGathered() ); + + // MRM-84 + /* + List<RepositoryContentStatistics> secondResults = dao.query( new MostRecentRepositoryScanStatistics( arepo.getId() ) ); + if ( CollectionUtils.isNotEmpty( results ) ) + { + RepositoryContentStatistics lastStats = secondResults.get( 0 ); + sinceWhen = lastStats.getWhenGathered().getTime() + lastStats.getDuration(); + } + */ + + // total artifact count + try + { + List artifacts = dao.getArtifactDAO().queryArtifacts( + new ArtifactsByRepositoryConstraint( arepo.getId(), stats.getWhenGathered(), "groupId", true ) ); + dbstats.setTotalArtifactCount( artifacts.size() ); + } + catch ( ObjectNotFoundException oe ) + { + log.error( "Object not found in the database : " + oe.getMessage() ); + } + catch ( ArchivaDatabaseException ae ) + { + log.error( "Error occurred while querying artifacts for artifact count : " + ae.getMessage() ); + } + + + // total repo size + long size = FileUtils.sizeOfDirectory( new File( arepo.getLocation() ) ); + dbstats.setTotalSize( size ); + + /* + TODO: + + // total unique groups + List<String> repos = new ArrayList<String>(); + repos.add( arepo.getId() ); + try + { + List<String> groupIds = dao.getArtifactDAO().queryArtifacts( new UniqueGroupIdConstraint( repos ) ); + dbstats.setTotalGroupCount( groupIds.size() ); + } + catch ( ObjectNotFoundException oe ) + { + + } + catch ( ArchivaDatabaseException ae ) + { + + } + + // total unique projects + try + { + List<Object[]> artifactIds = dao.getArtifactDAO().queryArtifacts( new UniqueArtifactIdConstraint( arepo.getId(), true ) ); + dbstats.setTotalProjectCount( artifactIds.size() ); + } + catch ( ObjectNotFoundException oe ) + { + + } + catch ( ArchivaDatabaseException ae ) + { + + }*/ + + return dbstats; + } } diff --git a/archiva-modules/archiva-web/archiva-rss/src/main/java/org/apache/archiva/rss/processor/NewArtifactsRssFeedProcessor.java b/archiva-modules/archiva-web/archiva-rss/src/main/java/org/apache/archiva/rss/processor/NewArtifactsRssFeedProcessor.java index 3ef5c9182..031fc11d4 100644 --- a/archiva-modules/archiva-web/archiva-rss/src/main/java/org/apache/archiva/rss/processor/NewArtifactsRssFeedProcessor.java +++ b/archiva-modules/archiva-web/archiva-rss/src/main/java/org/apache/archiva/rss/processor/NewArtifactsRssFeedProcessor.java @@ -89,7 +89,7 @@ public class NewArtifactsRssFeedProcessor Calendar greaterThanThisDate = Calendar.getInstance( DateUtils.UTC_TIME_ZONE ); greaterThanThisDate.add( Calendar.DATE, -( getNumberOfDaysBeforeNow() ) ); - Constraint artifactsByRepo = new ArtifactsByRepositoryConstraint( repoId, greaterThanThisDate.getTime(), "whenGathered" ); + Constraint artifactsByRepo = new ArtifactsByRepositoryConstraint( repoId, greaterThanThisDate.getTime(), "whenGathered", false ); List<ArchivaArtifact> artifacts = artifactDAO.queryArtifacts( artifactsByRepo ); List<RssFeedEntry> entries = processData( artifacts, true ); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java index 747ec9802..f254422df 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java @@ -21,25 +21,40 @@ package org.apache.maven.archiva.web.action.reports; import com.opensymphony.webwork.interceptor.ServletRequestAware; import com.opensymphony.xwork.Preparable; + +import org.apache.maven.archiva.configuration.ArchivaConfiguration; 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.RepositoryContentStatisticsDAO; import org.apache.maven.archiva.database.constraints.RangeConstraint; +import org.apache.maven.archiva.database.constraints.RepositoryContentStatisticsByRepositoryConstraint; import org.apache.maven.archiva.database.constraints.RepositoryProblemByGroupIdConstraint; import org.apache.maven.archiva.database.constraints.RepositoryProblemByRepositoryIdConstraint; import org.apache.maven.archiva.database.constraints.RepositoryProblemConstraint; import org.apache.maven.archiva.database.constraints.UniqueFieldConstraint; +import org.apache.maven.archiva.model.RepositoryContentStatistics; import org.apache.maven.archiva.model.RepositoryProblem; import org.apache.maven.archiva.model.RepositoryProblemReport; +import org.apache.maven.archiva.reporting.ArchivaReportException; +import org.apache.maven.archiva.reporting.DataLimits; +import org.apache.maven.archiva.reporting.RepositoryStatistics; +import org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator; import org.apache.maven.archiva.security.ArchivaRoleConstants; import org.codehaus.plexus.redback.rbac.Resource; import org.codehaus.plexus.redback.xwork.interceptor.SecureAction; import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle; import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException; import org.codehaus.plexus.xwork.action.PlexusActionSupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -51,10 +66,17 @@ public class GenerateReportAction extends PlexusActionSupport implements SecureAction, ServletRequestAware, Preparable { + private Logger log = LoggerFactory.getLogger( GenerateReportAction.class ); + /** * @plexus.requirement role-hint="jdo" */ protected ArchivaDAO dao; + + /** + * @plexus.requirement + */ + private ArchivaConfiguration archivaConfiguration; protected Constraint constraint; @@ -90,13 +112,45 @@ public class GenerateReportAction protected Map<String, List<RepositoryProblemReport>> repositoriesMap = new TreeMap<String, List<RepositoryProblemReport>>(); - + + // for statistics report + /** + * @plexus.requirement role-hint="simple" + */ + private RepositoryStatisticsReportGenerator generator; + + private List<String> selectedRepositories = new ArrayList<String>(); + + private List<String> availableRepositories; + + private Date startDate; + + private Date endDate; + + private int reposSize; + + private String selectedRepo; + + private List<RepositoryStatistics> repositoryStatistics = new ArrayList<RepositoryStatistics>(); + public void prepare() { repositoryIds = new ArrayList<String>(); repositoryIds.add( ALL_REPOSITORIES ); // comes first to be first in the list repositoryIds.addAll( dao.query( new UniqueFieldConstraint( RepositoryProblem.class.getName(), "repositoryId" ) ) ); + + availableRepositories = new ArrayList<String>(); + + // remove selected repositories in the option for the statistics report + availableRepositories.addAll( archivaConfiguration.getConfiguration().getManagedRepositoriesAsMap().keySet() ); + for( String repo : selectedRepositories ) + { + if( availableRepositories.contains( repo ) ) + { + availableRepositories.remove( repo ); + } + } } public Collection<String> getRepositoryIds() @@ -104,9 +158,149 @@ public class GenerateReportAction return repositoryIds; } + /** + * Generate the statistics report. + * + * check whether single repo report or comparison report + * 1. if it is a single repository, get all the statistics for the repository on the specified date + * - if no date is specified, get only the latest + * (total page = 1 --> no pagination since only the most recent stats will be displayed) + * - otherwise, get everything within the date range (total pages = repo stats / rows per page) + * - required params: repository, startDate, endDate + * + * 2. if multiple repositories, get the latest statistics on each repository on the specified date + * - if no date is specified, use the current date endDate + * - required params: repositories, endDate + * - total pages = repositories / rows per page + * + * @return + */ + public String generateStatistics() + { + DataLimits limits = new DataLimits(); + setDefaults(); + reposSize = selectedRepositories.size(); + + try + { + RepositoryContentStatisticsDAO repoContentStatsDao = dao.getRepositoryContentStatisticsDAO(); + if( selectedRepositories.size() > 1 ) + { + limits.setTotalCount( selectedRepositories.size() ); + limits.setCurrentPage( 1 ); + limits.setPerPageCount( 1 ); + limits.setCountOfPages( 1 ); + + // multiple repos + for( String repo : selectedRepositories ) + { + try + { + List contentStats = repoContentStatsDao.queryRepositoryContentStatistics( + new RepositoryContentStatisticsByRepositoryConstraint( repo, startDate, endDate ) ); + + if( contentStats == null || contentStats.isEmpty() ) + { + log.info( "No statistics available for repository '" + repo + "'." ); + // TODO set repo's stats to 0 + + continue; + } + repositoryStatistics.addAll( generator.generateReport( contentStats, repo, startDate, endDate, limits ) ); + } + catch ( ObjectNotFoundException oe ) + { + log.error( "No statistics available for repository '" + repo + "'." ); + // TODO set repo's stats to 0 + } + catch ( ArchivaDatabaseException ae ) + { + log.error( "Error encountered while querying statistics of repository '" + repo + "'." ); + // TODO set repo's stats to 0 + } + } + } + else if ( selectedRepositories.size() == 1 ) + { + limits.setCurrentPage( getPage() ); + limits.setPerPageCount( getRowCount() ); + + selectedRepo = selectedRepositories.get( 0 ); + try + { + List<RepositoryContentStatistics> contentStats = repoContentStatsDao.queryRepositoryContentStatistics( + new RepositoryContentStatisticsByRepositoryConstraint( selectedRepo, startDate, endDate ) ); + + if( contentStats == null || contentStats.isEmpty() ) + { + addActionError( "No statistics available for repository. Repository might not have been scanned." ); + return ERROR; + } + + limits.setTotalCount( contentStats.size() ); + int extraPage = ( limits.getTotalCount() % limits.getPerPageCount() ) != 0 ? 1 : 0; + int totalPages = ( limits.getTotalCount() / limits.getPerPageCount() ) + extraPage; + limits.setCountOfPages( totalPages ); + + repositoryStatistics = generator.generateReport( contentStats, selectedRepo, startDate, endDate, limits ); + } + catch ( ObjectNotFoundException oe ) + { + addActionError( oe.getMessage() ); + return ERROR; + } + catch ( ArchivaDatabaseException de ) + { + addActionError( de.getMessage() ); + return ERROR; + } + } + else + { + addFieldError( "availableRepositories", "Please select a repository (or repositories) from the list." ); + return INPUT; + } + } + catch ( ArchivaReportException e ) + { + addActionError( "Error encountered while generating report :: " + e.getMessage() ); + return ERROR; + } + + return SUCCESS; + } + + private void setDefaults() + { + if( startDate == null ) + { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set( 1900, 1, 1, 0, 0, 0 ); + startDate = cal.getTime(); + } + + if( endDate == null ) + { + endDate = Calendar.getInstance().getTime(); + } + } + public String execute() throws Exception - { + { + if( repositoryId == null ) + { + addFieldError( "repositoryId", "You must provide a repository id."); + return INPUT; + } + + if( rowCount < 10 ) + { + addFieldError( "rowCount", "Row count must be larger than 10." ); + return INPUT; + } + List<RepositoryProblem> problemArtifacts = dao.getRepositoryProblemDAO().queryRepositoryProblems( configureConstraint() ); @@ -156,7 +350,7 @@ public class GenerateReportAction return SUCCESS; } } - + private static boolean isJasperPresent() { if ( jasperPresent == null ) @@ -207,6 +401,34 @@ public class GenerateReportAction return constraint; } + + public SecureActionBundle getSecureActionBundle() + throws SecureActionException + { + SecureActionBundle bundle = new SecureActionBundle(); + + bundle.setRequiresAuthentication( true ); + bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL ); + + return bundle; + } + + private void addToList( RepositoryProblemReport repoProblemReport ) + { + List<RepositoryProblemReport> problemsList = null; + + if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) ) + { + problemsList = ( List<RepositoryProblemReport> ) repositoriesMap.get( repoProblemReport.getRepositoryId() ); + } + else + { + problemsList = new ArrayList<RepositoryProblemReport>(); + repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList ); + } + + problemsList.add( repoProblemReport ); + } public void setServletRequest( HttpServletRequest request ) { @@ -283,31 +505,73 @@ public class GenerateReportAction return repositoriesMap; } - public SecureActionBundle getSecureActionBundle() - throws SecureActionException + public List<String> getSelectedRepositories() { - SecureActionBundle bundle = new SecureActionBundle(); + return selectedRepositories; + } - bundle.setRequiresAuthentication( true ); - bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL ); + public void setSelectedRepositories( List<String> selectedRepositories ) + { + this.selectedRepositories = selectedRepositories; + } - return bundle; + public List<String> getAvailableRepositories() + { + return availableRepositories; + } + + public void setAvailableRepositories( List<String> availableRepositories ) + { + this.availableRepositories = availableRepositories; + } + + public Date getStartDate() + { + return startDate; + } + + public void setStartDate( Date startDate ) + { + this.startDate = startDate; + } + + public Date getEndDate() + { + return endDate; + } + + public void setEndDate( Date endDate ) + { + this.endDate = endDate; + } + + public List<RepositoryStatistics> getRepositoryStatistics() + { + return repositoryStatistics; + } + + public void setRepositoryStatistics( List<RepositoryStatistics> repositoryStatistics ) + { + this.repositoryStatistics = repositoryStatistics; } - private void addToList( RepositoryProblemReport repoProblemReport ) + public int getReposSize() + { + return reposSize; + } + + public void setReposSize( int reposSize ) + { + this.reposSize = reposSize; + } + + public String getSelectedRepo() + { + return selectedRepo; + } + + public void setSelectedRepo( String selectedRepo ) { - List<RepositoryProblemReport> problemsList = null; - - if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) ) - { - problemsList = ( List<RepositoryProblemReport> ) repositoriesMap.get( repoProblemReport.getRepositoryId() ); - } - else - { - problemsList = new ArrayList<RepositoryProblemReport>(); - repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList ); - } - - problemsList.add( repoProblemReport ); + this.selectedRepo = selectedRepo; } } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/org/apache/maven/archiva/web/action/reports/GenerateReportAction-validation.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/org/apache/maven/archiva/web/action/reports/GenerateReportAction-validation.xml deleted file mode 100644 index a31c0652d..000000000 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/org/apache/maven/archiva/web/action/reports/GenerateReportAction-validation.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!-- - ~ 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. - --> - -<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" - "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> - -<validators> - <field name="rowCount"> - <field-validator type="int"> - <param name="min">10</param> - <message>Row count must be larger than ${min}.</message> - </field-validator> - </field> - <!-- - <field name="groupId"> - <field-validator type="regex"> - <param name="expression"><![CDATA[([a-zA-Z0-9]+[a-zA-Z0-9.]*)]]></param> - <message>You must provide a valid group id.</message> - </field-validator> - </field> - --> - <field name="repositoryId"> - <field-validator type="requiredstring"> - <message>You must provide a repository id.</message> - </field-validator> - </field> -</validators> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml index 36509e11e..b9580cfa9 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml @@ -511,6 +511,13 @@ <result name="blank">/WEB-INF/jsp/reports/blankReport.jsp</result> <result>/WEB-INF/jsp/reports/basicReport.jsp</result> </action> + + <action name="generateStatisticsReport" class="generateReport" method="generateStatistics"> + <result name="input">/WEB-INF/jsp/reports/pickReport.jsp</result> + <result name="blank">/WEB-INF/jsp/reports/blankReport.jsp</result> + <result>/WEB-INF/jsp/reports/statisticsReport.jsp</result> + </action> + </package> </xwork> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp index 117db55eb..5bcdb7986 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp @@ -27,13 +27,28 @@ <body> <h1>Reports</h1> - + <div id="contentArea"> - <ww:form action="generateReport" namespace="/report" validate="true"> + <h2>Repository Statistics</h2> + <ww:form action="generateStatisticsReport" namespace="/report" validate="true"> + + <ww:optiontransferselect label="Repositories To Be Compared" name="availableRepositories" + list="availableRepositories" doubleName="selectedRepositories" + doubleList="selectedRepositories" size="8" doubleSize="8"/> + + <ww:datepicker label="Start Date" name="startDate" id="startDate"/> + <ww:datepicker label="End Date" name="endDate" id="endDate"/> + + <ww:submit value="View Statistics"/> + </ww:form> + + <h2>Repository Health</h2> + <ww:form namespace="/report" action="generateReport" validate="true"> <ww:textfield label="Row Count" name="rowCount" /> <ww:textfield label="Group ID" name="groupId"/> - <ww:select label="Repository ID" name="repositoryId" list="repositoryIds"/> + <ww:select label="Repository ID" name="repositoryId" list="repositoryIds"/> + <ww:submit value="Show Report"/> </ww:form> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/statisticsReport.jsp b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/statisticsReport.jsp new file mode 100644 index 000000000..8366f3eba --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/statisticsReport.jsp @@ -0,0 +1,115 @@ +<%-- + ~ 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. + --%> + +<%@ taglib prefix="ww" uri="/webwork" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="archiva" uri="http://archiva.apache.org" %> + +<html> +<head> + <title>Reports</title> + <ww:head/> +</head> + +<body> +<h1>Statistics Report</h1> + +<div id="contentArea"> + <c:choose> + <c:when test="${reposSize > 1}"> + + <h1>Latest Statistics Comparison Report</h1> + <table class="infoTable" border="1"> + <tr> + <th>Repository</th> + <th>Total File Count</th> + <th>Total Size</th> + <th>Artifact Count</th> + <th>Group Count</th> + <th>Project Count</th> + <th>Plugins</th> + <th>Archetypes</th> + <th>Jars</th> + <th>Wars</th> + <th>Deployments</th> + <th>Downloads</th> + </tr> + + <c:forEach var="stats" items="${repositoryStatistics}"> + <tr> + <td>${stats.repositoryId}</td> + <td align="right">${stats.fileCount}</td> + <td align="right">${stats.totalSize}</td> + <td align="right">${stats.artifactCount}</td> + <td align="right">${stats.groupCount}</td> + <td align="right">${stats.projectCount}</td> + <td align="right">${stats.pluginCount}</td> + <td align="right">${stats.archetypeCount}</td> + <td align="right">${stats.jarCount}</td> + <td align="right">${stats.warCount}</td> + <td align="right">${stats.deploymentCount}</td> + <td align="right">${stats.downloadCount}</td> + </tr> + </c:forEach> + </table> + + </c:when> + <c:otherwise> + + <h1>Statistics for Repository '${selectedRepo}'</h1> + <table class="infoTable" border="1"> + <tr> + <th>Date of Scan</th> + <th>Total File Count</th> + <th>Total Size</th> + <th>Artifact Count</th> + <th>Group Count</th> + <th>Project Count</th> + <th>Plugins</th> + <th>Archetypes</th> + <th>Jars</th> + <th>Wars</th> + <th>Deployments</th> + <th>Downloads</th> + </tr> + + <c:forEach var="stats" items="${repositoryStatistics}"> + <tr> + <td align="right">${stats.dateOfScan}</td> + <td align="right">${stats.fileCount}</td> + <td align="right">${stats.totalSize}</td> + <td align="right">${stats.artifactCount}</td> + <td align="right">${stats.groupCount}</td> + <td align="right">${stats.projectCount}</td> + <td align="right">${stats.pluginCount}</td> + <td align="right">${stats.archetypeCount}</td> + <td align="right">${stats.jarCount}</td> + <td align="right">${stats.warCount}</td> + <td align="right">${stats.deploymentCount}</td> + <td align="right">${stats.downloadCount}</td> + </tr> + </c:forEach> + </table> + + </c:otherwise> + </c:choose> + +</div> +</body> +</html> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css index 983e387b2..46856bafd 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css @@ -33,7 +33,8 @@ select, input { select { padding-left: 3px; - height: 1.4em; + height: auto; + width: auto; } input { |