Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added more to the VFS. Stubbed out test cases, and moved direct file …
…system access to an abstraction layer, so things like ssh mounting, streaming protocols, or memory file systems can easily be added later.
- Loading branch information
1 parent
eef673d
commit 605e96d
Showing
4 changed files
with
483 additions
and
30 deletions.
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
src/main/java/com/laytonsmith/PureUtilities/VirtualFS/FileSystemLayer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.laytonsmith.PureUtilities.VirtualFS; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
||
/** | ||
* A file system layer is a layer between a VirtualFile and the real file | ||
* system. This allows for non-traditional file systems to be transparently added | ||
* to the VFS system. These layers are specified by symlinks in the VFS, which | ||
* use a specific URI to denote the path. Once a FSL is implemented, | ||
* it is trivial for a user to add a new symlink to make use of the new FSL. | ||
* All functions may throw an IOException, which is not something real File objects | ||
* normally do (for instance, delete() will simply return false) but to give the user | ||
* more information, this class throws exceptions instead. | ||
* @author lsmith | ||
*/ | ||
public abstract class FileSystemLayer { | ||
|
||
protected final VirtualFile path; | ||
protected final VirtualFileSystem fileSystem; | ||
protected FileSystemLayer(VirtualFile path, VirtualFileSystem fileSystem){ | ||
this.path = path; | ||
this.fileSystem = fileSystem; | ||
} | ||
|
||
public abstract InputStream getInputStream() throws IOException; | ||
|
||
public abstract void writeByteArray(byte[] bytes) throws IOException; | ||
|
||
public abstract VirtualFile[] listFiles() throws IOException; | ||
|
||
public abstract void delete() throws IOException; | ||
|
||
/** | ||
* This may work the exact same as delete in some cases, but otherwise, | ||
* the file will be deleted upon exit of the virtual machine. | ||
* @throws IOException | ||
*/ | ||
public abstract void deleteOnExit() throws IOException; | ||
|
||
public abstract boolean exists() throws IOException; | ||
|
||
public abstract boolean canRead() throws IOException; | ||
|
||
public abstract boolean canWrite() throws IOException; | ||
|
||
public abstract boolean isDirectory() throws IOException; | ||
|
||
public abstract boolean isFile() throws IOException; | ||
|
||
public abstract void mkdirs() throws IOException; | ||
|
||
public abstract void createNewFile() throws IOException; | ||
|
||
/** | ||
* Used to denote a FileSystemLayer protocol | ||
*/ | ||
public static @interface fslayer { | ||
/** | ||
* The protocol identifier, for instance, "file", which would | ||
* map to a file://uri type uri. | ||
* @return | ||
*/ | ||
String value(); | ||
} | ||
|
||
} |
109 changes: 109 additions & 0 deletions
109
src/main/java/com/laytonsmith/PureUtilities/VirtualFS/RealFileSystemLayer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package com.laytonsmith.PureUtilities.VirtualFS; | ||
|
||
import com.laytonsmith.PureUtilities.FileUtility; | ||
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; | ||
|
||
/** | ||
* | ||
* @author lsmith | ||
*/ | ||
@FileSystemLayer.fslayer("file") | ||
public class RealFileSystemLayer extends FileSystemLayer { | ||
|
||
protected final File real; | ||
|
||
public RealFileSystemLayer(VirtualFile path, VirtualFileSystem fileSystem) throws IOException { | ||
super(path, fileSystem); | ||
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."); | ||
} | ||
} | ||
|
||
@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!"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.