source: trunk/gli/src/org/greenstone/gatherer/gems/MetadataSetManager.java@ 8809

Last change on this file since 8809 was 8809, checked in by mdewsnip, 19 years ago

Minor changes.

  • Property svn:keywords set to Author Date Id Revision
File size: 20.9 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.gems;
38
39import java.io.*;
40import java.util.*;
41import java.util.StringTokenizer;
42import javax.swing.*;
43import javax.swing.filechooser.*;
44import javax.swing.tree.TreePath;
45import org.greenstone.gatherer.Configuration;
46import org.greenstone.gatherer.DebugStream;
47import org.greenstone.gatherer.util.Utility;
48import org.greenstone.gatherer.collection.CollectionManager;
49import org.greenstone.gatherer.file.*;
50import org.greenstone.gatherer.util.XMLTools;
51import org.apache.xerces.parsers.*;
52import org.apache.xml.serialize.*;
53import org.w3c.dom.*;
54import org.xml.sax.*;
55
56/** This class is responsible for managing all the metadata sets in the collection and for providing methods for manipulating the aforementioned sets contents.
57 * @author John Thompson, Greenstone Digital Library, University of Waikato
58 * @version 2.3b
59 */
60public class MetadataSetManager {
61
62 /** The character used to separate name space from metadata element. */
63 static public char NS_SEP= '.';
64 /** The character used to separate subfields from metadata element. */
65 static public String SF_SEP= "#";
66
67 /** The name of the hidden, or system, metadata set. */
68 static final public String HIDDEN = "hidden";
69 static final public int MAX_LOADED_SETS = 64;
70 static public CollectionManager col_man = null;
71 /** A mapping from metadata namespace to metadata set. */
72 static private Hashtable mds_hashtable = new Hashtable();
73 public GEMS gemsptr;
74
75 /** The profiler is responsible for remembering what actions a user has requested when importing metadata, so as to prevent the user needlessly re-entering this information for each import. */
76 // public MSMProfiler profiler = null;
77
78
79 /** Constructor. */
80 public MetadataSetManager(GEMS gemscopy) {
81 gemsptr = gemscopy;
82 col_man = new CollectionManager();
83 }
84
85
86 public MetadataSet addSet(String namespace, String name) {
87 MetadataSet mds = new MetadataSet(GEMS.METADATA_SET_TEMPLATE);
88 mds.setAttribute("creator", "The Greenstone Librarian Interface");
89 // Calculate lastchanged to right now on this machine by this user
90 String user_name = System.getProperty("user.name");
91 String machine_name = Utility.getMachineName();
92 mds.setAttribute("lastchanged", Utility.getDateString() + " - " + user_name + " on " + machine_name);
93 // And the remaining attributes.
94 //mds.setAttribute("name", name);
95 mds.setAttribute("namespace", namespace);
96 // Add the name element.
97 mds.setName(name);
98 // this is the location for a global metadata set
99 File mds_file = new File(Utility.METADATA_DIR, namespace + ".mds");
100 mds.setFile(mds_file);
101 mds_hashtable.put(namespace, mds);
102 // fireSetChanged(mds);
103 return mds;
104 }
105 public Vector getVectorSets() {
106 Vector sets = new Vector();
107
108 File metadata_directory = new File(Utility.METADATA_DIR);
109 if (metadata_directory.exists()) {
110 // Load just those .mds files in this directory, and return them
111 File[] directory_files = metadata_directory.listFiles();
112 for (int i = 0; i < directory_files.length; i++) {
113 File child_file = directory_files[i];
114 if (!child_file.isDirectory() && child_file.getName().endsWith(".mds")) {
115 System.err.println("Found mds file: " + child_file);
116 MetadataSet metadata_set = loadMetadataSet(child_file);
117 // metadata_set.getName();
118 sets.add(new String(child_file.toString() + " ^ " + metadata_set.getName()));
119 //model.add(null, metadata_set, GEMSNode.SET);
120 }
121 }
122 }
123 return sets;
124 }
125 public Object [] getVectorSetsToStringArray() {
126
127 return getSets().toArray();
128 }
129 /** Add a value tree to a given metadata element represented as a GValueModel
130 * @param model The <strong>GValueTree</strong> model
131 */
132 public void addValueTree(GValueModel model) {
133 ElementWrapper element = model.getElement();
134 String namespace = element.getNamespace();
135 MetadataSet mds = (MetadataSet) mds_hashtable.get(namespace);
136 if(mds != null) {
137 mds.addValueTree(element, model);
138 }
139 }
140
141
142 /** Destructor.
143 */
144 public void destroy() {
145 mds_hashtable.clear();
146 }
147
148
149 /** Used to get all the (non-hidden) elements in this manager.
150 * @return A Vector of ElementWrappers.
151 */
152 public Vector getElements() {
153 return getElements(false);
154 }
155
156 public Vector getElements(boolean all) {
157 return getElements(all, false);
158 }
159
160 /** Used to get all the elements in this manager.
161 * @param all <i>true</i> if all elements, including hidden, should be returned.
162 * @return A Vector of ElementWrappers.
163 */
164 public Vector getElements(boolean all, boolean force_extracted) {
165 Vector all_elements = new Vector();
166 for(Enumeration keys = mds_hashtable.keys(); keys.hasMoreElements(); ) {
167 MetadataSet mds = (MetadataSet)mds_hashtable.get(keys.nextElement());
168 if((!mds.getNamespace().equals(Utility.EXTRACTED_METADATA_NAMESPACE) && !mds.getNamespace().equals(HIDDEN))
169 || (mds.getNamespace().equals(Utility.EXTRACTED_METADATA_NAMESPACE) && (Configuration.get("general.view_extracted_metadata", Configuration.COLLECTION_SPECIFIC) || force_extracted))
170 || (mds.getNamespace().equals(Utility.EXTRACTED_METADATA_NAMESPACE) && mds.getNamespace().equals(HIDDEN) && all)) {
171 NodeList set_elements = mds.getElements();
172 ///ystem.err.println("The set " + mds + " has " + set_elements.getLength() + " elements.");
173 for(int i = 0; i < set_elements.getLength(); i++) {
174 Element raw_element = (Element)set_elements.item(i);
175 ElementWrapper element = new ElementWrapper(raw_element);
176 // For now we do not add subfield elements and their parents, just the subfields.
177 NodeList child_elements = raw_element.getElementsByTagName("Element");
178 if(child_elements.getLength() == 0) {
179 all_elements.add(element);
180 }
181 }
182 }
183 }
184 Collections.sort(all_elements);
185 return all_elements;
186 }
187
188 /** Retrieve a metadata element by its index.
189 * @param index The specified index as an int.
190 * @return An ElementWrapper containing the specied element, or <i>null</i> is no such element exists.
191 */
192 public ElementWrapper getElement(int index) {
193 Vector elements = getElements(false);
194 ElementWrapper result = null;
195 if(0 <= index && index < elements.size()) {
196 result = (ElementWrapper) elements.get(index);
197 }
198 return result;
199 }
200 /** Retrieve a metadata element by looking at the current metadata element. Note that this 'index' element may now be disconnected from the DOM model, so we have to reload the target element by the string method.
201 * @param element The possibly out-of-data MetadataElement.
202 * @return An ElementWrapper containing the specied element, or <i>null</i> is no such element exists.
203 */
204 public ElementWrapper getElement(ElementWrapper element) {
205 return getElement(element.toString());
206 }
207 /** Retrieve a metadata element by its fully qualified name.
208 * @param name The elements name as a String.
209 * @return An ElementWrapper containing the specied element, or <i>null</i> is no such element exists.
210 */
211 public ElementWrapper getElement(String name) {
212 return getElement(name, false);
213 }
214
215 public ElementWrapper getElement(String name, boolean perfect) {
216 ///ystem.err.println("Retrieve element " + name);
217 if(name == null) {
218 ///ystem.err.println("No name!");
219 return null;
220 }
221 ElementWrapper result = null;
222 MetadataSet set = null;
223 String element = null;
224 // First we seperate off what set it is in, where we have '<set><namespace_separator><element>'.
225 if(name.indexOf(NS_SEP) != -1) {
226 String namespace = name.substring(0, name.indexOf(NS_SEP));
227 // Retrieve the correct set if possible.
228 set = (MetadataSet)mds_hashtable.get(namespace);
229 namespace = null;
230 // Now retrieve the element name.
231 element = name.substring(name.indexOf(NS_SEP) + 1);
232 }
233 // If we are looking for a perfect match, we can assume that no namespace means extracted metadata
234 else if(!perfect) {
235 // No namespace so assume that its extracted metadata.
236 set = (MetadataSet)mds_hashtable.get(Utility.EXTRACTED_METADATA_NAMESPACE);
237 element = name;
238 }
239 if(set != null) {
240 // Now we have a set we are ready to locate the requested element. Break the remaining element name down by the subfield separator, attempting to retrieve the element indicated by each step.
241 if(element.indexOf(SF_SEP) != -1) {
242 StringTokenizer tokenizer = new StringTokenizer(element, SF_SEP);
243 // Has to be at least two tokens
244 if(tokenizer.countTokens() >= 2) {
245 Element current_element = set.getElement(tokenizer.nextToken());
246 while(current_element != null && tokenizer.hasMoreTokens()) {
247 current_element = set.getElement(current_element, tokenizer.nextToken());
248 }
249 if(current_element != null) {
250 result = new ElementWrapper(current_element);
251 current_element = null;
252 }
253 }
254 tokenizer = null;
255 }
256 // No subfields - much easier.
257 if(result == null) {
258 ///ystem.err.print("Trying to match element " + element +"?");
259 Element temp = set.getElement(element);
260 if(temp != null) {
261 result = new ElementWrapper(temp);
262 }
263 temp = null;
264 }
265 set = null;
266 }
267 element = null;
268 return result;
269 }
270 /** Retrieve a certain named element from a certain named set.
271 * @param set The metadata set whose element you want.
272 * @param name The name of the element.
273 * @return An ElementWrapper around the requested element, or null if no such set or element.
274 */
275 public ElementWrapper getElement(String set, String name) {
276 if(mds_hashtable.containsKey(set)) {
277 MetadataSet temp = (MetadataSet)mds_hashtable.get(set);
278 return new ElementWrapper(temp.getElement(name));
279 }
280 return null;
281 }
282
283 /** Retrieve the named metadata set.
284 * @param name The sets name as a String.
285 * @return The MetadataSet as named, or null if no such set.
286 */
287 public MetadataSet getSet(String namespace) {
288 if(mds_hashtable.containsKey(namespace)) {
289 return (MetadataSet) mds_hashtable.get(namespace);
290 }
291// else if(name.equals(HIDDEN)) {
292// return createHidden();
293// }
294 return null;
295 }
296
297 /** Method to retrieve all of the metadata sets loaded in this collection.
298 * @return A Vector of metadata sets.
299 */
300 public Vector getSets() {
301 return getSets(true);
302 }
303
304 public Vector getSets(boolean include_greenstone_extracted) {
305 Vector result = new Vector();
306 for(Enumeration keys = mds_hashtable.keys(); keys.hasMoreElements(); ) {
307 MetadataSet set = (MetadataSet)mds_hashtable.get(keys.nextElement());
308 if(!set.getNamespace().equals(HIDDEN) && (include_greenstone_extracted || !set.getNamespace().equals(Utility.EXTRACTED_METADATA_NAMESPACE))) {
309 result.add(set);
310 }
311 }
312 return result;
313 }
314
315
316 /** Get the value tree that matches the given element.
317 * @param element The ElementWrapper representing the element.
318 * @return The GValueModel representing the value tree or null.
319 */
320 public GValueModel getValueTree(ElementWrapper element) {
321 GValueModel value_tree = null;
322 if(element != null) {
323 String namespace = element.getNamespace();
324 if(namespace.length() > 0) {
325 MetadataSet mds = (MetadataSet) mds_hashtable.get(namespace);
326 if(mds != null) {
327 value_tree = mds.getValueTree(element);
328 }
329 }
330 }
331 return value_tree;
332 }
333
334
335 public MetadataSet loadMetadataSet(File metadata_set_file)
336 {
337 File[] all_sets = new File[MAX_LOADED_SETS];
338 MetadataSet tempSet;
339 int i = 0;
340 System.err.println("Loading metadata set file " + metadata_set_file + "...");
341 MetadataSet metadata_set = new MetadataSet(metadata_set_file);
342
343 //write out existing namespaces to all_sets[]...we use this to determine if a set is
344 //already loaded-Attila
345 for(Enumeration keys = mds_hashtable.keys(); keys.hasMoreElements(); ) {
346 tempSet = (MetadataSet)mds_hashtable.get(keys.nextElement());
347
348 all_sets[i] = tempSet.getFile();
349 i++;
350 }
351
352 //Now check our metadata.set's namespace to see if it is already loaded in all_sets
353 for(int p = 0 ; p < i; p++) {
354
355 if(metadata_set.getFile().compareTo(all_sets[p]) == 0) {
356 // System.err.println("Not loading set: "+ metadata_set.getNamespace() + " is already loaded.\n");
357 // JOptionPane.showMessageDialog(self, Dictionary.get("MEM.Cannot_Add_Elements_To_Greenstone_MDS"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
358 gemsptr.warn_cant_load_set();
359
360 return null;
361 }
362
363 }
364
365 //check if this metadata set belongs to a collection
366 //if so, then change the metadata set's name in the interface to (collection) dublic core...
367 // System.out.println(new String("asdfd" + metadata_set.getFile().separator));
368 String sep = new String(metadata_set.getFile().separator);
369 StringTokenizer st = new StringTokenizer(metadata_set.getFile().toString(), sep);
370 String colName = new String("");
371
372 while ( st.hasMoreTokens() )
373 {
374 if(st.nextToken().compareTo("collect") == 0) {
375 colName = st.nextToken();
376 // metadata_set.old_filename = metadata_set.getName();
377 // metadata_set.setName(new String("(" + colName + ") " + metadata_set.getName()) );
378 break;
379 }
380 }
381
382 //Actual set loading code(if it gets this far-Attila
383 //**************
384 //mds_hashtable.put(metadata_set.getNamespace(), metadata_set);
385 if (colName.equals("")) {
386 mds_hashtable.put(colName+":"+metadata_set.getNamespace(), metadata_set);
387 } else {
388 metadata_set.setCollection(colName);
389 mds_hashtable.put(metadata_set.getNamespace(), metadata_set);
390 }
391 return metadata_set;
392 }
393
394
395 public void removeElement(ElementWrapper element) {
396 // Retrieve the metadata set this element belongs to.
397 String namespace = element.getNamespace();
398 MetadataSet set = (MetadataSet) mds_hashtable.get(namespace);
399 if(set != null) {
400 // Bugger. Get the old name -before- we remove the element from the set.
401 String old_name = element.toString();
402 // Remove the element.
403 set.removeElement(element.getElement());
404 }
405 else {
406 ///ystem.err.println("no such set " + namespace);
407 }
408 // No such set. No such element.
409 }
410/*Following write() and write() and save() were taken from msm/metadatasetmanager.java and converted to
411 *the gems standard
412 */
413 private void write(ElementWrapper element, GValueModel model, String etc_dir) {
414 try {
415 File out_file = new File(etc_dir + element.getName() + ".txt");
416 FileOutputStream fos = new FileOutputStream(out_file);
417 OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
418 BufferedWriter bw = new BufferedWriter(osw, Utility.BUFFER_SIZE);
419 Vector all_values = model.traverseTree();
420 for(int i = 0; i < all_values.size(); i++) {
421 GValueNode node = (GValueNode)all_values.get(i);
422 TreePath path = new TreePath(node.getPath());
423 String full_value = node.getFullPath(false);
424 String index = model.getHIndex(full_value);
425
426 write(bw, "\"" + full_value + "\"\t" + index + "\t\"" + node.toString(GValueNode.GREENSTONE) + "\"");
427 }
428 // Very important we do this, or else buffer may not be flushed
429 bw.flush();
430 bw.close();
431 }
432 catch(Exception error) {
433 error.printStackTrace();
434 }
435 }
436
437 private void write(Writer w, String text)
438 throws Exception {
439 text = text + "\r\n";
440 char buffer[] = text.toCharArray();
441 w.write(buffer, 0, buffer.length);
442 }
443 public void save() {
444 // Create the correct file to save these sets to...
445 //File file = new File(Gatherer.self.getCollectionMetadata());
446 //File file = new File(GEMS.config.gsdl_path + "/gli/metadata");
447 File file = new File(Utility.METADATA_DIR);
448
449
450 if (!file.exists()) {
451 //DebugStream.println("trying to save a collection and the metadata directory does not exist - creating it!");
452 System.out.println("trying to save a collection and the metadata directory does not exist - creating it!");
453
454 file.mkdir();
455 }
456 // And make back ups of all existing metadata set files.
457 File temp[] = file.listFiles();
458
459 //Null ptr exception here? Didnt see it, -Attila
460 /*for(int i = temp.length - 1; i >= 0; i--) {
461 // System.out.println("Itter: " + i);
462 if(temp[i].getName().endsWith(".mds") ) {
463 File backup = new File(temp[i].getAbsolutePath() + "~bak");
464
465 //System.out.println(temp[i].getAbsolutePath()+ "asdf\n backupfile:"+ backup.toString());
466
467
468 //backup.deleteOnExit();
469
470 if(!temp[i].renameTo(backup)) {
471 DebugStream.println("Error in MetadataSetManager.save(): FileRenamedException");
472 System.out.println("Error in MetadataSetManager.save(): FileRenamedException");
473 }
474 }
475 }*/
476 // Now save the latest versions of the metadata sets.
477 for(Enumeration keys = mds_hashtable.keys(); keys.hasMoreElements(); ) {
478 String namespace = (String) keys.nextElement();
479 MetadataSet set = (MetadataSet) mds_hashtable.get(namespace);
480 //
481 //col_man.loadCollection(GEMS.config.getString("general.open_collection",true));
482 //
483 try {
484 // this won't work if we have collection metadata open
485 //File mds_file = new File(file, set.getNamespace() + ".mds");
486
487 //set.setName(set.old_filename);
488
489 //set has not changed(or has been recently saved
490
491
492 /*
493 if(set.getSetChanged() == false){
494 continue;
495 }*/
496
497 // just use the existing file path
498 File mds_file = set.getFile();
499 //System.out.println(mds_file.toString() + "a\n");
500 //Saves the DOM obj that set.getDocument returns to mds_file name
501 // set.getF
502 // System.out.println(keys.toString());
503
504
505 // System.out.println("::: " + mds_file.toString());
506 XMLTools.export(set.getDocument(), mds_file);
507
508 set.setSetChanged(false);
509 //What does setfile do?
510 //set.setFile(mds_file);
511 //}
512 // Now for each element attempt to save its value tree.
513 //NodeList elements = set.getElements();
514 //for(int i = elements.getLength() - 1; i >= 0; i--) {
515 // ElementWrapper value_element = new ElementWrapper((Element)elements.item(i));
516 //if(value_element.hasValueTree()) {
517 //GValueModel value_tree = set.getValueTree(value_element);
518 //if(value_tree != null) {
519 //File value_file = new File(file, value_element.getName() + ".mdv");
520 ///ystem.err.println("Saving value file: " + value_file.toString());
521 //Utility.export(value_tree.getDocument(), value_file);
522 // If this is a hierarchy element, write hierarchy file.
523 //if(value_element.getNamespace().equals(MetadataSetManager.HIDDEN) || value_tree.isHierarchy()) {
524 //System.out.println("Val Tree: " +value_file.toString() + "\n");
525 // value_element.
526 // System.out.println(col_man.getCollectionEtc() + "<--getColEtc\n");
527 // write(value_element, value_tree, new String("/home/arosmain/gsdl/gli/"));
528 //}
529 //}
530 //}
531 //System.out.println("Val element: "+value_element.toString() + "\n");
532 //}
533 }
534 catch (Exception error) {
535 error.printStackTrace();
536 }
537 }
538 //profiler.save();
539 }
540 public void removeSet(MetadataSet set) {
541 mds_hashtable.remove(set.getNamespace());
542 File f = set.getFile();
543 f.delete();
544 //System.out.println(f.toString() + Utility.METADATA_DIR);
545 // fireSetChanged(set);
546 }
547}
Note: See TracBrowser for help on using the repository browser.