source: trunk/gli/src/org/greenstone/gatherer/collection/SaveCollectionTask.java@ 4366

Last change on this file since 4366 was 4366, checked in by kjdon, 21 years ago

re-tabbed the code for java

  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1package org.greenstone.gatherer.collection;
2/**
3 *#########################################################################
4 *
5 * A component of the Gatherer application, part of the Greenstone digital
6 * library suite from the New Zealand Digital Library Project at the
7 * University of Waikato, New Zealand.
8 *
9 * <BR><BR>
10 *
11 * Author: John Thompson, Greenstone Digital Library, University of Waikato
12 *
13 * <BR><BR>
14 *
15 * Copyright (C) 1999 New Zealand Digital Library Project
16 *
17 * <BR><BR>
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * <BR><BR>
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * <BR><BR>
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 *########################################################################
37 */
38import java.io.*;
39import java.util.*;
40import javax.swing.*;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.Message;
43import org.greenstone.gatherer.collection.Collection;
44import org.greenstone.gatherer.gui.GUIManager;
45import org.greenstone.gatherer.undo.UndoManager;
46import org.greenstone.gatherer.util.Utility;
47/** The actually saving of a collection must run in a thread other than the AWTEvent thread, or else the save progress box will never get updated. To that end this class provides a threaded save method, which saves the various parts of the collection to the appropriate disk location.
48 * @author John Thompson, Greenstone Digital Library, University of Waikato
49 * @version 2.3
50 */
51public class SaveCollectionTask
52 extends Thread {
53 private boolean close_after = false;
54 /** Should we exit the Gatherer once this save is complete. */
55 private boolean exit_after = false;
56 /** Do we run the import scripts once this save is complete. */
57 private boolean import_after = false;
58 /** The current collection. */
59 private Collection collection = null;
60 /** The filename of the collection we are saving. */
61 private String name = null;
62 static final private int CLOSE_COLLECTION = 0;
63 static final private int COLLECTION_COPIED = 1;
64 static final private int COLLECTION_SAVED = 2;
65 static final private int COLLECTION_CFG_SAVED = 3;
66 static final private int COPY_COLLECTION = 4;
67 static final private int MAKE_COLLECTION = 5;
68 static final private int METADATA_SAVED = 6;
69 static final private int METADATA_XML_SAVED = 7;
70 static final private int OPEN_COLLECTION = 8;
71 static final private int RESTORE_COLLECTION = 9;
72 /** Constructor.
73 * @param name The filename of the collection we are saving as.
74 */
75 public SaveCollectionTask(Collection collection) {
76 this.collection = collection;
77 }
78 /** Constructor.
79 * @param exit_after <i>true</i> to cause the Gatherer to exit once save is complete, <i>false</i> otherwise.
80 */
81 public SaveCollectionTask(Collection collection, boolean close_after, boolean exit_after) {
82 this.close_after = close_after;
83 this.collection = collection;
84 this.exit_after = exit_after;
85 }
86 /** Constructor.
87 * @param name The filename of the collection we are saving as.
88 */
89 public SaveCollectionTask(Collection collection, String name) {
90 this.collection = collection;
91 this.name = name;
92 }
93 /** <p>This method, when created in a forked process by start(), performs the actions necessary to save a collection. If this is a regular save it saves the state of the current collection, ensuring all files, metadata files, and configuration files are written to disk. If, instead, this is a "Save As" action then there as several more steps involved:</p>
94 * <p>1. Perform a regular collection save on what we will later refer to as the origin collection.</p>
95 * <p>2. Call CollectionManager.makeCollection() to create the collection structure to save into (copied collection).</p>
96 * <p>3. Copy files from the origin to the copied collections (except special collection files ending with ~).</p>
97 * <p>4. Restore origin collection by undoing file copy actions and removing the ~ from the end of collection files.</p>
98 * <p>5. Close the origin collection.</p>
99 * <p>6. Open the copied collection.</p>
100 * <p>Of course all of this takes a while, and depends on several other bits of code to work properly.</p>.
101 * @see org.greenstone.gatherer.collection.Collection
102 * @see org.greenstone.gatherer.collection.CollectionModel
103 * @see org.greenstone.gatherer.gui.GUIManager
104 * @see org.greenstone.gatherer.gui.GConfigPane
105 * @see org.greenstone.gatherer.msm.MetadataSetManager
106 * @see org.greenstone.gatherer.util.Utility
107 */
108 public void run() {
109 // Change cursor to hourglass.
110 Gatherer.g_man.wait(true);
111 // Create progress monitor box. It will display itself as necessary.
112 ProgressMonitor spd = new ProgressMonitor(Gatherer.g_man, Gatherer.dictionary.get("SaveProgressDialog.Title", collection.getName()), null, 0, 100);
113 spd.setMillisToDecideToPopup(100);
114 spd.setMillisToPopup(100);
115 // 0. Force all remaining metadata.xml files to load.
116 // 1. Perform a regular collection save on what we will later refer to as the origin collection.
117 ///ystem.err.println("1. Save origin.");
118 String tmp_loc = Gatherer.c_man.getCollectionFilename();
119 String args[] = new String[1];
120 args[0] = collection.getName() + ".col";
121 try {
122 // Block until all of the metadata files have been read in.
123 collection.gdm.waitUntilComplete();
124 // Write out the metadata xml files. The destroy below is meant to do this, but never does.
125 collection.gdm.save();
126
127 spd.setProgress(getValue(METADATA_XML_SAVED));
128 File file = new File(tmp_loc);
129 // Create backup
130 if(file.exists()) {
131 File backup = new File(tmp_loc + "~");
132 backup.deleteOnExit();
133 if(!file.renameTo(backup)) {
134 Gatherer.println("Error in CollectionManager.load(): FileNotRenamedException");
135 }
136 }
137 // Carry on.
138 collection.save();
139 spd.setProgress(getValue(COLLECTION_SAVED));
140 // Write out the collection configuration file.
141 Gatherer.g_man.config_pane.saveConfiguration();
142 spd.setProgress(getValue(COLLECTION_CFG_SAVED));
143 // Write out the metadata files.
144 Gatherer.c_man.msm.save();
145 spd.setProgress(getValue(METADATA_SAVED));
146 // Clean-up
147 spd.setProgress(100);
148 ///atherer.g_man.collectionChanged(Gatherer.c_man.ready());
149 collection.setSaved(true);
150 }
151 catch (Exception error) {
152 Gatherer.printStackTrace(error);
153 }
154 // Now we check whether we've finished, or is this a Save As action, in which case we've got miles to go.
155 if(name != null) {
156 // 2. Call CollectionManager.makeCollection() to create the collection structure to save into (copied collection).
157 ///ystem.err.println("2. Make copy.");
158 Gatherer.c_man.createCollection(null, null, name, null, null, null);
159 spd.setProgress(getValue(MAKE_COLLECTION));
160 // 3. Copy files from the origin to the copied collections (except special collection files ending with ~).
161 // As part of this we must rename origin.col to copy.col
162 ///ystem.err.println("3. Copy origin.");
163 ArrayList files = new ArrayList();
164 File collection_file = new File(Gatherer.c_man.getCollectionFilename());
165 File copied_dir = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path) + name);
166 files.add(collection_file.getParentFile());
167 while(files.size() > 0) {
168 File file = (File) files.get(0);
169 files.remove(0);
170 if(file.isDirectory()) {
171 File children[] = file.listFiles();
172 for(int i = 0; i < children.length; i++) {
173 files.add(children[i]);
174 }
175 children = null;
176 }
177 else {
178 // Rename origin.col file.
179 if(file.equals(collection_file)) {
180 File copied_file = new File(copied_dir, name + ".col");
181 copy(collection_file, copied_file);
182 copied_file = null;
183 }
184 // Exclude *~ files from certain locations and lock.tmp file.
185 else if(!file.getName().endsWith("~") && !file.getName().equals(CollectionManager.LOCK_FILE)) {
186 StringTokenizer origin = new StringTokenizer(file.getAbsolutePath(), File.separator);
187 StringTokenizer destin = new StringTokenizer(copied_dir.getAbsolutePath(), File.separator);
188 while(destin.hasMoreTokens()) {
189 origin.nextToken();
190 destin.nextToken();
191 }
192 File copied_file = new File(copied_dir.getAbsolutePath());
193 while(origin.hasMoreTokens()) {
194 copied_file = new File(copied_file, origin.nextToken());
195 }
196 copy(file, copied_file);
197 copied_file = null;
198 origin = null;
199 destin = null;
200 }
201 }
202 file = null;
203 }
204 spd.setProgress(getValue(COPY_COLLECTION));
205 // 4. Restore origin collection by undoing file copy actions and removing the ~ from the end of collection files.
206 ///ystem.err.println("4. Restore origin.");
207 Gatherer.c_man.undo.undoAll();
208 ///ystem.err.println(" - UndoAll complete.");
209 // Recurse collection tree restoring *~
210 files.clear(); // Should be empty anyway.
211 files.add(collection_file.getParentFile());
212 while(files.size() > 0) {
213 File file = (File) files.get(0);
214 files.remove(0);
215 if(file.isDirectory()) {
216 File children[] = file.listFiles();
217 for(int i = 0; i < children.length; i++) {
218 files.add(children[i]);
219 }
220 children = null;
221 }
222 else if(file.getName().endsWith("~")) {
223 String filename = file.getAbsolutePath();
224 File original_file = new File(filename.substring(0, filename.length() - 1));
225 ///ystem.err.println("Renaming " + filename);
226 if(!file.renameTo(original_file)) {
227 Gatherer.println("Error in SaveCollectionTask.run(): FileRenameException");
228 }
229 }
230 }
231 ///ystem.err.println(" - Restore *~ complete.");
232 spd.setProgress(getValue(RESTORE_COLLECTION));
233 // 5. Close the origin collection.
234 ///ystem.err.println("5. Close origin.");
235 collection.setSaved(true);
236 Gatherer.c_man.closeCollection();
237 spd.setProgress(getValue(CLOSE_COLLECTION));
238 // 6. Open the copied collection.
239 ///ystem.err.println("6. Open copy.");
240 Gatherer.c_man.loadCollection(copied_dir.getAbsolutePath() + File.separator + name + ".col");
241 spd.setProgress(getValue(OPEN_COLLECTION));
242 copied_dir = null;
243 }
244 spd.close();
245 spd = null;
246 tmp_loc = null;
247 args = null;
248 // Reset undo queue.
249 if(Gatherer.c_man.ready()) {
250 Gatherer.c_man.undo.clear();
251 }
252 Gatherer.g_man.wait(false);
253
254 // Now we are finished action any necessary action.
255 if(import_after) {
256 Gatherer.c_man.importCollection();
257 }
258 if(close_after) {
259 Gatherer.c_man.closeCollection();
260 }
261 ///ystem.err.println("Save Complete.");
262 if(exit_after) {
263 Gatherer.self.exit();
264 }
265 }
266
267 public void setImportAfter(boolean state) {
268 import_after = true;
269 }
270
271 private void copy(File source, File destination) {
272 ///ystem.err.println("Copy: " + source.getAbsolutePath());
273 ///ystem.err.println(" to: " + destination.getAbsolutePath());
274 try {
275 destination.getParentFile().mkdirs();
276 FileInputStream f_in = new FileInputStream(source);
277 FileOutputStream f_out = new FileOutputStream(destination);
278 byte data[] = new byte[Utility.BUFFER_SIZE];
279 int data_size = 0;
280 while((data_size = f_in.read(data, 0, Utility.BUFFER_SIZE)) != -1) {
281 f_out.write(data, 0, data_size);
282 }
283 f_in.close();
284 f_out.close();
285 }
286 catch (Exception exception) {
287 Gatherer.printStackTrace(exception);
288 }
289 }
290
291 private int getValue(int reference) {
292 double multiplier;
293 if(name == null) {
294 multiplier = 1.0;
295 }
296 else {
297 multiplier = 0.25;
298 }
299 switch(reference) {
300 // Standard Save
301 case COLLECTION_SAVED:
302 return (int)((double)70 * multiplier);
303 case COLLECTION_CFG_SAVED:
304 case METADATA_SAVED:
305 case METADATA_XML_SAVED:
306 return (int)((double)10 * multiplier);
307 // Save As
308 case MAKE_COLLECTION:
309 return 5;
310 case COPY_COLLECTION:
311 return 30;
312 case RESTORE_COLLECTION:
313 return 30;
314 case CLOSE_COLLECTION:
315 return 10;
316 case OPEN_COLLECTION:
317 return 10;
318 }
319 return 0;
320 }
321}
322
323
324
325
326
Note: See TracBrowser for help on using the repository browser.