]> source.dussan.org Git - archiva.git/blob
6bbf38784d6fdddd8b0c2c40ef8580d5a01efb23
[archiva.git] /
1 package org.apache.maven.archiva.web.action.reports;
2
3 /*
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
11  *
12  *   http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
22 import com.opensymphony.xwork2.Preparable;
23
24 import org.apache.commons.io.IOUtils;
25 import org.apache.commons.lang.StringUtils;
26 import org.apache.commons.lang.time.DateUtils;
27 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
28 import org.apache.maven.archiva.database.ArchivaDAO;
29 import org.apache.maven.archiva.database.ArchivaDatabaseException;
30 import org.apache.maven.archiva.database.Constraint;
31 import org.apache.maven.archiva.database.ObjectNotFoundException;
32 import org.apache.maven.archiva.database.RepositoryContentStatisticsDAO;
33 import org.apache.maven.archiva.database.constraints.RangeConstraint;
34 import org.apache.maven.archiva.database.constraints.RepositoryContentStatisticsByRepositoryConstraint;
35 import org.apache.maven.archiva.database.constraints.RepositoryProblemByGroupIdConstraint;
36 import org.apache.maven.archiva.database.constraints.RepositoryProblemByRepositoryIdConstraint;
37 import org.apache.maven.archiva.database.constraints.RepositoryProblemConstraint;
38 import org.apache.maven.archiva.database.constraints.UniqueFieldConstraint;
39 import org.apache.maven.archiva.model.RepositoryContentStatistics;
40 import org.apache.maven.archiva.model.RepositoryProblem;
41 import org.apache.maven.archiva.model.RepositoryProblemReport;
42 import org.apache.maven.archiva.reporting.ArchivaReportException;
43 import org.apache.maven.archiva.reporting.DataLimits;
44 import org.apache.maven.archiva.reporting.RepositoryStatistics;
45 import org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator;
46 import org.apache.maven.archiva.security.ArchivaRoleConstants;
47 import org.codehaus.plexus.redback.rbac.Resource;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import javax.servlet.http.HttpServletRequest;
52
53 import java.io.ByteArrayInputStream;
54 import java.io.IOException;
55 import java.io.InputStream;
56 import java.io.StringReader;
57 import java.text.ParseException;
58 import java.util.ArrayList;
59 import java.util.Calendar;
60 import java.util.Collection;
61 import java.util.Date;
62 import java.util.List;
63 import java.util.Map;
64 import java.util.TreeMap;
65 import org.apache.maven.archiva.web.action.PlexusActionSupport;
66 import org.apache.struts2.interceptor.ServletRequestAware;
67 import org.codehaus.redback.integration.interceptor.SecureAction;
68 import org.codehaus.redback.integration.interceptor.SecureActionBundle;
69 import org.codehaus.redback.integration.interceptor.SecureActionException;
70
71 /**
72  * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="generateReport" instantiation-strategy="per-lookup"
73  */
74 public class GenerateReportAction
75     extends PlexusActionSupport
76     implements SecureAction, ServletRequestAware, Preparable
77 {
78     private Logger log = LoggerFactory.getLogger( GenerateReportAction.class );
79     
80     /**
81      * @plexus.requirement role-hint="jdo"
82      */
83     protected ArchivaDAO dao;
84     
85     /**
86      * @plexus.requirement
87      */
88     private ArchivaConfiguration archivaConfiguration;
89
90     protected Constraint constraint;
91
92     protected HttpServletRequest request;
93
94     protected List<RepositoryProblemReport> reports = new ArrayList<RepositoryProblemReport>();
95
96     protected String groupId;
97
98     protected String repositoryId;
99
100     protected String prev;
101
102     protected String next;
103
104     protected int[] range = new int[2];
105
106     protected int page = 1;
107
108     protected int rowCount = 100;
109
110     protected boolean isLastPage;
111
112     public static final String BLANK = "blank";
113
114     public static final String BASIC = "basic";
115
116     private static Boolean jasperPresent;
117
118     private Collection<String> repositoryIds;
119
120     public static final String ALL_REPOSITORIES = "All Repositories";
121     
122     protected Map<String, List<RepositoryProblemReport>> repositoriesMap = 
123                 new TreeMap<String, List<RepositoryProblemReport>>();
124     
125     // for statistics report
126     /**
127      * @plexus.requirement role-hint="simple"
128      */
129     private RepositoryStatisticsReportGenerator generator;
130     
131     private List<String> selectedRepositories = new ArrayList<String>();
132     
133     private List<String> availableRepositories;  
134     
135     private String startDate;
136     
137     private String endDate;
138     
139     private int reposSize;
140     
141     private String selectedRepo;
142     
143     private List<RepositoryStatistics> repositoryStatistics = new ArrayList<RepositoryStatistics>();
144     
145     private DataLimits limits = new DataLimits();
146     
147     private String[] datePatterns = new String[] { "MM/dd/yy", "MM/dd/yyyy", "MMMMM/dd/yyyy", "MMMMM/dd/yy", 
148         "dd MMMMM yyyy", "dd/MM/yy", "dd/MM/yyyy", "yyyy/MM/dd", "yyyy-MM-dd", "yyyy-dd-MM", "MM-dd-yyyy",
149         "MM-dd-yy" };
150     
151     public static final String SEND_FILE = "send-file";
152     
153     private InputStream inputStream;
154     
155     public void prepare()
156     {
157         repositoryIds = new ArrayList<String>();
158         repositoryIds.add( ALL_REPOSITORIES ); // comes first to be first in the list
159         repositoryIds.addAll(
160             dao.query( new UniqueFieldConstraint( RepositoryProblem.class.getName(), "repositoryId" ) ) );
161         
162         availableRepositories = new ArrayList<String>();
163      
164         // remove selected repositories in the option for the statistics report
165         availableRepositories.addAll( archivaConfiguration.getConfiguration().getManagedRepositoriesAsMap().keySet() );        
166         for( String repo : selectedRepositories )
167         {
168             if( availableRepositories.contains( repo ) )
169             {
170                 availableRepositories.remove( repo );
171             }
172         }
173     }
174
175     public Collection<String> getRepositoryIds()
176     {
177         return repositoryIds;
178     }
179
180     /**
181      * Generate the statistics report.
182      * 
183      * check whether single repo report or comparison report
184      * 1. if it is a single repository, get all the statistics for the repository on the specified date
185      *    - if no date is specified, get only the latest 
186      *          (total page = 1 --> no pagination since only the most recent stats will be displayed)
187      *    - otherwise, get everything within the date range (total pages = repo stats / rows per page)
188      *       - required params: repository, startDate, endDate
189      *       
190      * 2. if multiple repositories, get the latest statistics on each repository on the specified date
191      *    - if no date is specified, use the current date endDate
192      *       - required params: repositories, endDate
193      *    - total pages = repositories / rows per page
194      * 
195      * @return
196      */
197     public String generateStatistics()
198     {   
199         if( rowCount < 10 )
200         {
201             addFieldError( "rowCount", "Row count must be larger than 10." );
202             return INPUT;
203         }
204         reposSize = selectedRepositories.size();                
205         
206         try
207         {
208             RepositoryContentStatisticsDAO repoContentStatsDao = dao.getRepositoryContentStatisticsDAO();
209             Date startDateInDF = null;
210             Date endDateInDF = null;
211             
212             if( selectedRepositories.size() > 1 )
213             {
214                 limits.setTotalCount( selectedRepositories.size() );            
215                 limits.setCurrentPage( 1 );
216                 limits.setPerPageCount( 1 );
217                 limits.setCountOfPages( 1 );
218                 
219                 try
220                 {
221                         startDateInDF = getStartDateInDateFormat();                     
222                         endDateInDF = getEndDateInDateFormat();
223                 }
224                 catch ( ParseException e )
225                 {
226                         addActionError( "Error parsing date(s)." );
227                         return ERROR;
228                 }
229                 
230                 // multiple repos
231                 generateReportForMultipleRepos(repoContentStatsDao, startDateInDF, endDateInDF, true);                
232             }
233             else if ( selectedRepositories.size() == 1 )
234             {   
235                 limits.setCurrentPage( getPage() );
236                 limits.setPerPageCount( getRowCount() );
237                 
238                 selectedRepo = selectedRepositories.get( 0 );
239                 try
240                 {        
241                         startDateInDF = getStartDateInDateFormat();                     
242                         endDateInDF = getEndDateInDateFormat();
243                          
244                     List<RepositoryContentStatistics> contentStats = repoContentStatsDao.queryRepositoryContentStatistics( 
245                            new RepositoryContentStatisticsByRepositoryConstraint( selectedRepo, startDateInDF, endDateInDF ) );
246                     
247                     if( contentStats == null || contentStats.isEmpty() )
248                     {   
249                         addActionError( "No statistics available for repository. Repository might not have been scanned." );
250                         return ERROR;
251                     }   
252                     
253                     limits.setTotalCount( contentStats.size() );                    
254                     int extraPage = ( limits.getTotalCount() % limits.getPerPageCount() ) != 0 ? 1 : 0;
255                     int totalPages = ( limits.getTotalCount() / limits.getPerPageCount() ) + extraPage;                    
256                     limits.setCountOfPages( totalPages );
257                     
258                     repositoryStatistics = generator.generateReport( contentStats, selectedRepo, startDateInDF, endDateInDF, limits );
259                 }
260                 catch ( ObjectNotFoundException oe )
261                 {
262                     addActionError( oe.getMessage() );
263                     return ERROR;
264                 }
265                 catch ( ArchivaDatabaseException de )
266                 {
267                     addActionError( de.getMessage() );
268                     return ERROR;
269                 }
270                 catch ( ParseException pe )
271                 {
272                         addActionError( pe.getMessage() );
273                         return ERROR;
274                 }
275             }
276             else
277             {
278                 addFieldError( "availableRepositories", "Please select a repository (or repositories) from the list." );
279                 return INPUT;
280             } 
281             
282             if( repositoryStatistics.isEmpty() )
283             {
284                 return BLANK;
285             }            
286         }
287         catch ( ArchivaReportException e )
288         {
289             addActionError( "Error encountered while generating report :: " + e.getMessage() );
290             return ERROR;
291         }
292         
293         return SUCCESS;
294     }
295         
296     /**
297      * Export report to CSV.
298      * 
299      * @return
300      */
301     public String downloadStatisticsReport()
302     {   
303         try
304         {
305                 Date startDateInDF = null;
306             Date endDateInDF = null;
307             
308             selectedRepositories = parseSelectedRepositories();
309             repositoryStatistics = new ArrayList<RepositoryStatistics>();
310             
311             RepositoryContentStatisticsDAO repoContentStatsDao = dao.getRepositoryContentStatisticsDAO();            
312             if( selectedRepositories.size() > 1 )
313             {   
314                 try
315                 {        
316                         startDateInDF = getStartDateInDateFormat();                     
317                         endDateInDF = getEndDateInDateFormat();
318                 }
319                 catch ( ParseException e )
320                 {
321                         addActionError( "Error parsing date(s)." );
322                         return ERROR;
323                 }
324                 
325              // multiple repos
326                 generateReportForMultipleRepos( repoContentStatsDao, startDateInDF, endDateInDF, false );
327             }
328             else if ( selectedRepositories.size() == 1 )
329             {   
330                 selectedRepo = selectedRepositories.get( 0 );
331                 try
332                 {                 
333                         startDateInDF = getStartDateInDateFormat();
334                         endDateInDF = getEndDateInDateFormat();
335                         
336                     List<RepositoryContentStatistics> contentStats = repoContentStatsDao.queryRepositoryContentStatistics( 
337                            new RepositoryContentStatisticsByRepositoryConstraint( selectedRepo, startDateInDF, endDateInDF ) );
338                                         
339                     if( contentStats == null || contentStats.isEmpty() )
340                     {   
341                         addActionError( "No statistics available for repository. Repository might not have been scanned." );
342                         return ERROR;
343                     }   
344                     
345                     repositoryStatistics = generator.generateReport( contentStats, selectedRepo, startDateInDF, endDateInDF, false );                    
346                 }
347                 catch ( ObjectNotFoundException oe )
348                 {
349                     addActionError( oe.getMessage() );
350                     return ERROR;
351                 }
352                 catch ( ArchivaDatabaseException de )
353                 {
354                     addActionError( de.getMessage() );
355                     return ERROR;
356                 }
357                 catch ( ParseException pe )
358                 {
359                         addActionError( pe.getMessage() );
360                         return ERROR;
361                 }
362             }
363             else
364             {
365                 addFieldError( "availableRepositories", "Please select a repository (or repositories) from the list." );
366                 return INPUT;
367             } 
368             
369             if( repositoryStatistics.isEmpty() )
370             {
371                 return BLANK;
372             }            
373         }
374         catch ( ArchivaReportException e )
375         {
376             addActionError( "Error encountered while generating report :: " + e.getMessage() );
377             return ERROR;
378         }    
379         
380         // write output stream depending on single or comparison report              
381         StringBuffer input = getInput();        
382         StringReader reader = new StringReader( input.toString() );
383         
384         try
385         {
386                 inputStream = new ByteArrayInputStream( IOUtils.toByteArray( reader ) );
387         }
388         catch ( IOException i )
389         {       
390                 addActionError( "Error occurred while generating CSV file." );
391                 return ERROR;
392         }
393         
394         return SEND_FILE;
395     }
396     
397     // hack for parsing the struts list passed as param in <s:url ../>
398     private List<String> parseSelectedRepositories()
399     {           
400         List<String> pasedSelectedRepos = new ArrayList<String>();
401      
402         for( String repo : selectedRepositories )
403         {   
404             String[] tokens = StringUtils.split( repo, ',' );
405             if( tokens.length > 1 )
406             {
407                 for( int i = 0; i < tokens.length; i++ )
408                 {   
409                     pasedSelectedRepos.add( StringUtils.remove( StringUtils.remove( tokens[i], '[' ), ']' ).trim() );
410                 }
411             }
412             else
413             {
414                 pasedSelectedRepos.add( StringUtils.remove( StringUtils.remove( repo, '[' ), ']' ).trim() );
415             }
416         }
417         return pasedSelectedRepos;
418     }
419
420     private void generateReportForMultipleRepos( RepositoryContentStatisticsDAO repoContentStatsDao,
421                                                  Date startDateInDF, Date endDateInDF, boolean useLimits )
422         throws ArchivaReportException
423     {   
424         for ( String repo : selectedRepositories )
425         {   
426             try
427             {                
428                 List contentStats = repoContentStatsDao.queryRepositoryContentStatistics( 
429                          new RepositoryContentStatisticsByRepositoryConstraint( repo, startDateInDF, endDateInDF ) );
430
431                 if ( contentStats == null || contentStats.isEmpty() )
432                 {
433                     log.info( "No statistics available for repository '" + repo + "'." );
434                     // TODO set repo's stats to 0
435                     continue;
436                 }
437                 
438                 if( useLimits )
439                 {
440                     repositoryStatistics.addAll( generator.generateReport( contentStats, repo, startDateInDF, endDateInDF,
441                                                                        limits ) );
442                 }
443                 else
444                 {
445                     repositoryStatistics.addAll( generator.generateReport( contentStats, repo, startDateInDF, endDateInDF, true ) );
446                 }
447             }
448             catch ( ObjectNotFoundException oe )
449             {
450                 log.error( "No statistics available for repository '" + repo + "'." );
451                 // TODO set repo's stats to 0
452             }
453             catch ( ArchivaDatabaseException ae )
454             {
455                 log.error( "Error encountered while querying statistics of repository '" + repo + "'." );
456                 // TODO set repo's stats to 0
457             }
458         }
459     }
460
461     private Date getStartDateInDateFormat()
462         throws ParseException
463     {
464         Date startDateInDF;
465         if ( startDate == null || "".equals( startDate ) )
466         {
467             startDateInDF = getDefaultStartDate();
468         }
469         else
470         {
471             startDateInDF = DateUtils.parseDate( startDate, datePatterns );
472         }
473         return startDateInDF;
474     }
475
476     private Date getEndDateInDateFormat()
477         throws ParseException
478     {
479         Date endDateInDF;
480         if ( endDate == null || "".equals( endDate ) )
481         {
482             endDateInDF = getDefaultEndDate();
483         }
484         else
485         {
486             endDateInDF = DateUtils.parseDate( endDate, datePatterns );
487         }
488         
489         return endDateInDF;
490     }
491     
492     private StringBuffer getInput()
493     {
494         StringBuffer input = null;
495         
496         if( selectedRepositories.size() == 1 )
497         {               
498                 input = new StringBuffer( "Date of Scan,Total File Count,Total Size,Artifact Count,Group Count,Project Count," +
499                                 "Plugins,Archetypes,Jars,Wars,Deployments,Downloads\n" );
500                 
501                 for( RepositoryStatistics stats : repositoryStatistics )
502                 {
503                         input.append( stats.getDateOfScan() ).append( "," );
504                         input.append( stats.getFileCount() ).append( "," );
505                         input.append( stats.getTotalSize() ).append( "," );
506                         input.append( stats.getArtifactCount() ).append( "," );
507                         input.append( stats.getGroupCount() ).append( "," );
508                         input.append( stats.getProjectCount() ).append( "," );
509                         input.append( stats.getPluginCount() ).append( "," );
510                         input.append( stats.getArchetypeCount() ).append( "," );
511                         input.append( stats.getJarCount() ).append( "," );
512                         input.append( stats.getWarCount() ).append( "," );
513                         input.append( stats.getDeploymentCount() ).append( "," );
514                         input.append( stats.getDownloadCount() ).append( "\n" );
515                 }               
516         }            
517         else if( selectedRepositories.size() > 1 )
518         {
519                 input = new StringBuffer( "Repository,Total File Count,Total Size,Artifact Count,Group Count,Project Count," +
520                                         "Plugins,Archetypes,Jars,Wars,Deployments,Downloads\n" );
521                         
522                         for( RepositoryStatistics stats : repositoryStatistics )
523                         {
524                                 input.append( stats.getRepositoryId() ).append( "," );
525                                 input.append( stats.getFileCount() ).append( "," );
526                                 input.append( stats.getTotalSize() ).append( "," );
527                                 input.append( stats.getArtifactCount() ).append( "," );
528                                 input.append( stats.getGroupCount() ).append( "," );
529                                 input.append( stats.getProjectCount() ).append( "," );
530                                 input.append( stats.getPluginCount() ).append( "," );
531                                 input.append( stats.getArchetypeCount() ).append( "," );
532                                 input.append( stats.getJarCount() ).append( "," );
533                                 input.append( stats.getWarCount() ).append( "," );
534                                 input.append( stats.getDeploymentCount() ).append( "," );
535                                 input.append( stats.getDownloadCount() ).append( "\n" );
536                         }
537         }
538         
539         return input;
540     }
541     
542     private Date getDefaultStartDate()
543     {
544         Calendar cal = Calendar.getInstance();
545         cal.clear();
546         cal.set( 1900, 1, 1, 0, 0, 0 );
547         
548         return cal.getTime();
549     }
550     
551     private Date getDefaultEndDate()
552     {
553         return Calendar.getInstance().getTime();
554     }
555     
556     public String execute()
557         throws Exception
558     {   
559         if( repositoryId == null )
560         {
561             addFieldError( "repositoryId", "You must provide a repository id.");            
562             return INPUT;
563         }
564         
565         if( rowCount < 10 )
566         {
567             addFieldError( "rowCount", "Row count must be larger than 10." );
568             return INPUT;
569         }
570         
571         List<RepositoryProblem> problemArtifacts =
572             dao.getRepositoryProblemDAO().queryRepositoryProblems( configureConstraint() );
573
574         String contextPath =
575             request.getRequestURL().substring( 0, request.getRequestURL().indexOf( request.getRequestURI() ) );
576         RepositoryProblem problemArtifact;
577         RepositoryProblemReport problemArtifactReport;
578         for ( int i = 0; i < problemArtifacts.size(); i++ )
579         {
580             problemArtifact = (RepositoryProblem) problemArtifacts.get( i );
581             problemArtifactReport = new RepositoryProblemReport( problemArtifact );
582
583             problemArtifactReport.setGroupURL( contextPath + "/browse/" + problemArtifact.getGroupId() );
584             problemArtifactReport.setArtifactURL(
585                 contextPath + "/browse/" + problemArtifact.getGroupId() + "/" + problemArtifact.getArtifactId() );
586
587             addToList( problemArtifactReport );
588             
589             // retained the reports list because this is the datasource for the jasper report            
590             reports.add( problemArtifactReport );
591         }
592         
593         if ( reports.size() <= rowCount )
594         {
595             isLastPage = true;
596         }
597         else
598         {
599             reports.remove( rowCount );
600         }
601
602         prev = request.getRequestURL() + "?page=" + ( page - 1 ) + "&rowCount=" + rowCount + "&groupId=" + groupId +
603             "&repositoryId=" + repositoryId;
604         next = request.getRequestURL() + "?page=" + ( page + 1 ) + "&rowCount=" + rowCount + "&groupId=" + groupId +
605             "&repositoryId=" + repositoryId;
606
607         if ( reports.size() == 0 && page == 1 )
608         {
609             return BLANK;
610         }
611         else if ( isJasperPresent() )
612         {
613             return "jasper";
614         }
615         else
616         {
617             return SUCCESS;
618         }
619     }
620     
621     private static boolean isJasperPresent()
622     {
623         if ( jasperPresent == null )
624         {
625             try
626             {
627                 Class.forName( "net.sf.jasperreports.engine.JRExporterParameter" );
628                 jasperPresent = Boolean.TRUE;
629             }
630             catch ( NoClassDefFoundError e )
631             {
632                 jasperPresent = Boolean.FALSE;
633             }
634             catch ( ClassNotFoundException e )
635             {
636                 jasperPresent = Boolean.FALSE;
637             }
638         }
639         return jasperPresent.booleanValue();
640     }
641
642     private Constraint configureConstraint()
643     {
644         Constraint constraint;
645
646         range[0] = ( page - 1 ) * rowCount;
647         range[1] = ( page * rowCount ) + 1; // Add 1 to check if it's the last page or not.
648
649         if ( groupId != null && ( !groupId.equals( "" ) ) )
650         {
651             if ( repositoryId != null && ( !repositoryId.equals( "" ) && !repositoryId.equals( ALL_REPOSITORIES ) ) )
652             {
653                 constraint = new RepositoryProblemConstraint( range, groupId, repositoryId );
654             }
655             else
656             {
657                 constraint = new RepositoryProblemByGroupIdConstraint( range, groupId );
658             }
659         }
660         else if ( repositoryId != null && ( !repositoryId.equals( "" ) && !repositoryId.equals( ALL_REPOSITORIES ) ) )
661         {
662             constraint = new RepositoryProblemByRepositoryIdConstraint( range, repositoryId );
663         }
664         else
665         {
666             constraint = new RangeConstraint( range, "repositoryId" );
667         }
668
669         return constraint;
670     }
671     
672     public SecureActionBundle getSecureActionBundle()
673         throws SecureActionException
674     {
675         SecureActionBundle bundle = new SecureActionBundle();
676     
677         bundle.setRequiresAuthentication( true );
678         bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL );
679     
680         return bundle;
681     }
682     
683     private void addToList( RepositoryProblemReport repoProblemReport )
684     {
685         List<RepositoryProblemReport> problemsList = null;
686         
687         if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) )
688         {
689             problemsList = ( List<RepositoryProblemReport> ) repositoriesMap.get( repoProblemReport.getRepositoryId() );
690         }
691         else
692         {
693             problemsList = new ArrayList<RepositoryProblemReport>();
694             repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList );
695         }
696         
697         problemsList.add( repoProblemReport );
698     }
699
700     public void setServletRequest( HttpServletRequest request )
701     {
702         this.request = request;
703     }
704
705     public List<RepositoryProblemReport> getReports()
706     {
707         return reports;
708     }
709
710     public String getGroupId()
711     {
712         return groupId;
713     }
714
715     public void setGroupId( String groupId )
716     {
717         this.groupId = groupId;
718     }
719
720     public String getRepositoryId()
721     {
722         return repositoryId;
723     }
724
725     public void setRepositoryId( String repositoryId )
726     {
727         this.repositoryId = repositoryId;
728     }
729
730     public String getPrev()
731     {
732         return prev;
733     }
734
735     public String getNext()
736     {
737         return next;
738     }
739
740     public int getPage()
741     {
742         return page;
743     }
744
745     public void setPage( int page )
746     {
747         this.page = page;
748     }
749
750     public int getRowCount()
751     {
752         return rowCount;
753     }
754
755     public void setRowCount( int rowCount )
756     {
757         this.rowCount = rowCount;
758     }
759
760     public boolean getIsLastPage()
761     {
762         return isLastPage;
763     }
764
765     public void setRepositoriesMap( Map<String, List<RepositoryProblemReport>> repositoriesMap )
766     {
767         this.repositoriesMap = repositoriesMap;
768     }
769     
770     public Map<String, List<RepositoryProblemReport>> getRepositoriesMap()
771     {
772         return repositoriesMap;
773     }
774     
775     public List<String> getSelectedRepositories()
776     {
777         return selectedRepositories;
778     }
779
780     public void setSelectedRepositories( List<String> selectedRepositories )
781     {
782         this.selectedRepositories = selectedRepositories;
783     }
784
785     public List<String> getAvailableRepositories()
786     {
787         return availableRepositories;
788     }
789
790     public void setAvailableRepositories( List<String> availableRepositories )
791     {
792         this.availableRepositories = availableRepositories;
793     }
794
795     public String getStartDate()
796     {
797         return startDate;
798     }
799
800     public void setStartDate( String startDate )
801     {
802         this.startDate = startDate;
803     }
804
805     public String getEndDate()
806     {
807         return endDate;
808     }
809
810     public void setEndDate( String endDate )
811     {
812         this.endDate = endDate;
813     }
814
815     public List<RepositoryStatistics> getRepositoryStatistics()
816     {
817         return repositoryStatistics;
818     }
819
820     public void setRepositoryStatistics( List<RepositoryStatistics> repositoryStatistics )
821     {
822         this.repositoryStatistics = repositoryStatistics;
823     }
824     
825     public int getReposSize()
826     {
827         return reposSize;
828     }
829
830     public void setReposSize( int reposSize )
831     {
832         this.reposSize = reposSize;
833     }
834
835     public String getSelectedRepo()
836     {
837         return selectedRepo;
838     }
839
840     public void setSelectedRepo( String selectedRepo )
841     {
842         this.selectedRepo = selectedRepo;
843     }
844
845     public DataLimits getLimits()
846     {
847         return limits;
848     }
849
850     public void setLimits( DataLimits limits )
851     {
852         this.limits = limits;
853     }
854     
855     public InputStream getInputStream()
856     {
857         return inputStream;
858     }
859 }