/** *############################################################################ * A component of the Greenstone Librarian Interface, part of the Greenstone * digital library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ * * Copyright (C) 2004 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. *############################################################################ */ package org.greenstone.gatherer.metadata; import java.io.*; import java.util.*; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.file.FileNode; import org.greenstone.gatherer.util.Utility; import org.greenstone.gatherer.util.XMLTools; /** This class is a static class that manages the metadata.xml files */ public class MetadataXMLFileManager { static private ArrayList metadata_xml_files = new ArrayList(); static public void addMetadata(FileNode file_node, MetadataValue metadata_value) { FileNode[] file_nodes = new FileNode[1]; file_nodes[0] = file_node; addMetadata(file_nodes, metadata_value); } static public void addMetadata(FileNode[] file_nodes, MetadataValue metadata_value) { // Add the metadata to each file node in turn for (int i = 0; i < file_nodes.length; i++) { File current_file = file_nodes[i].getFile(); DebugStream.println("Adding metadata to " + current_file.getAbsolutePath()); // Find which metadata.xml file needs editing boolean applicable_metadata_xml_file_found = false; File current_file_directory = (current_file.isDirectory() ? current_file : current_file.getParentFile()); for (int j = 0; j < metadata_xml_files.size(); j++) { MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(j); // This metadata.xml file is only applicable if it is at the same level as the file if (current_file_directory.getAbsolutePath().equals(metadata_xml_file.getParentFile().getAbsolutePath())) { applicable_metadata_xml_file_found = true; metadata_xml_file.addMetadata(current_file, metadata_value); } } // If no applicable metadata.xml file exists, we have to create a new one if (!applicable_metadata_xml_file_found) { // Create a new (empty) metadata.xml file in the file's directory... File new_metadata_xml_file_file = new File(current_file_directory, "metadata.xml"); XMLTools.writeXMLFile(new_metadata_xml_file_file, Utility.parse("xml/metadata.xml", true)); // ...load it... MetadataXMLFile new_metadata_xml_file = loadMetadataXMLFile(new_metadata_xml_file_file); // ...and add the metadata new_metadata_xml_file.addMetadata(current_file, metadata_value); } } } static public void clearMetadataXMLFiles() { metadata_xml_files.clear(); } /** Returns the metadata assigned to a file outside the collection, excluding folder-level/inherited metadata. */ static public ArrayList getMetadataAssignedDirectlyToExternalFile(File file) { DebugStream.println("Getting metadata assigned directly to external file " + file + "..."); // Build up a list of applicable metadata.xml files ArrayList applicable_metadata_xml_files = new ArrayList(); File directory = (file.isDirectory() ? file : file.getParentFile()); while (directory != null) { File[] directory_files = directory.listFiles(); for (int i = 0; i < directory_files.length; i++) { File child_file = directory_files[i]; if (!child_file.isDirectory() && child_file.getName().equals("metadata.xml")) { // It is very important that shallower files come before deeper ones applicable_metadata_xml_files.add(0, new MetadataXMLFile(child_file.getAbsolutePath())); } } directory = directory.getParentFile(); } // Get the metadata assigned to the specified file from the applicable metadata.xml files ArrayList assigned_metadata = getMetadataAssignedToFile(file, applicable_metadata_xml_files); // Remove any folder-level metadata for (int i = assigned_metadata.size() - 1; i >= 0; i--) { if (((MetadataValue) assigned_metadata.get(i)).isInheritedMetadata()) { assigned_metadata.remove(i); } } return assigned_metadata; } /** Returns the metadata assigned to a file inside the collection, excluding folder-level/inherited metadata. */ static public ArrayList getMetadataAssignedDirectlyToFile(File file) { // Get all the metadata assigned to the specified file... ArrayList assigned_metadata = getMetadataAssignedToFile(file); // ...then remove any folder-level metadata for (int i = assigned_metadata.size() - 1; i >= 0; i--) { if (((MetadataValue) assigned_metadata.get(i)).isInheritedMetadata()) { assigned_metadata.remove(i); } } return assigned_metadata; } /** Returns all the metadata assigned to a file inside the collection. */ static public ArrayList getMetadataAssignedToFile(File file) { // Build up a list of applicable metadata.xml files ArrayList applicable_metadata_xml_files = new ArrayList(); // Look at each loaded metadata.xml file to see if it is potentially applicable File file_directory = (file.isDirectory() ? file : file.getParentFile()); for (int i = 0; i < metadata_xml_files.size(); i++) { MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(i); // This metadata.xml file is only potentially applicable if it is above or at the same level as the file if (file_directory.getAbsolutePath().startsWith(metadata_xml_file.getParentFile().getAbsolutePath())) { applicable_metadata_xml_files.add(metadata_xml_file); } } // Return the metadata assigned to the specified file from the applicable metadata.xml files return getMetadataAssignedToFile(file, applicable_metadata_xml_files); } static private ArrayList getMetadataAssignedToFile(File file, ArrayList applicable_metadata_xml_files) { // Build up a list of metadata values assigned to this file ArrayList metadata_values_all = new ArrayList(); // Look at each applicable metadata.xml file to see if it assigns metadata to this file for (int i = 0; i < applicable_metadata_xml_files.size(); i++) { MetadataXMLFile metadata_xml_file = (MetadataXMLFile) applicable_metadata_xml_files.get(i); DebugStream.println("Applicable metadata.xml file: " + metadata_xml_file); ArrayList metadata_values = metadata_xml_file.getMetadataAssignedToFile(file); for (int j = 0; j < metadata_values.size(); j++) { MetadataValue metadata_value = (MetadataValue) metadata_values.get(j); // Overriding metadata: remove any values with this metadata element if (metadata_value.isAccumulatingMetadata() == false) { for (int k = metadata_values_all.size() - 1; k >= 0; k--) { if (((MetadataValue) metadata_values_all.get(k)).getMetadataElement().equals(metadata_value.getMetadataElement())) { metadata_values_all.remove(k); } } } metadata_values_all.add(metadata_value); } } return metadata_values_all; } static public void loadMetadataXMLFiles(File directory) { // Make sure the directory (import) exists if (directory.exists() == false) { return; } // Look recursively at each subfile of the directory for metadata.xml files File[] directory_files = directory.listFiles(); for (int i = 0; i < directory_files.length; i++) { File child_file = directory_files[i]; if (child_file.isDirectory()) { loadMetadataXMLFiles(child_file); } else if (child_file.getName().equals("metadata.xml")) { loadMetadataXMLFile(child_file); } } } static private MetadataXMLFile loadMetadataXMLFile(File metadata_xml_file_file) { MetadataXMLFile metadata_xml_file = new MetadataXMLFile(metadata_xml_file_file.getAbsolutePath()); metadata_xml_file.skimFile(); metadata_xml_files.add(metadata_xml_file); return metadata_xml_file; } static public void removeMetadata(FileNode file_node, MetadataValue metadata_value) { FileNode[] file_nodes = new FileNode[1]; file_nodes[0] = file_node; removeMetadata(file_nodes, metadata_value); } static public void removeMetadata(FileNode[] file_nodes, MetadataValue metadata_value) { // Remove the metadata from each file node in turn for (int i = 0; i < file_nodes.length; i++) { File current_file = file_nodes[i].getFile(); DebugStream.println("Removing metadata from " + current_file.getAbsolutePath()); // Find which metadata.xml file needs editing File current_file_directory = (current_file.isDirectory() ? current_file : current_file.getParentFile()); for (int j = 0; j < metadata_xml_files.size(); j++) { MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(j); // This metadata.xml file is only potentially applicable if it is above or at the same level as the file if (current_file_directory.getAbsolutePath().startsWith(metadata_xml_file.getParentFile().getAbsolutePath())) { metadata_xml_file.removeMetadata(current_file, metadata_value); } } } } static public void unloadMetadataXMLFile(File metadata_xml_file_file) { DebugStream.println("Unloading metadata.xml file " + metadata_xml_file_file); // Find the metadata.xml file in the list of loaded files, and remove it for (int i = 0; i < metadata_xml_files.size(); i++) { MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(i); if (metadata_xml_file_file.getAbsolutePath().equals(metadata_xml_file.getAbsolutePath())) { metadata_xml_files.remove(i); break; } } } }