Class WebdavPath

java.lang.Object
no.maddin.niofs.webdav.WebdavPath
All Implemented Interfaces:
Comparable<Path>, Iterable<Path>, Path, Watchable

public class WebdavPath extends Object implements Path
Denotes a WebDAV Path.
Author:
Copyright 2012-2023 University of Stavanger, Norway
, Martin Goldhahn, (https://github.com/maddingo)
, Andrew Goh (https://github.com/ag88)

This is an implemtation of java.nio.file.Path for Webdav nio filesystem provider.

The current implementaion uses the simplified notion that an absolute path is a path that begins with "/", followed by a set of path elements that define the path. e.g. "/a/b/c" is an absolute path. while "a/b/c" is a relative path. The paths needs to be normalized, paths with "." and ".." in the elements are not (yet) supported.

This implementation attempts to be similar with 'file://' implementation for Unix (e.g. UnixPath). However, as WebDAV is after all different from a normal (unix) filesystem, there are various differences.

toAbsolutePath()

For toAbsolutePath(), for paths that are absolute paths, it simply return itself.

However, for relative paths, the paths are altered. In 'file://' (unix) implementation, Path.toAbsolutePath() apparently resolves relative path against the current working directory.

However, with web and WebDAV url it is difficult to define 'current working directory'. To make this implementation more usable, WebdavPathtoAbsolutePath() use a 'current working path' instance variable to resolve relative paths into absolute paths. If 'current working path' is not found (null), it is resolved against the default root path "/".

The prefix absolute path are preserved when relative paths are created with several methods.

  • WebdavPath.relativize(Path path)
  • WebdavPath.getFileName()
  • WebdavPath.getName(int index)

To get predictable behavior e.g. that it would be resolved against "current work path" it is necessary that the relative path is derived by calling the above methods against base objects that are absolute paths. e.g.

'/a/b'.relativize('/a/b/c') = 'c', '/a/b' preserved as "current work path", 'c'.toAbsolutePath() returns '/a/b/c'
'/a/b/c'.getFileName() = 'c', '/a/b' preserved as "current work path", 'c'.toAbsolutePath() returns '/a/b/c'
'/a/b/c'.getName(1) = 'b', '/a' preserved as "current work path", 'b'.toAbsolutePath() returns '/a/b'

However, it is not saved in the cases where relative paths are used as base path

'a/b'.relativize('a/b/c') = 'c', current work path is not saved as 'a/b' is a relative path

hence, 'c'.toAbsolutePath() returns '/c'

the current work path can be retrieved and set using the methods

  • WebdavPath.getCurrentWorkPath()
  • WebdavPath.setCurrentWorkPath(WebdavPath path)

However, the currentworkpath needs to be set before calling toAbsolutePath() and the currentworkpath must not be null to have it resolved that way deterministically

Normalized paths only

Current implementation of WebdavPath requires that paths are normalized. i.e. that they do not contain ".." or "." that needs to be resolved.
and they contain distinct and unique path elements e.g. "/a/b/c". If they do contain ".." or ".", these are treated as literals
See Also:
  • Field Details

    • PATH_SEP

      final String PATH_SEP
  • Constructor Details

  • Method Details

    • toString

      public String toString()
      Returns path as string
      Specified by:
      toString in interface Path
      Overrides:
      toString in class Object
      Returns:
      string
    • getFileSystem

      public FileSystem getFileSystem()
      Returns the file system. Would be an instance of WebdavFileSystem}
      Specified by:
      getFileSystem in interface Path
      Returns:
      filesystem
    • isAbsolute

      public boolean isAbsolute()
      Checks if is absolute.
      Specified by:
      isAbsolute in interface Path
      Returns:
      true, if is absolute
    • toAbsolutePath

      public Path toAbsolutePath()
      To absolute path. If this path is an absolute path, this method simply returns this.

      If this path is a relative path, this method attempts to return this path resolved against the "current work path".

      If however, if "current work path" is not found it resolves it against the default root path "/".

      The "current work path" is formed and preserved when the following methods are called:

      • WebdavPath.relativize(Path path)
      • WebdavPath.getFileName()
      • WebdavPath.getName(int index)

      However, with web and WebDAV url it is difficult to define 'current working directory'. To make this implementation more usable, WebdavPathtoAbsolutePath() use a 'current working path' instance variable to resolve relative paths into absolute paths. If 'current working path' is not found (null), it is resolved against the default root path "/".

      To get predictable behavior e.g. that it would be resolved against "current work path" it is necessary that the relative path is derived by calling the above methods against base objects that are absolute paths. e.g.

      '/a/b'.relativize('/a/b/c') = 'c', '/a/b' preserved as "current work path", 'c'.toAbsolutePath() returns '/a/b/c'
      '/a/b/c'.getFileName() = 'c', '/a/b' preserved as "current work path", 'c'.toAbsolutePath() returns '/a/b/c'
      '/a/b/c'.getName(1) = 'b', '/a' preserved as "current work path", 'b'.toAbsolutePath() returns '/a/b'

      However, it is not saved in the cases where relative paths are used as the base

      'a/b'.relativize('a/b/c') = 'c', current work path is not saved as 'a/b/c' is a relative path

      hence, 'c'.toAbsolutePath() returns '/c'

      The current work path can be retrieved and set using the methods

      • WebdavPath.getCurrentWorkPath()
      • WebdavPath.setCurrentWorkPath(WebdavPath currentworkpath)

      However, the currentworkpath needs to be set before calling toAbsolutePath() and the currentworkpath must not be null to have it resolved that way deterministically

      Specified by:
      toAbsolutePath in interface Path
      See Also:
    • getFileName

      public Path getFileName()
      Gets the file name of the leaf in the path

      If this path is the empty root path "/" it returns null.
      If this path is ann empty relative path it returns an empty string ""
      Returns the filename as a path in normal cases

      If this path is an absolute path, this method preserves the parent in "current work path" in the returned filename path.

      Specified by:
      getFileName in interface Path
      Returns:
      file name as a Path
      null for root path
      blank for empty relative path
    • getName

      public Path getName(int index)
      Returns the name at index in the path. If this path is an absolute path, this method preserves the parent in "current work path" in the returned filename path.
      Specified by:
      getName in interface Path
      Parameters:
      index - the index
      Returns:
      name at index
      Throws:
      IllegalArgumentException - if this is an empty root path and index = 0
      IllegalArgumentException - if index is out of bounds
    • getNameCount

      public int getNameCount()
      Gets the name count.
      Specified by:
      getNameCount in interface Path
      Returns:
      the name count
    • iterator

      public Iterator<Path> iterator()
      return the name paths in an iterator

      from the root to leaf (left to right)

      Specified by:
      iterator in interface Iterable<Path>
      Specified by:
      iterator in interface Path
      Returns:
      iterator of name paths
    • getParent

      public Path getParent()
      Gets the parent. Returns the parent path.

      Returns null if this path does not have a parent.

      note that parent of "/" is null.

      Specified by:
      getParent in interface Path
      Returns:
      parent path
    • getRoot

      public Path getRoot()
      Gets the root path. Returns the root path, note that this simply returns "/".

      It returns null for relative paths

      Specified by:
      getRoot in interface Path
      Returns:
      rootpath
    • compareTo

      public int compareTo(Path other)
      Compare to the other path. Paths with number of elements less than this is deem less and vice versa.

      Otherwise it compares the elements each from root to leaf as a string

      The difference from String.compareTo() is returned for the different member

      Specified by:
      compareTo in interface Comparable<Path>
      Specified by:
      compareTo in interface Path
      Parameters:
      other - the other path
      Returns:
      int = 0 if the other is equal
      < 0 if other is less than this
      > 0 if other is greater than this
    • equals

      public boolean equals(Object other)
      Equals this

      This and other both must be relative or absolute to be equal.
      Paths with number of elements different from this is deemed not equal.
      Otherwise it compares the elements each from root to leaf as a string.
      Returns true only if every element match

      Specified by:
      equals in interface Path
      Overrides:
      equals in class Object
      Parameters:
      other - the other path
      Returns:
      true, if successful
    • startsWith

      public boolean startsWith(Path other)
      Starts with. compare elements from root to leaf, returns true if they match both this and other needs to be the same host both this and other needs to be relative or absolute
      Specified by:
      startsWith in interface Path
      Parameters:
      other - the other needs to be an instance of WebdavPath
      Returns:
      true, if successful
    • startsWith

      public boolean startsWith(String other)
      Starts with. converts string other to WebdavPath and call startsWith(Path other)
      Specified by:
      startsWith in interface Path
      Parameters:
      other - the other
      Returns:
      true, if successful
    • endsWith

      public boolean endsWith(Path other)
      Ends with. compare elements alighed to leaf, returns true if they match refer to Path.endsWith(Path) both this and other needs to be the same host other needs to be relative path
      Specified by:
      endsWith in interface Path
      Parameters:
      other - the other
      Returns:
      true, if successful
    • endsWith

      public boolean endsWith(String other)
      Ends with. converts string other to WebdavPath and call endssWith(Path other)
      Specified by:
      endsWith in interface Path
      Parameters:
      other - the other
      Returns:
      true, if successful
    • normalize

      public Path normalize()
      Normalize.
      Specified by:
      normalize in interface Path
      Returns:
      the path
      See Also:
    • register

      public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) throws IOException
      Register not supported
      Specified by:
      register in interface Path
      Specified by:
      register in interface Watchable
      Parameters:
      watcher - the watcher
      events - the events
      Returns:
      the watch key
      Throws:
      IOException - Signals that an I/O exception has occurred.
      UnsupportedOperationException - not supported.
    • register

      public WatchKey register(WatchService watcher, WatchEvent.Kind<?>[] events, WatchEvent.Modifier... arg2) throws IOException
      Register not supported
      Specified by:
      register in interface Path
      Specified by:
      register in interface Watchable
      Parameters:
      watcher - the watcher
      events - the events
      arg2 - the arg 2
      Returns:
      the watch key
      Throws:
      IOException - Signals that an I/O exception has occurred.
      UnsupportedOperationException - not supported
    • relativize

      public Path relativize(Path other)
      Constructs a relative path between this path and a given path.

      relativize() is the inverse of resolve().

      This method attempts to construct a relative path that is less this path as preceeding path

      e.g. this "/a/b" , other "/a/b/c/d" - '/a/b'.relativize('/a/b/c/d') returns "c/d"

      This and other path needs to be both relative or both absolute.

      If this path is an absolute path, the returned relative path would contain a "current work path", which is the leading common part of the absolute path dropped to construct the relative path returned. Normally, that "current work path" is this path.

      The current implementation requires that both paths are normalized.
      i.e. that they do not contain ".." or "." that needs to be resolved.
      and they contain distinct and unique path elements e.g. "/a/b/c".
      If they do contain ".." or ".", these are treated as literals

      Specified by:
      relativize in interface Path
      Parameters:
      other - the other path
      Returns:
      path relativized path
      Throws:
      IllegalArgumentException - if the other path is not a WebdavPath
      IllegalArgumentException - if one path is absolute while the other is not
      IllegalArgumentException - if the other path is shorter than this path
      IllegalArgumentException - if the other path does not start with this path
      See Also:
    • resolve

      public Path resolve(Path other)
      Resolve the given path against this path. In the simplest case, this method joins the given path to this path and returns a resulting path that ends with the given path.
      Normally, the other path needs to be a relative path

      e.g. '/a/b'.resolve('c/d') = '/a/b/c/d'

      If the other path is an absolute path, returns other.
      If other is an empty path, returns this path.

      Otherwise this method considers this path to be a directory and resolves the given path against this path.

      Specified by:
      resolve in interface Path
      Parameters:
      other - The other path to resolved against this
      Returns:
      If the other parameter is an absolute path, returns other.
      If other is an empty path, returns this path.
      Otherwise this method considers this path to be a directory and resolves the given path against this path.
      See Also:
    • resolve

      public Path resolve(String other)
      Resolve the given path (string) against this path. converts to WebdavPath and calls resolve(other)
      Specified by:
      resolve in interface Path
      Parameters:
      other - the other
      Returns:
      the path
    • resolveSibling

      public Path resolveSibling(Path other)
      Resolve sibling. In normal case, resolves/returns the given path against this path's parent path.

      If the other path is absolute, returns the other path.
      If there is no parent, returns the other path
      If the other is an empty (relative) path, returns this path
      If this path do not have a parent, returns an empty path ""

      Specified by:
      resolveSibling in interface Path
      Parameters:
      other - the other path
      Returns:
      path resolved path
    • resolveSibling

      public Path resolveSibling(String other)
      Resolve sibling. Converts to WebdavPath and calls resolveSibling(other)
      Specified by:
      resolveSibling in interface Path
      Parameters:
      other - the other
      Returns:
      the path
    • subpath

      public Path subpath(int beginIndex, int endIndex)
      Returns a relative Path that is a subsequence of the name elements of this path.
      Specified by:
      subpath in interface Path
      Parameters:
      beginIndex - begin index
      endIndex - end index
      Returns:
      a relative path with elements from elements[beingIndex] to elements[endIndex-1] elements[endIndex-1] is included.
      Throws:
      IllegalArgumentException - if this path is empty.
      IllegalArgumentException if index is out of bounds
    • toFile

      public File toFile()
      To file unsupported
      Specified by:
      toFile in interface Path
      Returns:
      the file
      Throws:
      UnsupportedOperationException - not supported
    • toRealPath

      public Path toRealPath(LinkOption... options) throws IOException
      To real path unsupported
      Specified by:
      toRealPath in interface Path
      Parameters:
      options - the options
      Returns:
      the path
      Throws:
      UnsupportedOperationException - not supported
      IOException
    • toUri

      public URI toUri()
      To uri. returns URI represented by this path
      Specified by:
      toUri in interface Path
      Returns:
      uri URI represented by this path
    • getElements

      public ArrayList<String> getElements()
      Gets the internal elements of this path

      Specific to WebdavPath, not in Path api

      not recommended to use this, use those documented in Path api instead

      Returns:
      the elements
    • setElements

      public void setElements(ArrayList<String> elements)
      Sets the internal elements of this path

      Specific to WebdavPath, not in Path api

      not recommended to use this, use those documented in Path api instead

      Parameters:
      elements - the new elements
    • getCurrentWorkPath

      public WebdavPath getCurrentWorkPath()
      Gets the current work path.

      Specific to WebdavPath, not in Path api

      Returns:
      the current work path
      See Also:
    • setCurrentWorkPath

      public void setCurrentWorkPath(WebdavPath currentWorkPath)
      Sets the current work path.

      Makes it an absolute path even if it isn't.

      Specific to WebdavPath, not in Path api

      Parameters:
      currentWorkPath - the new current work path
      See Also:
    • setIsabsolute

      public void setIsabsolute(boolean isabsolute)
      Sets isabsolute. Specific to WebdavPath, not in Path api

      not recommended to use this, use those documented in Path api instead

      Parameters:
      isabsolute - the new isabsolute *