-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-ffa450edef68tags/archiva-1.2-M1
@@ -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> |
@@ -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() |
@@ -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() | |||
{ |
@@ -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() | |||
{ |
@@ -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 ) |
@@ -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 | |||
{ |
@@ -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() ); | |||
} | |||
} |
@@ -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(); |
@@ -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 | |||
{ |
@@ -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> |
@@ -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 ); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 ); |
@@ -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; | |||
} | |||
} |
@@ -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> |
@@ -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> | |||
@@ -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> | |||
@@ -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> |
@@ -33,7 +33,8 @@ select, input { | |||
select { | |||
padding-left: 3px; | |||
height: 1.4em; | |||
height: auto; | |||
width: auto; | |||
} | |||
input { |