blob: 56c73e2d85c6f6b4b658efe63e28375c55aa6b44 [file] [log] [blame]
/*
* Copyright (C) 2012 The Guava 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 com.google.common.io;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.io.SourceSinkFactory.ByteSinkFactory;
import static com.google.common.io.SourceSinkFactory.ByteSourceFactory;
import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
import com.google.common.base.Charsets;
import com.google.common.jdk5backport.Arrays;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.CharBuffer;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* {@link SourceSinkFactory} implementations.
*
* @author Colin Decker
*/
public class SourceSinkFactories {
private SourceSinkFactories() {}
public static CharSourceFactory stringCharSourceFactory() {
return new StringSourceFactory();
}
public static ByteSourceFactory byteArraySourceFactory() {
return new ByteArraySourceFactory();
}
public static ByteSourceFactory emptyByteSourceFactory() {
return new EmptyByteSourceFactory();
}
public static CharSourceFactory emptyCharSourceFactory() {
return new EmptyCharSourceFactory();
}
public static ByteSourceFactory fileByteSourceFactory() {
return new FileByteSourceFactory();
}
public static ByteSinkFactory fileByteSinkFactory() {
return new FileByteSinkFactory(null);
}
public static ByteSinkFactory appendingFileByteSinkFactory() {
String initialString = IoTestCase.ASCII + IoTestCase.I18N;
try {
return new FileByteSinkFactory(initialString.getBytes(Charsets.UTF_8.name()));
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}
public static CharSourceFactory fileCharSourceFactory() {
return new FileCharSourceFactory();
}
public static CharSinkFactory fileCharSinkFactory() {
return new FileCharSinkFactory(null);
}
public static CharSinkFactory appendingFileCharSinkFactory() {
String initialString = IoTestCase.ASCII + IoTestCase.I18N;
return new FileCharSinkFactory(initialString);
}
public static ByteSourceFactory urlByteSourceFactory() {
return new UrlByteSourceFactory();
}
public static CharSourceFactory urlCharSourceFactory() {
return new UrlCharSourceFactory();
}
public static CharSourceFactory asCharSourceFactory(final ByteSourceFactory factory) {
checkNotNull(factory);
return new CharSourceFactory() {
@Override
public CharSource createSource(String string) throws IOException {
return factory.createSource(string.getBytes(Charsets.UTF_8.name()))
.asCharSource(Charsets.UTF_8);
}
@Override
public String getExpected(String data) {
try {
return new String(factory.getExpected(data.getBytes(Charsets.UTF_8.name())),
Charsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new AssertionError();
}
}
@Override
public void tearDown() throws IOException {
factory.tearDown();
}
};
}
public static CharSinkFactory asCharSinkFactory(final ByteSinkFactory factory) {
checkNotNull(factory);
return new CharSinkFactory() {
@Override
public CharSink createSink() throws IOException {
return factory.createSink().asCharSink(Charsets.UTF_8);
}
@Override
public String getSinkContents() throws IOException {
return new String(factory.getSinkContents(), Charsets.UTF_8.name());
}
@Override
public String getExpected(String data) {
/*
* Get what the byte sink factory would expect for no written bytes, then append expected
* string to that.
*/
byte[] factoryExpectedForNothing = factory.getExpected(new byte[0]);
try {
return new String(factoryExpectedForNothing, Charsets.UTF_8.name()) + checkNotNull(data);
} catch (UnsupportedEncodingException e) {
throw new AssertionError();
}
}
@Override
public void tearDown() throws IOException {
factory.tearDown();
}
};
}
public static ByteSourceFactory asSlicedByteSourceFactory(final ByteSourceFactory factory,
final int off, final int len) {
checkNotNull(factory);
return new ByteSourceFactory() {
@Override
public ByteSource createSource(byte[] bytes) throws IOException {
return factory.createSource(bytes).slice(off, len);
}
@Override
public byte[] getExpected(byte[] bytes) {
byte[] baseExpected = factory.getExpected(bytes);
return Arrays.copyOfRange(baseExpected, off, Math.min(baseExpected.length, off + len));
}
@Override
public void tearDown() throws IOException {
factory.tearDown();
}
};
}
private static class StringSourceFactory implements CharSourceFactory {
@Override
public CharSource createSource(String data) throws IOException {
return CharSource.wrap(data);
}
@Override
public String getExpected(String data) {
return data;
}
@Override
public void tearDown() throws IOException {
}
}
private static class ByteArraySourceFactory implements ByteSourceFactory {
@Override
public ByteSource createSource(byte[] bytes) throws IOException {
return ByteSource.wrap(bytes);
}
@Override
public byte[] getExpected(byte[] bytes) {
return bytes;
}
@Override
public void tearDown() throws IOException {
}
}
private static class EmptyCharSourceFactory implements CharSourceFactory {
@Override
public CharSource createSource(String data) throws IOException {
return CharSource.empty();
}
@Override
public String getExpected(String data) {
return "";
}
@Override
public void tearDown() throws IOException {
}
}
private static class EmptyByteSourceFactory implements ByteSourceFactory {
@Override
public ByteSource createSource(byte[] bytes) throws IOException {
return ByteSource.empty();
}
@Override
public byte[] getExpected(byte[] bytes) {
return new byte[0];
}
@Override
public void tearDown() throws IOException {
}
}
private abstract static class FileFactory {
private static final Logger logger = Logger.getLogger(FileFactory.class.getName());
private final ThreadLocal<File> fileThreadLocal = new ThreadLocal<File>();
protected File createFile() throws IOException {
File file = File.createTempFile("SinkSourceFile", "txt");
fileThreadLocal.set(file);
return file;
}
protected File getFile() {
return fileThreadLocal.get();
}
public final void tearDown() throws IOException {
if (!fileThreadLocal.get().delete()) {
logger.warning("Unable to delete file: " + fileThreadLocal.get());
}
fileThreadLocal.remove();
}
}
private static class FileByteSourceFactory extends FileFactory implements ByteSourceFactory {
@Override
public ByteSource createSource(byte[] bytes) throws IOException {
checkNotNull(bytes);
File file = createFile();
OutputStream out = new FileOutputStream(file);
try {
out.write(bytes);
} finally {
out.close();
}
return Files.asByteSource(file);
}
@Override
public byte[] getExpected(byte[] bytes) {
return checkNotNull(bytes);
}
}
private static class FileByteSinkFactory extends FileFactory implements ByteSinkFactory {
private final byte[] initialBytes;
private FileByteSinkFactory(@Nullable byte[] initialBytes) {
this.initialBytes = initialBytes;
}
@Override
public ByteSink createSink() throws IOException {
File file = createFile();
if (initialBytes != null) {
FileOutputStream out = new FileOutputStream(file);
try {
out.write(initialBytes);
} finally {
out.close();
}
return Files.asByteSink(file, FileWriteMode.APPEND);
}
return Files.asByteSink(file);
}
@Override
public byte[] getExpected(byte[] bytes) {
if (initialBytes == null) {
return checkNotNull(bytes);
} else {
byte[] result = new byte[initialBytes.length + bytes.length];
System.arraycopy(initialBytes, 0, result, 0, initialBytes.length);
System.arraycopy(bytes, 0, result, initialBytes.length, bytes.length);
return result;
}
}
@Override
public byte[] getSinkContents() throws IOException {
File file = getFile();
InputStream in = new FileInputStream(file);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[100];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
return out.toByteArray();
}
}
private static class FileCharSourceFactory extends FileFactory implements CharSourceFactory {
@Override
public CharSource createSource(String string) throws IOException {
checkNotNull(string);
File file = createFile();
Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
try {
writer.write(string);
} finally {
writer.close();
}
return Files.asCharSource(file, Charsets.UTF_8);
}
@Override
public String getExpected(String string) {
return checkNotNull(string);
}
}
private static class FileCharSinkFactory extends FileFactory implements CharSinkFactory {
private final String initialString;
private FileCharSinkFactory(@Nullable String initialString) {
this.initialString = initialString;
}
@Override
public CharSink createSink() throws IOException {
File file = createFile();
if (initialString != null) {
Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
try {
writer.write(initialString);
} finally {
writer.close();
}
return Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND);
}
return Files.asCharSink(file, Charsets.UTF_8);
}
@Override
public String getExpected(String string) {
checkNotNull(string);
return initialString == null
? string
: initialString + string;
}
@Override
public String getSinkContents() throws IOException {
File file = getFile();
Reader reader = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8);
StringBuilder builder = new StringBuilder();
CharBuffer buffer = CharBuffer.allocate(100);
while (reader.read(buffer) != -1) {
buffer.flip();
builder.append(buffer);
buffer.clear();
}
return builder.toString();
}
}
private static class UrlByteSourceFactory extends FileByteSourceFactory {
@Override
public ByteSource createSource(byte[] bytes) throws IOException {
super.createSource(bytes);
return Resources.asByteSource(getFile().toURI().toURL());
}
}
private static class UrlCharSourceFactory extends FileCharSourceFactory {
@Override
public CharSource createSource(String string) throws IOException {
super.createSource(string); // just ignore returned CharSource
return Resources.asCharSource(getFile().toURI().toURL(), Charsets.UTF_8);
}
}
}