Package org.freeplane.plugin.workspace.io

Source Code of org.freeplane.plugin.workspace.io.FileSystemManager

/**
* author: Marcel Genzmehr
* 19.07.2011
*/
package org.freeplane.plugin.workspace.io;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.freeplane.core.io.ListHashTable;
import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.util.LogUtils;
import org.freeplane.plugin.workspace.creator.DefaultFileNodeCreator;
import org.freeplane.plugin.workspace.model.AWorkspaceTreeNode;

public class FileSystemManager {

  private final FileReadManager typeManager;
  private boolean filtering = true;
  private FileReadManager fileTypeManager;
  private static IConflictHandler directoryConflictHandler;
  private static IConflictHandler fileConflictHandler;

  public FileSystemManager(final FileReadManager typeManager) {
    if(typeManager == null) {
      this.typeManager = getDefaultFileTypeManager();
    }
    else {
      this.typeManager = typeManager;
    }
  }

  public boolean isFiltering() {
    return filtering;
  }

  public void setFiltering(boolean filtering) {
    this.filtering = filtering;
  }
 
  public void scanFileSystem(AWorkspaceTreeNode node, File file) {
    scanFileSystem(node, file, null);
  }

  public void scanFileSystem(AWorkspaceTreeNode node, File file, FileFilter filter) {

    if (file != null && file.exists()) {
      if (file.isDirectory()) {
        if(node instanceof IFileSystemRepresentation) {
          iterateDirectory(node, file, filter, ((IFileSystemRepresentation) node).orderDescending());
        }
        else {
          iterateDirectory(node, file, filter, false);
        }
      }
      else {
        createFileNode(node, file);
      }
    }
  }
 
  /**
   * @param directoryName
   * @param parentDir
   * @throws IOException
   */
  public File createDirectory(String directoryName, File parentDir) throws IOException {
    File newDir = new File(parentDir, directoryName);
    int count = 0;
    while(newDir.exists() && count++ < 100) {
      newDir = new File(parentDir, directoryName + " ("+count+")");
    }
    if(!newDir.mkdirs()) {
      throw new IOException("could not create directory: "+newDir.getPath());
    }
    return newDir;
  }
 
  /**
   * @param directoryName
   * @param parentDir
   * @throws IOException
   */
  public File createFile(String fileName, File parentDir) throws IOException {
    String pureName = fileName;
    String fileExtension = "";
   
    int strPointer = fileName.lastIndexOf(".");
    if(strPointer > -1) {
      pureName = fileName.substring(0, strPointer);
      fileExtension = fileName.substring(strPointer+1);
    }
    File newFile = new File(parentDir, pureName+"."+fileExtension);
    int count = 0;
    while(newFile.exists() && count++ < 100) {
      newFile = new File(parentDir, pureName + " ("+count+")" +(fileExtension.trim().length() > 0 ? "."+fileExtension : ""));
    }
    if(!newFile.createNewFile()) {
      throw new IOException("could not create file: "+newFile.getPath());
    }
    return newFile;
  }
 
  public static void copyFile(File srcFile, File destDir) throws IOException {
    copyFile(srcFile, destDir, false);
  }
 
  public static void copyFile(File srcFile, File destDir, Boolean overwrite) throws IOException {
    if(srcFile == null || destDir == null) {
      throw new IllegalArgumentException("NULL");
    }
    if(!srcFile.exists() || !srcFile.isFile()) {
      throw new IllegalArgumentException("srcFile is not a file or does not exist");
    }
   
    copyFiles(Arrays.asList(new File[]{srcFile}), destDir, overwrite);
//    if(targetFile.exists()) {
//      if(silentOverwrite) {
//        if(!FileUtils.deleteQuietly(targetFile)) {
//          throw new IOException("can not copy file "+targetFile);
//        }
//      }
//      else {
//        throw new FileExistsException(targetFile);
//      }
//    }
//   
//    FileUtils.copyFile(file, targetFile);
  }
 
  public static void copyDirectory(File dir, File newParentDir) throws IOException {
    copyDirectory(dir, newParentDir, false);
  }
 
  public static void copyDirectory(File dir, File newParentDir, boolean overwrite) throws IOException {
    if(dir == null || newParentDir == null) {
      throw new IllegalArgumentException("NULL");
    }
   
    if(newParentDir.exists() && !newParentDir.isDirectory()) {
      throw new IOException("dest is no directory. a directory cannot be copied to a file.");
    }
   
    copyFiles(Arrays.asList(new File[]{dir}), newParentDir, overwrite);
  }
 
  public static void moveFile(File srcFile, File destDir) throws IOException {
    moveFile(srcFile, destDir, false);
  }
 
  public static void moveFile(File srcFile, File destDir, Boolean overwrite) throws IOException {
    if(srcFile == null || destDir == null) {
      throw new IllegalArgumentException("NULL");
    }
    if(!srcFile.exists() || !srcFile.isFile()) {
      throw new IllegalArgumentException("srcFile is not a file or does not exist");
    }
   
    moveFiles(Arrays.asList(new File[]{srcFile}), destDir, overwrite);
  }
 
  public static void moveDirectory(File dir, File newParentDir) throws IOException {
    copyDirectory(dir, newParentDir, false);
  }
 
  public static void moveDirectory(File dir, File newParentDir, boolean overwrite) throws IOException {
    if(dir == null || newParentDir == null) {
      throw new IllegalArgumentException("NULL");
    }
   
    if(newParentDir.exists() && !newParentDir.isDirectory()) {
      throw new IOException("dest is no directory. a directory cannot be copied to a file.");
    }
   
    moveFiles(Arrays.asList(new File[]{dir}), newParentDir, overwrite);
  }
 
  public static void copyFiles(List<File> files, File destDir, boolean overwrite) throws IOException {
    if(files == null || destDir == null) {
      throw new IllegalArgumentException("NULL");
    }
    if(destDir.exists() && !destDir.isDirectory()) {
      throw new IOException("destDir is no directory.");
    }
    List<ITask> opList = new ArrayList<ITask>();
   
    for (File file : files) {
      buildCopyOperationList(file, new File(destDir, file.getName()), opList);
    }
   
    Properties props = new Properties();
    props.setProperty("overwriteAll", String.valueOf(overwrite));
    props.setProperty("mergeAll", String.valueOf(overwrite));
   
    execOperations(opList, props);
  }
 
  public static void moveFiles(List<File> files, File destDir, boolean overwrite) throws IOException {
    if(files == null || destDir == null) {
      throw new IllegalArgumentException("NULL");
    }
    if(destDir.exists() && !destDir.isDirectory()) {
      throw new IOException("destDir is no directory.");
    }
    List<ITask> opList = new ArrayList<ITask>();
   
    for (File file : files) {
      buildMoveOperationList(file, new File(destDir, file.getName()), opList);
    }
   
    Properties props = new Properties();
    props.setProperty("overwriteAll", String.valueOf(overwrite));
    props.setProperty("mergeAll", String.valueOf(overwrite));
   
    execOperations(opList, props);
  }
 
  public static List<ITask> buildCopyOperationList(final File srcFile, final File destFile) {
    List<ITask> list = new ArrayList<ITask>();
    buildCopyOperationList(srcFile, destFile, list);
    return list;
  }
 
  public static List<ITask> buildMoveOperationList(final File srcFile, final File destFile) {
    List<ITask> list = new ArrayList<ITask>();
    buildMoveOperationList(srcFile, destFile, list);
    return list;
  }
 
  public static void buildCopyOperationList(final File srcFile, final File destFile, final List<ITask> ops) {
    if(srcFile.isDirectory()) {
      ops.add(new ITask() {       
        public void exec(Properties properties) throws IOException {
          if(onSkipList(destFile.getParentFile(), properties)) {
            addSkippedDir(destFile, properties);
            throw new SkipTaskException();
          }
         
          if(destFile.exists()) {
            properties.setProperty("opType", "1");
            if(!Boolean.parseBoolean(properties.getProperty("mergeAll", "false"))) {
              try {
                getDirectoryConflictHandler().resolveConflict(destFile, properties);
              }
              catch (SkipTaskException e) {
                addSkippedDir(destFile, properties);
                throw e;
              }
            }
            FileUtils.touch(destFile);
          }
          else {
            destFile.mkdirs();
          }
        }
      });
      for(File file : srcFile.listFiles()) {
        buildCopyOperationList(file, new File(destFile, file.getName()), ops);
      }
    }
    else {
      ops.add(new ITask() {
        public void exec(Properties properties) throws IOException {
          if(onSkipList(destFile.getParentFile(), properties)) {
            throw new SkipTaskException();
          }
         
          if(destFile.exists()) {
            properties.setProperty("opType", "1");
            if(!Boolean.parseBoolean(properties.getProperty("overwriteAll", "false"))) {
              getFileConflictHandler().resolveConflict(destFile, properties);
            }
          }
          FileUtils.copyFile(srcFile, destFile);
        }
      });
    }
  }
 
  public static void buildMoveOperationList(final File srcFile, final File destFile, final List<ITask> ops) {
    if(srcFile.isDirectory()) {
      ops.add(new ITask() {       
        public void exec(Properties properties) throws IOException {
          if(onSkipList(destFile.getParentFile(), properties)) {
            addSkippedDir(destFile, properties);
            throw new SkipTaskException();
          }
         
          if(destFile.exists()) {
            properties.setProperty("opType", "2");
            if(!Boolean.parseBoolean(properties.getProperty("mergeAll", "false"))) {
              try {
                getDirectoryConflictHandler().resolveConflict(destFile, properties);
              }
              catch (SkipTaskException e) {
                addSkippedDir(destFile, properties);
                throw e;
              }
            }
            FileUtils.touch(destFile);
          }
          else {
            destFile.mkdirs();
          }
        }
      });
      for(File file : srcFile.listFiles()) {
        buildMoveOperationList(file, new File(destFile, file.getName()), ops);
      }
    }
    else {
      ops.add(new ITask() {
        public void exec(Properties properties) throws IOException {
          if(onSkipList(destFile.getParentFile(), properties)) {
            throw new SkipTaskException();
          }
         
          if(destFile.exists()) {
            properties.setProperty("opType", "2");
            if(!Boolean.parseBoolean(properties.getProperty("overwriteAll", "false"))) {
              getFileConflictHandler().resolveConflict(destFile, properties);
            }
            if(!FileUtils.deleteQuietly(destFile)) {
              throw new SkipTaskException();
            }
          }
          FileUtils.moveFile(srcFile, destFile);
        }
      });
    }
  }
 
  private static void addSkippedDir(File dest, Properties properties) {
    if(properties == null || dest == null) {
      return;
    }
    String list = properties.getProperty("skippedDirs", "");
    String entry = dest.getPath()+";";
    if(!list.contains(entry)) {
      list += entry;
      properties.setProperty("skippedDirs", list);
    }
  }
 
  private static boolean onSkipList(File dest, Properties properties) {
    if(properties == null || dest == null) {
      return false;
    }
    String list = properties.getProperty("skippedDirs", "");
    String entry = dest.getPath()+";";
    if(list.contains(entry)) {
      return true;
    }
    return false;
  }

  public static IConflictHandler getDirectoryConflictHandler() {
    if(directoryConflictHandler == null) {
      directoryConflictHandler = new IConflictHandler() {
        public void resolveConflict(File file, Properties properties) throws IOException {
          LogUtils.info("Error in org.freeplane.plugin.workspace.io.FileSystemManager: directory already exists: " + file);
          throw new SkipTaskException();
        }
      };
    }
    return directoryConflictHandler;
  }
 
  public static IConflictHandler getFileConflictHandler() {
    if(fileConflictHandler == null) {
      fileConflictHandler = new IConflictHandler() {
        public void resolveConflict(File file, Properties properties) throws IOException {
          LogUtils.info("Error in org.freeplane.plugin.workspace.io.FileSystemManager: file already exists: " + file);
          throw new SkipTaskException();
        }
      };
    }
    return fileConflictHandler;
  }
 
  public static void setDirectoryConflictHandler(IConflictHandler handler) {
    directoryConflictHandler = handler;
  }

  public static void setFileConflictHandler(IConflictHandler handler) {
    fileConflictHandler = handler;
  }
 
  public static void execOperations(List<ITask> ops) throws IOException {
    execOperations(ops, null);
  }
 
  public static void execOperations(List<ITask> ops, Properties properties) throws IOException {
    if(ops == null) {
      return;
    }
    if(properties == null) {
      properties = new Properties();
    }
    Iterator<ITask> iter = ops.iterator();
    while (iter.hasNext()) {
      ITask op = iter.next();
      try {
        op.exec(properties);
        iter.remove();
      }
      catch (SkipTaskException e) {
        iter.remove();
        continue;
      }
    }
  }
 
  private ListHashTable<String, IFileTypeHandler> getFileTypeHandlers() {
    return typeManager.getFileTypeHandlers();
  }

  private void iterateDirectory(AWorkspaceTreeNode parent, File directory, FileFilter filter, final boolean orderDescending) {
    boolean orderDesc = orderDescending;
//    if(parent instanceof IFileSystemRepresentation) {
//      orderDesc = ((IFileSystemRepresentation) parent).orderDescending();
//    }
   
    for (File file : sortFiles(directory.listFiles(new DirectoryFilter(filter)), orderDesc, true)) {
      AWorkspaceTreeNode newParent = createFileNode(parent, FileReadManager.DIRECTORY_HANDLE, file);
      iterateDirectory(newParent, file, filter, orderDesc);

    }
    for (File file : sortFiles(directory.listFiles(new FilesOnlyFilter(filter)), orderDesc, true)) {
      createFileNode(parent, file);
    }
  }

  /**
   * @param files
   * @param orderAscending
   * @param ignoreCase
   * @return
   */
  private File[] sortFiles(File[] files, final boolean orderDescending, final boolean ignoreCase) {
    Comparator<File> comparator = new Comparator<File>() {
      public int compare(File o1, File o2) {
        File f1 = o1;
        File f2 = o2;
        if(ignoreCase) {
          f1 = new File(f1.getParentFile(), f1.getName().toLowerCase());
          f2 = new File(f2.getParentFile(), f2.getName().toLowerCase());
        }
        int compareResult = f1.compareTo(f2);
        if(orderDescending) {
          return compareResult*-1;
        }
        return compareResult;
      }
    };
    Arrays.sort(files, comparator);
    return files;
  }

  private AWorkspaceTreeNode createFileNode(final AWorkspaceTreeNode parent, final File file) {
    String fileExtension = FileReadManager.DEFAULT_HANDLE;
    int dot = file.getPath().lastIndexOf('.');
    if (-1 != dot) {
      fileExtension = file.getPath().substring(dot);
    }
    return createFileNode(parent, fileExtension, file);
  }

  private AWorkspaceTreeNode createFileNode(final AWorkspaceTreeNode parent, String fileExtension, final File file) {
    List<IFileTypeHandler> handlers = getFileTypeHandlers().list(fileExtension);
    if (handlers == null) {
      fileExtension = FileReadManager.DEFAULT_HANDLE;
      handlers = getFileTypeHandlers().list(fileExtension);
    }
    if (handlers != null && handlers.size() == 1) { //WORKSPACE - ToDo: what if there is more than one handler for a single type?
      IFileTypeHandler nodeCreator = handlers.get(0);
      AWorkspaceTreeNode newParent = nodeCreator.createFileNode(parent, fileExtension, file);
      return newParent;
    }
    return parent;
 
 
 
  /***********************************************************************************
   * INTERNAL CLASS DEFINITIONS
   **********************************************************************************/
 
  private class DirectoryFilter implements FileFilter  {
    private boolean filtering = true;
    private FileFilter extraFilter;
   
    public DirectoryFilter(FileFilter filter) {
      this.extraFilter = filter;
    }

    public boolean accept(File pathname) {
      if(filtering && pathname.getName().startsWith(".") && !pathname.getName().equals("."+ResourceController.getResourceController().getProperty("workspace.profile"))) {
        return false;
      }
      if (pathname.isDirectory()) {
        if(this.extraFilter == null) {
          return true;
        }
        return this.extraFilter.accept(pathname);
      }
      return false;
    }
  }
 
  private class FilesOnlyFilter implements FileFilter {
    private boolean filtering = true;
    private FileFilter extraFilter;
   
    public FilesOnlyFilter(FileFilter filter) {
      this.extraFilter = filter;
    }

    public boolean accept(File pathname) {
      if(filtering && pathname.getName().startsWith(".")) {
        return false;
      }
      if (pathname.isFile()) {
        if(this.extraFilter == null) {
          return true;
        }
        return this.extraFilter.accept(pathname);
      }
      return false;
    }
  }
 
  private FileReadManager getDefaultFileTypeManager() {
    if (this.fileTypeManager == null) {
      this.fileTypeManager = new FileReadManager();
      Properties props = new Properties();
      try {
        props.load(this.getClass().getResourceAsStream("/conf/filenodetypes.properties"));

        Class<?>[] args = {};
        for (Object key : props.keySet()) {
          try {
            Class<?> clazz = DefaultFileNodeCreator.class;
           
            clazz = this.getClass().getClassLoader().loadClass(key.toString());

            AFileNodeCreator handler = (AFileNodeCreator) clazz.getConstructor(args).newInstance();
            handler.setFileTypeList(props.getProperty(key.toString(), ""), "\\|");
            this.fileTypeManager.addFileHandler(handler);
          }
          catch (ClassNotFoundException e) {
            LogUtils.warn("Class not found [" + key + "]", e);
          }
          catch (ClassCastException e) {
            LogUtils.warn("Class [" + key + "] is not of type: PhysicalNode", e);
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      catch (IOException e) {
        e.printStackTrace();
      }
    }
    return this.fileTypeManager;
  }
}
TOP

Related Classes of org.freeplane.plugin.workspace.io.FileSystemManager

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.