Return-Path: Delivered-To: apmail-archiva-commits-archive@www.apache.org Received: (qmail 69548 invoked from network); 1 Oct 2008 10:28:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Oct 2008 10:28:20 -0000 Received: (qmail 18105 invoked by uid 500); 1 Oct 2008 10:28:19 -0000 Delivered-To: apmail-archiva-commits-archive@archiva.apache.org Received: (qmail 18036 invoked by uid 500); 1 Oct 2008 10:28:19 -0000 Mailing-List: contact commits-help@archiva.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@archiva.apache.org Delivered-To: mailing list commits@archiva.apache.org Received: (qmail 18027 invoked by uid 99); 1 Oct 2008 10:28:19 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Oct 2008 03:28:18 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Oct 2008 10:27:16 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 0502C2388A01; Wed, 1 Oct 2008 03:27:20 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r700729 [2/2] - in /archiva/trunk/archiva-modules: archiva-base/archiva-model/src/main/mdo/ archiva-database/src/main/java/org/apache/maven/archiva/database/constraints/ archiva-database/src/test/java/org/apache/maven/archiva/database/const... Date: Wed, 01 Oct 2008 10:27:18 -0000 To: commits@archiva.apache.org From: oching@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20081001102721.0502C2388A01@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java?rev=700729&r1=700728&r2=700729&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/reports/GenerateReportAction.java Wed Oct 1 03:27:16 2008 @@ -21,25 +21,40 @@ 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 @@ 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 @@ protected Map> repositoriesMap = new TreeMap>(); - + + // for statistics report + /** + * @plexus.requirement role-hint="simple" + */ + private RepositoryStatisticsReportGenerator generator; + + private List selectedRepositories = new ArrayList(); + + private List availableRepositories; + + private Date startDate; + + private Date endDate; + + private int reposSize; + + private String selectedRepo; + + private List repositoryStatistics = new ArrayList(); + public void prepare() { repositoryIds = new ArrayList(); 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(); + + // 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 getRepositoryIds() @@ -104,9 +158,149 @@ 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 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 problemArtifacts = dao.getRepositoryProblemDAO().queryRepositoryProblems( configureConstraint() ); @@ -156,7 +350,7 @@ return SUCCESS; } } - + private static boolean isJasperPresent() { if ( jasperPresent == null ) @@ -207,6 +401,34 @@ 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 problemsList = null; + + if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) ) + { + problemsList = ( List ) repositoriesMap.get( repoProblemReport.getRepositoryId() ); + } + else + { + problemsList = new ArrayList(); + repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList ); + } + + problemsList.add( repoProblemReport ); + } public void setServletRequest( HttpServletRequest request ) { @@ -283,31 +505,73 @@ return repositoriesMap; } - public SecureActionBundle getSecureActionBundle() - throws SecureActionException + public List getSelectedRepositories() { - SecureActionBundle bundle = new SecureActionBundle(); + return selectedRepositories; + } - bundle.setRequiresAuthentication( true ); - bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL ); + public void setSelectedRepositories( List selectedRepositories ) + { + this.selectedRepositories = selectedRepositories; + } - return bundle; + public List getAvailableRepositories() + { + return availableRepositories; + } + + public void setAvailableRepositories( List 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 getRepositoryStatistics() + { + return repositoryStatistics; + } + + public void setRepositoryStatistics( List 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 problemsList = null; - - if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) ) - { - problemsList = ( List ) repositoriesMap.get( repoProblemReport.getRepositoryId() ); - } - else - { - problemsList = new ArrayList(); - repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList ); - } - - problemsList.add( repoProblemReport ); + this.selectedRepo = selectedRepo; } } Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml?rev=700729&r1=700728&r2=700729&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml Wed Oct 1 03:27:16 2008 @@ -511,6 +511,13 @@ /WEB-INF/jsp/reports/blankReport.jsp /WEB-INF/jsp/reports/basicReport.jsp + + + /WEB-INF/jsp/reports/pickReport.jsp + /WEB-INF/jsp/reports/blankReport.jsp + /WEB-INF/jsp/reports/statisticsReport.jsp + + Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp?rev=700729&r1=700728&r2=700729&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/pickReport.jsp Wed Oct 1 03:27:16 2008 @@ -27,13 +27,28 @@

Reports

- +
- +

Repository Statistics

+ + + + + + + + + + +

Repository Health

+ - + + Added: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/statisticsReport.jsp URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/statisticsReport.jsp?rev=700729&view=auto ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/statisticsReport.jsp (added) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/reports/statisticsReport.jsp Wed Oct 1 03:27:16 2008 @@ -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" %> + + + + Reports + + + + +

Statistics Report

+ +
+ + + +

Latest Statistics Comparison Report

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RepositoryTotal File CountTotal SizeArtifact CountGroup CountProject CountPluginsArchetypesJarsWarsDeploymentsDownloads
${stats.repositoryId}${stats.fileCount}${stats.totalSize}${stats.artifactCount}${stats.groupCount}${stats.projectCount}${stats.pluginCount}${stats.archetypeCount}${stats.jarCount}${stats.warCount}${stats.deploymentCount}${stats.downloadCount}
+ +
+ + +

Statistics for Repository '${selectedRepo}'

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Date of ScanTotal File CountTotal SizeArtifact CountGroup CountProject CountPluginsArchetypesJarsWarsDeploymentsDownloads
${stats.dateOfScan}${stats.fileCount}${stats.totalSize}${stats.artifactCount}${stats.groupCount}${stats.projectCount}${stats.pluginCount}${stats.archetypeCount}${stats.jarCount}${stats.warCount}${stats.deploymentCount}${stats.downloadCount}
+ +
+
+ +
+ + Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css?rev=700729&r1=700728&r2=700729&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/maven-theme.css Wed Oct 1 03:27:16 2008 @@ -33,7 +33,8 @@ select { padding-left: 3px; - height: 1.4em; + height: auto; + width: auto; } input {