
io.jsync.file.impl.DefaultFileSystem Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsync.io Show documentation
Show all versions of jsync.io Show documentation
jsync.io is a non-blocking, event-driven networking framework for Java
/*
* Copyright (c) 2011-2013 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.jsync.file.impl;
import io.jsync.AsyncResult;
import io.jsync.Handler;
import io.jsync.buffer.Buffer;
import io.jsync.file.AsyncFile;
import io.jsync.file.FileProps;
import io.jsync.file.FileSystem;
import io.jsync.file.FileSystemProps;
import io.jsync.impl.AsyncInternal;
import io.jsync.impl.BlockingAction;
import io.jsync.impl.DefaultContext;
import io.jsync.logging.Logger;
import io.jsync.logging.impl.LoggerFactory;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.EnumSet;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author Tim Fox
*/
public class DefaultFileSystem implements io.jsync.file.FileSystem {
@SuppressWarnings("unused")
private static final Logger log = LoggerFactory.getLogger(DefaultFileSystem.class);
protected final AsyncInternal async;
public DefaultFileSystem(AsyncInternal async) {
this.async = async;
}
public io.jsync.file.FileSystem copy(String from, String to, Handler> handler) {
copyInternal(from, to, handler).run();
return this;
}
public io.jsync.file.FileSystem copySync(String from, String to) {
copyInternal(from, to, null).action();
return this;
}
public FileSystem copy(String from, String to, boolean recursive, Handler> handler) {
copyInternal(from, to, recursive, handler).run();
return this;
}
public io.jsync.file.FileSystem copySync(String from, String to, boolean recursive) {
copyInternal(from, to, recursive, null).action();
return this;
}
public io.jsync.file.FileSystem move(String from, String to, Handler> handler) {
moveInternal(from, to, handler).run();
return this;
}
public io.jsync.file.FileSystem moveSync(String from, String to) {
moveInternal(from, to, null).action();
return this;
}
public io.jsync.file.FileSystem truncate(String path, long len, Handler> handler) {
truncateInternal(path, len, handler).run();
return this;
}
public io.jsync.file.FileSystem truncateSync(String path, long len) {
truncateInternal(path, len, null).action();
return this;
}
public io.jsync.file.FileSystem chmod(String path, String perms, Handler> handler) {
chmodInternal(path, perms, handler).run();
return this;
}
public io.jsync.file.FileSystem chmodSync(String path, String perms) {
chmodInternal(path, perms, null).action();
return this;
}
public io.jsync.file.FileSystem chmod(String path, String perms, String dirPerms, Handler> handler) {
chmodInternal(path, perms, dirPerms, handler).run();
return this;
}
public io.jsync.file.FileSystem chmodSync(String path, String perms, String dirPerms) {
chmodInternal(path, perms, dirPerms, null).action();
return this;
}
public io.jsync.file.FileSystem chown(String path, String user, String group, Handler> handler) {
chownInternal(path, user, group, handler).run();
return this;
}
public io.jsync.file.FileSystem chownSync(String path, String user, String group) {
chownInternal(path, user, group, null).action();
return this;
}
public io.jsync.file.FileSystem props(String path, Handler> handler) {
propsInternal(path, handler).run();
return this;
}
public FileProps propsSync(String path) {
return propsInternal(path, null).action();
}
public io.jsync.file.FileSystem lprops(String path, Handler> handler) {
lpropsInternal(path, handler).run();
return this;
}
public FileProps lpropsSync(String path) {
return lpropsInternal(path, null).action();
}
public io.jsync.file.FileSystem link(String link, String existing, Handler> handler) {
linkInternal(link, existing, handler).run();
return this;
}
public io.jsync.file.FileSystem linkSync(String link, String existing) {
linkInternal(link, existing, null).action();
return this;
}
public io.jsync.file.FileSystem symlink(String link, String existing, Handler> handler) {
symlinkInternal(link, existing, handler).run();
return this;
}
public io.jsync.file.FileSystem symlinkSync(String link, String existing) {
symlinkInternal(link, existing, null).action();
return this;
}
public io.jsync.file.FileSystem unlink(String link, Handler> handler) {
unlinkInternal(link, handler).run();
return this;
}
public io.jsync.file.FileSystem unlinkSync(String link) {
unlinkInternal(link, null).action();
return this;
}
public io.jsync.file.FileSystem readSymlink(String link, Handler> handler) {
readSymlinkInternal(link, handler).run();
return this;
}
public String readSymlinkSync(String link) {
return readSymlinkInternal(link, null).action();
}
public io.jsync.file.FileSystem delete(String path, Handler> handler) {
deleteInternal(path, handler).run();
return this;
}
public io.jsync.file.FileSystem deleteSync(String path) {
deleteInternal(path, null).action();
return this;
}
public io.jsync.file.FileSystem delete(String path, boolean recursive, Handler> handler) {
deleteInternal(path, recursive, handler).run();
return this;
}
public io.jsync.file.FileSystem deleteSync(String path, boolean recursive) {
deleteInternal(path, recursive, null).action();
return this;
}
public io.jsync.file.FileSystem mkdir(String path, Handler> handler) {
mkdirInternal(path, handler).run();
return this;
}
public io.jsync.file.FileSystem mkdirSync(String path) {
mkdirInternal(path, null).action();
return this;
}
public io.jsync.file.FileSystem mkdir(String path, boolean createParents, Handler> handler) {
mkdirInternal(path, createParents, handler).run();
return this;
}
public io.jsync.file.FileSystem mkdirSync(String path, boolean createParents) {
mkdirInternal(path, createParents, null).action();
return this;
}
public io.jsync.file.FileSystem mkdir(String path, String perms, Handler> handler) {
mkdirInternal(path, perms, handler).run();
return this;
}
public io.jsync.file.FileSystem mkdirSync(String path, String perms) {
mkdirInternal(path, perms, null).action();
return this;
}
public io.jsync.file.FileSystem mkdir(String path, String perms, boolean createParents, Handler> handler) {
mkdirInternal(path, perms, createParents, handler).run();
return this;
}
public io.jsync.file.FileSystem mkdirSync(String path, String perms, boolean createParents) {
mkdirInternal(path, perms, createParents, null).action();
return this;
}
public io.jsync.file.FileSystem readDir(String path, Handler> handler) {
readDirInternal(path, handler).run();
return this;
}
public String[] readDirSync(String path) {
return readDirInternal(path, null).action();
}
public io.jsync.file.FileSystem readDir(String path, String filter, Handler> handler) {
readDirInternal(path, filter, handler).run();
return this;
}
public String[] readDirSync(String path, String filter) {
return readDirInternal(path, filter, null).action();
}
public io.jsync.file.FileSystem readFile(String path, Handler> handler) {
readFileInternal(path, handler).run();
return this;
}
public Buffer readFileSync(String path) {
return readFileInternal(path, null).action();
}
public io.jsync.file.FileSystem writeFile(String path, Buffer data, Handler> handler) {
writeFileInternal(path, data, handler).run();
return this;
}
public io.jsync.file.FileSystem writeFileSync(String path, Buffer data) {
writeFileInternal(path, data, null).action();
return this;
}
public io.jsync.file.FileSystem open(String path, Handler> handler) {
openInternal(path, handler).run();
return this;
}
public AsyncFile openSync(String path) {
return openInternal(path, null).action();
}
public io.jsync.file.FileSystem open(String path, String perms, Handler> handler) {
openInternal(path, perms, handler).run();
return this;
}
public AsyncFile openSync(String path, String perms) {
return openInternal(path, perms, null).action();
}
public io.jsync.file.FileSystem open(String path, String perms, boolean createNew, Handler> handler) {
openInternal(path, perms, createNew, handler).run();
return this;
}
public AsyncFile openSync(String path, String perms, boolean createNew) {
return openInternal(path, perms, createNew, null).action();
}
public io.jsync.file.FileSystem open(String path, String perms, boolean read, boolean write, boolean createNew, Handler> handler) {
openInternal(path, perms, read, write, createNew, handler).run();
return this;
}
public AsyncFile openSync(String path, String perms, boolean read, boolean write, boolean createNew) {
return openInternal(path, perms, read, write, createNew, null).action();
}
public io.jsync.file.FileSystem open(String path, String perms, boolean read, boolean write, boolean createNew,
boolean flush, Handler> handler) {
openInternal(path, perms, read, write, createNew, flush, handler).run();
return this;
}
public AsyncFile openSync(String path, String perms, boolean read, boolean write, boolean createNew, boolean flush) {
return openInternal(path, perms, read, write, createNew, flush, null).action();
}
public io.jsync.file.FileSystem createFile(String path, Handler> handler) {
createFileInternal(path, handler).run();
return this;
}
public io.jsync.file.FileSystem createFileSync(String path) {
createFileInternal(path, null).action();
return this;
}
public io.jsync.file.FileSystem createFile(String path, String perms, Handler> handler) {
createFileInternal(path, perms, handler).run();
return this;
}
public io.jsync.file.FileSystem createFileSync(String path, String perms) {
createFileInternal(path, perms, null).action();
return this;
}
public io.jsync.file.FileSystem exists(String path, Handler> handler) {
existsInternal(path, handler).run();
return this;
}
public boolean existsSync(String path) {
return existsInternal(path, null).action();
}
public io.jsync.file.FileSystem fsProps(String path, Handler> handler) {
fsPropsInternal(path, handler).run();
return this;
}
public FileSystemProps fsPropsSync(String path) {
return fsPropsInternal(path, null).action();
}
private BlockingAction copyInternal(String from, String to, Handler> handler) {
return copyInternal(from, to, false, handler);
}
private BlockingAction copyInternal(String from, String to, final boolean recursive, Handler> handler) {
final Path source = PathAdjuster.adjust(async, Paths.get(from));
final Path target = PathAdjuster.adjust(async, Paths.get(to));
return new BlockingAction(async, handler) {
public Void action() {
try {
if (recursive) {
Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new SimpleFileVisitor() {
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
Path targetDir = target.resolve(source.relativize(dir));
try {
Files.copy(dir, targetDir);
} catch (FileAlreadyExistsException e) {
if (!Files.isDirectory(targetDir)) {
throw e;
}
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
Files.copy(file, target.resolve(source.relativize(file)));
return FileVisitResult.CONTINUE;
}
});
} else {
Files.copy(source, target);
}
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction moveInternal(String from, String to, Handler> handler) {
final Path source = PathAdjuster.adjust(async, Paths.get(from));
final Path target = PathAdjuster.adjust(async, Paths.get(to));
return new BlockingAction(async, handler) {
public Void action() {
try {
Files.move(source, target);
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction truncateInternal(String p, final long len, Handler> handler) {
final String path = PathAdjuster.adjust(async, p);
return new BlockingAction(async, handler) {
public Void action() {
if (len < 0) {
throw new io.jsync.file.FileSystemException("Cannot truncate file to size < 0");
}
if (!Files.exists(Paths.get(path))) {
throw new io.jsync.file.FileSystemException("Cannot truncate file " + path + ". Does not exist");
}
RandomAccessFile raf = null;
try {
try {
raf = new RandomAccessFile(path, "rw");
raf.setLength(len);
} finally {
if (raf != null) raf.close();
}
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction chmodInternal(String path, String perms, Handler> handler) {
return chmodInternal(path, perms, null, handler);
}
protected BlockingAction chmodInternal(String path, String perms, String dirPerms, Handler> handler) {
final Path target = PathAdjuster.adjust(async, Paths.get(path));
final Set permissions = PosixFilePermissions.fromString(perms);
final Set dirPermissions = dirPerms == null ? null : PosixFilePermissions.fromString(dirPerms);
return new BlockingAction(async, handler) {
public Void action() {
try {
if (dirPermissions != null) {
Files.walkFileTree(target, new SimpleFileVisitor() {
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
//The directory entries typically have different permissions to the files, e.g. execute permission
//or can't cd into it
Files.setPosixFilePermissions(dir, dirPermissions);
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.setPosixFilePermissions(file, permissions);
return FileVisitResult.CONTINUE;
}
});
} else {
Files.setPosixFilePermissions(target, permissions);
}
} catch (SecurityException e) {
throw new io.jsync.file.FileSystemException("Accessed denied for chmod on " + target);
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
protected BlockingAction chownInternal(String path, final String user, final String group, Handler> handler) {
final Path target = PathAdjuster.adjust(async, Paths.get(path));
final UserPrincipalLookupService service = target.getFileSystem().getUserPrincipalLookupService();
return new BlockingAction(async, handler) {
public Void action() {
try {
final UserPrincipal userPrincipal = user == null ? null : service.lookupPrincipalByName(user);
final GroupPrincipal groupPrincipal = group == null ? null : service.lookupPrincipalByGroupName(group);
if (groupPrincipal != null) {
PosixFileAttributeView view = Files.getFileAttributeView(target, PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
if (view == null) {
throw new io.jsync.file.FileSystemException("Change group of file not supported");
}
view.setGroup(groupPrincipal);
}
if (userPrincipal != null) {
Files.setOwner(target, userPrincipal);
}
} catch (SecurityException e) {
throw new io.jsync.file.FileSystemException("Accessed denied for chown on " + target);
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction propsInternal(String path, Handler> handler) {
return props(path, true, handler);
}
private BlockingAction lpropsInternal(String path, Handler> handler) {
return props(path, false, handler);
}
private BlockingAction props(String path, final boolean followLinks, Handler> handler) {
final Path target = PathAdjuster.adjust(async, Paths.get(path));
return new BlockingAction(async, handler) {
public FileProps action() {
try {
BasicFileAttributes attrs;
if (followLinks) {
attrs = Files.readAttributes(target, BasicFileAttributes.class);
} else {
attrs = Files.readAttributes(target, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
}
return new DefaultFileProps(attrs);
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
}
};
}
private BlockingAction linkInternal(String link, String existing, Handler> handler) {
return link(link, existing, false, handler);
}
private BlockingAction symlinkInternal(String link, String existing, Handler> handler) {
return link(link, existing, true, handler);
}
private BlockingAction link(String link, String existing, final boolean symbolic, Handler> handler) {
final Path source = PathAdjuster.adjust(async, Paths.get(link));
final Path target = PathAdjuster.adjust(async, Paths.get(existing));
return new BlockingAction(async, handler) {
public Void action() {
try {
if (symbolic) {
Files.createSymbolicLink(source, target);
} else {
Files.createLink(source, target);
}
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction unlinkInternal(String link, Handler> handler) {
return deleteInternal(link, handler);
}
private BlockingAction readSymlinkInternal(String link, Handler> handler) {
final Path source = PathAdjuster.adjust(async, Paths.get(link));
return new BlockingAction(async, handler) {
public String action() {
try {
return Files.readSymbolicLink(source).toString();
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
}
};
}
private BlockingAction deleteInternal(String path, Handler> handler) {
return deleteInternal(path, false, handler);
}
private BlockingAction deleteInternal(String path, final boolean recursive, Handler> handler) {
final Path source = PathAdjuster.adjust(async, Paths.get(path));
return new BlockingAction(async, handler) {
public Void action() {
try {
if (recursive) {
Files.walkFileTree(source, new SimpleFileVisitor() {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
} else {
throw e;
}
}
});
} else {
Files.delete(source);
}
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction mkdirInternal(String path, Handler> handler) {
return mkdirInternal(path, null, false, handler);
}
private BlockingAction mkdirInternal(String path, boolean createParents, Handler> handler) {
return mkdirInternal(path, null, createParents, handler);
}
private BlockingAction mkdirInternal(String path, String perms, Handler> handler) {
return mkdirInternal(path, perms, false, handler);
}
protected BlockingAction mkdirInternal(String path, final String perms, final boolean createParents, Handler> handler) {
final Path source = PathAdjuster.adjust(async, Paths.get(path));
final FileAttribute> attrs = perms == null ? null : PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString(perms));
return new BlockingAction(async, handler) {
public Void action() {
try {
if (createParents) {
if (attrs != null) {
Files.createDirectories(source, attrs);
} else {
Files.createDirectories(source);
}
} else {
if (attrs != null) {
Files.createDirectory(source, attrs);
} else {
Files.createDirectory(source);
}
}
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction readDirInternal(String path, Handler> handler) {
return readDirInternal(path, null, handler);
}
private BlockingAction readDirInternal(String p, final String filter, Handler> handler) {
final String path = PathAdjuster.adjust(async, p);
return new BlockingAction(async, handler) {
public String[] action() {
try {
File file = new File(path);
if (!file.exists()) {
throw new io.jsync.file.FileSystemException("Cannot read directory " + path + ". Does not exist");
}
if (!file.isDirectory()) {
throw new io.jsync.file.FileSystemException("Cannot read directory " + path + ". It's not a directory");
} else {
FilenameFilter fnFilter;
if (filter != null) {
fnFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return Pattern.matches(filter, name);
}
};
} else {
fnFilter = null;
}
File[] files;
if (fnFilter == null) {
files = file.listFiles();
} else {
files = file.listFiles(fnFilter);
}
String[] ret = new String[files.length];
int i = 0;
for (File f : files) {
ret[i++] = f.getCanonicalPath();
}
return ret;
}
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
}
};
}
private BlockingAction readFileInternal(String path, Handler> handler) {
final Path target = PathAdjuster.adjust(async, Paths.get(path));
return new BlockingAction(async, handler) {
public Buffer action() {
try {
byte[] bytes = Files.readAllBytes(target);
Buffer buff = new Buffer(bytes);
return buff;
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
}
};
}
private BlockingAction writeFileInternal(String path, final Buffer data, Handler> handler) {
final Path target = PathAdjuster.adjust(async, Paths.get(path));
return new BlockingAction(async, handler) {
public Void action() {
try {
Files.write(target, data.getBytes());
return null;
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
}
};
}
private BlockingAction openInternal(String path, Handler> handler) {
return openInternal(path, null, true, true, true, false, handler);
}
private BlockingAction openInternal(String path, String perms, Handler> handler) {
return openInternal(path, perms, true, true, true, false, handler);
}
private BlockingAction openInternal(String path, String perms, boolean createNew, Handler> handler) {
return openInternal(path, perms, true, true, createNew, false, handler);
}
private BlockingAction openInternal(String path, String perms, boolean read, boolean write, boolean createNew, Handler> handler) {
return openInternal(path, perms, read, write, createNew, false, handler);
}
private BlockingAction openInternal(String p, final String perms, final boolean read, final boolean write, final boolean createNew,
final boolean flush, Handler> handler) {
final String path = PathAdjuster.adjust(async, p);
return new BlockingAction(async, handler) {
public AsyncFile action() {
return doOpen(path, perms, read, write, createNew, flush, context);
}
};
}
protected AsyncFile doOpen(String path, String perms, boolean read, boolean write, boolean createNew,
boolean flush, DefaultContext context) {
return new DefaultAsyncFile(async, path, perms, read, write, createNew, flush, context);
}
private BlockingAction createFileInternal(String path, Handler> handler) {
return createFileInternal(path, null, handler);
}
protected BlockingAction createFileInternal(String p, final String perms, Handler> handler) {
final String path = PathAdjuster.adjust(async, p);
final FileAttribute> attrs = perms == null ? null : PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString(perms));
return new BlockingAction(async, handler) {
public Void action() {
try {
Path target = Paths.get(path);
if (attrs != null) {
Files.createFile(target, attrs);
} else {
Files.createFile(target);
}
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
return null;
}
};
}
private BlockingAction existsInternal(String path, Handler> handler) {
final File file = new File(PathAdjuster.adjust(async, path));
return new BlockingAction(async, handler) {
public Boolean action() {
return file.exists();
}
};
}
private BlockingAction fsPropsInternal(String path, Handler> handler) {
final Path target = PathAdjuster.adjust(async, Paths.get(path));
return new BlockingAction(async, handler) {
public FileSystemProps action() {
try {
FileStore fs = Files.getFileStore(target);
return new DefaultFileSystemProps(fs.getTotalSpace(), fs.getUnallocatedSpace(), fs.getUsableSpace());
} catch (IOException e) {
throw new io.jsync.file.FileSystemException(e);
}
}
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy