Package com.adito.vfs

Source Code of com.adito.vfs.FileObjectVFSResource

package com.adito.vfs;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileType;
import org.apache.commons.vfs.NameScope;

import com.adito.core.CoreServlet;
import com.adito.policyframework.LaunchSession;
import com.adito.security.PasswordCredentials;
import com.adito.vfs.webdav.DAVAuthenticationRequiredException;
import com.adito.vfs.webdav.DAVException;
import com.adito.vfs.webdav.DAVListener;
import com.adito.vfs.webdav.DAVMultiStatus;
import com.adito.vfs.webdav.DAVStatus;
import com.adito.vfs.webdav.DAVUtilities;
import com.adito.vfs.webdav.methods.GET;

/**
* <p>
* This class implements {@link com.adito.vfs.VFSResource} and and
* provides axcess to the file system.
*/
public class FileObjectVFSResource implements VFSResource {
  final static Log log = LogFactory.getLog(VFSResource.class);

  //  Private instance variables
 
  private VFSMount mount = null;
  private FileObject file = null;
 
  //  Protected instance variables
  protected LaunchSession launchSession;
  protected String relativePath;
  protected VFSResource parent;
  protected VFSRepository repository;
  protected PasswordCredentials requestCredentials;

  /**
   * @param launchSession launch session
   * @param mount The Mount acociated with this resource.
   * @param parent parent
   * @param relativePath path relative to root of mount
   * @param repository repository
   * @param requestCredentials request credentials
   * @throws IOException on any error
   */
  public FileObjectVFSResource(LaunchSession launchSession, VFSMount mount, VFSResource parent, String relativePath,
                  VFSRepository repository, PasswordCredentials requestCredentials)
    throws IOException {
    if (mount == null)
      throw new NullPointerException("Null mount");
    this.launchSession = launchSession;
    this.mount = mount;
    this.parent = parent;
    this.relativePath = relativePath;
    this.repository = repository;
    this.requestCredentials = requestCredentials;

    // get the parent now if possible
    if (this.parent == null) {
      if (this.relativePath != null) {
        String parentPath = DAVUtilities.getParentPath(relativePath);
        if (parentPath == null) {
        } else {
          this.parent = mount.getResource(parentPath, requestCredentials /*, transaction */);
        }
      }
    }
  }
   
  /*
   * (non-Javadoc)
   *
   * @see java.lang.Object#hashCode()
   */
  public int hashCode() {
    try {
      return getFile().hashCode();
    } catch (IOException e) {
      return hashCode();
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#isMount()
   */
  public boolean isMount() {
    return false;
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getWebFolderPath()
   */
  public String getWebFolderPath() {
    return "/fs/" + mount.getMountString()
      + (mount.getMountString().endsWith("/") || relativePath.startsWith("/") ? "" : "/")
      + relativePath;
  }


  /* (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  public boolean equals(Object object) {
    if (object == null)
      return (false);
    if (object instanceof FileObjectVFSResource) {
      FileObjectVFSResource resource = (FileObjectVFSResource) object;
      try {
        boolean u = getFile().equals(resource.getFile());
        boolean r = this.getMount() == resource.mount;
        return (u && r);
      } catch (IOException ioe) {
        return false;
      }
    } else {
      return (false);
    }
  }

  /* (non-Javadoc)
   * @see java.lang.Comparable#compareTo(java.lang.Object)
   */
  public int compareTo(Object object) {
    FileObjectVFSResource resource = (FileObjectVFSResource) object;
    try {
      return (getFile().getURL().toExternalForm().compareTo(resource.getFile().getURL().toExternalForm()));
    } catch (IOException ioe) {
      log.warn("Failed to compare two files.", ioe);
      return -999;
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#verifyAccess()
   */
  public void verifyAccess() throws Exception, DAVAuthenticationRequiredException {
    this.getFile().exists();
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#isNull()
   */
  public boolean isNull() throws IOException {
    return !getFile().exists();
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#isCollection()
   */
  public boolean isCollection() throws IOException {
    if (this.isNull())
      return false;
    try {
      FileObject temp = getFile();
      FileType type = temp.getType();
      if (type == null) {
        type = temp.getName().getType();
      }
      return (type.equals(FileType.FOLDER));
    } catch (IOException e) {
      if (log.isDebugEnabled()) {
        log.warn("Failed to test if resource is a collection.", e);
      } else {
        log.warn("Failed to test if resource is a collection : " + e.getMessage());
      }
      return false;
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#isResource()
   */
  public boolean isResource() throws IOException {
    if (this.isNull()) {
      return false;
    } else {
      return (!this.isCollection());
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getFile()
   */
  public FileObject getFile() throws IOException {
    if (file == null) {
            FileObject root = getFileObject("");
            String stripLeadingSlash = DAVUtilities.stripLeadingSlash(getRelativePath());
      file = root.resolveFile(stripLeadingSlash, NameScope.DESCENDENT_OR_SELF);
      if (file == null) {
        throw new IOException("Could not create file object.");
      }
    }
    return file;
  }
   
    private FileObject getFileObject(String relativePath) throws DAVAuthenticationRequiredException, IOException {
        FileObject fileObject = mount.createAuthenticatedVFSFileObject(relativePath, requestCredentials);
        return fileObject;
    }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getMount()
   */
  public VFSMount getMount() {
    return this.mount;
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getDisplayName()
   */
  public String getDisplayName() {
    try {
      String name = getFile().getName().getBaseName();
      if (this.isCollection())
        return (name + "/");
      return name;
    } catch (IOException ioe) {
      return getBasename();
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getBasename()
   */
  public String getBasename() {
    String p = relativePath;
    int idx = p.length() < 2 ? -1 : (p.lastIndexOf('/', p.endsWith("/") ? p.length() - 2 : p.length() - 1));
    if (idx != 1) {
      p = p.substring(idx + 1);
    }
    return p;
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getRelativePath()
   */
  public String getRelativePath() {
    return relativePath;
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getRelativeURI()
   */
  public URI getRelativeURI() {
    try {
      return new URI(DAVUtilities.encodePath(getRelativePath()));
    } catch (Exception e) {
      log.warn("Failed to get the relativeURI for the resource", e);
      e.printStackTrace();
      return null;
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getParent()
   */
  public VFSResource getParent() {
    try {
      if (parent == null) {
        String parentPath = DAVUtilities.stripLeadingSlash(DAVUtilities.getParentPath(getFullPath()));
        if (parentPath == null || parentPath.equals("/")) {
          return null;
        } else {
          return repository.getResource(getLaunchSession(), parentPath, requestCredentials/*
                                                   * ,
                                                   * transaction
                                                   */);
        }
      }
    } catch (Throwable throwable) {
      throwable.printStackTrace();
    }
    return parent;
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getChildren()
   */
  public Iterator<VFSResource> getChildren() throws IOException {
    if (!this.isCollection())
      return null;

    // this forces VFS to re cashe.
    this.getFile().close();

    FileObject children[] = this.getFile().getChildren();
    List<VFSResource> resources = new ArrayList<VFSResource>(children.length);

    for (int x = 0; x < children.length; x++) {
      String fileName = children[x].getName().getBaseName();
      if (fileName.startsWith(PREFIX) && fileName.endsWith(SUFFIX))
        continue;
      if (!isCollection() && !isResource())
        continue;
      try {
        /*
         * TODO BPS - I think we have a problem here.
         *
         * When getting children that require further authentication we
         * get a {@link DAVAuthenticationRequiredException} exception.
         * We do not want to throw an exception at this point but we do
         * want add the child. Its only when children of the child are
         * accessed that we want to throw the exception. Because
         * DAVMount.getResource() is the one that throws this, a
         * resource object can never be created.
         *
         * This will happen for example when listomg /fs/[store] and a
         * network place that requires auth. is hit.
         */

        VFSResource r = getMount().getResource(DAVUtilities.concatenatePaths(relativePath, fileName), requestCredentials/*
                                                                 * ,
                                                                 * transaction
                                                                 */);
        resources.add(r);
      } catch (Exception e) {
        /*
         * NOTE - BPS - We cannot log this exception as it may have user
         * information in the URI.
         */
        // log.warn("Failed to get resource.", e);
      }
    }
    return resources.iterator();
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getContentType()
   */
  public String getContentType() throws IOException {
    if (this.isNull())
      return null;
    if (this.isCollection())
      return GET.COLLECTION_MIME_TYPE;
    String mime = CoreServlet.getServlet().getServletContext().getMimeType(this.getDisplayName());
    return mime == null ? "application/octet-stream" : mime;
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getContentLength()
   */
  public Long getContentLength() throws IOException {
    if (this.isNull() || this.isCollection())
      return null;
    try {
      return new Long(getFile().getContent().getSize());
    } catch (IOException e) {
      log.error("Failed to get content length.", e);
      return null;
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getLastModified()
   */
  public Date getLastModified() throws IOException {
    if (this.isNull())
      return null;
    try {
      return new Date(getFile().getContent().getLastModifiedTime());
    } catch (IOException e) {
      log.error("Failed to get last modified date of resource.", e);
      return null;
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getEntityTag()
   */
  public String getEntityTag() throws IOException {
    if (this.isNull())
      return null;

    String path = this.getRelativePath();
    return DAVUtilities.getETAG(path, this.getLastModified());
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#delete()
   */
  public void delete() throws DAVMultiStatus, IOException {
    if (this.isNull())
      throw new DAVException(404, "Not found", this);

    if (getMount().isReadOnly()) {
      throw new DAVException(DAVStatus.SC_FORBIDDEN, "You cannot delete this file because the the mount is readonly!");
    }

    if (this.isResource()) {
      try {
        if (!getFile().delete()) {
          throw new DAVException(403, "Can't delete resource '" + getRelativePath() + "'", this);
        } else {
          this.getMount().getStore().getRepository().notify(this, DAVListener.RESOURCE_REMOVED);
        }
      } catch (IOException e) {
        throw new DAVException(403, "Can't delete resource. " + VfsUtils.maskSensitiveArguments(e.getMessage()), this);
      }
    } else if (this.isMount()) {
      throw new DAVException(403, "Can't delete resource '" + getRelativePath()
        + "' as it is the root for the mount point "
        + this.getMount().getMountString(), this);
    } else if (this.isCollection()) {

      DAVMultiStatus multistatus = new DAVMultiStatus();

      Iterator children = this.getChildren();
      while (children.hasNext())
        try {
          ((VFSResource) children.next()).delete();
        } catch (DAVException exception) {
          multistatus.merge(exception);
        }

      if (multistatus.size() > 0)
        throw multistatus;
      try {
        if (!getFile().delete()) {
          throw new DAVException(403, "Can't delete collection", this);
        } else {
          this.getMount().getStore().getRepository().notify(this, DAVListener.COLLECTION_REMOVED);
        }
      } catch (IOException e) {
        log.error("Failed to delete resource.", e);
        throw new DAVException(403, "Can't delete collection " + getRelativePath() + ". " + e.getMessage(), this);
      }
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#copy(com.adito.vfs.VFSResource, boolean, boolean)
   */
  public void copy(VFSResource dest, boolean overwrite, boolean recursive) throws DAVMultiStatus, IOException {

    /*
     * NOTE: Since the COPY operation relies on other operation defined in
     * this class (and in DAVOutputStream for resources) rather than on
     * files temselves, notifications are sent elsewhere, not here.
     */

    if (this.isNull())
      throw new DAVException(404, "Not found", this);

    /* Check if the destination exists and delete if possible */
    if (!dest.isNull()) {
      if (!overwrite) {
        String msg = "Not overwriting existing destination";
        throw new DAVException(412, msg, dest);
      }
      dest.delete();
    }

    /* Copy a single resource (destination is null as we deleted it) */
    if (this.isResource()) {
      VFSInputStream in = this.getInputStream();
      VFSOutputStream out = dest.getOutputStream();
      byte buffer[] = new byte[4096];
      int k = -1;
      while ((k = in.read(buffer)) != -1)
        out.write(buffer, 0, k);
      out.close();
    }

    /* Copy the collection and all nested members */
    if (this.isCollection()) {
      dest.makeCollection();
      if (!recursive)
        return;

      DAVMultiStatus multistatus = new DAVMultiStatus();
      Iterator children = this.getChildren();
      while (children.hasNext())
        try {
          FileObjectVFSResource childResource = (FileObjectVFSResource) children.next();
          try {
            FileObject child = ((FileObjectVFSResource) dest).getFile().resolveFile(childResource.getFile()
                    .getName()
                    .getBaseName());
            FileObjectVFSResource target = new FileObjectVFSResource(getLaunchSession(),
                    this.getMount(),
                    this, /* transaction, */
                    this.getMount().getMountString(),
                    repository,
                    requestCredentials);
            childResource.copy(target, overwrite, recursive);
          } catch (IOException e) {
            throw new DAVException(403, "Could not resolve child.", e);
          }
        } catch (DAVException exception) {
          multistatus.merge(exception);
        }
      if (multistatus.size() > 0)
        throw multistatus;
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#move(com.adito.vfs.VFSResource, boolean)
   */
  public void move(VFSResource dest, boolean overwrite) throws DAVMultiStatus, IOException {

    /*
     * NOTE: Since the COPY operation relies on other operation defined in
     * this class (and in DAVOutputStream for resources) rather than on
     * files temselves, notifications are sent elsewhere, not here.
     */

    if (this.isNull())
      throw new DAVException(404, "Not found", this);

    /* Check read only */
    if (getMount().isReadOnly()) {
      throw new DAVException(DAVStatus.SC_FORBIDDEN, "You cannot move this file because the the mount is readonly!");
    }

    /* Check if the destination exists and delete if possible */
    if (!dest.isNull()) {
      if (!overwrite) {
        String msg = "Not overwriting existing destination";
        throw new DAVException(412, msg, dest);
      }
      dest.delete();
    }

    /* If the file system supports then move then just do it */
    if (getFile().canRenameTo(dest.getFile())) {
      getFile().moveTo(dest.getFile());
      return;
    }

    /* Otherwise copy */
    copy(dest, overwrite, true);
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#makeCollection()
   */
  public void makeCollection() throws IOException {
    VFSResource parent = this.getParent();
    if (!this.isNull())
      throw new DAVException(405, "Resource exists", this);
    if (parent.isNull())
      throw new DAVException(409, "Parent does not not exist", this);
    if (!parent.isCollection())
      throw new DAVException(403, "Parent not a collection", this);

    /* Check read only */
    if (getMount().isReadOnly()) {
      throw new DAVException(DAVStatus.SC_FORBIDDEN, "You cannot create a folder here because the the mount is readonly!");
    }

    try {
      getFile().createFolder();
      this.getMount().getStore().getRepository().notify(this, DAVListener.COLLECTION_CREATED);
    } catch (IOException e) {
      throw new DAVException(507, "Can't create collection", this);
    }
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getInputStream()
   */
  public VFSInputStream getInputStream() throws IOException {
    if (this.isNull())
      throw new DAVException(404, "Not found", this);
    if (this.isCollection())
      throw new DAVException(403, "Resource is collection", this);
    return new VFSInputStream(this);
  }

  /* (non-Javadoc)
   * @see com.adito.vfs.VFSResource#getOutputStream()
   */
  public VFSOutputStream getOutputStream() throws IOException {
    if (this.isCollection())
      throw new DAVException(409, "Can't write a collection", this);

    if (getMount().isReadOnly()) {
      throw new DAVException(DAVStatus.SC_FORBIDDEN, "You cannot create a write here because the the mount is readonly!");
    }
    return new VFSOutputStream(this);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.vfs.VFSResource#getFullURI()
   */
  public URI getFullURI() {
    VFSMount mount = getMount();
    URI uri = URI.create(mount == null ? ("/" + getRelativeURI())
      : ("/" + DAVUtilities.stripTrailingSlash(DAVUtilities.encodePath(mount.getMountString(), true)) + "/" + DAVUtilities.stripLeadingSlash(DAVUtilities.encodePath(getRelativePath(),
        true))));
    return uri;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.vfs.VFSResource#getFullPath()
   */
  public String getFullPath() {
    VFSMount mount = getMount();
    return mount == null ? ("/" + getRelativeURI()) : ("/" + mount.getMountString()
      + (mount.getMountString().endsWith("/") || getRelativePath().startsWith("/") ? "" : "/") + getRelativePath());
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.vfs.VFSResource#getLaunchSession()
   */
  public LaunchSession getLaunchSession() {
    return launchSession;
  }

  public boolean isBrowsable() throws IOException {
    return true;
  }
}
TOP

Related Classes of com.adito.vfs.FileObjectVFSResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.