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