Package net.sourceforge.pebble.domain

Source Code of net.sourceforge.pebble.domain.FileManager

/*
* Copyright (c) 2003-2011, Simon Brown
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*   - Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*
*   - Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in
*     the documentation and/or other materials provided with the
*     distribution.
*
*   - Neither the name of Pebble nor the names of its contributors may
*     be used to endorse or promote products derived from this software
*     without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.sourceforge.pebble.domain;

import net.sourceforge.pebble.comparator.FileMetaDataComparator;
import net.sourceforge.pebble.util.FileUtils;
import net.sourceforge.pebble.PebbleContext;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.*;

/**
* Encapsulates methods for managing and manipulating files under the
* following locations:
* <ul>
* <li>${blog.dir}/images</li>
* <li>${blog.dir}/files</li>
* <li>${editableTheme}</li>
* </ul>
*
* @author Simon Brown
*/
public class FileManager {

  /** the type of files being managed */
  private String type;

  /** the root directory for the particular file type */
  private File root;

  /**
   * Creates a new instande for the specified blog and type.
   *
   * @param blog    the blog that this manager refers to
   * @param type    the type of files to manage
   */
  public FileManager(Blog blog, String type) {
    this.type = type;

    // which directory are we looking at?
    if (type.equals(FileMetaData.BLOG_IMAGE)) {
      this.root = new File(blog.getImagesDirectory());
    } else if (type.equals(FileMetaData.THEME_FILE)) {
      this.root = blog.getEditableTheme().getPathToLiveTheme();
    } else if (type.equals(FileMetaData.BLOG_DATA)) {
      this.root = new File(blog.getRoot());
    } else {
      this.root = new File(blog.getFilesDirectory());
    }
  }

  /**
   * Gets the root directory that this class is managing.
   *
   * @return  a File instance
   */
  public File getRootDirectory() {
    return this.root;
  }

  /**
   * Gets meta data about a specific file or directory.
   *
   * @param path    the path of the file/directory
   * @return        a FileMetaData object
   */
  public FileMetaData getFileMetaData(String path) {
    FileMetaData metaData = new FileMetaData(this, path);
    metaData.setType(type);

    // is it a directory?
    File file = getFile(metaData);
    if (file.exists()) {
      if (file.isDirectory()) {
        metaData.setDirectory(true);
        try {
          List files = getFiles(metaData, true);
          long size = 0;
          Iterator it = files.iterator();
          while (it.hasNext()) {
            size += ((FileMetaData)it.next()).getSize();
          }
          metaData.setSize(size);
        } catch (IllegalFileAccessException ifae) {
          // do nothing
        }
      } else {
        metaData.setSize(file.length());
      }

      metaData.setLastModified(new Date(file.lastModified()));
    }

    return metaData;
  }

  public FileMetaData getParent(FileMetaData file) {
    if (file.getAbsolutePath().equals("/")) {
      return null;
    } else {
      return getFileMetaData(file.getPath());
    }
  }

  /**
   * Gets meta data about a specific file or directory.
   *
   * @param path    the path of the file/directory
   * @param name    the name of the file/directory
   * @return        a FileMetaData object
   */
  public FileMetaData getFileMetaData(String path, String name) {
    if (path != null && path.endsWith("/")) {
      return getFileMetaData(path + name);
    } else {
      return getFileMetaData(path + "/" + name);
    }
  }

  /**
   * Gets a java.io.File reference to the specified path, regardless
   * of whether it represents a file or directory.
   *
   * @param path    an absolute path from the root
   * @return    a java.io.File instance
   */
  public File getFile(String path) {
    String relativePath;
    if (path != null && path.startsWith("/")) {
      relativePath = path.substring(1);
    } else {
      relativePath = path;
    }

    return new File(root, relativePath);
  }

  /**
   * Convenience method to get a java.io.File reference to the file represented
   * by the specified FileMetaData object.
   *
   * @param file    the FileMetaData object representing the path
   * @return    a java.io.File instance
   */
  private File getFile(FileMetaData file) {
    String relativePath = file.getAbsolutePath().substring(1);
    return new File(root, relativePath);
  }

  /**
   * Determines whether the specified file is underneath the root directory
   * for this file manager.
   *
   * @param file    the java.io.File to test
   * @return    true if the file is underneath the root, false otherwise
   */
  public boolean isUnderneathRootDirectory(File file) {
    return FileUtils.underneathRoot(root, file);
  }

  /**
   * Creates a new directory with the specified name underneath the given path.
   *
   * @param path    the path under which to create the directory
   * @param name    the name of the directory
   * @return    a java.io.File instance representing the new directory
   */
  public File createDirectory(String path, String name) throws IllegalFileAccessException {
    FileMetaData subDirectory = getFileMetaData(path);

    File newDirectory = new File(getFile(subDirectory), name);
    if (!isUnderneathRootDirectory(newDirectory)) {
      throw new IllegalFileAccessException();
    } else {
      newDirectory.mkdirs();
    }

    return newDirectory;
  }

  /**
   * Copies a file.
   *
   * @param path      the path under which the file exists
   * @param name      the name of the file
   * @param newName   the new name of the file
   * @return    a java.io.File instance representing the new file, or null
   *            if the file isn't copied because no new name was given, or the
   *            new name is the same as the old name
   */
  public File copyFile(String path, String name, String newName) throws IOException, IllegalFileAccessException {
    if (newName != null && newName.length() > 0 && !newName.equals(name)) {
      FileMetaData subDirectory = getFileMetaData(path);
      File originalFile = new File(getFile(subDirectory), name);
      File newFile = new File(getFile(subDirectory), newName);

      if (!isUnderneathRootDirectory(originalFile) || !isUnderneathRootDirectory(newFile)) {
        throw new IllegalFileAccessException();
      }

      FileUtils.copyFile(originalFile, newFile);

      return newFile;
    } else {
      return null;
    }
  }

  /**
   * Renames a file.
   *
   * @param path      the path under which the file exists
   * @param name      the name of the file
   * @param newName   the new name of the file
   * @return    a java.io.File instance representing the new file, or null
   *            if the file isn't copied because no new name was given, or the
   *            new name is the same as the old name
   */
  public File renameFile(String path, String name, String newName) throws IllegalFileAccessException {
    if (newName != null && newName.length() > 0 && !newName.equals(name)) {
      FileMetaData subDirectory = getFileMetaData(path);
      File originalFile = new File(getFile(subDirectory), name);
      File newFile = new File(getFile(subDirectory), newName);

      // check that newFile is underneath the root directory
      if (!isUnderneathRootDirectory(originalFile) || !isUnderneathRootDirectory(newFile)) {
        throw new IllegalFileAccessException();
      }

      originalFile.renameTo(newFile);
      return newFile;
    } else {
      return null;
    }
  }

  /**
   * Deletes a file.
   *
   * @param path      the path under which the file exists
   * @param name      the name of the file
   */
  public void deleteFile(String path, String name) throws IllegalFileAccessException {
    FileMetaData subDirectory = getFileMetaData(path);
    File fileToDelete = new File(getFile(subDirectory), name);

    if (!isUnderneathRootDirectory(fileToDelete)) {
      throw new IllegalFileAccessException();
    }

    FileUtils.deleteFile(fileToDelete);
  }

  /**
   * Loads a file into a String.
   *
   * @param path      the path under which the file exists
   * @param name      the name of the file
   * @return  a String containing the content of the specified file
   */
  public String loadFile(String path, String name) throws IllegalFileAccessException {
    StringBuffer content = new StringBuffer();

    FileMetaData subDirectory = getFileMetaData(path);
    File fileToLoad = new File(getFile(subDirectory), name);

    if (!isUnderneathRootDirectory(fileToLoad)) {
      throw new IllegalFileAccessException();
    }

    BufferedReader reader = null;
    try {
      reader = new BufferedReader(new FileReader(fileToLoad));
      String line = reader.readLine();
      while (line != null) {
        content.append(line);

        line = reader.readLine();
        if (line != null) {
          content.append(System.getProperty("line.separator"));
        }
      }
    } catch (IOException ioe) {
      ioe.printStackTrace();
    } finally {
      IOUtils.closeQuietly(reader);
    }

    return content.toString();
  }

  /**
   * Saves a file with the given content.
   *
   * @param path      the path under which the file exists
   * @param name      the name of the file
   * @param content   the content as a String
   */
  public void saveFile(String path, String name, String content) throws IOException, IllegalFileAccessException {
    FileMetaData subDirectory = getFileMetaData(path);
    File fileToSave = new File(getFile(subDirectory), name);

    if (!isUnderneathRootDirectory(fileToSave)) {
      throw new IllegalFileAccessException();
    }

    BufferedWriter writer = null;
    try {
      writer = new BufferedWriter(new FileWriter(fileToSave));
      writer.write(content);
      writer.flush();
    } finally {
      IOUtils.closeQuietly(writer);
    }
  }

  /**
   * Saves a file with the given binary content.
   *
   * @param name      the name of the file
   * @param content   the binary content
   * @return  a FileMetaData instance representing the saved file
   */
  public FileMetaData saveFile(String name, byte[] content) throws IOException, IllegalFileAccessException {
    FileMetaData file = getFileMetaData(name);
    File fileToSave = getFile(name);

    if (!isUnderneathRootDirectory(fileToSave)) {
      throw new IllegalFileAccessException();
    }

    BufferedOutputStream out = null;
    try {
      out = new BufferedOutputStream(new FileOutputStream(fileToSave));
      out.write(content);
      out.flush();
    } finally {
      IOUtils.closeQuietly(out);
    }

    return file;
  }

  /**
   * Gets a list of files that reside under a given path.
   *
   * @param path      the path under which the file exists
   * @return  a List of FileMetaData instances
   * @throws IllegalFileAccessException   if trying to access a file outside the root
   */
  public List getFiles(String path) throws IllegalFileAccessException {
    return getFiles(path, false);
  }

  public List getFiles(String path, boolean includeChildren) throws IllegalFileAccessException {
    FileMetaData subDirectory = getFileMetaData(path);
    return getFiles(subDirectory, includeChildren);
  }

  private List getFiles(FileMetaData path, boolean includeChildren) throws IllegalFileAccessException {
    File directoryToView = getFile(path);

    if (!isUnderneathRootDirectory(directoryToView)) {
      throw new IllegalFileAccessException();
    }

    List directoriesAndFiles = new ArrayList();
    List files = new ArrayList();
    List directories = new ArrayList();
    File f[] = directoryToView.listFiles();
    if (f != null) {
      File file;
      for (int i = 0; i < f.length; i++) {
        file = f[i];
        if (file.isDirectory()) {
          FileMetaData metaData = getFileMetaData(path.getAbsolutePath(), file.getName());
          directories.add(metaData);

          if (includeChildren) {
            directories.addAll(getFiles(metaData.getAbsolutePath(), true));
          } else {
            Collections.sort(directories, new FileMetaDataComparator());
          }
        }
      }

      for (int i = 0; i < f.length; i++) {
        file = f[i];
        if (file.isFile()) {
          FileMetaData metaData = getFileMetaData(path.getAbsolutePath(), file.getName());
          files.add(metaData);
        }
      }

      Collections.sort(files, new FileMetaDataComparator());
    }

    directoriesAndFiles.addAll(directories);
    directoriesAndFiles.addAll(files);

    return directoriesAndFiles;
  }

  /**
   * Determines how much space is being used in files, images and theme.
   *
   * @param blog    the blog to check against
   * @return  the number of KB
   */
  public static double getCurrentUsage(Blog blog) {
    FileManager imagesFileManager = new FileManager(blog, FileMetaData.BLOG_IMAGE);
    FileManager filesFileManager = new FileManager(blog, FileMetaData.BLOG_FILE);
    FileManager themeFileManager = new FileManager(blog, FileMetaData.THEME_FILE);
    return  imagesFileManager.getFileMetaData("/").getSizeInKB() +
            filesFileManager.getFileMetaData("/").getSizeInKB() +
            themeFileManager.getFileMetaData("/").getSizeInKB();
  }


  /**
   * Determines whether there is enough space to store the given number of KB.
   *
   * @param blog    the blog to check against
   * @param itemSize  the size of the item to be written
   * @return  true if there is enough space or quotas aren't active
   */
  public static boolean hasEnoughSpace(Blog blog, double itemSize) {
    long quota = PebbleContext.getInstance().getConfiguration().getFileUploadQuota();

    return (quota == -1) || ((quota - getCurrentUsage(blog)) > itemSize);
  }

}
TOP

Related Classes of net.sourceforge.pebble.domain.FileManager

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.