org.crsh.vfs.Path Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.crsh.vfs;
import org.crsh.util.BaseIterator;
import java.io.File;
import java.util.Iterator;
import java.util.NoSuchElementException;
public abstract class Path implements Iterable {
/** . */
private static final String[] EMPTY_STRING = new String[0];
/** . */
public static final Absolute ROOT = new Absolute(true, EMPTY_STRING);
/** . */
public static final Relative EMPTY = new Relative(true, EMPTY_STRING);
private static String[] path(java.io.File file, int size) {
String[] ret;
java.io.File parent = file.getParentFile();
if (parent != null && parent.isDirectory()) {
ret = path(parent, 1 + size);
} else {
ret = new String[1 + size];
}
ret[ret.length - size - 1] = file.getName();
return ret;
}
public static Path get(java.io.File file) {
String[] names = path(file, 0);
if (file.isAbsolute()) {
return new Absolute(file.isDirectory(), names);
} else {
return new Relative(file.isDirectory(), names);
}
}
public static Path get(String s) {
if (s.length() == 0) {
return EMPTY;
}
//
int start;
boolean absolute;
if (s.charAt(0) != '/') {
start = 0;
absolute = false;
} else {
if (s.length() == 1) {
return ROOT;
} else {
start = 1;
absolute = true;
}
}
//
boolean dir;
int end;
if (s.charAt(s.length() - 1) == '/' || s.charAt(s.length() - 1) == File.separatorChar) {
dir = true;
end = s.length() - 1;
} else {
dir = false;
end = s.length();
}
//
String[] names = parseNames(s, start, end, 0);
//
return absolute ? new Absolute(dir, names) : new Relative(dir, names);
}
private static String[] parseNames(final String s, final int prev, int end, final int count) {
int next = s.indexOf('/', prev);
if (next == -1) next = s.indexOf(File.separatorChar, prev);
if (next == -1 || next > end) {
if (prev < end) {
String[] ret = new String[count + 1];
ret[count] = s.substring(prev);
return ret;
} else {
return new String[count];
}
} else if (next - prev > 0) {
String[] ret = parseNames(s, next + 1, end, count + 1);
ret[count] = s.substring(prev, next);
return ret;
} else {
return parseNames(s, next + 1, end, count);
}
}
/** . */
protected final boolean dir;
/** . */
protected final String[] names;
/** . */
private String value;
private Path(boolean dir, String[] names) {
this.dir = dir;
this.names = names;
}
public Iterator iterator() {
return new BaseIterator() {
int index = 0;
public boolean hasNext() {
return index < names.length;
}
public String next() {
if (index < names.length) {
return names[index++];
} else {
throw new NoSuchElementException();
}
}
};
}
public Path append(String name, boolean dir) {
int length = names.length;
String[] names = new String[length + 1];
System.arraycopy(names, 0, names, 0, length);
names[length] = name;
return create(dir, names);
}
protected abstract Path create(boolean dir, String[] names);
public abstract boolean isAbsolute();
public abstract Absolute absolute();
public int getSize() {
return names.length;
}
public boolean isDir() {
return dir;
}
public String getName() {
return names.length > 0 ? names[names.length - 1] : "";
}
public String nameAt(int index) throws IndexOutOfBoundsException {
if (index < 0 || index >= names.length) {
throw new IndexOutOfBoundsException("Index out of bounds [0" + (names.length - 1) + "]" + index);
} else {
return names[index];
}
}
public boolean isChildOf(Path parent) {
if (parent.dir) {
int length = parent.names.length;
if (names.length == length + 1) {
for (int i = 0;i < length;i++) {
if (names[i].equals(parent.names[i])) {
return false;
}
}
return true;
}
}
return false;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof Path) {
Path that = (Path)o;
int length = that.names.length;
if (names.length == length) {
for (int i = 0;i < length;i++) {
if (!names[i].equals(that.names[i])) {
return false;
}
}
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hashCode = dir ? 1 : 0;
for (int i = names.length - 1;i >= 0;i--) {
hashCode = hashCode * 41 + names[i].hashCode();
}
return hashCode;
}
/**
* Returns the canonical path value.
*
* @return the value
*/
public String getValue() {
if (value == null) {
if (names.length == 0) {
if (isAbsolute()) {
return "/";
} else {
return "";
}
} else {
StringBuilder sb = new StringBuilder(8 * names.length);
if (isAbsolute()) {
sb.append('/');
}
for (int i = 0;i < names.length;i++) {
if (i > 0) {
sb.append('/');
}
sb.append(names[i]);
}
if (dir) {
sb.append('/');
}
value = sb.toString();
}
}
return value;
}
public String toString() {
return "Path[value=" + getValue() + "]";
}
public static class Absolute extends Path {
private Absolute(boolean dir, String[] names) {
super(dir, names);
}
@Override
public Absolute append(String name, boolean dir) {
return (Absolute)super.append(name, dir);
}
@Override
protected Absolute create(boolean dir, String[] names) {
return new Absolute(dir, names);
}
@Override
public Absolute absolute() {
return this;
}
@Override
public boolean isAbsolute() {
return true;
}
}
public static class Relative extends Path {
private Relative(boolean dir, String[] names) {
super(dir, names);
}
@Override
public Relative append(String name, boolean dir) {
return (Relative)super.append(name, dir);
}
@Override
protected Relative create(boolean dir, String[] names) {
return new Relative(dir, names);
}
@Override
public Absolute absolute() {
return new Absolute(dir, names);
}
@Override
public boolean isAbsolute() {
return false;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy