[4293] | 1 | /**
|
---|
| 2 | *#########################################################################
|
---|
| 3 | *
|
---|
| 4 | * A component of the Gatherer application, part of the Greenstone digital
|
---|
| 5 | * library suite from the New Zealand Digital Library Project at the
|
---|
| 6 | * University of Waikato, New Zealand.
|
---|
| 7 | *
|
---|
| 8 | * <BR><BR>
|
---|
| 9 | *
|
---|
[10245] | 10 | * Author: John Thompson, NZDL Project, University of Waikato
|
---|
[4293] | 11 | *
|
---|
| 12 | * <BR><BR>
|
---|
| 13 | *
|
---|
[10245] | 14 | * Copyright (C) 2005 New Zealand Digital Library Project
|
---|
[4293] | 15 | *
|
---|
| 16 | * <BR><BR>
|
---|
| 17 | *
|
---|
| 18 | * This program is free software; you can redistribute it and/or modify
|
---|
| 19 | * it under the terms of the GNU General Public License as published by
|
---|
| 20 | * the Free Software Foundation; either version 2 of the License, or
|
---|
| 21 | * (at your option) any later version.
|
---|
| 22 | *
|
---|
| 23 | * <BR><BR>
|
---|
| 24 | *
|
---|
| 25 | * This program is distributed in the hope that it will be useful,
|
---|
| 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 28 | * GNU General Public License for more details.
|
---|
| 29 | *
|
---|
| 30 | * <BR><BR>
|
---|
| 31 | *
|
---|
| 32 | * You should have received a copy of the GNU General Public License
|
---|
| 33 | * along with this program; if not, write to the Free Software
|
---|
| 34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
| 35 | *########################################################################
|
---|
| 36 | */
|
---|
[5564] | 37 | package org.greenstone.gatherer.file;
|
---|
| 38 |
|
---|
[4293] | 39 | import java.io.File;
|
---|
| 40 | import javax.swing.*;
|
---|
[5564] | 41 | import org.greenstone.gatherer.Dictionary;
|
---|
[4293] | 42 | import org.greenstone.gatherer.Gatherer;
|
---|
[13586] | 43 | import org.greenstone.gatherer.collection.CollectionManager;
|
---|
[11246] | 44 | import org.greenstone.gatherer.collection.CollectionTree;
|
---|
[8783] | 45 | import org.greenstone.gatherer.collection.CollectionTreeNode;
|
---|
[13455] | 46 | import org.greenstone.gatherer.gui.ExplodeMetadataDatabasePrompt;
|
---|
[15105] | 47 | import org.greenstone.gatherer.gui.ReplaceSrcDocWithHtmlPrompt;
|
---|
[11073] | 48 | import org.greenstone.gatherer.gui.GProgressBar;
|
---|
[9114] | 49 | import org.greenstone.gatherer.gui.NewFolderOrFilePrompt;
|
---|
[11246] | 50 | import org.greenstone.gatherer.gui.RenamePrompt;
|
---|
[4293] | 51 | import org.greenstone.gatherer.gui.tree.DragTree;
|
---|
[10376] | 52 | import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
|
---|
[4293] | 53 | import org.greenstone.gatherer.util.DragComponent;
|
---|
[7647] | 54 | import org.greenstone.gatherer.util.Utility;
|
---|
[34261] | 55 | import org.greenstone.gatherer.DebugStream;
|
---|
[5564] | 56 |
|
---|
[4675] | 57 | /** Manages the moving of files within a separate thread.
|
---|
[10245] | 58 | * @author John Thompson, NZDL Project, University of Waikato
|
---|
[4293] | 59 | */
|
---|
[10245] | 60 | public class FileManager
|
---|
| 61 | {
|
---|
| 62 | /** Not only the queue of files to be moved, but also the object that moves them. */
|
---|
| 63 | static private FileQueue file_queue = null;
|
---|
[6319] | 64 |
|
---|
[22605] | 65 | public static final int COPY = 0;
|
---|
| 66 | public static final int MOVE = 1;
|
---|
| 67 |
|
---|
| 68 | public static final int FILE_TYPE = 0;
|
---|
| 69 | public static final int FOLDER_TYPE = 1;
|
---|
[11440] | 70 | protected static File startup_directory = null;
|
---|
[9114] | 71 |
|
---|
[6319] | 72 |
|
---|
[4366] | 73 | /** Constructor.
|
---|
| 74 | * @see org.greenstone.gatherer.file.FileQueue
|
---|
| 75 | */
|
---|
[10245] | 76 | public FileManager()
|
---|
| 77 | {
|
---|
| 78 | file_queue = new FileQueue();
|
---|
| 79 | file_queue.start();
|
---|
[4366] | 80 | }
|
---|
[4293] | 81 |
|
---|
[10245] | 82 |
|
---|
| 83 | /** Determine what action should be carried out by the file queue, and add all of the necessary file jobs. */
|
---|
| 84 | public void action(DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node)
|
---|
| 85 | {
|
---|
[10246] | 86 | // Check there is something to do
|
---|
[10265] | 87 | if (source_nodes == null || source_nodes.length == 0) {
|
---|
[10246] | 88 | return;
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | // We need a unique ID for each file task
|
---|
[10245] | 92 | long id = System.currentTimeMillis();
|
---|
| 93 |
|
---|
| 94 | // If source and target are the same we're moving
|
---|
| 95 | if (source == target) {
|
---|
| 96 | // Start a new move FileTask and we're done
|
---|
| 97 | (new FileTask(id, source, source_nodes, target, target_node, FileJob.MOVE)).start();
|
---|
| 98 | return;
|
---|
[4366] | 99 | }
|
---|
[7647] | 100 |
|
---|
[10245] | 101 | // If target isn't the RecycleBin, we're copying
|
---|
| 102 | if (!(target instanceof RecycleBin)) {
|
---|
| 103 | // Start a new copy FileTask and we're done
|
---|
| 104 | (new FileTask(id, source, source_nodes, target, target_node, FileJob.COPY)).start();
|
---|
| 105 | return;
|
---|
| 106 | }
|
---|
[8391] | 107 |
|
---|
[10245] | 108 | // We're deleting... but first make sure source isn't read-only
|
---|
| 109 | boolean read_only_source = false;
|
---|
| 110 |
|
---|
| 111 | // The workspace tree is read-only...
|
---|
| 112 | if (source.toString().equals("Workspace")) {
|
---|
| 113 | read_only_source = true;
|
---|
| 114 |
|
---|
| 115 | // ...except for files from the "Downloaded Files" folder
|
---|
[10342] | 116 | String downloaded_files_folder_path = Gatherer.getGLIUserCacheDirectoryPath();
|
---|
[10245] | 117 | for (int i = 0; i < source_nodes.length; i++) {
|
---|
| 118 | // Is this the "Downloaded Files" folder?
|
---|
| 119 | if (source_nodes[i].getFile().getAbsolutePath().startsWith(downloaded_files_folder_path)) {
|
---|
| 120 | read_only_source = false;
|
---|
[4366] | 121 | }
|
---|
| 122 | }
|
---|
| 123 | }
|
---|
[10245] | 124 |
|
---|
| 125 | // The source is read-only, so tell the user and abort
|
---|
| 126 | if (read_only_source) {
|
---|
| 127 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Read_Only"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 128 | return;
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | // Start a new delete FileTask and we're done
|
---|
| 132 | (new FileTask(id, source, source_nodes, target, target_node, FileJob.DELETE)).start();
|
---|
[4366] | 133 | }
|
---|
[4293] | 134 |
|
---|
[22605] | 135 | /** For moving and copying of folders. */
|
---|
| 136 | public void action(File sourceFolder, File targetFolder, int operation) {
|
---|
| 137 | (new SimpleFileTask(sourceFolder, targetFolder, operation)).start();
|
---|
| 138 | }
|
---|
| 139 |
|
---|
[10245] | 140 |
|
---|
[4366] | 141 | /** Retrieves the file queue object. */
|
---|
[10245] | 142 | public FileQueue getQueue()
|
---|
| 143 | {
|
---|
| 144 | return file_queue;
|
---|
[4366] | 145 | }
|
---|
[4293] | 146 |
|
---|
[22605] | 147 | /** Performs the simple file task of moving or copying folders. */
|
---|
| 148 | private class SimpleFileTask
|
---|
| 149 | extends Thread
|
---|
| 150 | {
|
---|
| 151 | private File sourceFolder;
|
---|
| 152 | private File targetFolder;
|
---|
| 153 | int operation; // MOVE or COPY
|
---|
[10245] | 154 |
|
---|
[22605] | 155 | public SimpleFileTask(File sourceFolder, File targetFolder, int operation)
|
---|
| 156 | {
|
---|
| 157 | this.sourceFolder = sourceFolder;
|
---|
| 158 | this.targetFolder = targetFolder;
|
---|
| 159 | this.operation = operation;
|
---|
| 160 | }
|
---|
| 161 |
|
---|
| 162 |
|
---|
| 163 | public void run()
|
---|
| 164 | {
|
---|
| 165 | // check if we're moving or overwriting the current collection
|
---|
| 166 | String currentColPath = Gatherer.getCollectDirectoryPath()+CollectionManager.getLoadedCollectionName();
|
---|
| 167 | if(currentColPath.equals(sourceFolder.getAbsolutePath())
|
---|
| 168 | || currentColPath.equals(targetFolder.getAbsolutePath())) {
|
---|
| 169 | Gatherer.g_man.saveThenCloseCurrentCollection();
|
---|
| 170 | }
|
---|
| 171 |
|
---|
| 172 | // if moving, try a simple move operation (if it works, it
|
---|
| 173 | // shouldn't take long at all and doesn't need a progress bar)
|
---|
| 174 | if(operation == MOVE && sourceFolder.renameTo(targetFolder)) {
|
---|
| 175 | //System.err.println("**** A simple renameTo() worked.");
|
---|
| 176 | WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
|
---|
| 177 | return;
|
---|
| 178 | }
|
---|
| 179 |
|
---|
| 180 | // Reset the progress bar and set it to indeterminate while calculating its size
|
---|
| 181 | GProgressBar progress_bar = file_queue.getProgressBar();
|
---|
| 182 | progress_bar.reset();
|
---|
| 183 | progress_bar.setIndeterminate(true);
|
---|
| 184 |
|
---|
| 185 | String status = "FileActions.Moving";
|
---|
| 186 | if(operation == COPY) {
|
---|
| 187 | status = "FileActions.Copying";
|
---|
| 188 | }
|
---|
| 189 | progress_bar.setString(Dictionary.get(status));
|
---|
| 190 | file_queue.getFileStatus().setText(Dictionary.get(status,
|
---|
| 191 | file_queue.formatPath(status,
|
---|
| 192 | sourceFolder.getAbsolutePath(),
|
---|
| 193 | file_queue.getFileStatus().getSize().width)));
|
---|
| 194 |
|
---|
| 195 | // do the move or copy operation
|
---|
| 196 | try {
|
---|
| 197 | //System.err.println("**** Copying " + sourceFolder + " to: " + targetFolder);
|
---|
| 198 | file_queue.copyDirectoryContents(sourceFolder, targetFolder);
|
---|
| 199 | } catch(Exception e) {
|
---|
| 200 | JOptionPane.showMessageDialog(Gatherer.g_man, e.getMessage(),
|
---|
| 201 | "Can't perform file operation", JOptionPane.ERROR_MESSAGE);
|
---|
| 202 |
|
---|
| 203 | progress_bar.setIndeterminate(false);
|
---|
| 204 | progress_bar.clear();
|
---|
| 205 | return;
|
---|
| 206 | }
|
---|
| 207 |
|
---|
| 208 | // if moving, delete the original source folder and
|
---|
| 209 | // update the docs in GS collections node in the workspace tree
|
---|
| 210 |
|
---|
| 211 | if(operation == MOVE) {
|
---|
| 212 | Utility.delete(sourceFolder);
|
---|
| 213 | WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 |
|
---|
| 217 | progress_bar.setIndeterminate(false);
|
---|
| 218 | progress_bar.clear();
|
---|
| 219 | file_queue.getFileStatus().setText(Dictionary.get("FileActions.No_Activity"));
|
---|
| 220 | progress_bar.setString(Dictionary.get("FileActions.No_Activity"));
|
---|
| 221 | }
|
---|
| 222 | }
|
---|
| 223 |
|
---|
[10245] | 224 | private class FileTask
|
---|
| 225 | extends Thread
|
---|
| 226 | {
|
---|
| 227 | private long id;
|
---|
| 228 | private DragComponent source;
|
---|
| 229 | private FileNode[] source_nodes;
|
---|
| 230 | private DragComponent target;
|
---|
| 231 | private FileNode target_node;
|
---|
| 232 | private byte type;
|
---|
| 233 |
|
---|
| 234 |
|
---|
| 235 | public FileTask(long id, DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node, byte type)
|
---|
| 236 | {
|
---|
| 237 | this.id = id;
|
---|
| 238 | this.source = source;
|
---|
| 239 | this.source_nodes = source_nodes;
|
---|
| 240 | this.target = target;
|
---|
| 241 | this.target_node = target_node;
|
---|
| 242 | this.type = type;
|
---|
| 243 | }
|
---|
| 244 |
|
---|
| 245 |
|
---|
| 246 | public void run()
|
---|
| 247 | {
|
---|
| 248 | // Reset the progress bar and set it to indeterminate while calculating its size
|
---|
[11073] | 249 | GProgressBar progress_bar = file_queue.getProgressBar();
|
---|
[10245] | 250 | progress_bar.reset();
|
---|
| 251 | progress_bar.setIndeterminate(true);
|
---|
| 252 |
|
---|
| 253 | // Calculate the progress bar size
|
---|
| 254 | boolean cancelled = file_queue.calculateSize(source_nodes);
|
---|
| 255 | if (!cancelled) {
|
---|
[11241] | 256 | file_queue.addJob(id, source, source_nodes, target, target_node, type);
|
---|
[10248] | 257 | if (Gatherer.isGsdlRemote) {
|
---|
[22410] | 258 | String collection_name = CollectionManager.getLoadedCollectionName();
|
---|
[10561] | 259 |
|
---|
| 260 | // Perform the appropriate action based on the job type (RemoteGreenstoneServer will queue)
|
---|
| 261 | if (type == FileJob.COPY) {
|
---|
[10726] | 262 | // Copies: upload all the files at once in one zip file
|
---|
[10561] | 263 | File[] source_files = new File[source_nodes.length];
|
---|
| 264 | for (int i = 0; i < source_nodes.length; i++) {
|
---|
| 265 | source_files[i] = source_nodes[i].getFile();
|
---|
| 266 | }
|
---|
[17612] | 267 | Gatherer.remoteGreenstoneServer.uploadFilesIntoCollection(collection_name, source_files, target_node.getFile());
|
---|
[10561] | 268 | }
|
---|
| 269 | else if (type == FileJob.DELETE) {
|
---|
[10726] | 270 | // Deletes: delete each top-level file/directory one at a time
|
---|
| 271 | for (int i = 0; i < source_nodes.length; i++) {
|
---|
[17612] | 272 | Gatherer.remoteGreenstoneServer.deleteCollectionFile(collection_name, source_nodes[i].getFile());
|
---|
[10726] | 273 | }
|
---|
[10561] | 274 | }
|
---|
| 275 | else if (type == FileJob.MOVE) {
|
---|
[10726] | 276 | // Moves: move each top-level file/directory one at a time
|
---|
| 277 | for (int i = 0; i < source_nodes.length; i++) {
|
---|
[17612] | 278 | Gatherer.remoteGreenstoneServer.moveCollectionFile(
|
---|
| 279 | collection_name, source_nodes[i].getFile(), target_node.getFile());
|
---|
[10726] | 280 | }
|
---|
[10561] | 281 | }
|
---|
[10248] | 282 | }
|
---|
[10245] | 283 | }
|
---|
| 284 |
|
---|
| 285 | progress_bar.setIndeterminate(false);
|
---|
| 286 | progress_bar.clear();
|
---|
| 287 | }
|
---|
| 288 | }
|
---|
| 289 |
|
---|
[13455] | 290 | public void explodeMetadataDatabase(File file)
|
---|
| 291 | {
|
---|
| 292 | // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
|
---|
| 293 | new ExplodeMetadataDatabasePromptTask(file).start();
|
---|
| 294 | }
|
---|
| 295 |
|
---|
[15105] | 296 | // Works with replace_srcdoc_with_html.pl
|
---|
| 297 | public void replaceSrcDocWithHtml(File[] files)
|
---|
| 298 | {
|
---|
| 299 | // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
|
---|
| 300 | new ReplaceSrcDocWithHtmlPromptTask(files).start();
|
---|
| 301 | }
|
---|
[13455] | 302 |
|
---|
| 303 | private class ExplodeMetadataDatabasePromptTask
|
---|
| 304 | extends Thread
|
---|
| 305 | {
|
---|
| 306 | private File metadata_database_file = null;
|
---|
| 307 |
|
---|
| 308 | public ExplodeMetadataDatabasePromptTask(File metadata_database_file)
|
---|
| 309 | {
|
---|
| 310 | this.metadata_database_file = metadata_database_file;
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | public void run()
|
---|
| 314 | {
|
---|
| 315 | ExplodeMetadataDatabasePrompt emp = new ExplodeMetadataDatabasePrompt(metadata_database_file);
|
---|
| 316 | }
|
---|
| 317 | }
|
---|
| 318 |
|
---|
[15105] | 319 | // Works with replace_srcdoc_with_html.pl
|
---|
| 320 | private class ReplaceSrcDocWithHtmlPromptTask
|
---|
| 321 | extends Thread
|
---|
| 322 | {
|
---|
| 323 | private File[] replace_these_srcdoc_files = null;
|
---|
[13455] | 324 |
|
---|
[15105] | 325 | public ReplaceSrcDocWithHtmlPromptTask(File[] replace_these_srcdoc_files)
|
---|
| 326 | {
|
---|
| 327 | this.replace_these_srcdoc_files = replace_these_srcdoc_files;
|
---|
| 328 | }
|
---|
| 329 |
|
---|
| 330 | public void run()
|
---|
| 331 | {
|
---|
| 332 | ReplaceSrcDocWithHtmlPrompt prompt = new ReplaceSrcDocWithHtmlPrompt(replace_these_srcdoc_files);
|
---|
| 333 | }
|
---|
| 334 | }
|
---|
| 335 |
|
---|
| 336 |
|
---|
[10555] | 337 | public void openFileInExternalApplication(File file)
|
---|
| 338 | {
|
---|
| 339 | // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
|
---|
| 340 | new OpenFileInExternalApplicationTask(file).start();
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 |
|
---|
| 344 | private class OpenFileInExternalApplicationTask
|
---|
| 345 | extends Thread
|
---|
| 346 | {
|
---|
| 347 | private File file = null;
|
---|
| 348 |
|
---|
| 349 | public OpenFileInExternalApplicationTask(File file)
|
---|
| 350 | {
|
---|
| 351 | this.file = file;
|
---|
| 352 | }
|
---|
| 353 |
|
---|
| 354 | public void run()
|
---|
| 355 | {
|
---|
| 356 | // If we're using a remote Greenstone server, we need to download the file before viewing it...
|
---|
| 357 | if (Gatherer.isGsdlRemote) {
|
---|
| 358 | // ... but only if it is inside the collection and we haven't already downloaded it
|
---|
| 359 | if (file.getAbsolutePath().startsWith(Gatherer.getCollectDirectoryPath()) && file.length() == 0) {
|
---|
[17612] | 360 | if (Gatherer.remoteGreenstoneServer.downloadCollectionFile(
|
---|
[22410] | 361 | CollectionManager.getLoadedCollectionName(), file).equals("")) {
|
---|
[10726] | 362 | // Something has gone wrong downloading the file
|
---|
| 363 | return;
|
---|
| 364 | }
|
---|
[10555] | 365 | }
|
---|
| 366 | }
|
---|
| 367 |
|
---|
| 368 | // View the file in an external application
|
---|
| 369 | Gatherer.spawnApplication(file);
|
---|
| 370 | }
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 |
|
---|
[9114] | 374 | public void newDummyDoc(DragTree tree, CollectionTreeNode parent_node){
|
---|
| 375 | newFolderOrDummyDoc(tree, parent_node, FILE_TYPE);
|
---|
| 376 | }
|
---|
| 377 |
|
---|
[10245] | 378 |
|
---|
[8783] | 379 | public void newFolder(DragTree tree, CollectionTreeNode parent_node) {
|
---|
[9114] | 380 | newFolderOrDummyDoc(tree, parent_node, FOLDER_TYPE);
|
---|
| 381 | }
|
---|
[10245] | 382 |
|
---|
| 383 |
|
---|
[9114] | 384 | protected void newFolderOrDummyDoc(DragTree tree, CollectionTreeNode parent_node, int type) {
|
---|
[10726] | 385 | (new NewFolderOrDummyDocumentTask(tree, parent_node, type)).start();
|
---|
| 386 | }
|
---|
| 387 |
|
---|
| 388 |
|
---|
| 389 | private class NewFolderOrDummyDocumentTask
|
---|
| 390 | extends Thread
|
---|
| 391 | {
|
---|
| 392 | private DragTree tree = null;
|
---|
| 393 | private CollectionTreeNode parent_node = null;
|
---|
| 394 | private int type;
|
---|
| 395 |
|
---|
| 396 | public NewFolderOrDummyDocumentTask(DragTree tree, CollectionTreeNode parent_node, int type)
|
---|
| 397 | {
|
---|
| 398 | this.tree = tree;
|
---|
| 399 | this.parent_node = parent_node;
|
---|
| 400 | this.type = type;
|
---|
[9114] | 401 | }
|
---|
[10726] | 402 |
|
---|
| 403 | public void run()
|
---|
| 404 | {
|
---|
| 405 | // Ask the user for the directories name.
|
---|
| 406 | String extension = "";
|
---|
| 407 | if (type == FILE_TYPE) {
|
---|
| 408 | extension = ".nul";
|
---|
[4366] | 409 | }
|
---|
[10726] | 410 |
|
---|
| 411 | NewFolderOrFilePrompt new_folder_prompt = new NewFolderOrFilePrompt(parent_node, type, extension);
|
---|
| 412 | String name = new_folder_prompt.display();
|
---|
| 413 | new_folder_prompt.dispose();
|
---|
| 414 | new_folder_prompt = null;
|
---|
| 415 |
|
---|
| 416 | // And if the name is non-null...
|
---|
| 417 | if (name != null) {
|
---|
| 418 | FileSystemModel model = (FileSystemModel) tree.getModel();
|
---|
| 419 | File folder_file = new File(parent_node.getFile(), name);
|
---|
| 420 |
|
---|
| 421 | //... check if it already exists.
|
---|
| 422 | if (folder_file.exists()) {
|
---|
[9114] | 423 | if (type == FILE_TYPE) {
|
---|
[10726] | 424 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Already_Exists_No_Create", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 425 | }
|
---|
| 426 | else {
|
---|
| 427 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Already_Exists", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 428 | }
|
---|
| 429 | }
|
---|
| 430 | // Otherwise create it.
|
---|
| 431 | else {
|
---|
| 432 | try {
|
---|
| 433 | if (type == FILE_TYPE) {
|
---|
| 434 | folder_file.createNewFile();
|
---|
[13300] | 435 | if (Gatherer.isGsdlRemote) {
|
---|
[17612] | 436 | Gatherer.remoteGreenstoneServer.uploadCollectionFile(
|
---|
[22410] | 437 | CollectionManager.getLoadedCollectionName(), folder_file);
|
---|
[13300] | 438 | }
|
---|
[10265] | 439 | }
|
---|
[10726] | 440 | else {
|
---|
| 441 | folder_file.mkdirs();
|
---|
| 442 | if (Gatherer.isGsdlRemote) {
|
---|
[17612] | 443 | Gatherer.remoteGreenstoneServer.newCollectionDirectory(
|
---|
[22410] | 444 | CollectionManager.getLoadedCollectionName(), folder_file);
|
---|
[10726] | 445 | }
|
---|
| 446 | }
|
---|
| 447 |
|
---|
| 448 | // Update the parent node to show the new folder
|
---|
| 449 | parent_node.refresh();
|
---|
| 450 |
|
---|
| 451 | // Refresh workspace tree (collection tree is done automatically)
|
---|
| 452 | Gatherer.g_man.refreshWorkspaceTree(DragTree.COLLECTION_CONTENTS_CHANGED);
|
---|
[9114] | 453 | }
|
---|
[10726] | 454 | catch (Exception exception) {
|
---|
| 455 | if (type == FILE_TYPE) {
|
---|
| 456 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 457 | }
|
---|
| 458 | else {
|
---|
| 459 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 460 | }
|
---|
[9114] | 461 | }
|
---|
| 462 | }
|
---|
[10726] | 463 |
|
---|
| 464 | folder_file = null;
|
---|
| 465 | model = null;
|
---|
[4366] | 466 | }
|
---|
[10726] | 467 | name = null;
|
---|
[4366] | 468 | }
|
---|
| 469 | }
|
---|
[11246] | 470 |
|
---|
| 471 |
|
---|
| 472 | public void renameCollectionFile(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
|
---|
| 473 | {
|
---|
| 474 | // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
|
---|
| 475 | new RenameTask(collection_tree, collection_tree_node).start();
|
---|
| 476 | }
|
---|
| 477 |
|
---|
| 478 |
|
---|
| 479 | private class RenameTask
|
---|
| 480 | extends Thread
|
---|
| 481 | {
|
---|
| 482 | private CollectionTree collection_tree = null;
|
---|
| 483 | private CollectionTreeNode collection_tree_node = null;
|
---|
| 484 |
|
---|
| 485 | public RenameTask(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
|
---|
| 486 | {
|
---|
| 487 | this.collection_tree = collection_tree;
|
---|
| 488 | this.collection_tree_node = collection_tree_node;
|
---|
| 489 | }
|
---|
| 490 |
|
---|
| 491 | public void run()
|
---|
| 492 | {
|
---|
| 493 | RenamePrompt rename_prompt = new RenamePrompt(collection_tree_node);
|
---|
| 494 | String new_collection_file_name = rename_prompt.display();
|
---|
| 495 | rename_prompt.dispose();
|
---|
| 496 | rename_prompt = null;
|
---|
| 497 |
|
---|
| 498 | if (new_collection_file_name != null) {
|
---|
| 499 | File collection_file = collection_tree_node.getFile();
|
---|
| 500 | File new_collection_file = new File(collection_file.getParentFile(), new_collection_file_name);
|
---|
| 501 | CollectionTreeNode new_collection_tree_node = new CollectionTreeNode(new_collection_file);
|
---|
| 502 | file_queue.addJob(System.currentTimeMillis(), collection_tree, new FileNode[] { collection_tree_node }, collection_tree, new_collection_tree_node, FileJob.RENAME);
|
---|
[13604] | 503 | if (Gatherer.isGsdlRemote) {
|
---|
[17612] | 504 | Gatherer.remoteGreenstoneServer.moveCollectionFile(
|
---|
[22410] | 505 | CollectionManager.getLoadedCollectionName(), collection_file, new_collection_file);
|
---|
[13604] | 506 | }
|
---|
[11246] | 507 | }
|
---|
| 508 | }
|
---|
| 509 | }
|
---|
[11314] | 510 |
|
---|
| 511 | public void replaceCollectionFile(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
|
---|
| 512 | {
|
---|
| 513 | // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
|
---|
| 514 | new ReplaceTask(collection_tree, collection_tree_node).start();
|
---|
| 515 | }
|
---|
| 516 |
|
---|
| 517 |
|
---|
| 518 | private class ReplaceTask
|
---|
[34288] | 519 | extends Thread implements FileCopiedSuccessListener
|
---|
[11314] | 520 | {
|
---|
| 521 | private CollectionTree collection_tree = null;
|
---|
| 522 | private CollectionTreeNode collection_tree_node = null;
|
---|
| 523 |
|
---|
| 524 | public ReplaceTask(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
|
---|
| 525 | {
|
---|
| 526 | this.collection_tree = collection_tree;
|
---|
| 527 | this.collection_tree_node = collection_tree_node;
|
---|
| 528 | }
|
---|
| 529 |
|
---|
| 530 | public void run()
|
---|
| 531 | {
|
---|
[11440] | 532 | JFileChooser file_chooser = new JFileChooser(startup_directory);
|
---|
[11314] | 533 | file_chooser.setDialogTitle(Dictionary.get("ReplacePrompt.Title"));
|
---|
| 534 | File new_file = null;
|
---|
| 535 | int return_val = file_chooser.showOpenDialog(null);
|
---|
| 536 | if(return_val == JFileChooser.APPROVE_OPTION) {
|
---|
| 537 | new_file = file_chooser.getSelectedFile();
|
---|
| 538 | }
|
---|
| 539 |
|
---|
| 540 | if (new_file == null) {
|
---|
| 541 | return;
|
---|
| 542 | }
|
---|
| 543 |
|
---|
[11440] | 544 | // save the search path for next time
|
---|
| 545 | startup_directory = new_file.getParentFile();
|
---|
[11314] | 546 | // make up a node for the file to bring in
|
---|
| 547 | WorkspaceTreeNode source_node = new WorkspaceTreeNode(new_file);
|
---|
| 548 |
|
---|
[34261] | 549 | //DebugStream.setDebugging(true, "FileManager.ReplaceTask");
|
---|
| 550 |
|
---|
| 551 | // Some different handling if the old and new tail file names are the same and target file goes into the same
|
---|
| 552 | // location in collection tree as source.
|
---|
| 553 | // This avoids past errors upon replacing with same filename (diff file contents) where the attached meta gets lost,
|
---|
| 554 | // or remote file gets updated but file gone missing in client-GLI view until collection reopened.
|
---|
| 555 | boolean isSameLeafName = false;
|
---|
| 556 | if(collection_tree_node.getFile().getName().equals(new_file.getName())) {
|
---|
| 557 | DebugStream.println(" @@@ File Replace: New file has the same name as existing.");
|
---|
| 558 | isSameLeafName = true;
|
---|
| 559 | }
|
---|
| 560 |
|
---|
[11314] | 561 | File target_directory = collection_tree_node.getFile().getParentFile();
|
---|
| 562 | CollectionTreeNode new_collection_tree_node = new CollectionTreeNode(new File(target_directory, new_file.getName()));
|
---|
[34261] | 563 |
|
---|
| 564 | FileNode parent = (FileNode)collection_tree_node.getParent(); // store the original source's parent, need it several times after changing source
|
---|
| 565 |
|
---|
| 566 | if(isSameLeafName) {
|
---|
| 567 | // If the file name of the replacing file IS the same as the one being replaced
|
---|
[34288] | 568 | // perform a COPY operation, which will copy across metadata too, after confirming whether the user really wants to replace the source with identically named target
|
---|
| 569 |
|
---|
| 570 | // (a) First, this instance of ReplaceTask and no other starts listening to whether the user
|
---|
| 571 | // DIDN'T CANCEL out of an identical filename copy operation and if this local file copy
|
---|
| 572 | // was a success. If so, on successful file copy event fired (only then), the source file
|
---|
| 573 | // from the workspace tree will also be uploaded to the remote GS3
|
---|
| 574 | file_queue.addFileCopiedSuccessListener(this);
|
---|
| 575 |
|
---|
| 576 | // (b) Now can finally add the COPY job to the queue
|
---|
[34261] | 577 | file_queue.addJob(System.currentTimeMillis(), Gatherer.g_man.gather_pane.workspace_tree, new FileNode[] { source_node }, collection_tree, parent, FileJob.COPY);
|
---|
[34288] | 578 |
|
---|
[36237] | 579 | } else {
|
---|
| 580 | // If the file name of the replacing file is NOT the same as the one being replaced:
|
---|
| 581 | // (a) Again, this ReplaceTask instance needs to listen for the file copy event fired,
|
---|
| 582 | // so that the source file will also get uploaded to the remote GS3 on FileCopiedSuccess
|
---|
| 583 | file_queue.addFileCopiedSuccessListener(this);
|
---|
| 584 |
|
---|
| 585 | // (b) copy the new file in - but don't bring metadata
|
---|
[34288] | 586 | file_queue.addJob(System.currentTimeMillis(), Gatherer.g_man.gather_pane.workspace_tree, new FileNode[] { source_node }, collection_tree, parent, FileJob.COPY_FILE_ONLY);
|
---|
| 587 |
|
---|
[36237] | 588 | // (c) final step to finish off: do a replace of old file with new file
|
---|
[34261] | 589 | file_queue.addJob(System.currentTimeMillis(), collection_tree, new FileNode[] { collection_tree_node }, collection_tree, new_collection_tree_node, FileJob.REPLACE);
|
---|
| 590 | }
|
---|
| 591 |
|
---|
[34288] | 592 |
|
---|
[34261] | 593 | //DebugStream.setDebugging(false, "FileManager.ReplaceTask");
|
---|
[34288] | 594 | }
|
---|
| 595 |
|
---|
| 596 |
|
---|
| 597 | /** In order to detect that the user cancelled out of replacing an identically named target file,
|
---|
| 598 | * we now listen to events fired that the file was successfully copied across. Only then do we
|
---|
| 599 | * bother transferring the source file (from the workspace) into the target location in the
|
---|
| 600 | * collection on the remote file system. We don't do this if the user cancelled.
|
---|
| 601 | */
|
---|
| 602 | public void fileCopiedSuccessfully(File new_file) {
|
---|
| 603 |
|
---|
| 604 | //DebugStream.setDebugging(true, "FileManager.ReplaceTask.fileCopiedSuccessfully");
|
---|
| 605 |
|
---|
| 606 | if (Gatherer.isGsdlRemote) {
|
---|
| 607 | File target_directory = this.collection_tree_node.getFile().getParentFile();
|
---|
| 608 | File collection_tree_node_file = this.collection_tree_node.getFile();
|
---|
| 609 |
|
---|
| 610 | String collection_name = CollectionManager.getLoadedCollectionName();
|
---|
| 611 | Gatherer.remoteGreenstoneServer.deleteCollectionFile(collection_name, collection_tree_node_file);
|
---|
| 612 | Gatherer.remoteGreenstoneServer.uploadFilesIntoCollection(collection_name, new File[] { new_file }, target_directory);
|
---|
| 613 | }
|
---|
[34261] | 614 |
|
---|
[34288] | 615 | // stop listening to further events fired now that we've handled this event successfully
|
---|
| 616 | file_queue.removeFileCopiedSuccessListener(this);
|
---|
| 617 | //DebugStream.setDebugging(false, "FileManager.ReplaceTask.fileCopiedSuccessfully");
|
---|
[11314] | 618 | }
|
---|
| 619 | }
|
---|
[4293] | 620 | }
|
---|