001/* 002 * #%L 003 * Netarchivesuite - common 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.common.distribute.arcrepository; 024 025import java.io.File; 026import java.io.OutputStream; 027import java.util.Collection; 028import java.util.List; 029 030import dk.netarkivet.common.distribute.RemoteFile; 031import dk.netarkivet.common.exceptions.ArgumentNotValid; 032import dk.netarkivet.common.exceptions.IllegalState; 033import dk.netarkivet.common.utils.batch.FileBatchJob; 034import dk.netarkivet.common.utils.batch.FileBatchJob.ExceptionOccurrence; 035 036/** 037 * Class for transferring batch status information. 038 */ 039public class BatchStatus { 040 041 /** The total number of files processed so far. */ 042 private final int noOfFilesProcessed; 043 /** A list of files that the batch job could not process. */ 044 private final Collection<File> filesFailed; 045 /** The application ID identifying the bitarchive, that run this batch job. */ 046 private final String bitArchiveAppId; 047 /** The file containing the result of the batch job. */ 048 private RemoteFile resultFile; 049 050 /** A list of exceptions caught during the execution of the batchJob. */ 051 private final List<ExceptionOccurrence> exceptions; 052 053 /** 054 * Create a new BatchStatus object for a specific bitarchive. 055 * 056 * @param bitArchiveAppId The application ID identifying the bitarchive, that run this batch job. 057 * @param filesFailed A list of files that the batch job could not process. 058 * @param noOfFilesProcessed The total number of files processed 059 * @param resultFile A file containing the result of the batch job 060 * @param exceptions A list of exceptions caught during the execution of the batchJob 061 */ 062 public BatchStatus(String bitArchiveAppId, Collection<File> filesFailed, int noOfFilesProcessed, 063 RemoteFile resultFile, List<FileBatchJob.ExceptionOccurrence> exceptions) { 064 this.bitArchiveAppId = bitArchiveAppId; 065 this.filesFailed = filesFailed; 066 this.noOfFilesProcessed = noOfFilesProcessed; 067 this.resultFile = resultFile; 068 this.exceptions = exceptions; 069 } 070 071 /** 072 * Create a new BatchStatus object for a specific bitarchive. 073 * 074 * @param filesFailed A list of files that the batch job could not process 075 * @param noOfFilesProcessed The total number of files processed 076 * @param resultFile A file containing the result of the batch job 077 * @param exceptions A list of exceptions caught during the execution of the batchJob 078 */ 079 public BatchStatus(Collection<File> filesFailed, int noOfFilesProcessed, RemoteFile resultFile, 080 List<FileBatchJob.ExceptionOccurrence> exceptions) { 081 this("ALL_BITARCHIVE_APPS", filesFailed, noOfFilesProcessed, resultFile, exceptions); 082 } 083 084 /** 085 * Get the number of files processed by the batch job. This counts all files whether failed or not. 086 * 087 * @return number of files passed to processFile 088 */ 089 public int getNoOfFilesProcessed() { 090 return noOfFilesProcessed; 091 } 092 093 /** 094 * Get the File objects for the files that failed. 095 * 096 * @return A collection containing the files that processFile returned false on. 097 */ 098 public Collection<File> getFilesFailed() { 099 return filesFailed; 100 } 101 102 /** 103 * Get the appId (internal string) for the bitarchive that these are the results from. Set to ALL_BITARCHIVE_APPS if 104 * this it the combined status. 105 * 106 * @return A uniquely identifying string that should *not* be parsed 107 */ 108 public String getBitArchiveAppId() { 109 return bitArchiveAppId; 110 } 111 112 /** 113 * Get the file containing results from a batch job. This may be null, if the batch job resulted in errors. 114 * 115 * @return A remote file containing results in some job-specific format. 116 */ 117 public RemoteFile getResultFile() { 118 return resultFile; 119 } 120 121 /** 122 * Get the list of exceptions that happened during the batch job. 123 * 124 * @return List of exceptions with information on where they occurred. 125 */ 126 public List<ExceptionOccurrence> getExceptions() { 127 return exceptions; 128 } 129 130 /** 131 * Copy the results of a batch job into a local file. This deletes the file from the remote server as appropriate. 132 * Note that this method or appendResults can only be called once on a given object. If hasResultFile() returns 133 * true, this method is safe to call. 134 * 135 * @param targetFile File to copy the results into. This file will be overridden if hasResultFile() returns true; 136 * @throws IllegalState If the results have already been copied, or there are no results to copy due to errors. 137 */ 138 public void copyResults(File targetFile) throws IllegalState { 139 ArgumentNotValid.checkNotNull(targetFile, "targetFile"); 140 if (resultFile != null) { 141 try { 142 resultFile.copyTo(targetFile); 143 } finally { 144 RemoteFile tmpResultFile = resultFile; 145 resultFile = null; 146 tmpResultFile.cleanup(); 147 } 148 } else { 149 throw new IllegalState("No results to copy into '" + targetFile + "' from batch job on '" + bitArchiveAppId 150 + "' (" + filesFailed.size() + " failures in " + noOfFilesProcessed + " processed files)"); 151 } 152 } 153 154 /** 155 * Append the results of a batch job into a stream. This deletes the results file from the remote server, so this or 156 * copyResults can only be called once. If hasResultFile() returns true, this method is safe to call. 157 * 158 * @param stream A stream to append results to. 159 * @throws IllegalState If the results have already been copied, or there are no results to copy due to errors. 160 */ 161 public void appendResults(OutputStream stream) throws IllegalState { 162 ArgumentNotValid.checkNotNull(stream, "OutputStream stream"); 163 if (resultFile != null) { 164 try { 165 resultFile.appendTo(stream); 166 } finally { 167 RemoteFile tmpResultFile = resultFile; 168 resultFile = null; 169 tmpResultFile.cleanup(); 170 } 171 } else { 172 throw new IllegalState("No results to append to '" + stream + "' from batch job on '" + bitArchiveAppId 173 + "' (" + filesFailed.size() + " failures in " + noOfFilesProcessed + " processed files)"); 174 } 175 } 176 177 /** 178 * Returns true if this object has a result file. There is no result file if no bitarchives succeeded in processing 179 * any files, or if the result file sent has already been deleted (e.g., by calling copyResults or appendResults). 180 * 181 * @return True if this object has a result file. 182 */ 183 public boolean hasResultFile() { 184 return resultFile != null; 185 } 186 187 /** 188 * Returns a human-readable description of this object. The value returned should not be machine-processed, as it is 189 * subject to change without notice. 190 * 191 * @return Human-readable description of this object. 192 */ 193 public String toString() { 194 return getFilesFailed().size() + " failures in processing " + getNoOfFilesProcessed() + " files at " 195 + getBitArchiveAppId(); 196 } 197 198}