/********************************************************************************
* CruiseControl, a Continuous Integration Toolkit
* Copyright (c) 2007, ThoughtWorks, Inc.
* 200 E. Randolph, 25th Floor
* Chicago, IL 60601 USA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* + Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
package net.sourceforge.cruisecontrol.dashboard.service;
import net.sourceforge.cruisecontrol.dashboard.Build;
import net.sourceforge.cruisecontrol.dashboard.BuildSummary;
import net.sourceforge.cruisecontrol.dashboard.CurrentStatus;
import net.sourceforge.cruisecontrol.dashboard.utils.TimeConverter;
import net.sourceforge.cruisecontrol.dashboard.utils.functors.AlphabeticalDescOrderComparator;
import net.sourceforge.cruisecontrol.dashboard.utils.functors.BuildSummariesFilters;
import net.sourceforge.cruisecontrol.dashboard.utils.functors.ReportableFilter;
import org.joda.time.DateTime;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class HistoricalBuildSummariesService {
private static final int LIST_MAXIUM = 25;
private BuildSummaryService buildSummaryService;
private static final FilenameFilter CCLOG_FILTER = BuildSummariesFilters.cclogFilter();
private static final AlphabeticalDescOrderComparator LOG_FILE_DESC_COMPARATOR =
new AlphabeticalDescOrderComparator();
private final ConfigurationService configuration;
public HistoricalBuildSummariesService(ConfigurationService configuration,
BuildSummaryService buildSummaryService) {
this.configuration = configuration;
this.buildSummaryService = buildSummaryService;
}
public List getLastest25(String projectName) {
File pjDir = configuration.getLogRoot(projectName);
List buildSummariesObjects = getBuildSummariesObject(getBuildSummariesFile(pjDir, CCLOG_FILTER, LIST_MAXIUM));
for (int i = 0; i < buildSummariesObjects.size(); i++) {
BuildSummary summary = (BuildSummary) buildSummariesObjects.get(i);
summary.updateStatus(CurrentStatus.WAITING.getCruiseStatus());
}
return buildSummariesObjects;
}
public BuildSummary getLatest(String projectName) {
File pjDir = configuration.getLogRoot(projectName);
ReportableFilter latest = BuildSummariesFilters.lastFilter();
getBuildSummariesFile(pjDir, latest, 1);
File logFileXml = latest.report();
if (logFileXml == null) {
return buildSummaryService.createInactive(projectName);
}
return buildSummaryService.createBuildSummary(logFileXml);
}
public List getAllSucceed(String projectName) {
File pjDir = configuration.getLogRoot(projectName);
List buildSummariesObjects = getBuildSummariesObject(getBuildSummariesFile(pjDir,
BuildSummariesFilters.succeedFilter(), Integer.MAX_VALUE));
for (int i = 0; i < buildSummariesObjects.size(); i++) {
BuildSummary summary = (BuildSummary) buildSummariesObjects.get(i);
summary.updateStatus(CurrentStatus.WAITING.getCruiseStatus());
}
return buildSummariesObjects;
}
public List getAll(String projectName) {
File pjDir = configuration.getLogRoot(projectName);
List buildSummariesObjects = getBuildSummariesObject(getBuildSummariesFile(pjDir,
CCLOG_FILTER, Integer.MAX_VALUE));
for (int i = 0; i < buildSummariesObjects.size(); i++) {
BuildSummary summary = (BuildSummary) buildSummariesObjects.get(i);
summary.updateStatus(CurrentStatus.WAITING.getCruiseStatus());
}
return buildSummariesObjects;
}
public Build getLastSucceed(String projectName, DateTime datetime) {
return filterBuildSummaries(projectName, BuildSummariesFilters.lastSucceedFilter(datetime));
}
public BuildSummary getLastFailed(String projectName, DateTime datetime) {
return filterBuildSummaries(projectName, BuildSummariesFilters.lastFailedFilter(datetime));
}
private BuildSummary filterBuildSummaries(String projectName, ReportableFilter filter) {
File pjDir = configuration.getLogRoot(projectName);
getBuildSummariesObject(getBuildSummariesFile(pjDir, filter, 1));
if (filter.report() == null) {
return null;
} else {
return buildSummaryService.createBuildSummary(filter.report());
}
}
public Build getEaliestFailed(String projectName, DateTime datetime) {
Build lastSucceeded = getLastSucceed(projectName, datetime);
if (lastSucceeded == null) {
List summaries = getAll(projectName);
return summaries.size() == 0 ? null : (Build) summaries.get(summaries.size() - 1);
}
return filterBuildSummaries(projectName, BuildSummariesFilters.earliestFailedFilter(lastSucceeded
.getBuildDate()));
}
public BuildSummary getEarliestSucceeded(String projectName, DateTime datetime) {
Build lastFailed = getLastFailed(projectName, datetime);
if (lastFailed == null) {
List summaries = getAll(projectName);
return summaries.size() == 0 ? null : (BuildSummary) summaries.get(summaries.size() - 1);
}
return filterBuildSummaries(projectName, BuildSummariesFilters.earliestSucceededFilter(lastFailed
.getBuildDate()));
}
public String getDurationFromLastSuccessfulBuild(String projectName, DateTime datetime) {
Build lastSucessfulBuild = getLastSucceed(projectName, datetime);
if (lastSucessfulBuild == null) {
return "N/A";
}
long timeSpan = datetime.getMillis() - lastSucessfulBuild.getBuildDate().getMillis();
return new TimeConverter().getConvertedTime(timeSpan / 1000);
}
public List createDiscontinuedProjects() {
Collection discontinued = configuration.getDiscontinuedProjects();
List allSummaries = new ArrayList();
for (Iterator iter = discontinued.iterator(); iter.hasNext();) {
ReportableFilter latest = BuildSummariesFilters.lastFilter();
File folder = (File) iter.next();
getBuildSummariesFile(folder, latest, 1);
allSummaries.add(buildSummaryService.createDiscontinued(latest.report()));
}
return allSummaries;
}
public List createActiveProjects() {
Collection actives = configuration.getActiveProjects();
List allSummaries = new ArrayList();
for (Iterator iter = actives.iterator(); iter.hasNext();) {
ReportableFilter latest = BuildSummariesFilters.lastFilter();
File folder = (File) iter.next();
getBuildSummariesFile(folder, latest, 1);
allSummaries.add(buildSummaryService.createBuildSummary(latest.report()));
}
return allSummaries;
}
public List createInactiveProjects() {
Collection inactives = configuration.getInactiveProjects();
List allSummaries = new ArrayList();
for (Iterator iter = inactives.iterator(); iter.hasNext();) {
File inactiveFolder = (File) iter.next();
allSummaries.add(buildSummaryService.createInactive(inactiveFolder.getName()));
}
return allSummaries;
}
private File[] getBuildSummariesFile(File pjDir, FilenameFilter logFilter, int maxium) {
String[] logFileNames = pjDir.list(logFilter);
if (logFileNames == null) {
return new File[]{};
}
Arrays.sort(logFileNames, LOG_FILE_DESC_COMPARATOR);
int size = Math.min(logFileNames.length, maxium);
File[] logFiles = new File[size];
for (int i = 0; i < logFiles.length; i++) {
logFiles[i] = new File(pjDir, logFileNames[i]);
}
return logFiles;
}
private List getBuildSummariesObject(File[] buildSummariesFiles) {
List summaries = new ArrayList();
for (int i = 0; i < buildSummariesFiles.length; i++) {
final Build summary = buildSummaryService.createBuildSummary(buildSummariesFiles[i]);
if (summary != null) {
summaries.add(summary);
}
}
return summaries;
}
}