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 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 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 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(name)) {
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(name)) {
// 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);
}
}
}