package com.laytonsmith.PureUtilities.VirtualFS;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
/**
*
*
*/
@FileSystemLayer.fslayer("file")
public class RealFileSystemLayer extends FileSystemLayer {
protected final File real;
public RealFileSystemLayer(VirtualFile path, VirtualFileSystem fileSystem, String symlink) throws IOException {
super(path, fileSystem);
if (symlink == null) {
real = new File(fileSystem.root, path.getPath());
if (!real.getCanonicalPath().startsWith(fileSystem.root.getCanonicalPath())) {
throw new PermissionException(path.getPath() + " extends above the root directory of this file system, and does not point to a valid file.");
}
} else {
File symlinkRoot = new File(fileSystem.symlinkFile, symlink);
real = new File(symlinkRoot, path.getPath());
//If the path extends above the symlink, disallow it
if (!real.getCanonicalPath().startsWith(symlinkRoot.getCanonicalPath())) {
//Unless of course, the path is still within the full real path, then
//eh, we'll allow it.
if (!real.getCanonicalPath().startsWith(fileSystem.root.getCanonicalPath())) {
throw new PermissionException(path.getPath() + " extends above the root directory of this file system, and does not point to a valid file.");
}
}
}
}
@Override
public InputStream getInputStream() throws FileNotFoundException {
return new FileInputStream(real);
}
@Override
public void writeByteArray(byte[] bytes) throws IOException {
FileUtils.writeByteArrayToFile(real, bytes);
}
@Override
public VirtualFile[] listFiles() throws IOException {
List<VirtualFile> virtuals = new ArrayList<VirtualFile>();
for (File sub : real.listFiles()) {
virtuals.add(normalize(sub));
}
return virtuals.toArray(new VirtualFile[virtuals.size()]);
}
private VirtualFile normalize(File real) throws IOException {
String path = real.getCanonicalPath().replaceFirst(Pattern.quote(fileSystem.root.getCanonicalPath()), "");
path = path.replace('\\', '/');
if (!path.startsWith("/")) {
path = "/" + path;
}
return new VirtualFile(path);
}
@Override
public void delete() throws IOException {
if (!real.delete()) {
throw new IOException("Could not delete the file");
}
}
@Override
public void deleteOnExit() {
real.deleteOnExit();
}
@Override
public boolean exists() {
return real.exists();
}
@Override
public boolean canRead() {
return real.canRead();
}
@Override
public boolean canWrite() {
return real.canWrite();
}
@Override
public boolean isDirectory() {
return real.isDirectory();
}
@Override
public boolean isFile() {
return real.isFile();
}
@Override
public void mkdirs() throws IOException {
if (!real.mkdirs()) {
throw new IOException("Directory structure could not be created");
}
}
@Override
public void createNewFile() throws IOException {
if (!real.createNewFile()) {
throw new IOException("File already exists!");
}
}
}