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

Last change on this file since 8236 was 8236, checked in by mdewsnip, 20 years ago

Replaced all Gatherer.print* with DebugStream.print*.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
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 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
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 */
37package org.greenstone.gatherer.collection;
38
39import java.io.*;
40import java.util.*;
41import javax.swing.*;
42import org.greenstone.gatherer.Configuration;
43import org.greenstone.gatherer.DebugStream;
44import org.greenstone.gatherer.Gatherer;
45import org.greenstone.gatherer.collection.Collection;
46import org.greenstone.gatherer.util.Utility;
47
48/** 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.
49 * @author John Thompson, Greenstone Digital Library, University of Waikato
50 * @version 2.3
51 */
52public class SaveCollectionTask
53 extends Thread {
54 private boolean close_after = false;
55 /** Should we exit the Gatherer once this save is complete. */
56 private boolean exit_after = false;
57 /** Do we run the import scripts once this save is complete. */
58 private boolean import_after = false;
59 /** The current collection. */
60 private Collection collection = null;
61 /** The filename of the collection we are saving. */
62 private String name = null;
63 static final private int CLOSE_COLLECTION = 0;
64 static final private int COLLECTION_COPIED = 1;
65 static final private int COLLECTION_SAVED = 2;
66 static final private int COLLECTION_CFG_SAVED = 3;
67 static final private int COPY_COLLECTION = 4;
68 static final private int MAKE_COLLECTION = 5;
69 static final private int METADATA_SAVED = 6;
70 static final private int METADATA_XML_SAVED = 7;
71 static final private int OPEN_COLLECTION = 8;
72 static final private int RESTORE_COLLECTION = 9;
73 /** Constructor.
74 * @param collection The <strong>Collection</strong> we are saving.
75 * @see org.greenstone.gatherer.collection.Collection
76 */
77 public SaveCollectionTask(Collection collection) {
78 this.collection = collection;
79 }
80 /** Constructor.
81 * @param exit_after <i>true</i> to cause the Gatherer to exit once save is complete, <i>false</i> otherwise.
82 */
83 public SaveCollectionTask(Collection collection, boolean close_after, boolean exit_after) {
84 this.close_after = close_after;
85 this.collection = collection;
86 this.exit_after = exit_after;
87 }
88 /** Constructor.
89 * @param name The filename of the collection we are saving as.
90 */
91 public SaveCollectionTask(Collection collection, String name) {
92 this.collection = collection;
93 this.name = name;
94 }
95 /** <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>
96 * <p>1. Perform a regular collection save on what we will later refer to as the origin collection.</p>
97 * <p>2. Call CollectionManager.makeCollection() to create the collection structure to save into (copied collection).</p>
98 * <p>3. Copy files from the origin to the copied collections (except special collection files ending with ~).</p>
99 * <p>4. Restore origin collection by undoing file copy actions and removing the ~ from the end of collection files.</p>
100 * <p>5. Close the origin collection.</p>
101 * <p>6. Open the copied collection.</p>
102 * <p>Of course all of this takes a while, and depends on several other bits of code to work properly.</p>.
103 * @see org.greenstone.gatherer.collection.Collection
104 * @see org.greenstone.gatherer.gui.GUIManager
105 * @see org.greenstone.gatherer.util.Utility
106 */
107 public void run() {
108 // Change cursor to hourglass.
109 Gatherer.g_man.wait(true);
110 // Create progress monitor box. It will display itself as necessary.
111 // WARNING: ProgressMonitors seem to be extremely dodgy, and are not recommended!
112 // ProgressMonitor spd = new ProgressMonitor(Gatherer.g_man, 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 // spd.setProgress(getValue(METADATA_XML_SAVED));
127
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 DebugStream.println("Error in CollectionManager.load(): FileRenamedException");
135 }
136 }
137
138 // Carry on.
139 collection.save();
140 // spd.setProgress(getValue(COLLECTION_SAVED));
141
142 // Write out the collection configuration file.
143 Gatherer.g_man.design_pane.saveConfiguration();
144 // spd.setProgress(getValue(COLLECTION_CFG_SAVED));
145
146 // Write out the metadata files.
147 Gatherer.c_man.msm.save();
148 // spd.setProgress(getValue(METADATA_SAVED));
149
150 collection.setSaved(true);
151 }
152 catch (Exception error) {
153 DebugStream.printStackTrace(error);
154 }
155 // Now we check whether we've finished, or is this a Save As action, in which case we've got miles to go.
156 if(name != null) {
157 // 2. Call CollectionManager.makeCollection() to create the collection structure to save into (copied collection).
158 ///ystem.err.println("2. Make copy.");
159 Gatherer.c_man.createCollection(null, null, name, null, null, null);
160 // spd.setProgress(getValue(MAKE_COLLECTION));
161 // 3. Copy files from the origin to the copied collections (except special collection files ending with ~).
162 // As part of this we must rename origin.col to copy.col
163 ///ystem.err.println("3. Copy origin.");
164 ArrayList files = new ArrayList();
165 File collection_file = new File(Gatherer.c_man.getCollectionFilename());
166 File copied_dir;
167 if (Gatherer.GS3) {
168 copied_dir = new File(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, name));
169 } else {
170 copied_dir = new File(Utility.getCollectionDir(Configuration.gsdl_path, name));
171 }
172 files.add(collection_file.getParentFile());
173 while(files.size() > 0) {
174 File file = (File) files.get(0);
175 files.remove(0);
176 if(file.isDirectory()) {
177 File children[] = file.listFiles();
178 for(int i = 0; i < children.length; i++) {
179 files.add(children[i]);
180 }
181 children = null;
182 }
183 else {
184 // Rename origin.col file.
185 if(file.equals(collection_file)) {
186 File copied_file = new File(copied_dir, name + ".col");
187 copy(collection_file, copied_file);
188 copied_file = null;
189 }
190 // Exclude *~ files from certain locations and lock.tmp file.
191 else if(!file.getName().endsWith("~") && !file.getName().equals(CollectionManager.LOCK_FILE)) {
192 StringTokenizer origin = new StringTokenizer(file.getAbsolutePath(), File.separator);
193 StringTokenizer destin = new StringTokenizer(copied_dir.getAbsolutePath(), File.separator);
194 while(destin.hasMoreTokens()) {
195 origin.nextToken();
196 destin.nextToken();
197 }
198 File copied_file = new File(copied_dir.getAbsolutePath());
199 while(origin.hasMoreTokens()) {
200 copied_file = new File(copied_file, origin.nextToken());
201 }
202 copy(file, copied_file);
203 copied_file = null;
204 origin = null;
205 destin = null;
206 }
207 }
208 file = null;
209 }
210 // spd.setProgress(getValue(COPY_COLLECTION));
211 // 4. Restore origin collection by undoing file copy actions and removing the ~ from the end of collection files.
212 ///ystem.err.println("4. Restore origin.");
213 // Gatherer.c_man.undo.undoAll();
214 ///ystem.err.println(" - UndoAll complete.");
215 // Recurse collection tree restoring *~
216 files.clear(); // Should be empty anyway.
217 files.add(collection_file.getParentFile());
218 while(files.size() > 0) {
219 File file = (File) files.get(0);
220 files.remove(0);
221 if(file.isDirectory()) {
222 File children[] = file.listFiles();
223 for(int i = 0; i < children.length; i++) {
224 files.add(children[i]);
225 }
226 children = null;
227 }
228 else if(file.getName().endsWith("~")) {
229 String filename = file.getAbsolutePath();
230 File original_file = new File(filename.substring(0, filename.length() - 1));
231 ///ystem.err.println("Renaming " + filename);
232 if(!file.renameTo(original_file)) {
233 DebugStream.println("Error in SaveCollectionTask.run(): FileRenameException");
234 }
235 }
236 }
237 ///ystem.err.println(" - Restore *~ complete.");
238 // spd.setProgress(getValue(RESTORE_COLLECTION));
239 // 5. Close the origin collection.
240 ///ystem.err.println("5. Close origin.");
241 collection.setSaved(true);
242 Gatherer.c_man.closeCollection();
243 // spd.setProgress(getValue(CLOSE_COLLECTION));
244 // 6. Open the copied collection.
245 ///ystem.err.println("6. Open copy.");
246 Gatherer.c_man.loadCollection(copied_dir.getAbsolutePath() + File.separator + name + ".col");
247 // spd.setProgress(getValue(OPEN_COLLECTION));
248 copied_dir = null;
249 }
250 // spd.close();
251 // spd = null;
252 tmp_loc = null;
253 args = null;
254 // Reset undo queue.
255 // if(Gatherer.c_man.ready()) {
256 // Gatherer.c_man.undo.clear();
257 // }
258 Gatherer.g_man.wait(false);
259
260 // Now we are finished action any necessary action.
261 if(import_after) {
262 Gatherer.c_man.importCollection();
263 }
264 if(close_after) {
265 Gatherer.c_man.closeCollection();
266 }
267 ///ystem.err.println("Save Complete.");
268 if(exit_after) {
269 Gatherer.self.exit();
270 }
271 }
272
273 public void setImportAfter(boolean state) {
274 import_after = true;
275 }
276
277 private void copy(File source, File destination) {
278 ///ystem.err.println("Copy: " + source.getAbsolutePath());
279 ///ystem.err.println(" to: " + destination.getAbsolutePath());
280 try {
281 destination.getParentFile().mkdirs();
282 FileInputStream f_in = new FileInputStream(source);
283 FileOutputStream f_out = new FileOutputStream(destination);
284 byte data[] = new byte[Utility.BUFFER_SIZE];
285 int data_size = 0;
286 while((data_size = f_in.read(data, 0, Utility.BUFFER_SIZE)) != -1) {
287 f_out.write(data, 0, data_size);
288 }
289 f_in.close();
290 f_out.close();
291 }
292 catch (Exception exception) {
293 DebugStream.printStackTrace(exception);
294 }
295 }
296
297 private int getValue(int reference) {
298 double multiplier;
299 if(name == null) {
300 multiplier = 1.0;
301 }
302 else {
303 multiplier = 0.25;
304 }
305 switch(reference) {
306 // Standard Save
307 case COLLECTION_SAVED:
308 return (int)((double)70 * multiplier);
309 case COLLECTION_CFG_SAVED:
310 case METADATA_SAVED:
311 case METADATA_XML_SAVED:
312 return (int)((double)10 * multiplier);
313 // Save As
314 case MAKE_COLLECTION:
315 return 5;
316 case COPY_COLLECTION:
317 return 30;
318 case RESTORE_COLLECTION:
319 return 30;
320 case CLOSE_COLLECTION:
321 return 10;
322 case OPEN_COLLECTION:
323 return 10;
324 }
325 return 0;
326 }
327}
328
329
330
331
332
Note: See TracBrowser for help on using the repository browser.