package org.greenstone.gatherer.collection; /** *######################################################################### * * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * *

* * Author: John Thompson, Greenstone Digital Library, University of Waikato * *

* * Copyright (C) 1999 New Zealand Digital Library Project * *

* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *

* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *

* * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.tree.*; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.cdm.CollectionDesignManager; import org.greenstone.gatherer.collection.BuildOptions; import org.greenstone.gatherer.collection.CollectionManager; import org.greenstone.gatherer.file.FileNode; import org.greenstone.gatherer.msm.ElementWrapper; import org.greenstone.gatherer.msm.GDMManager; import org.greenstone.gatherer.msm.MetadataSetManager; import org.greenstone.gatherer.msm.MSMUtils; import org.greenstone.gatherer.util.Utility; import org.w3c.dom.*; /** Collection provides a common collection point for all the information about a certain collection build session. It keeps a record of several other managers that actually handle the content of the collection, such as metadata sets and metadata itself. * @author John Thompson, Greenstone Digital Library, University of Waikato * @version 2.3c */ public class Collection { /** A reference to the BuildOptions. */ public BuildOptions build_options; /** A reference to the Collection Design Manager. */ public CollectionDesignManager cdm; /** A reference to the Greenstone Directory Metadata Manager. */ public GDMManager gdm; /** A reference to the Metadata Set Manager. */ public MetadataSetManager msm; /** true if the currently loaded collection has been saved since the last significant change, false otherwise. */ private boolean saved = false; /** The collectio configuration file for this collection. */ private CollectionConfiguration collect_cfg; /** The document around which this collection class is based. */ private Document document; /** The file the collection is in (the file may not actually exist, such in the case of a legacy collection)! */ private File file; /** The name of the argument element. */ static final private String ARGUMENT = "Argument"; /** The name of the build element. */ static final private String BUILD = "Build"; /** The name of the built attribute. */ static final private String BUILT = "built"; /** The name of the build config element. */ static final private String BUILD_CONFIG = "BuildConfig"; /** The name of the collection xml template. */ static final private String COLLECTION_XML_TEMPLATE = "xml/template.col"; /** The name of the directory mappings element. */ static final private String DIRECTORY_MAPPINGS = "DirectoryMappings"; /** The name of the file attribute. */ static final private String FILE = "file"; /** The name of the import element. */ static final private String IMPORT = "Import"; /** The name of the imported attribute. */ static final private String IMPORTED = "imported"; /** The name of the mapping element. */ static final private String MAPPING = "Mapping"; /** The name of the name attribute. */ static final private String NAME = "name"; /** The name of the true value. */ static final private String TRUE = "true"; /** Constructor. */ public Collection(File collection_xml) { this.file = collection_xml; // Try to load this collections details. document = Utility.parse(collection_xml, false); // If that fails load the default settings for a collection. if(document == null) { document = Utility.parse(COLLECTION_XML_TEMPLATE, true); } // Point the Configuration class at our gatherer config arguments. Gatherer.config.setCollectionConfiguration(document); // We also attempt to parse the collection configuration file. collect_cfg = new CollectionConfiguration(new File(collection_xml.getParentFile(), Utility.CONFIG_DIR)); // Finally create all of the child managers that are directly dependant on a collection build_options = new BuildOptions(getBuildValues(), getImportValues()); } /** Add a special directory mapping. */ public boolean addDirectoryMapping(String name, File file) { boolean result = false; try { Element document_element = document.getDocumentElement(); Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS); // Ensure the name isn't already in use. boolean found = false; NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING); for(int i = 0; !found && i < mappings.getLength(); i++) { Element mapping_element = (Element) mappings.item(i); if(mapping_element.getAttribute(NAME).equalsIgnoreCase(name)) { found = true; } mapping_element = null; } // Otherwise add the mapping. if(!found) { Element mapping_element = document.createElement(MAPPING); mapping_element.setAttribute(NAME, name); mapping_element.setAttribute(FILE, file.toString()); directory_mappings_element.appendChild(mapping_element); result = true; mapping_element = null; } mappings = null; directory_mappings_element = null; document_element = null; saved = false; } catch (Exception error) { Gatherer.printStackTrace(error); } return result; } /** Destructor. * @see org.greenstone.gatherer.collection.CollectionModel */ public void destroy() { cdm.destroy(); gdm.destroy(); msm.destroy(); Gatherer.config.setCollectionConfiguration(null); cdm = null; document = null; gdm = null; msm = null; } /** Determine whether this collection has been successfully built in the past. * @return true if the collection has been built, false otherwise. */ public boolean getBuilt() { return get(BUILT); } /** Determine the number of documents and folders in this collection. */ public int getCount() { return getCount((TreeNode)Gatherer.c_man.getRecordSet().getRoot(), true, true); } /** Calculates the number of documents in this collection. */ public int getDocumentCount() { return getCount((TreeNode)Gatherer.c_man.getRecordSet().getRoot(), false, true); } /** Retrieve the description of this collection. * @return The description as a String. */ public String getDescription() { return collect_cfg.getDescription(); } /** Retrieve a specific directory mapping associated with this collection. * @param name The name of the mapping to retrieve as a String. * @return The File this name maps to, or null if no such mapping. */ public File getDirectoryMapping(String name) { File result = null; try { Element document_element = document.getDocumentElement(); Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS); // Ensure the name isn't already in use. boolean found = false; NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING); for(int i = 0; !found && i < mappings.getLength(); i++) { Element mapping_element = (Element) mappings.item(i); if(mapping_element.getAttribute(NAME).equalsIgnoreCase(name)) { result = new File(MSMUtils.getValue(mapping_element)); found = true; } mapping_element = null; } mappings = null; directory_mappings_element = null; document_element = null; } catch(Exception error) { Gatherer.printStackTrace(error); } return result; } /** Retrieve the special directory mappings associated with this collection. * @return A HashMap containing mappings from names to directories. */ public HashMap getDirectoryMappings() { HashMap special_directories = new HashMap(); try { Element document_element = document.getDocumentElement(); Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS); // Ensure the name isn't already in use. boolean found = false; NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING); for(int i = 0; !found && i < mappings.getLength(); i++) { Element mapping_element = (Element) mappings.item(i); String name = mapping_element.getAttribute(NAME); File file = new File(mapping_element.getAttribute(FILE)); special_directories.put(name, file); file = null; name = null; mapping_element = null; } mappings = null; directory_mappings_element = null; document_element = null; } catch(Exception error) { Gatherer.printStackTrace(error); } return special_directories; } /** Retrieve the authors email for this collection. * @return The email as a String. */ public String getEmail() { return collect_cfg.getCreator(); } /** Counts the number of folders used in the current record set. */ public int getFolderCount() { return getCount((TreeNode)Gatherer.c_man.getRecordSet().getRoot(), true, false); } /** Determine if this collection has had an import action run upon it since the last major change. * @return true if an import has occured, false otherwise. */ public boolean getImported() { return get(IMPORTED); } /** Retrieve the short name for this collection. * @return The name as a String. */ public String getName() { return file.getParentFile().getName(); } /** Determine if this collection has been saved since the last major change. * @return true if it has been saved recently, false otherwise. */ public boolean getSaved() { return saved; } /** Retrieve the title of this collection. * @return The title as a String. */ public String getTitle() { return collect_cfg.getName(); } /** Remove a previously defined special directory mapping. * @param name The name of the mapping to remove as a String. * @return The File of the mapping removed. */ public File removeDirectoryMapping(String name) { File file = null; try { Element document_element = document.getDocumentElement(); Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS); // Ensure the name isn't already in use. boolean found = false; NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING); for(int i = 0; !found && i < mappings.getLength(); i++) { Element mapping_element = (Element) mappings.item(i); if(mapping_element.getAttribute(NAME).equalsIgnoreCase(name)) { file = new File(MSMUtils.getValue(mapping_element)); directory_mappings_element.removeChild(mapping_element); found = true; } mapping_element = null; } mappings = null; directory_mappings_element = null; document_element = null; saved = false; } catch(Exception error) { Gatherer.printStackTrace(error); } return file; } /** Save this xml document to the given file. */ public void save() { Utility.export(document, file); } /** Set the value of built to the given value. * @param value The new value for built, true if the collection has been built successfully, false otherwise. */ public void setBuilt(boolean value) { set(BUILT, value); saved = false; } /** Set the value of imported to the given value. * @param value The new value for imported, true if the collection has been imported successfully, false otherwise. */ public void setImported(boolean value) { set(IMPORTED, value); saved = false; } /** Set the value of saved to the given value. * @param value The new value for saved, true if the collection has been saved recently, false otherwise. */ public void setSaved(boolean value) { saved = value; } /** Set the value of title to the given value. * @param title The new String title. */ public void setTitle(String title) { collect_cfg.setName(title); } /** Method called to return a textual representation of a class, which in this case is the collections title. * @return A String containing the collections title. */ public String toString() { return collect_cfg.getName(); } /** Get the value of a collection argument. */ private boolean get(String name) { boolean result = false; try { Element document_element = document.getDocumentElement(); NodeList arguments = document_element.getElementsByTagName(ARGUMENT); boolean found = false; for(int i = 0; !found && i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); if(argument_element.getParentNode() == document_element) { if(argument_element.getAttribute(NAME).equalsIgnoreCase(BUILT)) { String value = MSMUtils.getValue(argument_element); if(value.equalsIgnoreCase(TRUE)) { result = true; } found = true; value = null; } } argument_element = null; } arguments = null; document_element = null; } catch (Exception error) { Gatherer.printStackTrace(error); } return result; } /** Method to retrieve the current build options associated with this Collection. */ private Element getBuildValues() { Element build_values_element = null; try { Element document_element = document.getDocumentElement(); Element build_config_element = (Element) MSMUtils.getNodeFromNamed(document_element, BUILD_CONFIG); build_values_element = (Element) MSMUtils.getNodeFromNamed(build_config_element, BUILD); build_config_element = null; document_element = null; } catch (Exception error) { Gatherer.printStackTrace(error); } return build_values_element; } /** Count either documents or folders, depending on the state of the given boolean. */ private int getCount(TreeNode node, boolean count_folders, boolean count_files) { int count = 0; File file = ((FileNode)node).getFile(); if(file.isFile() && count_files) { count++; } else if(file.isDirectory() && count_folders) { count++; } for(int i = 0; i < node.getChildCount(); i++) { count = count + getCount(node.getChildAt(i), count_folders, count_files); } return count; } /** Method to retrieve the current import options associated with this Collection. */ public Element getImportValues() { Element import_values_element = null; try { Element document_element = document.getDocumentElement(); Element build_config_element = (Element) MSMUtils.getNodeFromNamed(document_element, BUILD_CONFIG); import_values_element = (Element) MSMUtils.getNodeFromNamed(build_config_element, IMPORT); build_config_element = null; document_element = null; } catch (Exception error) { Gatherer.printStackTrace(error); } return import_values_element; } /** Set the value of a collection argument. */ private void set(String name, boolean value) { try { Element document_element = document.getDocumentElement(); NodeList arguments = document_element.getElementsByTagName(ARGUMENT); boolean found = false; for(int i = 0; !found && i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); if(argument_element.getParentNode() == document_element) { if(argument_element.getAttribute(NAME).equalsIgnoreCase(BUILT)) { // Strip any current value nodes. while(argument_element.hasChildNodes()) { argument_element.removeChild(argument_element.getFirstChild()); } // Append new value argument_element.appendChild(document.createTextNode(value ? "true" : "false")); } } argument_element = null; } arguments = null; document_element = null; } catch (Exception error) { Gatherer.printStackTrace(error); } } }