All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bridje.vfs.Path Maven / Gradle / Ivy


package org.bridje.vfs;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * An utility class for virtual path management.
 * 

* The path elements are separated by the {@literal "/"} character. */ public class Path implements Iterable { private final String[] pathElements; /** * Default constructor for the Path class. */ public Path() { this.pathElements = null; } /** * Creates a Path object from String *

* @param path The String object representing the path */ public Path(String path) { this(createElements(path)); } /** * Internal constructor that creates a Path from it´s elements. *

* @param pathElements The elements for the path. */ private Path(String[] pathElements) { if(pathElements != null && pathElements.length > 0) { this.pathElements = pathElements; } else { this.pathElements = null; } } /** * Gets an array with the list of elements for this path. *

* @return The list of elements for this path. */ public String[] getPathElements() { return pathElements; } /** * Gets the first element of the path. *

* For example, if the path represented by this object equals to * {@literal "usr/local"}, this method will return {@literal "usr"}. *

* @return An String object that represents the first element of the path. */ public String getFirstElement() { if(pathElements == null) return null; return pathElements[0]; } /** * Gets the first element of the path. *

* For example, if the path represented by this object equals to * {@literal "usr/local/somefile"}, this method will return * {@literal "somefile"}. *

* @return An String object that represents the first element of the path. */ public String getName() { if(pathElements == null) return "/"; return pathElements[pathElements.length - 1]; } /** * Creates a new Path object that represents the path to the parent object * of the current path. *

* For example, if the path represented by this object equals to * {@literal "usr/local/somefile"}, this method will return a path object * representing {@literal "usr/local"}. *

* @return The Path object parent of this object, or {@literal null} if this * is the last path. */ public Path getParent() { if (isLast()) return new Path(); String[] copyOfRange = Arrays.copyOfRange(pathElements, 0, pathElements.length - 1); return new Path(copyOfRange); } /** * Creates a new Path object that does not contains the first element of the * current path. *

* For example, if the path represented by this object equals to * {@literal "usr/local/somefile"}, this method will return a path object * representing {@literal "/local/somefile"}. *

* @return The Path object without the first element of the current path, or * {@literal null} if this is the las path. */ public Path getNext() { if (isLast()) return null; String[] copyOfRange = Arrays.copyOfRange(pathElements, 1, pathElements.length); return new Path(copyOfRange); } /** * Determines if this path has any element left. *

* For example, if the path represented by this object is a multiple element * path like {@literal "usr/local"} the this method will return * {@literal true}. *

* @return {@literal true} if this path is a multi element path, * {@literal false} otherwise. */ public boolean hasNext() { return !isLast(); } /** * If this path is the root path "/". *

* @return true this path is the root path. */ public boolean isRoot() { return pathElements == null || pathElements.length == 0; } /** * Determines if the first element of the path is the dot (.) character * witch represents the current folder. *

* @return {@literal true} if the first element of the path is the dot (.) * character, {@literal false} otherwise. */ public boolean isSelf() { if(isRoot()) return false; return ".".equalsIgnoreCase(pathElements[0]); } /** * Determines if the first element of the path is the (..) identifier witch * represents the parent folder. *

* @return {@literal true} if the first element of the path is the (..) * identifier, {@literal false} otherwise. */ public boolean isParent() { if(isRoot()) return false; return "..".equalsIgnoreCase(pathElements[0]); } /** * Determines if this path is the last element path. *

* If the path represented by this object is a single element path like * {@literal "usr"} then this method will return {@literal true}. *

* @return {@literal true} if this path is a single element, * {@literal false} otherwise. */ public boolean isLast() { if(isRoot()) return true; return (pathElements.length <= 1); } /** * This method creates a new path object that does not contains the (.) and * (..) identifiers. *

* For example, if the path represented by this element equals to * {@literal "usr/./local/../etc"}, this method will return * {@literal "usr/etc"}. *

* @return A new Path object representing the canonical path of this object. */ public Path getCanonicalPath() { if(isRoot()) return this; List str = new LinkedList<>(); for (String pe : pathElements) { if (pe.equalsIgnoreCase("..")) { if (str.isEmpty()) return null; str.remove(str.size() - 1); } else if (!pe.equalsIgnoreCase(".")) { str.add(pe); } } if (str.isEmpty()) return null; String[] els = new String[str.size()]; return new Path(str.toArray(els)); } /** * Gets a string representation of the current path. *

* @return The String object representing the current path. */ @Override public String toString() { if(isRoot()) return "/"; return toString("/"); } /** * Gets a string representation of the current path, separated by the * specified path separator. *

* @param pathSep The path separator to be used. * * @return The String object representing the current path. */ public String toString(String pathSep) { if(isRoot()) return pathSep; return String.join(pathSep, pathElements); } /** * Obtains the concatenation with another path. *

* @param path the other path to concatenate. * * @return a new path with the concatenation. */ public Path join(Path path) { if(path.isRoot()) return new Path(pathElements); if(isRoot()) return new Path(path.pathElements); String[] newElements = new String[pathElements.length + path.pathElements.length]; System.arraycopy(pathElements, 0, newElements, 0, pathElements.length); System.arraycopy(path.pathElements, 0, newElements, pathElements.length, path.pathElements.length); return new Path(newElements); } /** * Obtains the concatenation with a string. *

* @param path the string to concatenate. * * @return a new path with the concatenation. */ public Path join(String path) { if(isRoot()) return new Path(path); return join(new Path(path)); } /** * @see Iterable */ @Override public Iterator iterator() { return new Iterator() { private int currentIndex; @Override public boolean hasNext() { return !isRoot() && (currentIndex < pathElements.length); } @Override public Path next() { if(isRoot()) return null; String[] copyOfRange = Arrays.copyOfRange(pathElements, 0, currentIndex + 1); currentIndex++; return new Path(copyOfRange); } }; } /** * Gets the extension for the last component of this path. * * @return The extension of the last component of this path. */ public String getExtension() { if(isRoot()) return null; String[] split = getName().split("[\\.]"); if(split.length > 1) return split[split.length - 1]; return null; } private static String[] createElements(String path) { if (path == null || path.trim().isEmpty()) { throw new IllegalArgumentException("The specified path is not valid."); } if(path.equals("/")) return null; String normPath = normalize(path); String[] arr = normPath.split("/"); return arr; } private static String normalize(String path) { String normPath = path; String toReplace = "\\"; while (normPath.contains(toReplace)) { normPath = normPath.replace(toReplace, "/"); } if (path.startsWith("/")) normPath = normPath.substring(1); if (normPath.endsWith("/")) normPath = normPath.substring(0, normPath.length() - 1); return normPath.trim(); } @Override public int hashCode() { return toString().hashCode(); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Path other = (Path) obj; return toString().equals(other.toString()); } /** * Determines when ever this path starts with the given path. * * @param path The prefix path. * @return true if this path starts with the given path. */ public boolean startsWith(Path path) { if(path.pathElements == null || path.pathElements.length == 0) return true; if(this.pathElements == null || this.pathElements.length == 0) return true; if(path.pathElements.length > this.pathElements.length) return false; for(int i = 0; i < path.pathElements.length; i++) { if(!this.pathElements[i].equals(path.pathElements[i])) { return false; } } return true; } /** * Remove the given path from the current path if the given path is a prefix of this path. * * @param path The prefix path. * @return the new trimed path, or null if the given path is not a prefix for this path. */ public Path leftTrim(Path path) { if(path == null || path.pathElements == null || path.pathElements.length == 0) return new Path(this.pathElements); if(this.pathElements == null || this.pathElements.length == 0) return new Path(); if(path.pathElements.length > this.pathElements.length) return null; for(int i = 0; i < path.pathElements.length; i++) { if(!this.pathElements[i].equals(path.pathElements[i])) { return null; } } return new Path(Arrays.copyOfRange(pathElements, path.pathElements.length, this.pathElements.length)); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy