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

com.caucho.vfs.FilesystemPath Maven / Gradle / Ivy

There is a newer version: 4.0.66
Show newest version
/*
 * Copyright (c) 1998-2012 Caucho Technology -- all rights reserved
 *
 * This file is part of Resin(R) Open Source
 *
 * Each copy or derived work must preserve the copyright notice and this
 * notice unmodified.
 *
 * Resin Open Source is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Resin Open Source 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, or any warranty
 * of NON-INFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Resin Open Source; if not, write to the
 *
 *   Free Software Foundation, Inc.
 *   59 Temple Place, Suite 330
 *   Boston, MA 02111-1307  USA
 *
 * @author Scott Ferguson
 */

package com.caucho.vfs;

import com.caucho.util.CharBuffer;

import java.util.Map;

/**
 * Abstract FilesystemPath, the parent of hierarchical Paths like
 * FilePath or HttpPath.
 */
abstract public class FilesystemPath extends Path {
  protected FilesystemPath _root;
  protected BindPath _bindRoot;
  protected String _pathname;
  protected String _userPath;

  /**
   * Create a new filesystemPath
   *
   * @param root Root of url space
   * @param userPath the user's path
   * @param pathname Canonical path
   */
  protected FilesystemPath(FilesystemPath root,
                           String userPath,
                           String pathname)
  {
    super(root);

    init(root, userPath, pathname);
  }

  protected void init(FilesystemPath root,
                      String userPath,
                      String pathname)
  {
    if (pathname == null)
      throw new NullPointerException();

    _userPath = userPath;
    _pathname = pathname;

    if (root != null) {
      _root = root;
      _bindRoot = root._bindRoot;
    }
  }

  /**
   * Return the parent Path
   */
  @Override
  public Path getParent()
  {
    if (_pathname.length() <= 1)
      return lookup("/");

    int length = _pathname.length();
    int lastSlash = _pathname.lastIndexOf('/');

    if (lastSlash < 1)
      return lookup("/");

    if (lastSlash == length - 1) {
      lastSlash = _pathname.lastIndexOf('/', length - 2);
      if (lastSlash < 1)
        return lookup("/");
    }

    return lookup(_pathname.substring(0, lastSlash));
  }

  /**
   * schemeWalk is called by Path for a scheme lookup like file:/tmp/foo
   *
   * @param userPath the user's lookup() path
   * @param attributes the user's attributes
   * @param filePath the actual lookup() path
   * @param offset offset into filePath
   */
  @Override
  public Path schemeWalk(String userPath,
                         Map attributes,
                         String filePath,
                         int offset)
  {
    String canonicalPath;

    if (filePath.length() > offset
        && (filePath.charAt(offset) == '/'
            || filePath.charAt(offset) == _separatorChar))
      canonicalPath = normalizePath("/", filePath, offset, _separatorChar);
    else
      canonicalPath = normalizePath(_pathname, filePath, offset,
                                    _separatorChar);

    return fsWalk(userPath, attributes, canonicalPath);
  }

  /**
   * Lookup a path relative to the current filesystem's root.
   * Filesystems will specialize fsWalk.
   *
   * @param userPath the exact string passed by the user's lookup()
   * @param newAttributes the user's new attributes
   * @param newPath the normalized real path
   *
   * @return the matching path
   */
  abstract public Path fsWalk(String userPath,
                              Map newAttributes,
                              String newPath);

  /**
   * wrapper for the real normalize path routine to use CharBuffer.
   *
   * @param oldPath The parent Path's path
   * @param newPath The user's new path
   * @param offset Offset into the user path
   *
   * @return the normalized path
   */
  static protected String normalizePath(String oldPath,
                                        String newPath,
                                        int offset,
                                        char separatorChar)
  {
    CharBuffer cb = new CharBuffer();
    normalizePath(cb, oldPath, newPath, offset, separatorChar);
    return cb.toString();
  }

  /**
   * Normalizes a filesystemPath path.
   *
   * 
    *
  • foo//bar -> foo/bar *
  • foo/./bar -> foo/bar *
  • foo/../bar -> bar *
  • /../bar -> /bar *
* * @param cb charBuffer holding the normalized result * @param oldPath the parent path * @param newPath the relative path * @param offset where in the child path to start */ static protected void normalizePath(CharBuffer cb, String oldPath, String newPath, int offset, char separatorChar) { cb.clear(); cb.append(oldPath); if (cb.length() == 0 || cb.getLastChar() != '/') cb.append('/'); int length = newPath.length(); int i = offset; while (i < length) { char ch = newPath.charAt(i); char ch2; switch (ch) { default: if (ch != separatorChar) { cb.append(ch); i++; break; } // the separator character falls through to be treated as '/' case '/': // "//" -> "/" if (cb.getLastChar() != '/') cb.append('/'); i++; break; case '.': if (cb.getLastChar() != '/') { cb.append('.'); i++; break; } // "/." -> "" if (i + 1 >= length) { i += 2; break; } switch (newPath.charAt(i + 1)) { default: if (newPath.charAt(i + 1) != separatorChar) { cb.append('.'); i++; break; } // the separator falls through to be treated as '/' // "/./" -> "/" case '/': i += 2; break; // "foo/.." -> "" case '.': if ((i + 2 >= length || (ch2 = newPath.charAt(i + 2)) == '/' || ch2 == separatorChar) && cb.getLastChar() == '/') { int segment = cb.lastIndexOf('/', cb.length() - 2); if (segment == -1) { cb.clear(); cb.append('/'); } else cb.setLength(segment + 1); i += 3; } else { cb.append('.'); i++; } break; } } } // strip trailing "/" /* if (cb.length() > 1 && cb.getLastChar() == '/') cb.setLength(cb.length() - 1); */ } /** * Returns the root. */ public FilesystemPath getRoot() { return _root; } /** * Returns the path portion of the URL. */ public String getPath() { return _pathname; } /** * Return's the application's name for the path, e.g. for * a relative path. */ public String getUserPath() { return _userPath != null ? _userPath : _pathname; } public void setUserPath(String path) { _userPath = path; } /** * For chrooted filesystems return the real system path. */ public String getFullPath() { if (_root == this || _root == null) return getPath(); String rootPath = _root.getFullPath(); String path = getPath(); if (rootPath.length() <= 1) return path; else if (path.length() <= 1) return rootPath; else return rootPath + path; } public String getTail() { String path = getPath(); int length = path.length(); int p = path.lastIndexOf('/'); if (p == -1) return ""; else if (p < length - 1) return path.substring(p + 1); else { p = path.lastIndexOf('/', length - 2); if (p < 0) return ""; return path.substring(p + 1, length - 1); } } /** * Essentially chroot */ public Path createRoot(SchemeMap schemeMap) { FilesystemPath restriction = (FilesystemPath) copy(); restriction._schemeMap = schemeMap; restriction._root = this; restriction._pathname = "/"; restriction._userPath = "/"; return restriction; } public void bind(Path context) { if (_bindRoot == null) _bindRoot = _root._bindRoot; if (_bindRoot == null) { _bindRoot = new BindPath(_root); _root._bindRoot = _bindRoot; } _bindRoot.bind(getPath(), context); } public int hashCode() { return getURL().hashCode(); } public boolean equals(Object b) { if (this == b) return true; else if (b == null || ! getClass().equals(b.getClass())) return false; Path bPath = (Path) b; return getURL().equals(bPath.getURL()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy