+++ /dev/null
-package org.argeo.api.gcr.fs;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.LinkOption;
-import java.nio.file.Path;
-import java.nio.file.WatchEvent.Kind;
-import java.nio.file.WatchEvent.Modifier;
-import java.nio.file.WatchKey;
-import java.nio.file.WatchService;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-public abstract class AbstractFsPath<FS extends AbstractFsSystem<ST>, ST extends AbstractFsStore> implements Path {
- private final FS fs;
- /** null for non absolute paths */
- private final ST fileStore;
-
- private final String[] segments;// null means root
- private final boolean absolute;
-
- private final String separator;
-
- // optim
- private final int hashCode;
-
- public AbstractFsPath(FS filesSystem, String path) {
- if (path == null)
- throw new IllegalArgumentException("Path cannot be null");
- this.fs = filesSystem;
- this.separator = fs.getSeparator();
- // TODO deal with both path and separator being empty strings
- if (path.equals(separator)) {// root
- this.segments = null;
- this.absolute = true;
- this.hashCode = 0;
- this.fileStore = fs.getBaseFileStore();
- return;
- } else if (path.equals("")) {// empty path
- this.segments = new String[] { "" };
- this.absolute = false;
- this.hashCode = "".hashCode();
- this.fileStore = null;
- return;
- }
-
- this.absolute = path.startsWith(toStringRoot());
-
- String trimmedPath = path.substring(absolute ? toStringRoot().length() : 0,
- path.endsWith(separator) ? path.length() - separator.length() : path.length());
- this.segments = trimmedPath.split(separator);
- // clean up
- for (int i = 0; i < this.segments.length; i++) {
- this.segments[i] = cleanUpSegment(this.segments[i]);
- }
- this.hashCode = this.segments[this.segments.length - 1].hashCode();
-
- this.fileStore = isAbsolute() ? fs.getFileStore(path) : null;
- }
-
- protected AbstractFsPath(FS filesSystem, ST fileStore, String[] segments, boolean absolute) {
- this.segments = segments;
- this.absolute = absolute;
- this.hashCode = segments == null ? 0 : segments[segments.length - 1].hashCode();
- this.separator = filesSystem.getSeparator();
-// super(path, path == null ? true : absolute, filesSystem.getSeparator());
-// assert path == null ? absolute == true : true;
- this.fs = filesSystem;
-// this.path = path;
-// this.absolute = path == null ? true : absolute;
- if (isAbsolute() && fileStore == null)
- throw new IllegalArgumentException("Absolute path requires a file store");
- if (!isAbsolute() && fileStore != null)
- throw new IllegalArgumentException("A file store should not be provided for a relative path");
- this.fileStore = fileStore;
- assert !(absolute && fileStore == null);
- }
-
- protected Path retrieve(String path) {
- return getFileSystem().getPath(path);
- }
-
- @Override
- public FS getFileSystem() {
- return fs;
- }
-
- public ST getFileStore() {
- return fileStore;
- }
-
- @Override
- public boolean isAbsolute() {
- return absolute;
- }
-
- @Override
- public URI toUri() {
- try {
- return new URI(fs.provider().getScheme(), toString(), null);
- } catch (URISyntaxException e) {
- throw new IllegalStateException("Cannot create URI for " + toString(), e);
- }
- }
-
- @Override
- public Path toAbsolutePath() {
- if (isAbsolute())
- return this;
- // FIXME it doesn't seem right
- return newInstance(getSegments(), true);
- }
-
- @Override
- public Path toRealPath(LinkOption... options) throws IOException {
- return this;
- }
-
- @Override
- public File toFile() {
- throw new UnsupportedOperationException();
- }
-
- /*
- * PATH OPERATIONS
- */
- public final Path resolveSibling(Path other) {
- if (other == null)
- throw new NullPointerException();
- Path parent = getParent();
- return (parent == null) ? other : parent.resolve(other);
- }
-
- @Override
- public final Path resolveSibling(String other) {
- return resolveSibling(getFileSystem().getPath(other));
- }
-
- public final Path resolve(String other) {
- return resolve(retrieve(other));
- }
-
- public boolean startsWith(Path other) {
- return toString().startsWith(other.toString());
- }
-
- public boolean endsWith(Path other) {
- return toString().endsWith(other.toString());
- }
-
- @Override
- public Path normalize() {
- // always normalized
- return this;
- }
-
- @Override
- public final Iterator<Path> iterator() {
- return new Iterator<Path>() {
- private int i = 0;
-
- @Override
- public boolean hasNext() {
- return (i < getNameCount());
- }
-
- @Override
- public Path next() {
- if (i < getNameCount()) {
- Path result = getName(i);
- i++;
- return result;
- } else {
- throw new NoSuchElementException();
- }
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
- @Override
- public int compareTo(Path other) {
- return toString().compareTo(other.toString());
- }
-
- public Path resolve(Path other) {
- AbstractFsPath<?, ?> otherPath = (AbstractFsPath<?, ?>) other;
- if (otherPath.isAbsolute())
- return other;
- String[] newPath;
- if (isRoot()) {
- newPath = new String[otherPath.segments.length];
- System.arraycopy(otherPath.segments, 0, newPath, 0, otherPath.segments.length);
- } else {
- newPath = new String[segments.length + otherPath.segments.length];
- System.arraycopy(segments, 0, newPath, 0, segments.length);
- System.arraycopy(otherPath.segments, 0, newPath, segments.length, otherPath.segments.length);
- }
- if (!absolute)
- return newInstance(newPath, absolute);
- else {
- return newInstance(toString(newPath));
- }
- }
-
- public Path relativize(Path other) {
- if (equals(other))
- return newInstance("");
- if (other.toString().startsWith(this.toString())) {
- String p1 = toString();
- String p2 = other.toString();
- String relative = p2.substring(p1.length(), p2.length());
- if (relative.charAt(0) == '/')
- relative = relative.substring(1);
- return newInstance(relative);
- }
- throw new IllegalArgumentException(other + " cannot be relativized against " + this);
- }
-
- /*
- * FACTORIES
- */
- protected abstract AbstractFsPath<FS, ST> newInstance(String path);
-
- protected abstract AbstractFsPath<FS, ST> newInstance(String[] segments, boolean absolute);
-
- /*
- * CUSTOMISATIONS
- */
- protected String toStringRoot() {
- return separator;
- }
-
- protected String cleanUpSegment(String segment) {
- return segment;
- }
-
- protected boolean isRoot() {
- return segments == null;
- }
-
- protected boolean isEmpty() {
- return segments.length == 1 && "".equals(segments[0]);
- }
-
- /*
- * PATH OPERATIONS
- */
- public AbstractFsPath<FS, ST> getRoot() {
- return newInstance(toStringRoot());
- }
-
- public AbstractFsPath<FS, ST> getParent() {
- if (isRoot())
- return null;
- // FIXME empty path?
- if (segments.length == 1)// first level
- return newInstance(toStringRoot());
- String[] parentPath = Arrays.copyOfRange(segments, 0, segments.length - 1);
- if (!absolute)
- return newInstance(parentPath, absolute);
- else
- return newInstance(toString(parentPath));
- }
-
- public AbstractFsPath<FS, ST> getFileName() {
- if (isRoot())
- return null;
- return newInstance(segments[segments.length - 1]);
- }
-
- public int getNameCount() {
- if (isRoot())
- return 0;
- return segments.length;
- }
-
- public AbstractFsPath<FS, ST> getName(int index) {
- if (isRoot())
- return null;
- return newInstance(segments[index]);
- }
-
- public AbstractFsPath<FS, ST> subpath(int beginIndex, int endIndex) {
- if (isRoot())
- return null;
- String[] parentPath = Arrays.copyOfRange(segments, beginIndex, endIndex);
- return newInstance(parentPath, false);
- }
-
- public boolean startsWith(String other) {
- return toString().startsWith(other);
- }
-
- public boolean endsWith(String other) {
- return toString().endsWith(other);
- }
-
- /*
- * UTILITIES
- */
- protected String toString(String[] path) {
- if (isRoot())
- return toStringRoot();
- StringBuilder sb = new StringBuilder();
- if (isAbsolute())
- sb.append(separator);
- for (int i = 0; i < path.length; i++) {
- if (i != 0)
- sb.append(separator);
- sb.append(path[i]);
- }
- return sb.toString();
- }
-
- @Override
- public String toString() {
- return toString(segments);
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof AbstractFsPath))
- return false;
- AbstractFsPath<?, ?> other = (AbstractFsPath<?, ?>) obj;
-
- if (isRoot()) {// root
- if (other.isRoot())// root
- return true;
- else
- return false;
- } else {
- if (other.isRoot())// root
- return false;
- }
- // non root
- if (segments.length != other.segments.length)
- return false;
- for (int i = 0; i < segments.length; i++) {
- if (!segments[i].equals(other.segments[i]))
- return false;
- }
- return true;
- }
-
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return newInstance(toString());
- }
-
- /*
- * GETTERS / SETTERS
- */
- protected String[] getSegments() {
- return segments;
- }
-
- protected String getSeparator() {
- return separator;
- }
-
- /*
- * UNSUPPORTED
- */
- @Override
- public WatchKey register(WatchService watcher, Kind<?>[] events, Modifier... modifiers) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public WatchKey register(WatchService watcher, Kind<?>... events) throws IOException {
- throw new UnsupportedOperationException();
- }
-
-}