/**
*#########################################################################
*
* A component of the Gatherer application, part of the Greenstone digital
* library suite from the New Zealand Digital Library Project at the
* University of Waikato, New Zealand.
*
*
*
* Author: John Thompson, Greenstone Digital Library, University of Waikato
*
*
*
* Copyright (C) 1999 New Zealand Digital Library Project
*
*
*
* This program 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.
*
*
*
* This program 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. See the
* GNU General Public License for more details.
*
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*########################################################################
*/
package org.greenstone.gatherer.file;
import java.io.File;
import javax.swing.*;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.collection.CollectionTreeNode;
import org.greenstone.gatherer.gui.LongProgressBar;
import org.greenstone.gatherer.gui.NewFolderOrFilePrompt;
import org.greenstone.gatherer.gui.tree.DragTree;
import org.greenstone.gatherer.util.DragComponent;
import org.greenstone.gatherer.util.Utility;
/** Manages the moving of files within a separate thread.
* @author John Thompson, Greenstone Digital Library, University of Waikato
* @version 2.3
*/
public class FileManager {
public static int FILE_TYPE = 0;
public static int FOLDER_TYPE = 1;
static public int countFolderDepth(File file) {
int count = 0;
while(file != null) {
count++;
file = file.getParentFile();
}
return count;
}
/** Not only the queue of files to be moved, but also the object that moves them. */
private FileQueue queue = null;
/** Constructor.
* @see org.greenstone.gatherer.file.FileQueue
*/
public FileManager() {
queue = new FileQueue();
queue.start();
}
/** Given the arguments, determine what action should be carried out by the file queue, and add all of the necessary file jobs. */
public void action(DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node) {
byte type = 0;
// If source and target are the same we are moving
if(source == target) {
type = FileJob.MOVE;
}
// If source and target are different
else {
// If target is the RecycleBin, we're deleting
if (target instanceof RecycleBin) {
// The workspace tree is read only.
// ... except for files from the "Downloaded Files" folder
boolean from_downloaded_files_folder = false;
if (source_nodes != null) {
for (int i = 0; i < source_nodes.length; i++) {
if (source_nodes[i].getFile() != null) {
if (source_nodes[i].getFile().getAbsolutePath().startsWith(Utility.getCacheDir().getAbsolutePath())) {
from_downloaded_files_folder = true;
}
}
}
}
// Can only delete from the "Downloaded Files" folder if a collection is open
if (from_downloaded_files_folder && Gatherer.c_man.ready() == false) {
return;
}
if (source.toString().equals("Workspace") && !from_downloaded_files_folder) {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Read_Only"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
return;
}
// Normal delete. Go ahead.
else {
type = FileJob.DELETE;
}
}
// Otherwise we are copying
else {
type = FileJob.COPY;
}
}
Task task = new Task(System.currentTimeMillis(), source, source_nodes, target, target_node, type);
task.start();
}
/** Retrieves the file queue object. */
public FileQueue getQueue() {
return queue;
}
public void newDummyDoc(DragTree tree, CollectionTreeNode parent_node){
newFolderOrDummyDoc(tree, parent_node, FILE_TYPE);
}
public void newFolder(DragTree tree, CollectionTreeNode parent_node) {
newFolderOrDummyDoc(tree, parent_node, FOLDER_TYPE);
}
protected void newFolderOrDummyDoc(DragTree tree, CollectionTreeNode parent_node, int type) {
// Ask the user for the directories name.
String extension = "";
if (type == FILE_TYPE) {
extension = ".nul";
}
NewFolderOrFilePrompt new_folder_prompt = new NewFolderOrFilePrompt(parent_node, type, extension);
String name = new_folder_prompt.display();
new_folder_prompt.dispose();
new_folder_prompt = null;
// And if the name is non-null...
if(name != null) {
FileSystemModel model = (FileSystemModel) tree.getModel();
File folder_file = new File(parent_node.getFile(), name);
//... check if it already exists.
if(folder_file.exists()) {
if (type == FILE_TYPE) {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Already_Exists_No_Create", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Already_Exists", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
}
}
// Otherwise create it.
else {
try {
if (type == FILE_TYPE) {
folder_file.createNewFile();
} else {
folder_file.mkdirs();
}
// Update the parent node to show the new folder
parent_node.refresh();
// Refresh workspace tree (collection tree is done automatically)
Gatherer.g_man.refreshWorkspaceTree(DragTree.COLLECTION_CONTENTS_CHANGED);
} catch (Exception e) {
if (type == FILE_TYPE) {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
}
}
}
folder_file = null;
model = null;
}
name = null;
}
private class Task
extends Thread {
private byte type;
private DragComponent source;
private DragComponent target;
private FileNode target_node;
private FileNode[] source_nodes;
private long id;
public Task(long id, DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node, byte type) {
this.id = id;
this.source = source;
this.source_nodes = source_nodes;
this.target = target;
this.target_node = target_node;
this.type = type;
}
public void run()
{
// Check there is something to do
if (source_nodes == null) {
return;
}
// Reset the progress bar and set it to indeterminate while calculating its size
LongProgressBar progress_bar = queue.getProgressBar();
progress_bar.reset();
progress_bar.setIndeterminate(true);
// Calculate the progress bar size
boolean cancelled = queue.calculateSize(source_nodes);
if (!cancelled) {
// Queue the job(s) (this may fail if we are asked to delete a read only file)
for (int i = 0; i < source_nodes.length; i++) {
queue.addJob(id, source, source_nodes[i], target, target_node, type, true);
}
}
progress_bar.setIndeterminate(false);
progress_bar.clear();
}
}
}