source: trunk/gli/src/org/greenstone/gatherer/msm/GDMManager.java@ 6259

Last change on this file since 6259 was 6259, checked in by jmt12, 20 years ago

Removed a debug comment

  • Property svn:keywords set to Author Date Id Revision
File size: 25.7 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.msm;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.io.*;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.event.*;
45import javax.swing.tree.*;
46import org.greenstone.gatherer.Gatherer;
47import org.greenstone.gatherer.file.FileNode;
48import org.greenstone.gatherer.gui.MetaEditPrompt;
49import org.greenstone.gatherer.msm.ElementWrapper;
50import org.greenstone.gatherer.msm.GDMDocument;
51import org.greenstone.gatherer.msm.GDMParser;
52import org.greenstone.gatherer.msm.Metadata;
53import org.greenstone.gatherer.msm.MSMEvent;
54import org.greenstone.gatherer.msm.MSMListener;
55import org.greenstone.gatherer.util.DOMTree;
56import org.greenstone.gatherer.util.HashMap3D;
57import org.greenstone.gatherer.util.StaticStrings;
58import org.greenstone.gatherer.util.Utility;
59import org.w3c.dom.*;
60
61/** This object manages the metadata attached to file records. By storing all of the metadata in one place you garner several advantages. Firstly only one copy of each metadata object is retained, all actual entries are converted to references. Next you can immediately determine what metadata is assigned to an entire directory, thus the metadata.xml files can be built more effeciently (whereas the current 'optimal' method uses recursion through the tree contents). Finally, and perhaps most importantly, it allows for dynamic 'on demand' lookup of metadata. This is especially necessary with large collections, where the raw, unconnected metadata files could range into the tens of megabytes of memory and require hundreds of megabytes to read by in using serialization. Dynamic loading allows you to connect the metadata objects on load, reducing value node paths (possibly of hundreds of characters) down to a single reference pointer! At the very worst this object uses far less memory than the current method, and given that the current method is completely incapable of handling large collections, is necessary. The trade off of course is in time needed to load metadata.xml on demand, the worst possible case being the user selecting the root node of the collection tree of a large collection immediately after opening the collection. The subsequent attempt to build the metadata table will result in the metadata being loaded for every single file. But since this process is sequential and a small cache of metadata.xml files is implemented, and given that the table will actually be build on a separate thread, the wait should not be too arduous.<BR>
62 As for the size of the GDMParser cache, I was at first tempted to put around five. However after analysis of cache usage, I determined that no gain occured because of caching (in fact if everythings working as it should there should only ever be one call for a certain metadata.xml).
63*/
64public class GDMManager
65 extends LinkedHashMap
66 implements MSMListener {
67 /** A list of the known metadata instances, thus we only store one of each unique metadata, and reference the rest. */
68 static public HashMap3D metadata_cache = null;
69 private DOMTree tree = null;
70 private JComboBox documents_in_cache_combobox = null;
71 /** The root file node. */
72 private TreeNode root = null;
73 /** The threaded object responsible for loading all of the existing metadata.xml files prior to any save action. This is necessary so that hierarchy indexes within the metadata.xml files stay fresh. */
74 //private GDMLoader gdm_loader = null;
75 /** The maximum number of GDMDocuments to load at any one time */
76 static final private int MAX_DOCUMENTS = 25;
77 /** Constructor. */
78 public GDMManager() {
79 super();
80 this.metadata_cache = new HashMap3D(Gatherer.c_man.getCollection().msm.getSize());
81 // Connect
82 Gatherer.c_man.getCollection().msm.addMSMListener(this);
83 // We also have a debug dialog
84 if(Gatherer.debug != null) {
85 display();
86 }
87 }
88
89 /** This may seem a little odd but this method doesn't add the given metadata directly, instead calling fireMetadataChanged in MetadataSetManager so as to recursively add metadata if necessary, and to ensure that all listeners who are interested in data change (such as the Metadata Table and Save listeners) can be up to date. */
90 public void addMetadata(FileNode node, ArrayList metadatum) {
91 for(int i = 0; i < metadatum.size(); i++) {
92 Metadata metadata = (Metadata) metadatum.get(i);
93 Gatherer.c_man.getCollection().msm.fireMetadataChanged(node, (Metadata)null, metadata);
94 }
95 }
96
97 /** Destructor necessary for clean exit, subsequent to saving of metadata.xml files.
98 * @see org.greenstone.gatherer.Gatherer
99 * @see org.greenstone.gatherer.collection.CollectionManager
100 * @see org.greenstone.gatherer.msm.GDMParser
101 * @see org.greenstone.gatherer.msm.MetadataSetManager
102 */
103 public void destroy() {
104 // Destroy all the cached documents.
105 /*
106 Iterator iterator = keySet().iterator();
107 while(iterator.hasNext()) {
108 File file = (File) iterator.next();
109 GDMDocument document = (GDMDocument) get(file);
110 document.destroy(file);
111 }
112 */
113 // Deregister as listener
114 Gatherer.c_man.getCollection().msm.removeMSMListener(this);
115 // Deallocate all data members
116 metadata_cache.clear();
117 metadata_cache = null;
118 // Finally clear self
119 clear();
120 // Done!
121 }
122
123 /** This debug facility shows the currently loaded collect.cfg or CollectConfig.xml file as a DOM tree. */
124 public void display() {
125 JDialog dialog = new JDialog(Gatherer.g_man, "Greenstone Metadata Document Manager", false);
126 dialog.setSize(400,400);
127 JPanel content_pane = (JPanel) dialog.getContentPane();
128 GDMDocument metadata_xml = new GDMDocument();
129 tree = new DOMTree(metadata_xml.getDocument());
130 metadata_xml = null;
131 documents_in_cache_combobox = new JComboBox();
132 documents_in_cache_combobox.addItemListener(new DOMItemListener());
133 JButton refresh_button = new JButton("Refresh Tree");
134 refresh_button.addActionListener(new ActionListener() {
135 public void actionPerformed(ActionEvent event) {
136 File metadata_file = (File) documents_in_cache_combobox.getSelectedItem();
137 if(metadata_file != null) {
138 GDMDocument document = (GDMDocument) get(metadata_file);
139 tree.setDocument(document.getDocument());
140 document = null;
141 metadata_file = null;
142 }
143 }
144 });
145 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
146 content_pane.setLayout(new BorderLayout());
147 content_pane.add(documents_in_cache_combobox, BorderLayout.NORTH);
148 content_pane.add(new JScrollPane(tree), BorderLayout.CENTER);
149 content_pane.add(refresh_button, BorderLayout.SOUTH);
150 dialog.show();
151 }
152
153 private class DOMItemListener
154 implements ItemListener {
155
156 public void itemStateChanged(ItemEvent event) {
157 if(event.getStateChange() == ItemEvent.SELECTED) {
158 File metadata_file = (File) documents_in_cache_combobox.getSelectedItem();
159 if(metadata_file != null) {
160 GDMDocument document = (GDMDocument) get(metadata_file);
161 tree.setDocument(document.getDocument());
162 document = null;
163 metadata_file = null;
164 }
165 }
166 }
167 }
168
169 /** Method that is called whenever an element within a set is changed or modified. Ensure all cached GDMDocuments are marked as stale.
170 * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
171 */
172 public void elementChanged(MSMEvent event) {
173 for(Iterator values = values().iterator(); values.hasNext(); ) {
174 GDMDocument document = (GDMDocument) values.next();
175 document.setUpToDate(false);
176 document = null;
177 }
178 }
179 /** Retrieve the GreenstoneMetadataDocument that is associated with a certain file. If the document is in cache returns it. If the document exists but isn't in cache loads, caches, then returns it. Otherwise it creates a brand new document, caches it, then returns it.
180 * @see org.greenstone.gatherer.msm.GDMParser
181 */
182 public GDMDocument getDocument(File file) {
183 ///ystem.err.println("Get the GDMDocument for " + file.getAbsolutePath());
184 GDMDocument metadata_xml = null;
185 // Determine the name of the target files metadata.xml file.
186 File metadata_file = null;
187 if(file.isFile()) {
188 metadata_file = new File(file.getParentFile(), StaticStrings.METADATA_XML);
189 }
190 else {
191 metadata_file = new File(file, StaticStrings.METADATA_XML);
192 }
193 // Then try to retrieve it from cache. First we consider the case of a cache hit.
194 if(containsKey(metadata_file)) {
195 metadata_xml = (GDMDocument) get(metadata_file);
196 ///ystem.err.println("Get the GDMDocument for " + metadata_file.getAbsolutePath());
197 }
198 else {
199 // Now the two potential cache misses. The first requires us to load an existing metadata.xml
200 if(metadata_file.exists()) {
201 ///ystem.err.println("Reload the GDMDocument for " + metadata_file.getAbsolutePath());
202 metadata_xml = new GDMDocument(metadata_file);
203 }
204 // The final case is where no current metadata.xml exists. Create a new one just by creating a new GDMDocument.
205 else {
206 ///ystem.err.println("Create a new GDMDocument for " + metadata_file.getAbsolutePath());
207 metadata_xml = new GDMDocument();
208 }
209 put(metadata_file, metadata_xml);
210 if(documents_in_cache_combobox != null) {
211 documents_in_cache_combobox.addItem(metadata_file);
212 }
213 //Gatherer.println("[0ms]\tCached " + metadata_file);
214 }
215 return metadata_xml;
216 }
217
218 /*
219 // returns metadata file from cache or creates a new one
220 public GDMDocument getDummyDocument(File file) {
221 ///ystem.err.println("Get the GDMDocument for " + file.getAbsolutePath());
222 GDMDocument metadata_xml = null;
223 // Determine the name of the target files metadata.xml file.
224 File metadata_file = null;
225 if(file.isFile()) {
226 metadata_file = new File(file.getParentFile(), StaticStrings.METADATA_XML);
227 }
228 else {
229 metadata_file = new File(file, StaticStrings.METADATA_XML);
230 }
231 // Then try to retrieve it from cache. First we consider the case of a cache hit.
232 if(containsKey(metadata_file)) {
233 metadata_xml = (GDMDocument) get(metadata_file);
234 }
235 else {
236 metadata_xml = new GDMDocument();
237 put(metadata_file, metadata_xml);
238 }
239 return metadata_xml;
240 }
241 */
242
243 /*
244 public synchronized void dummyGetMetadata(File file) {
245 String filename = null;
246 if(file.isFile()) {
247 filename = file.getName();
248 file = file.getParentFile();
249 }
250 GDMDocument document = getDummyDocument(file);
251 }
252 */
253
254 /** Recover the metadata associated with a particular file. Note that this call is synchronized, so that all of the data holders don't need to be. */
255 public synchronized ArrayList getMetadata(File file) {
256 return getMetadata(file, false, true);
257 }
258
259/** Recover the metadata associated with a particular file excluding folder level metadata. Note that this call is synchronized, so that all of the data holders don't need to be. */
260 public synchronized ArrayList getMetadataOnly(File file) {
261 return getMetadata(file, false, false);
262 }
263
264 public synchronized ArrayList getMetadata(File file, ElementWrapper element) {
265 ArrayList metadata = getMetadata(file, false, true);
266 ArrayList values = new ArrayList();
267 for(int i = 0; i < metadata.size(); i++) {
268 Metadata data = (Metadata) metadata.get(i);
269 if(element.equals(data.getElement())) {
270 values.add(data.getValue());
271 }
272 }
273 if(values.size() > 0) {
274 Collections.sort(values);
275 }
276 return values;
277 }
278
279 private ArrayList getMetadata(File file, boolean remove, boolean append_folder_level) {
280 ArrayList metadata = null;
281 String filename = null;
282 if(file.isFile()) {
283 filename = file.getName();
284 file = file.getParentFile();
285 }
286 GDMDocument document = getDocument(file);
287 if(file != null && document != null) {
288 metadata = document.getMetadata(filename, remove, metadata, file, append_folder_level);
289 document = null;
290 }
291 return metadata;
292 }
293
294 public synchronized ArrayList getAllMetadata(File file) { // boolean remove) {
295 ///ystem.err.println("getMetadata(" + file.getAbsolutePath() + ")");
296 ArrayList metadata = null;
297 // Build up a list of all the metadata xml files we have to check for metadata.
298 ArrayList search_files = new ArrayList();
299 String filename = null;
300 File start_file = file;
301 if(file.isFile()) {
302 filename = file.getName();
303 start_file = file.getParentFile();
304 }
305 File collection_dir = new File(Gatherer.c_man.getCollectionDirectory());
306 ///ystem.err.println("Collection directory = " + collection_dir.getAbsolutePath());
307 ///ystem.err.println("Start directory = " + start_file.getAbsolutePath());
308 while(!start_file.equals(collection_dir)) {
309 ///ystem.err.println("Blip!");
310 search_files.add(0, new MetadataXMLFileSearch(start_file, filename));
311 if(filename != null) {
312 filename = start_file.getName() + "/" + filename;
313 }
314 else {
315 filename = start_file.getName() + "/";
316 }
317 start_file = start_file.getParentFile();
318 ///ystem.err.println("Start directory = " + start_file.getAbsolutePath());
319 }
320 // Now search each of these metadata xml for metadata, remembering to accumulate or overwrite as we go along.
321 for(int i = 0; i < search_files.size(); i++) {
322 MetadataXMLFileSearch a_search = (MetadataXMLFileSearch) search_files.get(i);
323 ///ystem.err.println("Search " + a_search.file.getAbsolutePath() + File.separator + "metadata.xml for " + (a_search.filename != null ? a_search.filename : "directory metadata"));
324 // Retrieve the document
325 GDMDocument document = getDocument(a_search.file);
326 if(document != null) {
327 // There is one piece of slight of hand here. You can never remove metadata during a get all metadata.
328 metadata = document.getMetadata(a_search.filename, false, metadata, a_search.file, true);
329 ///ystem.err.println("Current metadata: " + toString(metadata));
330 document = null;
331 }
332 a_search = null;
333 }
334 start_file = null;
335 collection_dir = null;
336 filename = null;
337 search_files.clear();
338 search_files = null;
339 return metadata;
340 }
341
342 public String toString(ArrayList list) {
343 StringBuffer text = new StringBuffer("(");
344 for(int i = 0; list != null && i < list.size(); i++) {
345 text.append((list.get(i)).toString());
346 if(i < list.size() - 1) {
347 text.append(", ");
348 }
349 }
350 text.append(")");
351 return text.toString();
352 }
353
354 private class MetadataXMLFileSearch {
355 public File file;
356 public String filename;
357 public MetadataXMLFileSearch(File file, String filename) {
358 this.file = file;
359 this.filename = filename;
360 }
361 }
362
363 /** Called whenever the metadata value changes in some way, such as the addition of a new value. This is the only event type we care about, but we care about it a lot. It tells us what metadata to add, remove, etc from the cached metadata.xml files. Note that this method is synchronized so that the data objects don't need to be.
364 * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
365 * @see org.greenstone.gatherer.msm.GDMDocument
366 * @see org.greenstone.gatherer.msm.Metadata
367 * @see org.greenstone.gatherer.util.HashMap3D
368 */
369 public synchronized void metadataChanged(MSMEvent event) {
370 ///ystem.err.println("Recieved Event: " + event.toString());
371 File file = event.getFile();
372 if(file == null) {
373 FileNode record = event.getRecord();
374 file = record.getFile();
375 }
376 Metadata new_metadata = event.getNewMetadata();
377 Metadata old_metadata = event.getOldMetadata();
378 // These metadata objects may be new instances of metadata objects that already exist. Replace them if they are.
379 new_metadata = checkCache(new_metadata);
380 old_metadata = checkCache(old_metadata);
381 // Now apply the change to the document in question.
382 GDMDocument metadata_xml = getDocument(file);
383 if(metadata_xml != null) {
384 if(old_metadata != null) {
385 // File level
386 if(file.isFile()) {
387 metadata_xml.removeMetadata(file.getName(), old_metadata);
388 }
389 // Folder level
390 else {
391 metadata_xml.removeMetadata(null, old_metadata);
392 }
393 }
394 if(new_metadata != null) {
395 // File level
396 if(file.isFile()) {
397 metadata_xml.addMetadata(file.getName(), new_metadata, event.getAction() == MetaEditPrompt.ACCUMULATE);
398 }
399 else {
400 metadata_xml.addMetadata(null, new_metadata, event.getAction() == MetaEditPrompt.ACCUMULATE);
401 }
402 }
403 }
404 }
405
406 public void removeExtractedMetadata() {
407 try {
408 // Remove all of the extracted metadata in the collection
409 removeExtractedMetadata(new File(Gatherer.c_man.getCollectionImport()));
410 }
411 catch (Exception exception) {
412 Gatherer.println("Exception in GDMManager.removeExtractedMetadata - unexpected");
413 Gatherer.printStackTrace(exception);
414 }
415 }
416
417 private void removeExtractedMetadata(File file) {
418 // Retrieve the gdm document for this file
419 GDMDocument metadata_xml_document = getDocument(file);
420 // Remove the extracted metadata
421 ///ystem.err.println("Removing the extracted metadata from the file: " + file);
422 metadata_xml_document.removeExtractedMetadata();
423 metadata_xml_document = null;
424 // Then recurse down the directory structure looking for other metadata.xml files
425 File child_files[] = file.listFiles();
426 for(int i = 0; i < child_files.length; i++) {
427 if(child_files[i].isDirectory()) {
428 removeExtractedMetadata(child_files[i]);
429 }
430 }
431 child_files = null;
432 }
433
434 public ArrayList removeMetadata(File file) {
435 return getMetadata(file, true, false);
436 }
437
438 /** Causes all currently loaded GDMDocuments to write themselves out.
439 * @see org.greenstone.gatherer.msm.GDMDocument
440 */
441 public void save() {
442 Iterator iterator = keySet().iterator();
443 while(iterator.hasNext()) {
444 File file = (File) iterator.next();
445 GDMDocument document = (GDMDocument) get(file);
446 if(!document.isUpToDate()) {
447 //ystem.err.println("Saving: " + file.getAbsolutePath());
448 // First purge any old references.
449 document.getMetadata(null, false, null, null, false, true);
450 // If there is no metadata in this document then don't write out a file. In fact delete any file that already exists.
451 int count = document.countMetadata();
452 if(count > 0) {
453 // Now write the xml
454 Utility.export(document.getDocument(), file);
455 document.setUpToDate(true);
456 }
457 else if(file.exists()) {
458 file.delete();
459 }
460 }
461 }
462 }
463 /** Used to cause the document associated with a particular file to write the latest copy of itself to disk. */
464 public void save(FileNode node) {
465 File file = node.getFile();
466 if(file != null && file.isFile()) {
467 GDMDocument document = getDocument(file);
468 File xml_file;
469 if(file.isFile()) {
470 xml_file = new File(file.getParentFile(), "metadata.xml");
471 }
472 else {
473 xml_file = new File(file, "metadata.xml");
474 }
475 if(document != null && !document.isUpToDate()) {
476 // First purge any old references.
477 document.getMetadata(null, false, null, null, true);
478 // Now write the xml
479 Utility.export(document.getDocument(), xml_file);
480 document.setUpToDate(true);
481 }
482 xml_file = null;
483 document = null;
484 }
485 file = null;
486 }
487
488 /** Write out the latest copy of a certain document. */
489 public void save(File file, GDMDocument document) {
490 if(!document.isUpToDate()) {
491 // First purge any old references.
492 document.getMetadata(null, false, null, null, true);
493 // Now write the xml
494 Utility.export(document.getDocument(), file);
495 document.setUpToDate(true);
496 }
497 }
498
499
500 /** Method that is called whenever the metadata set collection changes in some way, such as the addition of a new set or the merging of two sets. If a set changes, mark all cached GDMDocuments as being stale.
501 * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
502 */
503 public void setChanged(MSMEvent event) {
504 for(Iterator values = values().iterator(); values.hasNext(); ) {
505 GDMDocument document = (GDMDocument) values.next();
506 document.setUpToDate(false);
507 document = null;
508 }
509 }
510 /** Called whenever the value tree of an metadata element changes in some way, such as the addition of a new value. --While the comments below are now obsolete, I'll keep them just to remind me of how easy it is to back yourself into a corner with issues such as caching and persisitant references--. Such an action would require us to painstakingly reload every metadata.xml file using the value model prior to the change, then painstakingly write out each metadata.xml file again using the modified model, but I'm a glutton for punishment so thats ok. The alternative is to not do this and watch in horror as heirarchy references quickly fall into disarray, pointing to the wrong place. This task gets even more complicated by three facts:<br>1. We want to do this is a seperate thread, as we don't want the program to come to a screaming halt while we're updating metadata.xml files.<br>2. We have to prevent any metadata.xml files being removed from cache while we're doing this, as if we encounter these more recently written files their heirarchy references will already be correct and that will balls up our little process. Note that this means the saving process may have to block while pending metadata heirarchy updates are in progress.<br>3. Regarding (2) we don't have to rewrite any metadata.xml files already in cache as they will be correctly written out whenever they happen to be dumped from cache.<br>4. We need the ability to pre-empt the general update to load a user demanded metadata.xml and store it in cache, using the old value tree model as per usual, and<br>5. We have to store a cue of these events, and process them one at a time. Perhaps one day when I'm feeling masacistic I'll figure out someway to merge several updates into one, but for now we have to change the tree one node at a time in order for references to remain correct.<br>Ok, so thats five facts, but you get the gist. Not an easy task, but crucial for accurate storage and recall of metadata heirarchies.
511 * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
512 */
513 public void valueChanged(MSMEvent event) {}
514
515 public void waitUntilComplete() {
516 //if(gdm_loader != null) {
517 // gdm_loader.waitUntilComplete();
518 //}
519 }
520
521 private Metadata checkCache(Metadata metadata) {
522 if(metadata != null) {
523 ///ystem.err.println("Search for " + metadata.toString());
524 if(metadata_cache.contains(metadata.getElement(), metadata.getValueNode())) {
525 metadata = (Metadata) metadata_cache.get(metadata.getElement(), metadata.getValueNode());
526 }
527 }
528 return metadata;
529 }
530
531 /** A separately threaded class to load all of the current metadata.xml files. Note that files can still be loaded on demand if they're not already in the cache. Also provides the functionality to block any other thread until the loading is complete, such as is necessary when moving values about in the value tree hierarchy. */
532 /*
533 private class GDMLoader
534 extends Thread {
535 private boolean complete = false;
536 private boolean dummy_load = false;
537
538 GDMLoader(boolean dummy_load) {
539 super("blarg");
540 this.dummy_load = dummy_load;
541 }
542
543
544 public void run() {
545 // Can't open a collections metadata when the collection isn't open!
546 while(!Gatherer.c_man.ready()) {
547 try {
548 wait(100);
549 }
550 catch(Exception error) {
551 }
552 }
553 // Now for each non-file directory in the tree, ask it to load its metadata
554 ArrayList remaining = new ArrayList();
555 remaining.add((FileNode)Gatherer.c_man.getRecordSet().getRoot());
556 int remaining_size = 0;
557 while((remaining_size = remaining.size()) > 0) {
558 FileNode record = (FileNode) remaining.remove(remaining_size - 1);
559 if(!record.isLeaf()) {
560 ///atherer.println("Retrieving metadata.xml for " + record);
561 if (this.dummy_load) {
562 dummyGetMetadata(record.getFile());
563 } else {
564 getMetadata(record.getFile());
565 }
566 for(int i = 0; i < record.getChildCount(); i++) {
567 remaining.add(record.getChildAt(i));
568 }
569
570 ///atherer.println("Retrieving metadata.xml for " + record);
571 getMetadata(record.getFile());
572
573 record.unmap();
574 }
575 record = null;
576 }
577 remaining = null;
578 complete = true;
579 }
580 public void waitUntilComplete() {
581 try {
582 while(!complete) {
583 sleep(100); // 1 second hopefully.
584 }
585 }
586 catch(Exception error) {
587 Gatherer.printStackTrace(error);
588 }
589 }
590 }
591 */
592
593 protected boolean removeEldestEntry(Map.Entry eldest) {
594 if(size() > MAX_DOCUMENTS) {
595 // Save the oldest document before its dumped
596 File file = (File) eldest.getKey();
597 ///ystem.err.println("Dumping oldest Document: " + file.getAbsolutePath());
598 GDMDocument document = (GDMDocument) eldest.getValue();
599 save(file, document);
600
601 if(documents_in_cache_combobox != null) {
602 documents_in_cache_combobox.removeItem(file);
603 }
604 // And then dump it
605 return true;
606 }
607 else {
608 return false;
609 }
610 }
611}
Note: See TracBrowser for help on using the repository browser.