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 | */
|
---|
37 | package org.greenstone.gatherer.collection;
|
---|
38 |
|
---|
39 | import java.io.*;
|
---|
40 | import java.util.*;
|
---|
41 | import javax.swing.*;
|
---|
42 | import javax.swing.event.*;
|
---|
43 | import javax.swing.filechooser.FileSystemView;
|
---|
44 | import javax.swing.tree.*;
|
---|
45 | import org.greenstone.gatherer.Configuration;
|
---|
46 | import org.greenstone.gatherer.DebugStream;
|
---|
47 | import org.greenstone.gatherer.Dictionary;
|
---|
48 | import org.greenstone.gatherer.Gatherer;
|
---|
49 | import org.greenstone.gatherer.LocalGreenstone;
|
---|
50 | import org.greenstone.gatherer.LocalLibraryServer;
|
---|
51 | import org.greenstone.gatherer.ServletConfiguration;
|
---|
52 | import org.greenstone.gatherer.cdm.CollectionDesignManager;
|
---|
53 | import org.greenstone.gatherer.cdm.CollectionMeta;
|
---|
54 | import org.greenstone.gatherer.cdm.CollectionMetaManager;
|
---|
55 | import org.greenstone.gatherer.cdm.CommandTokenizer;
|
---|
56 | import org.greenstone.gatherer.gui.LockFileDialog;
|
---|
57 | import org.greenstone.gatherer.gui.ModalProgressPopup;
|
---|
58 | import org.greenstone.gatherer.gui.WarningDialog;
|
---|
59 | import org.greenstone.gatherer.metadata.DocXMLFileManager;
|
---|
60 | import org.greenstone.gatherer.metadata.MetadataChangedListener;
|
---|
61 | import org.greenstone.gatherer.metadata.MetadataSet;
|
---|
62 | import org.greenstone.gatherer.metadata.MetadataSetManager;
|
---|
63 | import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
|
---|
64 | import org.greenstone.gatherer.metadata.ProfileXMLFileManager;
|
---|
65 | import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
|
---|
66 | import org.greenstone.gatherer.shell.GShell;
|
---|
67 | import org.greenstone.gatherer.shell.GShellEvent;
|
---|
68 | import org.greenstone.gatherer.shell.GShellListener;
|
---|
69 | import org.greenstone.gatherer.shell.GShellProgressMonitor;
|
---|
70 | import org.greenstone.gatherer.util.Codec;
|
---|
71 | import org.greenstone.gatherer.util.StaticStrings;
|
---|
72 | import org.greenstone.gatherer.util.Utility;
|
---|
73 | import org.greenstone.gatherer.util.XMLTools;
|
---|
74 | import org.w3c.dom.*;
|
---|
75 |
|
---|
76 | /** This class manages many aspects of the collection, from its creation via scripts, data access via methods and its importing and building into the final collection. It is also resposible for firing appropriate event when significant changes have occured within the collection, and for creating a new metadata set manager as necessary.
|
---|
77 | * @author John Thompson
|
---|
78 | * @version 2.3
|
---|
79 | */
|
---|
80 | public class CollectionManager
|
---|
81 | implements GShellListener, MetadataChangedListener
|
---|
82 | {
|
---|
83 | /** Are we currently in the process of building? */
|
---|
84 | private boolean building = false;
|
---|
85 | /** Are we currently in the process of importing? */
|
---|
86 | private boolean importing = false;
|
---|
87 | /** The objects listening for CollectionContentsChanged events. */
|
---|
88 | private ArrayList collection_contents_changed_listeners = new ArrayList();
|
---|
89 | /** The collection this manager is managing! */
|
---|
90 | static private Collection collection = null;
|
---|
91 | /** The collection tree (used in both Gather and Enrich panes). */
|
---|
92 | static private CollectionTree collection_tree = null;
|
---|
93 | /** The collection tree model. */
|
---|
94 | private CollectionTreeModel collection_tree_model = null;
|
---|
95 | /** An inner class listener responsible for noting tree changes and resetting saved when they occur. */
|
---|
96 | private FMTreeModelListener fm_tree_model_listener = null;
|
---|
97 | /** The monitor resposible for parsing the build process. */
|
---|
98 | private GShellProgressMonitor build_monitor = null;
|
---|
99 | /** The monitor resposible for parsing the import process. */
|
---|
100 | private GShellProgressMonitor import_monitor = null;
|
---|
101 |
|
---|
102 | /** Whether we have downloaded the collection configurations in this session, when using a remote Greenstone. */
|
---|
103 | static public boolean downloaded_collection_configurations = false;
|
---|
104 |
|
---|
105 | /** The name of the standard lock file. */
|
---|
106 | static final public String LOCK_FILE = "gli.lck";
|
---|
107 |
|
---|
108 | /** Used to indicate the source of the message is the file collection methods. */
|
---|
109 | static final public int COLLECT = 3;
|
---|
110 | /** Used to indicate the source of the message is the building methods. */
|
---|
111 | static final public int BUILDING = 5;
|
---|
112 |
|
---|
113 | /** Constructor. */
|
---|
114 | public CollectionManager() {
|
---|
115 | // Initialisation.
|
---|
116 | this.building = false;
|
---|
117 | this.importing = false;
|
---|
118 | this.collection = null;
|
---|
119 |
|
---|
120 | MetadataXMLFileManager.addMetadataChangedListener(this);
|
---|
121 |
|
---|
122 | // If using a remote Greenstone server, delete the local collect directory because it will be out of date
|
---|
123 | if (Gatherer.isGsdlRemote) {
|
---|
124 | System.err.println("Deleting user's local collect directory...");
|
---|
125 | Utility.delete(new File(Gatherer.getCollectDirectoryPath()));
|
---|
126 | System.err.println("Done.");
|
---|
127 | new File(Gatherer.getCollectDirectoryPath()).mkdirs();
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 |
|
---|
132 | public void addCollectionContentsChangedListener(CollectionContentsChangedListener listener)
|
---|
133 | {
|
---|
134 | collection_contents_changed_listeners.add(listener);
|
---|
135 | }
|
---|
136 |
|
---|
137 |
|
---|
138 | /** This method calls the builcol.pl scripts via a GShell so as to not lock up the processor.
|
---|
139 | * @see org.greenstone.gatherer.Configuration
|
---|
140 | * @see org.greenstone.gatherer.Gatherer
|
---|
141 | * @see org.greenstone.gatherer.collection.Collection
|
---|
142 | * @see org.greenstone.gatherer.gui.BuildOptions
|
---|
143 | * @see org.greenstone.gatherer.shell.GShell
|
---|
144 | * @see org.greenstone.gatherer.shell.GShellListener
|
---|
145 | * @see org.greenstone.gatherer.shell.GShellProgressMonitor
|
---|
146 | * @see org.greenstone.gatherer.util.Utility
|
---|
147 | */
|
---|
148 | public void buildCollection(boolean incremental_build)
|
---|
149 | {
|
---|
150 | DebugStream.println("In CollectionManager.buildCollection(), incremental_build: " + incremental_build);
|
---|
151 | DebugStream.println("Is event dispatch thread: " + SwingUtilities.isEventDispatchThread());
|
---|
152 | building = true;
|
---|
153 |
|
---|
154 | // Generate the buildcol.pl command
|
---|
155 | ArrayList command_parts_list = new ArrayList();
|
---|
156 | if ((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
|
---|
157 | command_parts_list.add(Configuration.perl_path);
|
---|
158 | command_parts_list.add("-S");
|
---|
159 | }
|
---|
160 | command_parts_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "buildcol.pl");
|
---|
161 | command_parts_list.add("-gli");
|
---|
162 | command_parts_list.add("-language");
|
---|
163 | command_parts_list.add(Configuration.getLanguage());
|
---|
164 | command_parts_list.add("-collectdir");
|
---|
165 | command_parts_list.add(getCollectDirectory());
|
---|
166 |
|
---|
167 | // If the user hasn't manually specified "-keepold" or "-removeold" then pick one based on incremental_build
|
---|
168 | if (!collection.build_options.getValueEnabled("keepold") && !collection.build_options.getValueEnabled("removeold")) {
|
---|
169 | command_parts_list.add(incremental_build ? "-keepold" : "-removeold");
|
---|
170 | }
|
---|
171 |
|
---|
172 | String[] build_options = collection.build_options.getValues();
|
---|
173 | for (int i = 0; i < build_options.length; i++) {
|
---|
174 | command_parts_list.add(build_options[i]);
|
---|
175 | }
|
---|
176 |
|
---|
177 | command_parts_list.add(collection.getName());
|
---|
178 |
|
---|
179 | // Run the buildcol.pl command
|
---|
180 | String[] command_parts = (String[]) command_parts_list.toArray(new String[0]);
|
---|
181 | GShell shell = new GShell(command_parts, GShell.BUILD, BUILDING, this, build_monitor, GShell.GSHELL_BUILD);
|
---|
182 | shell.addGShellListener(Gatherer.g_man.create_pane);
|
---|
183 | shell.start();
|
---|
184 |
|
---|
185 | }
|
---|
186 |
|
---|
187 |
|
---|
188 | /** Used to determine whether the currently active collection has been built.
|
---|
189 | * @return A boolean indicating the built status of the collection.
|
---|
190 | */
|
---|
191 | public boolean built() {
|
---|
192 | if(collection != null) {
|
---|
193 | // Determine if the collection has been built by looking for the build.cfg file
|
---|
194 | File build_cfg_file = new File(getCollectionIndexDirectoryPath() + "build.cfg");
|
---|
195 | return build_cfg_file.exists();
|
---|
196 | }
|
---|
197 | return false;
|
---|
198 | }
|
---|
199 |
|
---|
200 | /** a test method to see if we can delete a directory/file - returns false is the file or any of the contents of a directory cannot be deleted */
|
---|
201 | public boolean canDelete(File file) {
|
---|
202 | if (!file.isDirectory()) {
|
---|
203 | return file.canWrite();
|
---|
204 | }
|
---|
205 | File [] file_list = file.listFiles();
|
---|
206 | for (int i=0; i<file_list.length; i++) {
|
---|
207 | if (!canDelete(file_list[i])) {
|
---|
208 | return false;
|
---|
209 | }
|
---|
210 | }
|
---|
211 | return true;
|
---|
212 | }
|
---|
213 | /** Called to close the current collection and remove its lock file.
|
---|
214 | * @see org.greenstone.gatherer.Gatherer
|
---|
215 | * @see org.greenstone.gatherer.collection.Collection
|
---|
216 | * @see org.greenstone.gatherer.util.Utility
|
---|
217 | */
|
---|
218 | public void closeCollection() {
|
---|
219 | DebugStream.println("Close collection: " + collection.getName());
|
---|
220 |
|
---|
221 | // Remove the lock on this file, then remove the collection.
|
---|
222 | File lock_file = new File(getCollectionDirectoryPath() + LOCK_FILE);
|
---|
223 | lock_file.delete();
|
---|
224 | if (lock_file.exists()) {
|
---|
225 | System.err.println("Warning: Lockfile was not successfully deleted.");
|
---|
226 | }
|
---|
227 |
|
---|
228 | // Remove the lock file on the server
|
---|
229 | if (Gatherer.isGsdlRemote) {
|
---|
230 | RemoteGreenstoneServer.deleteCollectionFile(collection.getName(), lock_file);
|
---|
231 | }
|
---|
232 |
|
---|
233 | MetadataSetManager.clearMetadataSets();
|
---|
234 | MetadataXMLFileManager.clearMetadataXMLFiles();
|
---|
235 | DocXMLFileManager.clearDocXMLFiles();
|
---|
236 | ProfileXMLFileManager.clearProfileXMLFile();
|
---|
237 |
|
---|
238 | collection = null;
|
---|
239 | collection_tree_model = null;
|
---|
240 | Configuration.setCollectionConfiguration(null);
|
---|
241 | Gatherer.refresh(Gatherer.COLLECTION_CLOSED);
|
---|
242 | if (Gatherer.g_man != null) {
|
---|
243 | Gatherer.g_man.updateUI(); // !!! Necessary?
|
---|
244 | }
|
---|
245 | }
|
---|
246 |
|
---|
247 | /** Method that is called whenever something has changed in the configuration of this collection. */
|
---|
248 | public void configurationChanged() {
|
---|
249 | if(collection != null) {
|
---|
250 | collection.setSaved(false);
|
---|
251 | collection.cdm.update_collect_cfg_required = true;
|
---|
252 | }
|
---|
253 | }
|
---|
254 |
|
---|
255 | public void convertToGS3Collection() {
|
---|
256 | // Generate the convert_coll_from_gs2.pl command
|
---|
257 | ArrayList command_parts_list = new ArrayList();
|
---|
258 | if ((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
|
---|
259 | command_parts_list.add(Configuration.perl_path);
|
---|
260 | command_parts_list.add("-S");
|
---|
261 | }
|
---|
262 | command_parts_list.add(Configuration.getGS3ScriptPath() + "convert_coll_from_gs2.pl");
|
---|
263 | command_parts_list.add("-collectdir");
|
---|
264 | command_parts_list.add(getCollectDirectory());
|
---|
265 | command_parts_list.add(collection.getName());
|
---|
266 |
|
---|
267 | // Run the convert_coll_from_gs2.pl command
|
---|
268 | String[] command_parts = (String[]) command_parts_list.toArray(new String[0]);
|
---|
269 | GShell process = new GShell(command_parts, GShell.CONVERT, COLLECT, this, null, GShell.GSHELL_CONVERT);
|
---|
270 | process.addGShellListener(this);
|
---|
271 | process.run(); // Don't bother threading this... yet
|
---|
272 |
|
---|
273 | }
|
---|
274 |
|
---|
275 | /** When basing a new collection on an existing one, we need to copy
|
---|
276 | * over some extra directories: images and macros
|
---|
277 | */
|
---|
278 | private boolean copyExtraBaseCollStuff(File new_coll_dir, File base_coll_dir) {
|
---|
279 | if (!new_coll_dir.isDirectory() || !base_coll_dir.isDirectory()) {
|
---|
280 | return false;
|
---|
281 | }
|
---|
282 | DebugStream.println("Copying images and macros dirs from the base collection");
|
---|
283 | try {
|
---|
284 | // do the images dir
|
---|
285 | File base_coll_images = new File(base_coll_dir, "images");
|
---|
286 | if (base_coll_images.isDirectory()) {
|
---|
287 | // copy all the images over
|
---|
288 | File new_coll_images = new File(new_coll_dir, "images");
|
---|
289 | new_coll_images.mkdirs();
|
---|
290 |
|
---|
291 | // copy the contents over
|
---|
292 | Gatherer.f_man.getQueue().copyDirectoryContents(base_coll_images, new_coll_images);
|
---|
293 | }
|
---|
294 | }
|
---|
295 | catch (Exception e) {
|
---|
296 | DebugStream.println("Couldn't copy over the images dir from the base collection: "+e.toString());
|
---|
297 | }
|
---|
298 | try {
|
---|
299 | // do the macros dir
|
---|
300 | File base_coll_macros = new File(base_coll_dir, "macros");
|
---|
301 | if (base_coll_macros.isDirectory()) {
|
---|
302 | // copy all the macros over
|
---|
303 | File new_coll_macros = new File(new_coll_dir, "macros");
|
---|
304 | new_coll_macros.mkdirs();
|
---|
305 |
|
---|
306 | // copy the contents over
|
---|
307 | Gatherer.f_man.getQueue().copyDirectoryContents(base_coll_macros, new_coll_macros);
|
---|
308 | }
|
---|
309 | }
|
---|
310 | catch (Exception e) {
|
---|
311 | DebugStream.println("Couldn't copy over the macros dir from the base collection: "+e.toString());
|
---|
312 | }
|
---|
313 | return true;
|
---|
314 | }
|
---|
315 |
|
---|
316 | /** Used to set the current collection to the given collection. Note that this call should -always- be proceeded by a ready call, and if the collection is ready and the saved flag is unset then the user should be prompted to save. Also note that this method creates yet another GShell to run buildcol.pl.
|
---|
317 | * @param description a description of the collection as a String
|
---|
318 | * @param email the email address of the author/maintainer as a String
|
---|
319 | * @param name the short name of the collection, which will subsequently be used to refer to this particular collection, as a String
|
---|
320 | * @param title the longer title of the collection as a String
|
---|
321 | * @param base_collection_directory if the user has chosen to base their new collection on an existing one, this is the directory where this base collection can be found, as a File, otherwise its null
|
---|
322 | * @param metadata_sets if the user has decided to select several metadata sets with which to initially populate the GLI then this is an ArrayList of metadata set file names, otherwise its null
|
---|
323 | */
|
---|
324 | public void createCollection(String description, String email, String name, String title, File base_collection_directory, ArrayList metadata_sets)
|
---|
325 | {
|
---|
326 | try {
|
---|
327 | // first make sure that the collect directory exists
|
---|
328 | File collect_dir = new File(getCollectDirectory());
|
---|
329 | if (!collect_dir.exists()) {
|
---|
330 | collect_dir.mkdirs();
|
---|
331 | }
|
---|
332 |
|
---|
333 | // Create a progress monitor
|
---|
334 | ProgressMonitor progress = new ProgressMonitor(Gatherer.g_man, Dictionary.get("CollectionManager.Creating_New"), "mkcol.pl", 0, 4);
|
---|
335 |
|
---|
336 | // Create the new collection
|
---|
337 | makeCollection(name, email);
|
---|
338 | progress.setProgress(1);
|
---|
339 |
|
---|
340 | // Check that the collection has been created successfully
|
---|
341 | String collection_directory_path = getCollectionDirectoryPath(name);
|
---|
342 | if (!new File(collection_directory_path).exists()) {
|
---|
343 | // If there is no collection directory then the creation was unsuccessful, or cancelled
|
---|
344 | System.err.println("No collection directory...");
|
---|
345 | progress.close();
|
---|
346 | return;
|
---|
347 | }
|
---|
348 |
|
---|
349 | // Check for the existence of the collect.cfg file
|
---|
350 | File collect_cfg_file = new File(collection_directory_path + "etc" + File.separator + "collect.cfg");
|
---|
351 | if (!collect_cfg_file.exists()) {
|
---|
352 | System.err.println("Error: no collect.cfg file has been created!");
|
---|
353 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Create_Collection_With_Reason", Dictionary.get("CollectionManager.No_Config_File")), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
354 | progress.close();
|
---|
355 | return;
|
---|
356 | }
|
---|
357 |
|
---|
358 | // ACTIVE_DIR/log/
|
---|
359 | File log_dir = new File(collection_directory_path + "log");
|
---|
360 | log_dir.mkdirs();
|
---|
361 | progress.setNote(Dictionary.get("CollectionManager.Log_Created"));
|
---|
362 |
|
---|
363 | // Make sure an import folder exists
|
---|
364 | File import_directory = new File(collection_directory_path + "import");
|
---|
365 | if (!import_directory.exists()) {
|
---|
366 | import_directory.mkdirs();
|
---|
367 | }
|
---|
368 |
|
---|
369 | progress.setProgress(2);
|
---|
370 |
|
---|
371 | // Now create the collection object around the directory.
|
---|
372 | collection = new Collection(new File(collection_directory_path, name + ".col"));
|
---|
373 |
|
---|
374 | // "-removeold" is on by default for import.pl
|
---|
375 | collection.import_options.setValue("removeold", true, null);
|
---|
376 |
|
---|
377 | MetadataSetManager.clearMetadataSets();
|
---|
378 | MetadataXMLFileManager.clearMetadataXMLFiles();
|
---|
379 | DocXMLFileManager.clearDocXMLFiles();
|
---|
380 |
|
---|
381 | // Import default metadata sets, if any
|
---|
382 | for (int i = 0; metadata_sets != null && i < metadata_sets.size(); i++) {
|
---|
383 | importMetadataSet((MetadataSet) metadata_sets.get(i));
|
---|
384 | }
|
---|
385 |
|
---|
386 | ProfileXMLFileManager.loadProfileXMLFile(new File(collection_directory_path + "metadata"));
|
---|
387 |
|
---|
388 | // Before creating the CollectionDesignManager check if we are basing it upon some other collection
|
---|
389 | if (base_collection_directory != null) {
|
---|
390 | DebugStream.println("Basing new collection on existing one: " + base_collection_directory);
|
---|
391 |
|
---|
392 | // If we're using a remote Greenstone server, download the collection shell to get the files needed
|
---|
393 | if (Gatherer.isGsdlRemote) {
|
---|
394 | String base_collection_name = base_collection_directory.getName();
|
---|
395 | RemoteGreenstoneServer.downloadCollection(base_collection_name);
|
---|
396 | }
|
---|
397 |
|
---|
398 | collection.setBaseCollection(base_collection_directory.getAbsolutePath());
|
---|
399 | // copy over other needed directories
|
---|
400 | copyExtraBaseCollStuff(new File(collection_directory_path), base_collection_directory);
|
---|
401 |
|
---|
402 | // Try to import any existing metadata sets for this collection
|
---|
403 | // Look in base_collection_directory/metadata and import any metadata sets found.
|
---|
404 | File base_metadata_directory = new File(base_collection_directory, "metadata");
|
---|
405 | ArrayList base_metadata_sets = MetadataSetManager.listMetadataSets(base_metadata_directory);
|
---|
406 | if (base_metadata_sets != null) {
|
---|
407 | for (int i = 0; i < base_metadata_sets.size(); i++) {
|
---|
408 | importMetadataSet((MetadataSet) base_metadata_sets.get(i));
|
---|
409 | }
|
---|
410 | }
|
---|
411 | else {
|
---|
412 | DebugStream.println("This base collection has no metadata directory.");
|
---|
413 | }
|
---|
414 |
|
---|
415 | // Now we update our collect.cfg
|
---|
416 | DebugStream.println("Copy and update collect.cfg from base collection.");
|
---|
417 | updateCollectionCFG(new File(base_collection_directory, Utility.CONFIG_FILE), new File(collection_directory_path, Utility.CONFIG_FILE), description, email, title);
|
---|
418 | }
|
---|
419 |
|
---|
420 | // Always import the extracted metadata set if we didn't already
|
---|
421 | if (MetadataSetManager.getMetadataSet(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE) == null) {
|
---|
422 | File extracted_metadata_set_file = new File(Gatherer.getGLIMetadataDirectoryPath() + MetadataSetManager.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION);
|
---|
423 | importMetadataSet(new MetadataSet(extracted_metadata_set_file));
|
---|
424 | }
|
---|
425 |
|
---|
426 | collection.cdm = new CollectionDesignManager(new File(getCollectionConfigFilePath()));
|
---|
427 |
|
---|
428 | // We always set title and description here rather than calling mkcol.pl with Unicode arguments
|
---|
429 | CollectionMeta collection_name_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR);
|
---|
430 | collection_name_collectionmeta.setValue(title);
|
---|
431 | CollectionMeta collection_extra_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
|
---|
432 | collection_extra_collectionmeta.setValue(description);
|
---|
433 |
|
---|
434 | // Now that we have a CDM, update several settings, such as if we created this collection by basing it on another, set it as public automatically
|
---|
435 | if (base_collection_directory != null) {
|
---|
436 | // Update the creator and maintainer
|
---|
437 | CollectionMeta creator_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getCreator());
|
---|
438 | creator_collectionmeta.setValue(email);
|
---|
439 | creator_collectionmeta = null;
|
---|
440 | CollectionMeta maintainer_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getMaintainer());
|
---|
441 | maintainer_collectionmeta.setValue(email);
|
---|
442 | maintainer_collectionmeta = null;
|
---|
443 |
|
---|
444 | // All collections based on others are automatically public
|
---|
445 | CollectionMeta public_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getPublic());
|
---|
446 | public_collectionmeta.setValue(StaticStrings.TRUE_STR);
|
---|
447 | public_collectionmeta = null;
|
---|
448 |
|
---|
449 | // Finally reset the icons
|
---|
450 | CollectionMeta icon_collection_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR);
|
---|
451 | icon_collection_collectionmeta.setValue(StaticStrings.EMPTY_STR);
|
---|
452 | icon_collection_collectionmeta = null;
|
---|
453 | CollectionMeta icon_collection_small_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR);
|
---|
454 | icon_collection_small_collectionmeta.setValue(StaticStrings.EMPTY_STR);
|
---|
455 | icon_collection_small_collectionmeta = null;
|
---|
456 | }
|
---|
457 |
|
---|
458 | collection.cdm.save(true);
|
---|
459 | progress.setProgress(3);
|
---|
460 |
|
---|
461 | // Create a lock file
|
---|
462 | createLockFile(new File(collection_directory_path, LOCK_FILE));
|
---|
463 |
|
---|
464 | progress.setProgress(4);
|
---|
465 | progress.setNote(Dictionary.get("CollectionManager.Session_Ready", name));
|
---|
466 | progress.close();
|
---|
467 | }
|
---|
468 | catch (Exception error) {
|
---|
469 | DebugStream.printStackTrace(error);
|
---|
470 | }
|
---|
471 | }
|
---|
472 |
|
---|
473 |
|
---|
474 | private void createLockFile(File lock_file)
|
---|
475 | {
|
---|
476 | try {
|
---|
477 | Document default_lockfile = XMLTools.parseXMLFile("xml/" + LOCK_FILE, true);
|
---|
478 | String user_name = System.getProperty("user.name");
|
---|
479 | Element person_element = (Element) XMLTools.getNodeFromNamed(default_lockfile.getDocumentElement(), "User");
|
---|
480 | person_element.appendChild(default_lockfile.createTextNode(user_name));
|
---|
481 | person_element = null;
|
---|
482 | user_name = null;
|
---|
483 | String machine_name = Utility.getMachineName();
|
---|
484 | Element machine_element = (Element) XMLTools.getNodeFromNamed(default_lockfile.getDocumentElement(), "Machine");
|
---|
485 | machine_element.appendChild(default_lockfile.createTextNode(machine_name));
|
---|
486 | machine_element = null;
|
---|
487 | machine_name = null;
|
---|
488 | String date_time = Utility.getDateString();
|
---|
489 | Element date_element = (Element) XMLTools.getNodeFromNamed(default_lockfile.getDocumentElement(), "Date");
|
---|
490 | date_element.appendChild(default_lockfile.createTextNode(date_time));
|
---|
491 | date_element = null;
|
---|
492 | date_time = null;
|
---|
493 | XMLTools.writeXMLFile(lock_file, default_lockfile);
|
---|
494 | }
|
---|
495 | catch (Exception exception) {
|
---|
496 | DebugStream.printStackTrace(exception);
|
---|
497 | }
|
---|
498 | }
|
---|
499 |
|
---|
500 |
|
---|
501 | public boolean deleteCollection(String collection_name)
|
---|
502 | {
|
---|
503 | return Utility.delete(new File(getCollectionDirectoryPath(collection_name)));
|
---|
504 | }
|
---|
505 |
|
---|
506 |
|
---|
507 | public void fireFileAddedToCollection(File file)
|
---|
508 | {
|
---|
509 | // Send the event off to all the CollectionContentsChangedListeners
|
---|
510 | for (int i = 0; i < collection_contents_changed_listeners.size(); i++) {
|
---|
511 | ((CollectionContentsChangedListener) collection_contents_changed_listeners.get(i)).fileAddedToCollection(file);
|
---|
512 | }
|
---|
513 | }
|
---|
514 |
|
---|
515 |
|
---|
516 | /** Retrieve the current collection.
|
---|
517 | * @return The <strong>Collection</strong> itself.
|
---|
518 | */
|
---|
519 | public Collection getCollection() {
|
---|
520 | return collection;
|
---|
521 | }
|
---|
522 |
|
---|
523 |
|
---|
524 | static public String getCollectionDirectoryPath()
|
---|
525 | {
|
---|
526 | return Gatherer.getCollectDirectoryPath() + collection.getName() + File.separator;
|
---|
527 | }
|
---|
528 |
|
---|
529 |
|
---|
530 | /** Constructs the absolute filename of the collection's directory, which should resemble "$GSDLHOME/collect/<col_name>"
|
---|
531 | * @return A <strong>String</strong> containing the directory name.
|
---|
532 | */
|
---|
533 | static public String getCollectionDirectoryPath(String collection_name)
|
---|
534 | {
|
---|
535 | return Gatherer.getCollectDirectoryPath() + collection_name + File.separator;
|
---|
536 | }
|
---|
537 |
|
---|
538 |
|
---|
539 | /** Constructs the absolute filename of the collection's .col file, which should resemble "$GSDLHOME/collect/<col_name>/<col_name>.col"
|
---|
540 | * @return A <strong>String</strong> containing the filename.
|
---|
541 | */
|
---|
542 | public String getCollectionFilePath()
|
---|
543 | {
|
---|
544 | return getCollectionDirectoryPath() + collection.getName() + ".col";
|
---|
545 | }
|
---|
546 |
|
---|
547 |
|
---|
548 | /** Constructs the absolute filename of the collection's archives directory, which should resemble "$GSDLHOME/collect/<col_name>/archives/"
|
---|
549 | * @return A <strong>String</strong> containing the filename.
|
---|
550 | */
|
---|
551 | public String getCollectionArchivesDirectoryPath()
|
---|
552 | {
|
---|
553 | return getCollectionDirectoryPath() + "archives" + File.separator;
|
---|
554 | }
|
---|
555 |
|
---|
556 |
|
---|
557 | /** Constructs the absolute filename of the collection's building directory, which should resemble "$GSDLHOME/collect/<col_name>/building/"
|
---|
558 | * @return A <strong>String</strong> containing the filename.
|
---|
559 | */
|
---|
560 | public String getCollectionBuildingDirectoryPath()
|
---|
561 | {
|
---|
562 | return getCollectionDirectoryPath() + "building" + File.separator;
|
---|
563 | }
|
---|
564 |
|
---|
565 |
|
---|
566 | /** Constructs the absolute filename of the collection's collect.cfg file, which should resemble "$GSDLHOME/collect/<col_name>/etc/collect.cfg"
|
---|
567 | * @return A <strong>String</strong> containing the filename.
|
---|
568 | */
|
---|
569 | public String getCollectionConfigFilePath()
|
---|
570 | {
|
---|
571 | return getCollectionEtcDirectoryPath() + "collect.cfg";
|
---|
572 | }
|
---|
573 |
|
---|
574 |
|
---|
575 | /** Constructs the absolute filename of the collection's etc directory, which should resemble "$GSDLHOME/collect/<col_name>/etc/"
|
---|
576 | * @return A <strong>String</strong> containing the filename.
|
---|
577 | */
|
---|
578 | public String getCollectionEtcDirectoryPath()
|
---|
579 | {
|
---|
580 | return getCollectionDirectoryPath() + "etc" + File.separator;
|
---|
581 | }
|
---|
582 |
|
---|
583 |
|
---|
584 | /** Constructs the absolute filename of the collection's images directory, which should resemble "$GSDLHOME/collect/<col_name>/images/"
|
---|
585 | * @return A <strong>String</strong> containing the filename.
|
---|
586 | */
|
---|
587 | public String getCollectionImagesDirectoryPath()
|
---|
588 | {
|
---|
589 | return getCollectionDirectoryPath() + "images" + File.separator;
|
---|
590 | }
|
---|
591 |
|
---|
592 |
|
---|
593 | /** Constructs the absolute filename of the collection's import directory, which should resemble "$GSDLHOME/collect/<col_name>/import/"
|
---|
594 | * @return A <strong>String</strong> containing the filename.
|
---|
595 | */
|
---|
596 | public String getCollectionImportDirectoryPath()
|
---|
597 | {
|
---|
598 | return getCollectionDirectoryPath() + "import" + File.separator;
|
---|
599 | }
|
---|
600 |
|
---|
601 |
|
---|
602 | /** Constructs the absolute filename of the collection's index directory, which should resemble "$GSDLHOME/collect/<col_name>/index/"
|
---|
603 | * @return A <strong>String</strong> containing the filename.
|
---|
604 | */
|
---|
605 | public String getCollectionIndexDirectoryPath()
|
---|
606 | {
|
---|
607 | return getCollectionDirectoryPath() + "index" + File.separator;
|
---|
608 | }
|
---|
609 |
|
---|
610 |
|
---|
611 | /** Constructs the absolute filename of the collection's log directory, which should resemble "$GSDLHOME/collect/<col_name>/log/"
|
---|
612 | * @return A <strong>String</strong> containing the filename.
|
---|
613 | */
|
---|
614 | public String getCollectionLogDirectoryPath()
|
---|
615 | {
|
---|
616 | return getCollectionDirectoryPath() + "log" + File.separator;
|
---|
617 | }
|
---|
618 |
|
---|
619 |
|
---|
620 | /** Constructs the absolute filename of the collection's metadata directory, which should resemble "$GSDLHOME/collect/<col_name>/metadata/"
|
---|
621 | * @return A <strong>String</strong> containing the filename.
|
---|
622 | */
|
---|
623 | public String getCollectionMetadataDirectoryPath()
|
---|
624 | {
|
---|
625 | return getCollectionDirectoryPath() + "metadata" + File.separator;
|
---|
626 | }
|
---|
627 |
|
---|
628 | /** Constructs the absolute filename of the collection's metadata directory, which should resemble "$GSDLHOME/collect/<col_name>/metadata/"
|
---|
629 | * @return A <strong>String</strong> containing the filename.
|
---|
630 | */
|
---|
631 | public String getCollectionPluginsDirectoryPath()
|
---|
632 | {
|
---|
633 | return getCollectionDirectoryPath() + "perllib" + File.separator +
|
---|
634 | "plugins" + File.separator;
|
---|
635 | }
|
---|
636 | /** Constructs the absolute filename of the collection's metadata directory, which should resemble "$GSDLHOME/collect/<col_name>/metadata/"
|
---|
637 | * @return A <strong>String</strong> containing the filename.
|
---|
638 | */
|
---|
639 | public String getCollectionClassifiersDirectoryPath()
|
---|
640 | {
|
---|
641 | return getCollectionDirectoryPath() + "perllib" + File.separator +
|
---|
642 | "classify" + File.separator;
|
---|
643 | }
|
---|
644 |
|
---|
645 |
|
---|
646 | public CollectionTree getCollectionTree()
|
---|
647 | {
|
---|
648 | if (collection_tree == null) {
|
---|
649 | collection_tree = new CollectionTree(collection_tree_model, true);
|
---|
650 | }
|
---|
651 |
|
---|
652 | return collection_tree;
|
---|
653 | }
|
---|
654 |
|
---|
655 |
|
---|
656 | /** Retrieve the tree model associated with the current collection. */
|
---|
657 | public CollectionTreeModel getCollectionTreeModel()
|
---|
658 | {
|
---|
659 | if (collection_tree_model == null && collection != null) {
|
---|
660 | // Use the import directory to generate a new CollectionTreeModel
|
---|
661 | collection_tree_model = new CollectionTreeModel(new CollectionTreeNode(new File(getCollectionImportDirectoryPath())));
|
---|
662 | // Ensure that the manager is a change listener for the tree.
|
---|
663 | if (fm_tree_model_listener == null) {
|
---|
664 | fm_tree_model_listener = new FMTreeModelListener();
|
---|
665 | }
|
---|
666 | collection_tree_model.addTreeModelListener(fm_tree_model_listener);
|
---|
667 | }
|
---|
668 | return collection_tree_model;
|
---|
669 | }
|
---|
670 |
|
---|
671 |
|
---|
672 | /** This method when called, creates a new GShell in order to run the import.pl script.
|
---|
673 | * @see org.greenstone.gatherer.Configuration
|
---|
674 | * @see org.greenstone.gatherer.Gatherer
|
---|
675 | * @see org.greenstone.gatherer.gui.BuildOptions
|
---|
676 | * @see org.greenstone.gatherer.shell.GShell
|
---|
677 | * @see org.greenstone.gatherer.shell.GShellListener
|
---|
678 | * @see org.greenstone.gatherer.shell.GShellProgressMonitor
|
---|
679 | * @see org.greenstone.gatherer.util.Utility
|
---|
680 | */
|
---|
681 | public void importCollection() {
|
---|
682 | importing = true;
|
---|
683 |
|
---|
684 | if (!saved()) {
|
---|
685 | DebugStream.println("CollectionManager.importCollection().forcesave");
|
---|
686 | import_monitor.saving();
|
---|
687 | saveCollection();
|
---|
688 | }
|
---|
689 |
|
---|
690 | DebugStream.println("CollectionManager.importCollection()");
|
---|
691 | DebugStream.println("Is event dispatch thread: " + SwingUtilities.isEventDispatchThread());
|
---|
692 | //check that we can remove the old index before starting import
|
---|
693 | File index_dir = new File(getCollectionIndexDirectoryPath());
|
---|
694 | if (index_dir.exists()) {
|
---|
695 | DebugStream.println("Old Index = " + index_dir.getAbsolutePath()+", testing for deletability");
|
---|
696 | if (!canDelete(index_dir)) {
|
---|
697 | // tell the user
|
---|
698 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Delete_Index"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
699 | // tell the gui manager
|
---|
700 | // a message for the building log
|
---|
701 | GShellEvent event = new GShellEvent(this, 0, GShell.IMPORT, Dictionary.get("CollectionManager.Cannot_Delete_Index_Log"), GShell.ERROR);
|
---|
702 | Gatherer.g_man.create_pane.message(event);
|
---|
703 | event = new GShellEvent(this, 0, GShell.IMPORT, "", GShell.ERROR);
|
---|
704 | Gatherer.g_man.create_pane.processComplete(event);
|
---|
705 | importing = false;
|
---|
706 | return;
|
---|
707 | }
|
---|
708 | }
|
---|
709 |
|
---|
710 | // Generate the import.pl command
|
---|
711 | ArrayList command_parts_list = new ArrayList();
|
---|
712 | if ((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
|
---|
713 | command_parts_list.add(Configuration.perl_path);
|
---|
714 | command_parts_list.add("-S");
|
---|
715 | }
|
---|
716 | command_parts_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "import.pl");
|
---|
717 | command_parts_list.add("-gli");
|
---|
718 | command_parts_list.add("-language");
|
---|
719 | command_parts_list.add(Configuration.getLanguage());
|
---|
720 | command_parts_list.add("-collectdir");
|
---|
721 | command_parts_list.add(getCollectDirectory());
|
---|
722 |
|
---|
723 | String[] import_options = collection.import_options.getValues();
|
---|
724 | for (int i = 0; i < import_options.length; i++) {
|
---|
725 | command_parts_list.add(import_options[i]);
|
---|
726 | }
|
---|
727 |
|
---|
728 | command_parts_list.add(collection.getName());
|
---|
729 |
|
---|
730 | // Run the import.pl command
|
---|
731 | String[] command_parts = (String[]) command_parts_list.toArray(new String[0]);
|
---|
732 | GShell shell = new GShell(command_parts, GShell.IMPORT, BUILDING, this, import_monitor, GShell.GSHELL_IMPORT);
|
---|
733 | shell.addGShellListener(Gatherer.g_man.create_pane);
|
---|
734 | shell.start();
|
---|
735 | DebugStream.println("CollectionManager.importCollection().return");
|
---|
736 |
|
---|
737 | importing = false;
|
---|
738 | }
|
---|
739 |
|
---|
740 |
|
---|
741 | public void importMetadataSet(MetadataSet external_metadata_set)
|
---|
742 | {
|
---|
743 | // Copy the .mds file into the collection's "metadata" folder...
|
---|
744 | File external_metadata_set_file = external_metadata_set.getMetadataSetFile();
|
---|
745 |
|
---|
746 | // ...but not if it is the redundant "hidden.mds" file
|
---|
747 | if (external_metadata_set_file.getName().equals("hidden.mds")) {
|
---|
748 | return;
|
---|
749 | }
|
---|
750 |
|
---|
751 | // ...and only if it doesn't already exist
|
---|
752 | File metadata_set_file = new File(getCollectionMetadataDirectoryPath(), external_metadata_set_file.getName());
|
---|
753 | if (!metadata_set_file.exists()) {
|
---|
754 | try {
|
---|
755 | Gatherer.f_man.getQueue().copyFile(external_metadata_set_file, metadata_set_file, false);
|
---|
756 |
|
---|
757 | // If we're using a remote Greenstone server, upload the metadata file
|
---|
758 | if (Gatherer.isGsdlRemote) {
|
---|
759 | RemoteGreenstoneServer.uploadCollectionFile(collection.getName(), metadata_set_file);
|
---|
760 | }
|
---|
761 | }
|
---|
762 | catch (Exception ex) {
|
---|
763 | ex.printStackTrace();
|
---|
764 | }
|
---|
765 |
|
---|
766 | // Load it into the MetadataSetManager
|
---|
767 | MetadataSetManager.loadMetadataSet(metadata_set_file);
|
---|
768 | }
|
---|
769 | }
|
---|
770 |
|
---|
771 |
|
---|
772 | /** Determine if we are currently in the middle of importing (and thus, in this case, we can't allow the log writer to exit). Boy was this a mission to track down. The cascade of crap rolls out something like this: Joe Schmo clicks 'Build Collection', which calls the importCollection() method above, which in turn saves the collection with a saveTask, which fires a collectionChanged message once its finished, which drives the list of logs shown on the create pane to update, which fires a itemChanged() event to the OptionsPane who dutifully tells the current log writer thread to finish up writing (all zero lines its been asked to write) and then die. Wereapon Joe Schmo gets a pretty log to look at, but it isn't actually being written to file so the next time he tries to view it faeces hits the air motion cooling device. Joy.
|
---|
773 | * @return true if the gli is currently importing
|
---|
774 | */
|
---|
775 | public boolean isImporting() {
|
---|
776 | return importing;
|
---|
777 | }
|
---|
778 |
|
---|
779 |
|
---|
780 | public void loadCollection(String collection_file_path)
|
---|
781 | {
|
---|
782 | // Display a modal progress popup to indicate that the collection is being loaded
|
---|
783 | ModalProgressPopup load_collection_progress_popup = new ModalProgressPopup(Dictionary.get("CollectionManager.Loading_Collection"), Dictionary.get("CollectionManager.Loading_Collection_Please_Wait"));
|
---|
784 | load_collection_progress_popup.display();
|
---|
785 |
|
---|
786 | // Load the collection on a separate thread so the progress bar updates correctly
|
---|
787 | (new LoadCollectionTask(collection_file_path, load_collection_progress_popup)).start();
|
---|
788 | }
|
---|
789 |
|
---|
790 |
|
---|
791 | private class LoadCollectionTask
|
---|
792 | extends Thread
|
---|
793 | {
|
---|
794 | private String collection_file_path = null;
|
---|
795 | private ModalProgressPopup load_collection_progress_popup = null;
|
---|
796 |
|
---|
797 | public LoadCollectionTask(String collection_file_path, ModalProgressPopup load_collection_progress_popup)
|
---|
798 | {
|
---|
799 | this.collection_file_path = collection_file_path;
|
---|
800 | this.load_collection_progress_popup = load_collection_progress_popup;
|
---|
801 | }
|
---|
802 |
|
---|
803 | public void run()
|
---|
804 | {
|
---|
805 | loadCollectionInternal(collection_file_path);
|
---|
806 | load_collection_progress_popup.close();
|
---|
807 | }
|
---|
808 | }
|
---|
809 |
|
---|
810 |
|
---|
811 | /** Attempts to load the given collection. Currently uses simple serialization of the collection class.
|
---|
812 | * @param location The path to the collection as a <strong>String</strong>.
|
---|
813 | * @see org.greenstone.gatherer.Configuration
|
---|
814 | * @see org.greenstone.gatherer.Gatherer
|
---|
815 | * @see org.greenstone.gatherer.collection.Collection
|
---|
816 | * @see org.greenstone.gatherer.util.Utility
|
---|
817 | */
|
---|
818 | private void loadCollectionInternal(String location)
|
---|
819 | {
|
---|
820 | DebugStream.println("Loading collection " + location + "...");
|
---|
821 |
|
---|
822 | if (Gatherer.isGsdlRemote) {
|
---|
823 | String collection_name = location.substring(location.lastIndexOf(File.separator) + 1, location.length() - ".col".length());
|
---|
824 | if (RemoteGreenstoneServer.downloadCollection(collection_name).equals("")) {
|
---|
825 | return;
|
---|
826 | }
|
---|
827 | }
|
---|
828 |
|
---|
829 | boolean non_gli_collection = false;
|
---|
830 |
|
---|
831 | // Check we have actually been given a .col file.
|
---|
832 | if (!location.endsWith(".col")) {
|
---|
833 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Not_Col_File", location), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
834 | DebugStream.println("CollectionManager.loadCollection: Haven't been given a .col file.");
|
---|
835 | return;
|
---|
836 | }
|
---|
837 |
|
---|
838 | // Check that the collection configuration file is available
|
---|
839 | File collection_file = new File(location);
|
---|
840 |
|
---|
841 | // Ensure that the directory exists
|
---|
842 | File collection_directory = collection_file.getParentFile();
|
---|
843 | if (collection_directory == null || !collection_directory.exists()) {
|
---|
844 | // We can't open this
|
---|
845 | System.err.println("CollectionManager.loadCollection: No collection directory.");
|
---|
846 | return;
|
---|
847 | }
|
---|
848 |
|
---|
849 | File collection_config_file = new File(collection_directory, Utility.CONFIG_FILE);
|
---|
850 | if (!collection_config_file.exists()) {
|
---|
851 | System.err.println("CollectionManager.loadCollection: No config file.");
|
---|
852 | collection_directory = null;
|
---|
853 | collection_config_file = null;
|
---|
854 | return;
|
---|
855 | }
|
---|
856 |
|
---|
857 | // Ensure that an import directory exists for this collection
|
---|
858 | File collection_import_directory = new File(collection_directory, "import");
|
---|
859 | if (!collection_import_directory.exists()) {
|
---|
860 | collection_import_directory.mkdir();
|
---|
861 | }
|
---|
862 |
|
---|
863 | // Special case of a user trying to open an old greenstone collection.
|
---|
864 | File collection_metadata_directory = new File(collection_directory, "metadata");
|
---|
865 | if (!collection_metadata_directory.exists()) {
|
---|
866 | DebugStream.println("Loading non-gatherer collection...");
|
---|
867 | // Show a warning message in case user wants to quit now
|
---|
868 | non_gli_collection = true;
|
---|
869 | WarningDialog legacy_dialog = new WarningDialog("warning.LegacyCollection", Dictionary.get("LegacyCollection.Title"), Dictionary.get("LegacyCollection.Message"), null, true);
|
---|
870 | if (legacy_dialog.display()==JOptionPane.CANCEL_OPTION) {
|
---|
871 | legacy_dialog.dispose();
|
---|
872 | collection_directory = null;
|
---|
873 | collection_config_file = null;
|
---|
874 | return;
|
---|
875 | }
|
---|
876 | legacy_dialog.dispose();
|
---|
877 |
|
---|
878 | }
|
---|
879 |
|
---|
880 | // Now determine if a lock already exists on this collection.
|
---|
881 | String name = collection_directory.getName();
|
---|
882 | File lock_file = new File(collection_file.getParentFile(), LOCK_FILE);
|
---|
883 | if (lock_file.exists()) {
|
---|
884 | LockFileDialog dialog = new LockFileDialog(Gatherer.g_man, name, lock_file);
|
---|
885 | int choice = dialog.getChoice();
|
---|
886 | dialog.dispose();
|
---|
887 | dialog = null;
|
---|
888 |
|
---|
889 | if (choice != LockFileDialog.YES_OPTION) {
|
---|
890 | // user has cancelled
|
---|
891 | lock_file = null;
|
---|
892 | collection_directory = null;
|
---|
893 | collection_config_file = null;
|
---|
894 | return;
|
---|
895 | }
|
---|
896 |
|
---|
897 | lock_file.delete();
|
---|
898 | }
|
---|
899 |
|
---|
900 | try {
|
---|
901 | // Create a lock file.
|
---|
902 | createLockFile(lock_file);
|
---|
903 | // This lock file may not have been created so check
|
---|
904 | if(!lock_file.canWrite()) {
|
---|
905 | // The lock file cannot be written to. Most likely cause incorrect file permissions.
|
---|
906 | System.err.println("Cannot write lock file!");
|
---|
907 | String args[] = new String[2];
|
---|
908 | args[0] = location;
|
---|
909 | args[1] = Dictionary.get("FileActions.Write_Not_Permitted_Title");
|
---|
910 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open_With_Reason", args), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
911 | args = null;
|
---|
912 | return;
|
---|
913 | }
|
---|
914 |
|
---|
915 | // Open the collection file
|
---|
916 | this.collection = new Collection(collection_file);
|
---|
917 | if (collection.error) {
|
---|
918 | collection = null;
|
---|
919 | // Remove lock file
|
---|
920 | if (lock_file.exists()) {
|
---|
921 | lock_file.delete();
|
---|
922 | }
|
---|
923 | throw(new Exception(Dictionary.get("CollectionManager.Missing_Config"))); // this error message does not agree with the error
|
---|
924 | }
|
---|
925 |
|
---|
926 | MetadataSetManager.clearMetadataSets();
|
---|
927 | MetadataSetManager.loadMetadataSets(collection_metadata_directory);
|
---|
928 |
|
---|
929 | ProfileXMLFileManager.loadProfileXMLFile(collection_metadata_directory);
|
---|
930 |
|
---|
931 | // If this is a non-GLI (legacy) collection, load the
|
---|
932 | // default metadata
|
---|
933 | if (non_gli_collection) {
|
---|
934 | addDefaultMetadataSets(collection_directory);
|
---|
935 |
|
---|
936 | // Recurse the import folder tree, backing up the metadata.xml files before they are edited
|
---|
937 | LegacyCollectionImporter.backupMetadataXMLFiles(collection_directory);
|
---|
938 | }
|
---|
939 |
|
---|
940 | // Read through the metadata.xml files in the import directory, building up the metadata value trees
|
---|
941 | MetadataXMLFileManager.clearMetadataXMLFiles();
|
---|
942 | MetadataXMLFileManager.loadMetadataXMLFiles(collection_import_directory);
|
---|
943 |
|
---|
944 | // Read through the doc.xml files in the archives directory
|
---|
945 | File collection_archives_directory = new File(getCollectionArchivesDirectoryPath());
|
---|
946 | DocXMLFileManager.clearDocXMLFiles();
|
---|
947 | DocXMLFileManager.loadDocXMLFiles(collection_archives_directory);
|
---|
948 |
|
---|
949 | collection.cdm = new CollectionDesignManager(collection_config_file);
|
---|
950 | if (non_gli_collection) {
|
---|
951 | // Change the classifiers to use the namespaced element names
|
---|
952 | LegacyCollectionImporter.updateClassifiers(collection.cdm);
|
---|
953 | }
|
---|
954 |
|
---|
955 | // We're done. Let everyone know.
|
---|
956 | DebugStream.println(Dictionary.get("CollectionManager.Loading_Successful", name));
|
---|
957 | Gatherer.refresh(Gatherer.COLLECTION_OPENED);
|
---|
958 | }
|
---|
959 | catch (Exception error) {
|
---|
960 | // There is obviously no existing collection present.
|
---|
961 | DebugStream.printStackTrace(error);
|
---|
962 | if(error.getMessage() != null) {
|
---|
963 | String[] args = new String[2];
|
---|
964 | args[0] = location;
|
---|
965 | args[1] = error.getMessage();
|
---|
966 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open_With_Reason", args), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
967 | }
|
---|
968 | else {
|
---|
969 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open", location), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
970 | }
|
---|
971 | }
|
---|
972 |
|
---|
973 | lock_file = null;
|
---|
974 | collection_directory = null;
|
---|
975 | collection_config_file = null;
|
---|
976 | }
|
---|
977 |
|
---|
978 |
|
---|
979 | private void makeCollection(String name, String email)
|
---|
980 | {
|
---|
981 | // Generate the mkcol.pl command
|
---|
982 | ArrayList command_parts_list = new ArrayList();
|
---|
983 | if (Utility.isWindows() && (!Gatherer.isGsdlRemote)) {
|
---|
984 | command_parts_list.add(Configuration.perl_path);
|
---|
985 | command_parts_list.add("-S");
|
---|
986 | }
|
---|
987 | command_parts_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "mkcol.pl");
|
---|
988 |
|
---|
989 | command_parts_list.add("-collectdir");
|
---|
990 | command_parts_list.add(getCollectDirectory());
|
---|
991 | command_parts_list.add("-win31compat");
|
---|
992 | command_parts_list.add((Gatherer.isGsdlRemote) ? "false" : "true");
|
---|
993 |
|
---|
994 | if (email != null && !email.equals("")) {
|
---|
995 | command_parts_list.add("-creator");
|
---|
996 | command_parts_list.add(email);
|
---|
997 | }
|
---|
998 |
|
---|
999 | command_parts_list.add(name);
|
---|
1000 |
|
---|
1001 | // Run the mkcol.pl command
|
---|
1002 | String[] command_parts = (String[]) command_parts_list.toArray(new String[0]);
|
---|
1003 | GShell process = new GShell(command_parts, GShell.NEW, COLLECT, this, null, GShell.GSHELL_NEW);
|
---|
1004 | process.run(); // Don't bother threading this... yet
|
---|
1005 | }
|
---|
1006 |
|
---|
1007 |
|
---|
1008 | /** Any implementation of GShellListener must include this method to allow the GShell to send messages to listeners. However in this case the CollectionManager is in no way interested in what the messages are, just the import events which have a specific type and are handled elsewhere. Thus we can safely ignore this event.
|
---|
1009 | * @param event A <strong>GShellEvent</strong> which contains a the message.
|
---|
1010 | */
|
---|
1011 | public synchronized void message(GShellEvent event) {
|
---|
1012 | }
|
---|
1013 |
|
---|
1014 |
|
---|
1015 | public void metadataChanged(CollectionTreeNode[] file_nodes)
|
---|
1016 | {
|
---|
1017 | if (collection != null) {
|
---|
1018 | collection.setMetadataChanged(true);
|
---|
1019 | }
|
---|
1020 | }
|
---|
1021 |
|
---|
1022 |
|
---|
1023 | public void openCollectionFromLastTime()
|
---|
1024 | {
|
---|
1025 | // If there was an open collection last session, reopen it
|
---|
1026 | if (Gatherer.open_collection_file_path != null && !Gatherer.isGsdlRemote) {
|
---|
1027 | // If we're using a remote Greenstone server we must download the collection configurations first
|
---|
1028 | // if (Gatherer.isGsdlRemote && !CollectionManager.downloaded_collection_configurations) {
|
---|
1029 | // if (RemoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
|
---|
1030 | // Something went wrong downloading the collection configurations
|
---|
1031 | // return;
|
---|
1032 | // }
|
---|
1033 |
|
---|
1034 | // CollectionManager.downloaded_collection_configurations = true;
|
---|
1035 | // }
|
---|
1036 |
|
---|
1037 | // Load the collection now
|
---|
1038 | loadCollection(Gatherer.open_collection_file_path);
|
---|
1039 | }
|
---|
1040 | }
|
---|
1041 |
|
---|
1042 |
|
---|
1043 | /** This call is fired whenever a process within a GShell created by this class begins.
|
---|
1044 | * @param event A <strong>GShellEvent</strong> containing information about the GShell process.
|
---|
1045 | * @see org.greenstone.gatherer.Gatherer
|
---|
1046 | * @see org.greenstone.gatherer.gui.GUIManager
|
---|
1047 | * @see org.greenstone.gatherer.shell.GShell
|
---|
1048 | */
|
---|
1049 | public synchronized void processBegun(GShellEvent event) {
|
---|
1050 | DebugStream.println("CollectionManager.processBegun(" + event.getType() + ")");
|
---|
1051 | ///ystem.err.println("ProcessBegun " + event.getType());
|
---|
1052 | // If this is one of the types where we wish to lock user control
|
---|
1053 | Gatherer.g_man.lockCollection((event.getType() == GShell.IMPORT), true);
|
---|
1054 | }
|
---|
1055 | /** This call is fired whenever a process within a GShell created by this class ends.
|
---|
1056 | * @param event A <strong>GShellEvent</strong> containing information about the GShell process.
|
---|
1057 | * @see org.greenstone.gatherer.Gatherer
|
---|
1058 | * @see org.greenstone.gatherer.gui.GUIManager
|
---|
1059 | * @see org.greenstone.gatherer.shell.GShell
|
---|
1060 | */
|
---|
1061 | public synchronized void processComplete(GShellEvent event) {
|
---|
1062 | //ystem.err.println("CollectionManager.processComplete(" + event.getType() + ")");
|
---|
1063 | Gatherer.g_man.lockCollection((event.getType() == GShell.IMPORT), false);
|
---|
1064 | ///ystem.err.println("Recieved process complete event - " + event);
|
---|
1065 | // If we were running an import, now run a build.
|
---|
1066 | if(event.getType() == GShell.IMPORT && event.getStatus() == GShell.OK) {
|
---|
1067 | // Finish import.
|
---|
1068 | collection.setImported(true);
|
---|
1069 | buildCollection(false);
|
---|
1070 | }
|
---|
1071 | // If we were running a build, now is when we move files across.
|
---|
1072 | else if(event.getType() == GShell.BUILD && event.getStatus() == GShell.OK) {
|
---|
1073 | if(installCollection()) {
|
---|
1074 | // If we have a local library running then ask it to add our newly create collection
|
---|
1075 | if (LocalLibraryServer.isRunning() == true) {
|
---|
1076 | LocalLibraryServer.addCollection(collection.getName());
|
---|
1077 | }
|
---|
1078 | else if (Gatherer.GS3) {
|
---|
1079 | convertToGS3Collection();
|
---|
1080 | Gatherer.configGS3Server(Configuration.site_name, ServletConfiguration.ADD_COMMAND + collection.getName());
|
---|
1081 | }
|
---|
1082 |
|
---|
1083 | // Fire a collection changed first to update the preview etc buttons
|
---|
1084 | Gatherer.refresh(Gatherer.COLLECTION_REBUILT);
|
---|
1085 |
|
---|
1086 | // Now display a message dialog saying its all built
|
---|
1087 | WarningDialog collection_built_warning_dialog = new WarningDialog("warning.CollectionBuilt", "CollectionBuilt.Title", Dictionary.get("CollectionBuilt.Message"), null, false);
|
---|
1088 | collection_built_warning_dialog.setMessageOnly(true); // Not a warning
|
---|
1089 | collection_built_warning_dialog.display();
|
---|
1090 | collection_built_warning_dialog.dispose();
|
---|
1091 | collection_built_warning_dialog = null;
|
---|
1092 |
|
---|
1093 | //Set nothing as needing rebuilding, as a build has just finished :-)
|
---|
1094 | CollectionDesignManager.resetRebuildTypeRequired();
|
---|
1095 | }
|
---|
1096 | else {
|
---|
1097 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Preview_Ready_Failed"), Dictionary.get("CollectionManager.Preview_Ready_Title"), JOptionPane.ERROR_MESSAGE);
|
---|
1098 | Gatherer.refresh(Gatherer.COLLECTION_REBUILT);
|
---|
1099 | DebugStream.println("Status is ok but !installCollection()");
|
---|
1100 | }
|
---|
1101 | }
|
---|
1102 | else if (event.getStatus() == GShell.CANCELLED) {
|
---|
1103 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Build_Cancelled"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
1104 | Gatherer.g_man.repaint();
|
---|
1105 | }
|
---|
1106 | else if (event.getStatus() == GShell.ERROR) {
|
---|
1107 | DebugStream.println("There was an error in the gshell:"+ event.getMessage());
|
---|
1108 | if (event.getType() == GShell.NEW) {
|
---|
1109 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Create_Collection"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
1110 | } else {
|
---|
1111 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Preview_Ready_Failed"), Dictionary.get("CollectionManager.Preview_Ready_Title"), JOptionPane.ERROR_MESSAGE);
|
---|
1112 | Gatherer.refresh(Gatherer.COLLECTION_REBUILT);
|
---|
1113 | }
|
---|
1114 |
|
---|
1115 | Gatherer.g_man.repaint(); // It appears Java's own dialogs have the same not always painting correct area bug that I suffer from. Well I don't suffer from it personally, but my ModalDialog components do.
|
---|
1116 | }
|
---|
1117 | }
|
---|
1118 |
|
---|
1119 |
|
---|
1120 | /** Determine if the manager is ready for actions apon its collection.
|
---|
1121 | * @return A <i>boolean</i> which is <i>true</i> to indicate a collection has been loaded and thus the collection is ready for editing, <i>false</i> otherwise.
|
---|
1122 | */
|
---|
1123 | static public synchronized boolean ready() {
|
---|
1124 | if(collection != null) {
|
---|
1125 | return true;
|
---|
1126 | }
|
---|
1127 | else {
|
---|
1128 | return false;
|
---|
1129 | }
|
---|
1130 | }
|
---|
1131 |
|
---|
1132 |
|
---|
1133 | /** This method associates the collection build monitor with the build monitor created in CreatePane.
|
---|
1134 | * @param monitor A <strong>GShellProgressMonitor</strong> which we will use as the build monitor.
|
---|
1135 | */
|
---|
1136 | public void registerBuildMonitor(GShellProgressMonitor monitor) {
|
---|
1137 | build_monitor = monitor;
|
---|
1138 | }
|
---|
1139 | /** This method associates the collection import monitor with the import monitor created in CreatePane.
|
---|
1140 | * @param monitor A <strong>GShellProgressMonitor</strong> which we will use as the import monitor.
|
---|
1141 | */
|
---|
1142 | public void registerImportMonitor(GShellProgressMonitor monitor) {
|
---|
1143 | import_monitor = monitor;
|
---|
1144 | }
|
---|
1145 |
|
---|
1146 |
|
---|
1147 | public void removeCollectionContentsChangedListener(CollectionContentsChangedListener listener)
|
---|
1148 | {
|
---|
1149 | collection_contents_changed_listeners.remove(listener);
|
---|
1150 | }
|
---|
1151 |
|
---|
1152 |
|
---|
1153 | public void removeMetadataSet(MetadataSet metadata_set)
|
---|
1154 | {
|
---|
1155 | DebugStream.println("Removing metadata set...");
|
---|
1156 |
|
---|
1157 | // Delete the .mds file from the collection's "metadata" folder...
|
---|
1158 | File metadata_set_file = metadata_set.getMetadataSetFile();
|
---|
1159 |
|
---|
1160 | // ...but not if it is the "ex.mds" file
|
---|
1161 | if (metadata_set_file.getName().equals("ex.mds")) {
|
---|
1162 | return;
|
---|
1163 | }
|
---|
1164 |
|
---|
1165 | // ...and only if it exists
|
---|
1166 | if (metadata_set_file.exists()) {
|
---|
1167 | metadata_set_file.delete();
|
---|
1168 |
|
---|
1169 | // Unload it from the MetadataSetManager
|
---|
1170 | MetadataSetManager.unloadMetadataSet(metadata_set);
|
---|
1171 |
|
---|
1172 | // If we're using a remote Greenstone server, delete the metadata file on the server
|
---|
1173 | if (Gatherer.isGsdlRemote) {
|
---|
1174 | RemoteGreenstoneServer.deleteCollectionFile(collection.getName(), metadata_set_file);
|
---|
1175 | }
|
---|
1176 | }
|
---|
1177 | }
|
---|
1178 |
|
---|
1179 |
|
---|
1180 | /** Used to check whether all open collections have a 'saved' state.
|
---|
1181 | * @return A <i>boolean</i> which is <i>true</i> if the collection has been saved.
|
---|
1182 | * @see org.greenstone.gatherer.collection.Collection
|
---|
1183 | */
|
---|
1184 | public boolean saved() {
|
---|
1185 | boolean result = true;
|
---|
1186 | if(collection != null) {
|
---|
1187 | result = collection.getSaved();
|
---|
1188 | }
|
---|
1189 | return result;
|
---|
1190 | }
|
---|
1191 |
|
---|
1192 |
|
---|
1193 | /** Saves the currently loaded collection. */
|
---|
1194 | public void saveCollection()
|
---|
1195 | {
|
---|
1196 | DebugStream.println("Saving collection " + collection.getName() + "...");
|
---|
1197 |
|
---|
1198 | // Change cursor to hourglass
|
---|
1199 | Gatherer.g_man.wait(true);
|
---|
1200 |
|
---|
1201 | // Create a backup of the collection file, just in case anything goes wrong
|
---|
1202 | File collection_file = new File(getCollectionFilePath());
|
---|
1203 | if (collection_file.exists()) {
|
---|
1204 | File collection_file_backup = new File(collection_file.getAbsolutePath() + "~");
|
---|
1205 | if (!collection_file.renameTo(collection_file_backup)) {
|
---|
1206 | DebugStream.println("Error in CollectionManager.saveCollection(): could not create backup file.");
|
---|
1207 | }
|
---|
1208 | collection_file_backup.deleteOnExit();
|
---|
1209 | }
|
---|
1210 |
|
---|
1211 | // Write out the collection file
|
---|
1212 | collection.save();
|
---|
1213 |
|
---|
1214 | // Write out the collection configuration file
|
---|
1215 | //Gatherer.g_man.design_pane.saveConfiguration();
|
---|
1216 | collection.cdm.save();
|
---|
1217 | // Change cursor back to normal
|
---|
1218 | Gatherer.g_man.wait(false);
|
---|
1219 | }
|
---|
1220 |
|
---|
1221 |
|
---|
1222 | /** I started giving the user the choice of using an existing meta set or creating a new one. The second option being so that they didn't have to add/merge/ignore each element, they could all be added automatically. However, I am not sure where the merge prompt gets called from, and it is not essential, so I am leaving it for now - it should be added back in and finished. [kjdon] */
|
---|
1223 | private boolean addDefaultMetadataSets(File collection_dir) {
|
---|
1224 |
|
---|
1225 |
|
---|
1226 | // Add dublin core which is the default metadata set. The user
|
---|
1227 | // can change this later
|
---|
1228 | File dc_file = new File(Gatherer.getGLIMetadataDirectoryPath()+"dublin.mds");
|
---|
1229 | if (dc_file.exists()) {
|
---|
1230 | importMetadataSet(new MetadataSet(dc_file));
|
---|
1231 | }
|
---|
1232 |
|
---|
1233 | // Always import the extracted metadata set
|
---|
1234 | File extracted_metadata_set_file = new File(Gatherer.getGLIMetadataDirectoryPath() + MetadataSetManager.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION);
|
---|
1235 | importMetadataSet(new MetadataSet(extracted_metadata_set_file));
|
---|
1236 |
|
---|
1237 | return true;
|
---|
1238 | }
|
---|
1239 |
|
---|
1240 |
|
---|
1241 | // used as arg in the perl scripts
|
---|
1242 | private String getCollectDirectory() {
|
---|
1243 | String collect_dir = Gatherer.getCollectDirectoryPath();
|
---|
1244 |
|
---|
1245 | // Remove erroneous file windows file separator as it causes problems when running import.pl
|
---|
1246 | if(collect_dir.length() > 2 && collect_dir.endsWith("\\")) {
|
---|
1247 | collect_dir = collect_dir.substring(0, collect_dir.length() - 1);
|
---|
1248 | }
|
---|
1249 |
|
---|
1250 | return collect_dir;
|
---|
1251 | }
|
---|
1252 |
|
---|
1253 |
|
---|
1254 | /** Install collection by moving its files from building to index after a successful build.
|
---|
1255 | * @see org.greenstone.gatherer.Gatherer
|
---|
1256 | * @see org.greenstone.gatherer.util.Utility
|
---|
1257 | */
|
---|
1258 | private boolean installCollection()
|
---|
1259 | {
|
---|
1260 | DebugStream.println("Build complete. Moving files.");
|
---|
1261 |
|
---|
1262 | try {
|
---|
1263 | // Ensure that the local library has released this collection so we can delete the index directory
|
---|
1264 | if (LocalLibraryServer.isRunning() == true) {
|
---|
1265 | LocalLibraryServer.releaseCollection(collection.getName());
|
---|
1266 | }
|
---|
1267 | // deactivate it in tomcat so that windows will release the index files
|
---|
1268 | if (Gatherer.GS3) {
|
---|
1269 | Gatherer.configGS3Server(Configuration.site_name, ServletConfiguration.DEACTIVATE_COMMAND + collection.getName());
|
---|
1270 | }
|
---|
1271 | File index_dir = new File(getCollectionIndexDirectoryPath());
|
---|
1272 | DebugStream.println("Index = " + index_dir.getAbsolutePath());
|
---|
1273 |
|
---|
1274 | File building_dir = new File(getCollectionBuildingDirectoryPath());
|
---|
1275 | DebugStream.println("Building = " + building_dir.getAbsolutePath());
|
---|
1276 |
|
---|
1277 | // Get the build mode from the build options
|
---|
1278 | String build_mode = collection.build_options.getValue("mode");
|
---|
1279 |
|
---|
1280 | // Special case for build mode "all": replace index dir with building dir
|
---|
1281 | if (build_mode == null || build_mode.equals(Dictionary.get("CreatePane.Mode_All"))) {
|
---|
1282 | // Remove the old index directory
|
---|
1283 | if (index_dir.exists()) {
|
---|
1284 | Utility.delete(index_dir);
|
---|
1285 |
|
---|
1286 | // Wait for a couple of seconds, just for luck
|
---|
1287 | wait(2000);
|
---|
1288 |
|
---|
1289 | // Check the delete worked
|
---|
1290 | if (index_dir.exists()) {
|
---|
1291 | throw new Exception(Dictionary.get("CollectionManager.Index_Not_Deleted"));
|
---|
1292 | }
|
---|
1293 | }
|
---|
1294 |
|
---|
1295 | if (Gatherer.isGsdlRemote) {
|
---|
1296 | RemoteGreenstoneServer.deleteCollectionFile(collection.getName(), new File(getCollectionIndexDirectoryPath()));
|
---|
1297 | RemoteGreenstoneServer.moveCollectionFile(collection.getName(), new File(getCollectionBuildingDirectoryPath()), new File(getCollectionIndexDirectoryPath()));
|
---|
1298 | }
|
---|
1299 |
|
---|
1300 | // Move the building directory to become the new index directory
|
---|
1301 | if (building_dir.renameTo(index_dir) == false) {
|
---|
1302 | throw new Exception(Dictionary.get("CollectionManager.Build_Not_Moved"));
|
---|
1303 | }
|
---|
1304 | }
|
---|
1305 |
|
---|
1306 | // Otherwise copy everything in the building dir into the index dir
|
---|
1307 | else {
|
---|
1308 | moveContentsInto(building_dir, index_dir);
|
---|
1309 | }
|
---|
1310 | }
|
---|
1311 | catch (Exception exception) {
|
---|
1312 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Install_Exception", exception.getMessage()), "Error", JOptionPane.ERROR_MESSAGE);
|
---|
1313 | return false;
|
---|
1314 | }
|
---|
1315 | return true;
|
---|
1316 | }
|
---|
1317 |
|
---|
1318 |
|
---|
1319 | /** Moves all the files in one directory into another, overwriting existing files */
|
---|
1320 | private void moveContentsInto(File source_directory, File target_directory)
|
---|
1321 | {
|
---|
1322 | File[] source_files = source_directory.listFiles();
|
---|
1323 | for (int i = 0; i < source_files.length; i++) {
|
---|
1324 | File source_file = source_files[i];
|
---|
1325 | File target_file = new File(target_directory, source_file.getName());
|
---|
1326 |
|
---|
1327 | if (source_file.isDirectory()) {
|
---|
1328 | moveContentsInto(source_file, target_file);
|
---|
1329 | source_file.delete();
|
---|
1330 | }
|
---|
1331 | else {
|
---|
1332 | if (target_file.exists()) {
|
---|
1333 | target_file.delete();
|
---|
1334 | }
|
---|
1335 |
|
---|
1336 | source_file.renameTo(target_file);
|
---|
1337 | }
|
---|
1338 | }
|
---|
1339 | }
|
---|
1340 |
|
---|
1341 |
|
---|
1342 | private void updateCollectionCFG(File base_cfg, File new_cfg, String description, String email, String title)
|
---|
1343 | {
|
---|
1344 | boolean first_name = true;
|
---|
1345 | boolean first_extra = true;
|
---|
1346 |
|
---|
1347 | // Now read in base_cfg line by line, parsing important onces and/or replacing them with information pertinent to our collection. Each line is then written back out to the new collect.cfg file.
|
---|
1348 | try {
|
---|
1349 | BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(base_cfg), "UTF-8"));
|
---|
1350 | BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new_cfg), "UTF-8"));
|
---|
1351 | String command = null;
|
---|
1352 | while((command = in.readLine()) != null) {
|
---|
1353 | if (command.length()==0) {
|
---|
1354 | // output a new line
|
---|
1355 | out.newLine();
|
---|
1356 | continue;
|
---|
1357 | }
|
---|
1358 | // We have to test the end of command for the special character '\'. If found, remove it and append the next line, then repeat.
|
---|
1359 | while(command.trim().endsWith("\\")) {
|
---|
1360 | command = command.substring(0, command.lastIndexOf("\\"));
|
---|
1361 | String next_line = in.readLine();
|
---|
1362 | if(next_line != null) {
|
---|
1363 | command = command + next_line;
|
---|
1364 | }
|
---|
1365 | }
|
---|
1366 | // commands can extend over more than one line so use the CommandTokenizer which takes care of that
|
---|
1367 | CommandTokenizer tokenizer = new CommandTokenizer(command, in, false);
|
---|
1368 | String command_type_str = tokenizer.nextToken().toLowerCase();
|
---|
1369 |
|
---|
1370 | if (command_type_str.equals(StaticStrings.COLLECTIONMETADATA_STR)) {
|
---|
1371 | // read the whole thing in, but for collectionname, collectionextra, iconcollection, iconcollectionsmall we will ignore them
|
---|
1372 | StringBuffer new_command = new StringBuffer(command_type_str);
|
---|
1373 | String meta_name = tokenizer.nextToken();
|
---|
1374 | new_command.append(' ');
|
---|
1375 | new_command.append(meta_name);
|
---|
1376 | while (tokenizer.hasMoreTokens()) {
|
---|
1377 | new_command.append(' ');
|
---|
1378 | new_command.append(tokenizer.nextToken());
|
---|
1379 | }
|
---|
1380 | if (meta_name.equals(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR) || meta_name.equals(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR) || meta_name.equals(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR) || meta_name.equals(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR)) {
|
---|
1381 | // dont save
|
---|
1382 | } else {
|
---|
1383 | write(out, new_command.toString());
|
---|
1384 | }
|
---|
1385 | new_command = null;
|
---|
1386 | continue;
|
---|
1387 | } // if collectionmeta
|
---|
1388 |
|
---|
1389 | if (command_type_str.equals("classify")) {
|
---|
1390 | StringBuffer text = new StringBuffer(command_type_str);
|
---|
1391 | // Read in the classifier command watching for hfile, metadata and sort arguments.
|
---|
1392 | String buttonname = null;
|
---|
1393 | String hfile = null;
|
---|
1394 | String new_metadata = null;
|
---|
1395 | String old_metadata = null;
|
---|
1396 |
|
---|
1397 | while(tokenizer.hasMoreTokens()) {
|
---|
1398 | String token = tokenizer.nextToken();
|
---|
1399 | if (token.equals("-hfile")) {
|
---|
1400 | if(tokenizer.hasMoreTokens()) {
|
---|
1401 | text.append(" ");
|
---|
1402 | text.append(token);
|
---|
1403 | token = tokenizer.nextToken();
|
---|
1404 | hfile = token;
|
---|
1405 | }
|
---|
1406 | }
|
---|
1407 | else if (token.equals("-metadata")) {
|
---|
1408 | if(tokenizer.hasMoreTokens()) {
|
---|
1409 | text.append(" ");
|
---|
1410 | text.append(token);
|
---|
1411 | String temp_metadata = tokenizer.nextToken();
|
---|
1412 | String replacement = ProfileXMLFileManager.getMetadataElementFor(temp_metadata);
|
---|
1413 | if (replacement != null && !replacement.equals("")) {
|
---|
1414 | token = replacement;
|
---|
1415 | old_metadata = temp_metadata;
|
---|
1416 | new_metadata = replacement;
|
---|
1417 | }
|
---|
1418 | else {
|
---|
1419 | token = temp_metadata;
|
---|
1420 | }
|
---|
1421 | temp_metadata = null;
|
---|
1422 | replacement = null;
|
---|
1423 | }
|
---|
1424 | }
|
---|
1425 | else if (token.equals("-sort")) {
|
---|
1426 | if(tokenizer.hasMoreTokens()) {
|
---|
1427 | text.append(" ");
|
---|
1428 | text.append(token);
|
---|
1429 | String temp_metadata = tokenizer.nextToken();
|
---|
1430 | String replacement = ProfileXMLFileManager.getMetadataElementFor(temp_metadata);
|
---|
1431 | if (replacement != null && !replacement.equals("")) {
|
---|
1432 | token = replacement;
|
---|
1433 | }
|
---|
1434 | else {
|
---|
1435 | token = temp_metadata;
|
---|
1436 | }
|
---|
1437 | temp_metadata = null;
|
---|
1438 | replacement = null;
|
---|
1439 | }
|
---|
1440 | }
|
---|
1441 | else if(token.equals("-buttonname")) {
|
---|
1442 | buttonname = token;
|
---|
1443 | }
|
---|
1444 | text.append(' ');
|
---|
1445 | text.append(token);
|
---|
1446 | token = null;
|
---|
1447 | }
|
---|
1448 |
|
---|
1449 | // If we replaced the metadata argument and didn't encounter a buttonname, then add one now pointing back to the old metadata name in order to accomodate macro files which required such names (buttonname is metadata name by default)!
|
---|
1450 | if(old_metadata != null && new_metadata != null && buttonname == null) {
|
---|
1451 | text.append(' ');
|
---|
1452 | text.append("-buttonname");
|
---|
1453 | text.append(' ');
|
---|
1454 | text.append(old_metadata);
|
---|
1455 | }
|
---|
1456 | command = text.toString();
|
---|
1457 | // Replace the hfile if we found it
|
---|
1458 | if(hfile != null && new_metadata != null) {
|
---|
1459 | command = command.replaceAll(hfile, new_metadata + ".txt");
|
---|
1460 | }
|
---|
1461 |
|
---|
1462 | buttonname = null;
|
---|
1463 | hfile = null;
|
---|
1464 | new_metadata = null;
|
---|
1465 | old_metadata = null;
|
---|
1466 | write(out, command);
|
---|
1467 | } else {
|
---|
1468 | // the rest of the commands just want a string - we read in all the tokens from the tokeniser and get rid of it.
|
---|
1469 | StringBuffer new_command = new StringBuffer(command_type_str);
|
---|
1470 | while (tokenizer.hasMoreTokens()) {
|
---|
1471 | new_command.append(' ');
|
---|
1472 | new_command.append(tokenizer.nextToken());
|
---|
1473 | }
|
---|
1474 |
|
---|
1475 | command = new_command.toString();
|
---|
1476 |
|
---|
1477 | // There is still one special case, that of the format command. In such a command we have to search for [<target>] to ensure we don't change parts of the format which have nothing to do with the metadata elements.
|
---|
1478 | // we really want to build up the whole command here
|
---|
1479 | boolean format_command = command_type_str.equals("format");
|
---|
1480 | HashMap metadata_mapping = ProfileXMLFileManager.getMetadataMapping();
|
---|
1481 | if (metadata_mapping != null) {
|
---|
1482 | Iterator keys = metadata_mapping.keySet().iterator();
|
---|
1483 | while (keys.hasNext()) {
|
---|
1484 | String target = (String) keys.next();
|
---|
1485 | String replacement = (String) metadata_mapping.get(target);
|
---|
1486 | if (replacement != null && !replacement.equals("")) {
|
---|
1487 | if (format_command) {
|
---|
1488 | target = "\\[" + target + "\\]";
|
---|
1489 | replacement = "{Or}{[" + replacement + "]," + target + "}";
|
---|
1490 | }
|
---|
1491 | command = command.replaceAll(target, replacement);
|
---|
1492 | }
|
---|
1493 | }
|
---|
1494 | }
|
---|
1495 |
|
---|
1496 | write(out, command);
|
---|
1497 | }
|
---|
1498 | tokenizer = null;
|
---|
1499 | }
|
---|
1500 | in.close();
|
---|
1501 | in = null;
|
---|
1502 | out.flush();
|
---|
1503 | out.close();
|
---|
1504 | out = null;
|
---|
1505 | }
|
---|
1506 | catch(Exception error) {
|
---|
1507 | DebugStream.printStackTrace(error);
|
---|
1508 | }
|
---|
1509 | // All done, I hope.
|
---|
1510 | }
|
---|
1511 |
|
---|
1512 | private void write(BufferedWriter out, String message)
|
---|
1513 | throws Exception {
|
---|
1514 | out.write(message, 0, message.length());
|
---|
1515 | out.newLine();
|
---|
1516 | }
|
---|
1517 |
|
---|
1518 |
|
---|
1519 | /** The CollectionManager class is getting too confusing by half so I'll implement this TreeModelListener in a private class to make responsibility clear. */
|
---|
1520 | private class FMTreeModelListener
|
---|
1521 | implements TreeModelListener {
|
---|
1522 | /** Any action that changes one of the tree models within a collection, which are the only models we listen to, mean the collections contents have changed and so saved should be set to false.
|
---|
1523 | * @param event A <strong>TreeModelEvent</strong> encompassing all the information about the event which has changed the tree.
|
---|
1524 | */
|
---|
1525 | public void treeNodesChanged(TreeModelEvent event) {
|
---|
1526 | if(collection != null) {
|
---|
1527 | collection.setSaved(false);
|
---|
1528 | collection.setFilesChanged(true);
|
---|
1529 | }
|
---|
1530 | }
|
---|
1531 | /** Any action that changes one of the tree models within a collection, which are the only models we listen to, mean the collections contents have changed and so saved should be set to false.
|
---|
1532 | * @param event A <strong>TreeModelEvent</strong> encompassing all the information about the event which has changed the tree.
|
---|
1533 | */
|
---|
1534 | public void treeNodesInserted(TreeModelEvent event) {
|
---|
1535 | if(collection != null) {
|
---|
1536 | collection.setSaved(false);
|
---|
1537 | collection.setFilesChanged(true);
|
---|
1538 | }
|
---|
1539 | }
|
---|
1540 | /** Any action that changes one of the tree models within a collection, which are the only models we listen to, mean the collections contents have changed and so saved should be set to false.
|
---|
1541 | * @param event A <strong>TreeModelEvent</strong> encompassing all the information about the event which has changed the tree.
|
---|
1542 | */
|
---|
1543 | public void treeNodesRemoved(TreeModelEvent event) {
|
---|
1544 | if(collection != null) {
|
---|
1545 | collection.setSaved(false);
|
---|
1546 | collection.setFilesChanged(true);
|
---|
1547 |
|
---|
1548 | }
|
---|
1549 | }
|
---|
1550 | /** Any action that changes one of the tree models within a collection, which are the only models we listen to, mean the collections contents have changed and so saved should be set to false.
|
---|
1551 | * @param event A <strong>TreeModelEvent</strong> encompassing all the information about the event which has changed the tree.
|
---|
1552 | */
|
---|
1553 | public void treeStructureChanged(TreeModelEvent event) {
|
---|
1554 | if(collection != null) {
|
---|
1555 | collection.setSaved(false);
|
---|
1556 | }
|
---|
1557 | }
|
---|
1558 | }
|
---|
1559 | }
|
---|