package org.dru.clay.respository.transport.filesystem;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.URI;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import org.dru.clay.respository.transport.FileInfo;
import org.dru.clay.respository.transport.Transport;
import org.dru.clay.util.io.IOUtils;
public class FileSystemTransport implements Transport {
private static final Logger logger = Logger.getLogger(FileSystemTransport.class.getName());
private final Set<FileSystemOptions> options;
public FileSystemTransport(FileSystemOptions... options) {
if (options == null || options.length == 0) {
this.options = EnumSet.noneOf(FileSystemOptions.class);
} else {
this.options = EnumSet.<FileSystemOptions> copyOf(Arrays.asList(options));
}
}
@Override
public FileInfo get(URI uri) {
if (!"file".equalsIgnoreCase(uri.getScheme())) {
throw new IllegalArgumentException("Invalid scheme for " + this.getClass().getName());
}
try {
final File file = new File(uri.getPath());
return new FileInfo(file.length(), file.lastModified(), IOUtils.read(new FileInputStream(file)));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
@Override
public void get(URI file, File destination) {
if (!"file".equalsIgnoreCase(file.getScheme())) {
throw new IllegalArgumentException("Invalid scheme for " + this.getClass().getName());
}
copy(new File(file.getPath()), destination, true);
}
@Override
public void getIfNewer(URI file, File destination) {
if (!"file".equalsIgnoreCase(file.getScheme())) {
throw new IllegalArgumentException("Invalid scheme for " + this.getClass().getName());
}
copy(new File(file.getPath()), destination, false);
}
@Override
public void put(File source, URI destination) {
if (!"file".equalsIgnoreCase(destination.getScheme())) {
throw new IllegalArgumentException("Invalid scheme for " + this.getClass().getName());
}
copy(source, new File(destination.getPath()), true);
}
@Override
public List<URI> list(URI directory) {
if (!"file".equalsIgnoreCase(directory.getScheme())) {
throw new IllegalArgumentException("Invalid scheme for " + this.getClass().getName());
}
final File dir = new File(directory.getPath());
final List<URI> list = new ArrayList<URI>();
if (dir.exists()) {
for (File file : dir.listFiles()) {
list.add(file.toURI());
}
}
return list;
}
private void copy(File source, File destination, boolean overwrite) {
createDirectory(destination.getParentFile());
if (!overwrite && destination.exists() && destination.lastModified() >= source.lastModified()) {
logger.info("File on disk is same or newer : " + destination);
return;
}
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(source);
fileOutputStream = new FileOutputStream(destination);
final FileChannel channel = fileOutputStream.getChannel();
/* long bytes = */fileInputStream.getChannel().transferTo(0, Integer.MAX_VALUE, channel);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.silentClose(fileInputStream);
IOUtils.silentClose(fileOutputStream);
}
destination.setLastModified(source.lastModified());
}
private void createDirectory(File directory) {
if (!options.contains(FileSystemOptions.CreateDirectories) || !directory.isDirectory()) {
return;
}
directory.mkdirs();
}
@Override
public void cleanup() {
}
}