1 package org.apache.maven.archiva.web.action.reports;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import com.opensymphony.webwork.interceptor.ServletRequestAware;
23 import com.opensymphony.xwork.Preparable;
25 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
26 import org.apache.maven.archiva.database.ArchivaDAO;
27 import org.apache.maven.archiva.database.ArchivaDatabaseException;
28 import org.apache.maven.archiva.database.Constraint;
29 import org.apache.maven.archiva.database.ObjectNotFoundException;
30 import org.apache.maven.archiva.database.RepositoryContentStatisticsDAO;
31 import org.apache.maven.archiva.database.constraints.RangeConstraint;
32 import org.apache.maven.archiva.database.constraints.RepositoryContentStatisticsByRepositoryConstraint;
33 import org.apache.maven.archiva.database.constraints.RepositoryProblemByGroupIdConstraint;
34 import org.apache.maven.archiva.database.constraints.RepositoryProblemByRepositoryIdConstraint;
35 import org.apache.maven.archiva.database.constraints.RepositoryProblemConstraint;
36 import org.apache.maven.archiva.database.constraints.UniqueFieldConstraint;
37 import org.apache.maven.archiva.model.RepositoryContentStatistics;
38 import org.apache.maven.archiva.model.RepositoryProblem;
39 import org.apache.maven.archiva.model.RepositoryProblemReport;
40 import org.apache.maven.archiva.reporting.ArchivaReportException;
41 import org.apache.maven.archiva.reporting.DataLimits;
42 import org.apache.maven.archiva.reporting.RepositoryStatistics;
43 import org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator;
44 import org.apache.maven.archiva.security.ArchivaRoleConstants;
45 import org.codehaus.plexus.redback.rbac.Resource;
46 import org.codehaus.plexus.redback.xwork.interceptor.SecureAction;
47 import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
48 import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException;
49 import org.codehaus.plexus.xwork.action.PlexusActionSupport;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
53 import javax.servlet.http.HttpServletRequest;
54 import java.util.ArrayList;
55 import java.util.Calendar;
56 import java.util.Collection;
57 import java.util.Date;
58 import java.util.List;
60 import java.util.TreeMap;
63 * @plexus.component role="com.opensymphony.xwork.Action" role-hint="generateReport"
65 public class GenerateReportAction
66 extends PlexusActionSupport
67 implements SecureAction, ServletRequestAware, Preparable
69 private Logger log = LoggerFactory.getLogger( GenerateReportAction.class );
72 * @plexus.requirement role-hint="jdo"
74 protected ArchivaDAO dao;
79 private ArchivaConfiguration archivaConfiguration;
81 protected Constraint constraint;
83 protected HttpServletRequest request;
85 protected List<RepositoryProblemReport> reports = new ArrayList<RepositoryProblemReport>();
87 protected String groupId;
89 protected String repositoryId;
91 protected String prev;
93 protected String next;
95 protected int[] range = new int[2];
97 protected int page = 1;
99 protected int rowCount = 100;
101 protected boolean isLastPage;
103 public static final String BLANK = "blank";
105 public static final String BASIC = "basic";
107 private static Boolean jasperPresent;
109 private Collection<String> repositoryIds;
111 public static final String ALL_REPOSITORIES = "All Repositories";
113 protected Map<String, List<RepositoryProblemReport>> repositoriesMap =
114 new TreeMap<String, List<RepositoryProblemReport>>();
116 // for statistics report
118 * @plexus.requirement role-hint="simple"
120 private RepositoryStatisticsReportGenerator generator;
122 private List<String> selectedRepositories = new ArrayList<String>();
124 private List<String> availableRepositories;
126 private Date startDate;
128 private Date endDate;
130 private int reposSize;
132 private String selectedRepo;
134 private List<RepositoryStatistics> repositoryStatistics = new ArrayList<RepositoryStatistics>();
136 public void prepare()
138 repositoryIds = new ArrayList<String>();
139 repositoryIds.add( ALL_REPOSITORIES ); // comes first to be first in the list
140 repositoryIds.addAll(
141 dao.query( new UniqueFieldConstraint( RepositoryProblem.class.getName(), "repositoryId" ) ) );
143 availableRepositories = new ArrayList<String>();
145 // remove selected repositories in the option for the statistics report
146 availableRepositories.addAll( archivaConfiguration.getConfiguration().getManagedRepositoriesAsMap().keySet() );
147 for( String repo : selectedRepositories )
149 if( availableRepositories.contains( repo ) )
151 availableRepositories.remove( repo );
156 public Collection<String> getRepositoryIds()
158 return repositoryIds;
162 * Generate the statistics report.
164 * check whether single repo report or comparison report
165 * 1. if it is a single repository, get all the statistics for the repository on the specified date
166 * - if no date is specified, get only the latest
167 * (total page = 1 --> no pagination since only the most recent stats will be displayed)
168 * - otherwise, get everything within the date range (total pages = repo stats / rows per page)
169 * - required params: repository, startDate, endDate
171 * 2. if multiple repositories, get the latest statistics on each repository on the specified date
172 * - if no date is specified, use the current date endDate
173 * - required params: repositories, endDate
174 * - total pages = repositories / rows per page
178 public String generateStatistics()
180 DataLimits limits = new DataLimits();
182 reposSize = selectedRepositories.size();
186 RepositoryContentStatisticsDAO repoContentStatsDao = dao.getRepositoryContentStatisticsDAO();
187 if( selectedRepositories.size() > 1 )
189 limits.setTotalCount( selectedRepositories.size() );
190 limits.setCurrentPage( 1 );
191 limits.setPerPageCount( 1 );
192 limits.setCountOfPages( 1 );
195 for( String repo : selectedRepositories )
199 List contentStats = repoContentStatsDao.queryRepositoryContentStatistics(
200 new RepositoryContentStatisticsByRepositoryConstraint( repo, startDate, endDate ) );
202 if( contentStats == null || contentStats.isEmpty() )
204 log.info( "No statistics available for repository '" + repo + "'." );
205 // TODO set repo's stats to 0
209 repositoryStatistics.addAll( generator.generateReport( contentStats, repo, startDate, endDate, limits ) );
211 catch ( ObjectNotFoundException oe )
213 log.error( "No statistics available for repository '" + repo + "'." );
214 // TODO set repo's stats to 0
216 catch ( ArchivaDatabaseException ae )
218 log.error( "Error encountered while querying statistics of repository '" + repo + "'." );
219 // TODO set repo's stats to 0
223 else if ( selectedRepositories.size() == 1 )
225 limits.setCurrentPage( getPage() );
226 limits.setPerPageCount( getRowCount() );
228 selectedRepo = selectedRepositories.get( 0 );
231 List<RepositoryContentStatistics> contentStats = repoContentStatsDao.queryRepositoryContentStatistics(
232 new RepositoryContentStatisticsByRepositoryConstraint( selectedRepo, startDate, endDate ) );
234 if( contentStats == null || contentStats.isEmpty() )
236 addActionError( "No statistics available for repository. Repository might not have been scanned." );
240 limits.setTotalCount( contentStats.size() );
241 int extraPage = ( limits.getTotalCount() % limits.getPerPageCount() ) != 0 ? 1 : 0;
242 int totalPages = ( limits.getTotalCount() / limits.getPerPageCount() ) + extraPage;
243 limits.setCountOfPages( totalPages );
245 repositoryStatistics = generator.generateReport( contentStats, selectedRepo, startDate, endDate, limits );
247 catch ( ObjectNotFoundException oe )
249 addActionError( oe.getMessage() );
252 catch ( ArchivaDatabaseException de )
254 addActionError( de.getMessage() );
260 addFieldError( "availableRepositories", "Please select a repository (or repositories) from the list." );
264 catch ( ArchivaReportException e )
266 addActionError( "Error encountered while generating report :: " + e.getMessage() );
273 private void setDefaults()
275 if( startDate == null )
277 Calendar cal = Calendar.getInstance();
279 cal.set( 1900, 1, 1, 0, 0, 0 );
280 startDate = cal.getTime();
283 if( endDate == null )
285 endDate = Calendar.getInstance().getTime();
289 public String execute()
292 if( repositoryId == null )
294 addFieldError( "repositoryId", "You must provide a repository id.");
300 addFieldError( "rowCount", "Row count must be larger than 10." );
304 List<RepositoryProblem> problemArtifacts =
305 dao.getRepositoryProblemDAO().queryRepositoryProblems( configureConstraint() );
308 request.getRequestURL().substring( 0, request.getRequestURL().indexOf( request.getRequestURI() ) );
309 RepositoryProblem problemArtifact;
310 RepositoryProblemReport problemArtifactReport;
311 for ( int i = 0; i < problemArtifacts.size(); i++ )
313 problemArtifact = (RepositoryProblem) problemArtifacts.get( i );
314 problemArtifactReport = new RepositoryProblemReport( problemArtifact );
316 problemArtifactReport.setGroupURL( contextPath + "/browse/" + problemArtifact.getGroupId() );
317 problemArtifactReport.setArtifactURL(
318 contextPath + "/browse/" + problemArtifact.getGroupId() + "/" + problemArtifact.getArtifactId() );
320 addToList( problemArtifactReport );
322 // retained the reports list because this is the datasource for the jasper report
323 reports.add( problemArtifactReport );
326 if ( reports.size() <= rowCount )
332 reports.remove( rowCount );
335 prev = request.getRequestURL() + "?page=" + ( page - 1 ) + "&rowCount=" + rowCount + "&groupId=" + groupId +
336 "&repositoryId=" + repositoryId;
337 next = request.getRequestURL() + "?page=" + ( page + 1 ) + "&rowCount=" + rowCount + "&groupId=" + groupId +
338 "&repositoryId=" + repositoryId;
340 if ( reports.size() == 0 && page == 1 )
344 else if ( isJasperPresent() )
354 private static boolean isJasperPresent()
356 if ( jasperPresent == null )
360 Class.forName( "net.sf.jasperreports.engine.JRExporterParameter" );
361 jasperPresent = Boolean.TRUE;
363 catch ( NoClassDefFoundError e )
365 jasperPresent = Boolean.FALSE;
367 catch ( ClassNotFoundException e )
369 jasperPresent = Boolean.FALSE;
372 return jasperPresent.booleanValue();
375 private Constraint configureConstraint()
377 Constraint constraint;
379 range[0] = ( page - 1 ) * rowCount;
380 range[1] = ( page * rowCount ) + 1; // Add 1 to check if it's the last page or not.
382 if ( groupId != null && ( !groupId.equals( "" ) ) )
384 if ( repositoryId != null && ( !repositoryId.equals( "" ) && !repositoryId.equals( ALL_REPOSITORIES ) ) )
386 constraint = new RepositoryProblemConstraint( range, groupId, repositoryId );
390 constraint = new RepositoryProblemByGroupIdConstraint( range, groupId );
393 else if ( repositoryId != null && ( !repositoryId.equals( "" ) && !repositoryId.equals( ALL_REPOSITORIES ) ) )
395 constraint = new RepositoryProblemByRepositoryIdConstraint( range, repositoryId );
399 constraint = new RangeConstraint( range, "repositoryId" );
405 public SecureActionBundle getSecureActionBundle()
406 throws SecureActionException
408 SecureActionBundle bundle = new SecureActionBundle();
410 bundle.setRequiresAuthentication( true );
411 bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL );
416 private void addToList( RepositoryProblemReport repoProblemReport )
418 List<RepositoryProblemReport> problemsList = null;
420 if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) )
422 problemsList = ( List<RepositoryProblemReport> ) repositoriesMap.get( repoProblemReport.getRepositoryId() );
426 problemsList = new ArrayList<RepositoryProblemReport>();
427 repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList );
430 problemsList.add( repoProblemReport );
433 public void setServletRequest( HttpServletRequest request )
435 this.request = request;
438 public List<RepositoryProblemReport> getReports()
443 public String getGroupId()
448 public void setGroupId( String groupId )
450 this.groupId = groupId;
453 public String getRepositoryId()
458 public void setRepositoryId( String repositoryId )
460 this.repositoryId = repositoryId;
463 public String getPrev()
468 public String getNext()
478 public void setPage( int page )
483 public int getRowCount()
488 public void setRowCount( int rowCount )
490 this.rowCount = rowCount;
493 public boolean getIsLastPage()
498 public void setRepositoriesMap( Map<String, List<RepositoryProblemReport>> repositoriesMap )
500 this.repositoriesMap = repositoriesMap;
503 public Map<String, List<RepositoryProblemReport>> getRepositoriesMap()
505 return repositoriesMap;
508 public List<String> getSelectedRepositories()
510 return selectedRepositories;
513 public void setSelectedRepositories( List<String> selectedRepositories )
515 this.selectedRepositories = selectedRepositories;
518 public List<String> getAvailableRepositories()
520 return availableRepositories;
523 public void setAvailableRepositories( List<String> availableRepositories )
525 this.availableRepositories = availableRepositories;
528 public Date getStartDate()
533 public void setStartDate( Date startDate )
535 this.startDate = startDate;
538 public Date getEndDate()
543 public void setEndDate( Date endDate )
545 this.endDate = endDate;
548 public List<RepositoryStatistics> getRepositoryStatistics()
550 return repositoryStatistics;
553 public void setRepositoryStatistics( List<RepositoryStatistics> repositoryStatistics )
555 this.repositoryStatistics = repositoryStatistics;
558 public int getReposSize()
563 public void setReposSize( int reposSize )
565 this.reposSize = reposSize;
568 public String getSelectedRepo()
573 public void setSelectedRepo( String selectedRepo )
575 this.selectedRepo = selectedRepo;