* A rule which detects changes in output files.
*/
class OutputFilesStateChangeRule {
public static TaskStateChanges create(final TaskInternal task, final TaskExecution previousExecution, final TaskExecution currentExecution, final FileCollectionSnapshotter outputFilesSnapshotter) {
final FileCollectionSnapshot outputFilesBefore = outputFilesSnapshotter.snapshot(task.getOutputs().getFiles());
return new TaskStateChanges() {
public Iterator<TaskStateChange> iterator() {
if (previousExecution.getOutputFilesSnapshot() == null) {
return Collections.<TaskStateChange>singleton(new DescriptiveChange("Output file history is not available.")).iterator();
}
return new AbstractIterator<TaskStateChange>() {
final FileCollectionSnapshot.ChangeIterator<String> changeIterator = outputFilesBefore.iterateChangesSince(previousExecution.getOutputFilesSnapshot());
final ChangeListenerAdapter listenerAdapter = new ChangeListenerAdapter();
@Override
protected TaskStateChange computeNext() {
if (changeIterator.next(listenerAdapter)) {
return listenerAdapter.lastChange;
}
return endOfData();
}
};
}
public void snapshotAfterTask() {
FileCollectionSnapshot lastExecutionOutputFiles;
if (previousExecution == null || previousExecution.getOutputFilesSnapshot() == null) {
lastExecutionOutputFiles = outputFilesSnapshotter.emptySnapshot();
} else {
lastExecutionOutputFiles = previousExecution.getOutputFilesSnapshot();
}
FileCollectionSnapshot newOutputFiles = outputFilesBefore.changesSince(lastExecutionOutputFiles).applyTo(
lastExecutionOutputFiles, new ChangeListener<FileCollectionSnapshot.Merge>() {
public void added(FileCollectionSnapshot.Merge element) {
// Ignore added files
element.ignore();
}
public void removed(FileCollectionSnapshot.Merge element) {
// Discard any files removed since the task was last executed
}
public void changed(FileCollectionSnapshot.Merge element) {
// Update any files which were change since the task was last executed
}
});
FileCollectionSnapshot outputFilesAfter = outputFilesSnapshotter.snapshot(task.getOutputs().getFiles());
currentExecution.setOutputFilesSnapshot(outputFilesAfter.changesSince(outputFilesBefore).applyTo(newOutputFiles));
}
};
}