/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.xd.test.fixtures;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.hamcrest.Description;
import org.hamcrest.DiagnosingMatcher;
import org.hamcrest.Matcher;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.xd.test.fixtures.util.FixtureUtils;
/**
* Support class to capture output of a sink in a File.
*
* @author Eric Bottard
* @author David Turanski
*/
public class FileSink extends DisposableFileSupport<FileSink> {
/**
* A matcher on the trimmed String contents of the sink, that delegates to another (String) matcher.
*
* @author David Turanski
*/
public static final class FileSinkTrimmedContentsMatcher extends FileSinkContentsMatcher {
public FileSinkTrimmedContentsMatcher(Matcher<String> matcher) {
super(matcher);
}
@Override
protected boolean matches(Object item, Description mismatchDescription) {
FileSink fs = (FileSink) item;
try {
String contents = fs.getContents().trim();
mismatchDescription.appendValue(contents);
return matcher.matches(contents);
}
catch (IOException e) {
mismatchDescription.appendText("failed with an IOException: " + e.getMessage());
return false;
}
}
}
/**
* A matcher on the String contents of the sink, that delegates to another (String) matcher.
*
* <p>
* Instances are to be constructed using
* {@code org.springframework.xd.shell.command.fixtures.XDMatchers#hasContentsThat}.
*
* @author Eric Bottard
*/
public static class FileSinkContentsMatcher extends DiagnosingMatcher<FileSink> {
protected final Matcher<String> matcher;
public FileSinkContentsMatcher(Matcher<String> matcher) {
this.matcher = matcher;
}
@Override
public void describeTo(Description description) {
description.appendDescriptionOf(matcher);
}
@Override
protected boolean matches(Object item, Description mismatchDescription) {
FileSink fs = (FileSink) item;
try {
String contents = fs.getContents();
mismatchDescription.appendValue(contents);
return matcher.matches(contents);
}
catch (IOException e) {
mismatchDescription.appendText("failed with an IOException: " + e.getMessage());
return false;
}
}
}
private String charset = "UTF-8";
private boolean binary = false;
/**
* Create a file sink, but make sure that the future file is not present yet, so it can be waited upon with
* {@link #getContents()}.
*/
public FileSink() {
Assert.state(file.delete());
}
/**
* Wait for the file to appear (default timeout) and return its contents.
*/
// This MUST remain private. Use XDMatchers.hasContentsThat() to assert
private String getContents() throws IOException {
return getContents(DEFAULT_FILE_TIMEOUT);
}
public FileSink binary(boolean binary) {
this.binary = binary;
return this;
}
/**
* Wait at most {@code timeout} ms for the file to appear and return its contents.
*
*/
// This MUST remain private. Use XDMatchers.hasContentsThat() to assert
private String getContents(int timeout) throws IOException {
if (waitFor(file, timeout)) {
return FileCopyUtils.copyToString(new InputStreamReader(new FileInputStream(file), charset));
}
else {
throw new IOException(String.format("Timeout after %dms waiting for file %s", timeout, file));
}
}
@Override
protected String toDSL() {
String fileName = file.getName();
return String.format("file --dir=%s --name=%s --suffix=%s --charset=%s --binary=%b --mode=%s",
FixtureUtils.handleShellEscapeProcessing(file.getParent()),
fileName.substring(0, fileName.lastIndexOf(".txt")), "txt", charset, binary, "APPEND");
}
}