source: trunk/gli/src/org/greenstone/gatherer/msm/GreenstoneArchiveParser.java@ 6158

Last change on this file since 6158 was 6143, checked in by jmt12, 21 years ago

Archive parser now notices the presence of a SourceSegment piece of metadata - a sure sign that the doc.xml has been generated from a bibliographic source, and also a very good reason not to extract metadata from this file given that it will not only not make sense, but will also end up with thirty-thousand bits of metadata attached to one file

  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 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.io.*;
40import java.net.*;
41import java.util.*;
42import org.greenstone.gatherer.Configuration;
43import org.greenstone.gatherer.Dictionary;
44import org.greenstone.gatherer.Gatherer;
45import org.greenstone.gatherer.collection.Collection;
46import org.greenstone.gatherer.collection.CollectionManager;
47import org.greenstone.gatherer.file.FileNode;
48import org.greenstone.gatherer.msm.ElementWrapper;
49import org.greenstone.gatherer.msm.MetadataSet;
50import org.greenstone.gatherer.msm.MetadataSetManager;
51import org.greenstone.gatherer.msm.MSMUtils;
52import org.greenstone.gatherer.shell.GShell;
53import org.greenstone.gatherer.shell.GShellProgressMonitor;
54import org.greenstone.gatherer.util.StaticStrings;
55import org.greenstone.gatherer.util.Utility;
56import org.greenstone.gatherer.valuetree.GValueModel;
57import org.greenstone.gatherer.valuetree.GValueNode;
58import org.w3c.dom.*;
59
60public class GreenstoneArchiveParser {
61
62 private GShell shell;
63
64 static final String ignore_list[] = {"assocfilepath", "gsdl", "Identifier", "URL"}; //"Source",
65
66 public GreenstoneArchiveParser(GShellProgressMonitor progress, GShell shell) {
67 // We can only extract metadata if an extracted metadata set exists in our collection.
68 if(Gatherer.c_man.msm.getSet(Utility.EXTRACTED_METADATA_NAMESPACE) != null) {
69 this.shell = shell;
70 // Determine the collection archive directory.
71 File archive_directory = new File(Gatherer.c_man.getCollectionArchive());
72 // For each of the hash coded directories within.
73 File document_directories[] = archive_directory.listFiles();
74 for(int i = 0; i < document_directories.length; i++) {
75 // Find the doc.xml file within
76 if(document_directories[i].isDirectory()) {
77 File document_file = new File(document_directories[i], "doc.xml");
78 // Then extract the metadata from it.
79 if(document_file.exists()) {
80 int count = extractMetadata(document_file);
81 // Display a pretty progress message.
82 String[] args = new String[2];
83 args[0] = document_directories[i].getName();
84 args[1] = String.valueOf(count);
85 shell.fireMessage(GShell.IMPORT, shell.typeAsString(GShell.IMPORT) + "> " + Dictionary.get("GShell.Extracted", args), GShell.OK);
86 args = null;
87 progress.increment();
88 }
89 }
90 }
91 }
92 // All done. Outta here like a bald man.
93 }
94
95 private int extractMetadata(File file) {
96 int count = 0;
97 // Retrieve the DOM of the file.
98 Document document = Utility.parse(file, false);
99
100 Gatherer.println("Parsed greenstone archive document: " + file.getAbsolutePath());
101 // If we successfully parsed the document, then it is time to search through the DOM for the Metadata tags.
102 if(document != null) {
103 String file_path = null;
104 Element archive_element = document.getDocumentElement();
105 // Retrieve all of the Metadata sections.
106 NodeList metadata_elements = archive_element.getElementsByTagName("Metadata");
107 // We first zip through the retrieved metadata, and if we encounter the element 'SourceSegment' - a sure sign this collection came from a bibliographic type file - we break out of extracted metadata parsing as no sense could be made of the data extracted anyway (plus we suffer a death of thirty-thousand pointy bits of metadata!)
108 for(int i = 0; i < metadata_elements.getLength(); i++) {
109 Element metadata_element = (Element) metadata_elements.item(i);
110 String name = metadata_element.getAttribute("name");
111 if(name.equalsIgnoreCase(StaticStrings.SOURCESEGMENT_VALUE)) {
112 return 0;
113 }
114 }
115 // Now for each Metadata entry retrieved...
116 for(int i = 0; i < metadata_elements.getLength(); i++) {
117 Element metadata_element = (Element) metadata_elements.item(i);
118 String name = metadata_element.getAttribute("name");
119 // There is also a special case when the metadata name is gsdlsourcefilename, as we use this to find the FileRecord we want to add metadata to.
120 if(name.equals("gsdlsourcefilename")) {
121 file_path = MSMUtils.getValue(metadata_element);
122 }
123 else {
124 // Check if its name starts with, or is equal to, one of the values in our ignore list, and if so ignore this metadata.
125 boolean ignore = false;
126 for(int j = 0; !ignore && j < ignore_list.length; j++) {
127 ignore = name.startsWith(ignore_list[j]);
128 }
129 // Otherwise ensure the metadata is present in our collection.
130 if(!ignore && file_path != null) {
131 // If we successfully retrieved a record we can continue.
132 if(file_path != null) {
133 // We now retrieve the appropriate element. If no such element exists we create a new one in the greenstone mds. Remember that no element in the greenstone mds has an associated value tree, so it is perfect for metadata elements with a small number of repeated values but where the values have no relation between files (such as encoding, where many files will be iso_8859_1, but if you change one you don't intend to change them all).
134 ElementWrapper element = Gatherer.c_man.msm.getElement(name);
135 if(element == null) {
136 MetadataSet extracted_mds = Gatherer.c_man.msm.getSet(Utility.EXTRACTED_METADATA_NAMESPACE);
137 if(extracted_mds != null) {
138 element = extracted_mds.addElement(name, Gatherer.config.interface_language);
139 }
140 }
141 // If we successfully retrieved an element (and we should have) we can continue.
142 // WARNING!! There is one known exception - MARC records. Adding the extracted elements is all good, but adding the extracted metadata causes the whole thing to collapse in a pile of unhappy.
143 if(element != null && !file_path.endsWith(StaticStrings.MARC_EXTENSION) && (element.getNamespace().equals("") || element.getNamespace().equals(Utility.EXTRACTED_METADATA_NAMESPACE))) {
144 // Retrieve the metadata for the current file
145 File target_file = new File(file_path);
146 ArrayList metadatum = Gatherer.c_man.getCollection().gdm.getMetadata(target_file);
147 // Remove any existing metadata for this element
148 boolean found = false;
149 for(int k = 0; !found && k < metadatum.size(); k++) {
150 Metadata sibling = (Metadata) metadatum.get(k);
151 ///ystem.err.println("Comparing " + element + " to " + sibling.getElement());
152 if(element.equals(sibling.getElement())) {
153 ///ystem.err.println("Removing metadata for: " + sibling);
154 Gatherer.c_man.getCollection().gdm.metadataChanged(new MSMEvent(this, System.currentTimeMillis(), target_file, sibling, null));
155 }
156 }
157 metadatum = null;
158 if(!found) {
159 String value = "";
160 try {
161 value = Utility.decodeGreenstone(URLDecoder.decode(MSMUtils.getValue(metadata_element), "UTF-8"));
162 }
163 catch(UnsupportedEncodingException error) {
164 Gatherer.printStackTrace(error);
165 }
166 // If we successfully retrieved a value we can continue.
167 if(value != null) {
168 // Create a new metadata object.
169 GValueModel value_tree = Gatherer.c_man.msm.getValueTree(element);
170 GValueNode value_node = null;
171 if(value_tree != null) {
172 value_node = value_tree.getValue(value);
173 }
174 else {
175 value_node = new GValueNode(element.toString(), value);
176 }
177 Metadata metadata = new Metadata(element, value_node);
178 Gatherer.c_man.getCollection().gdm.metadataChanged(new MSMEvent(this, System.currentTimeMillis(), target_file, null, metadata));
179 count++;
180 // All done. On to next metadata.
181 }
182 }
183 target_file = null;
184 }
185 else {
186 Gatherer.println("Cannot retrieve metadata element " + name);
187 }
188 }
189 }
190 }
191 }
192 }
193 return count;
194 }
195
196 static final String metadata_ignore_list[] = {"assocfilepath", "gsdl", "Identifier","URL"};
197
198 static public ArrayList extractMetadataElements(File archive_directory) {
199 ArrayList extracted_metadata_elements = new ArrayList();
200 File document_directories[] = archive_directory.listFiles();
201 for(int i = 0; i < document_directories.length; i++) {
202 // Find the doc.xml file within
203 if(document_directories[i].isDirectory()) {
204 File document_file = new File(document_directories[i], "doc.xml");
205 // Then extract the metadata from it.
206 if(document_file.exists()) {
207 try {
208 Document document = Utility.parse(document_file, false);
209 // Retrieve all of the Metadata sections.
210 Element archive_element = document.getDocumentElement();
211 NodeList metadata_elements = archive_element.getElementsByTagName("Metadata");
212 // Now for each Metadata entry retrieved...
213 for(int j = 0; j < metadata_elements.getLength(); j++) {
214 Element metadata_element = (Element) metadata_elements.item(j);
215 String name = metadata_element.getAttribute("name");
216 // Check if its name starts with, or is equal to, one of the values in our ignore list, and if so ignore this metadata.
217 boolean ignore = false;
218 for(int k = 0; !ignore && k < metadata_ignore_list.length; k++) {
219 ignore = name.startsWith(metadata_ignore_list[k]);
220 }
221 if(!ignore && !extracted_metadata_elements.contains(name)) {
222 extracted_metadata_elements.add(name);
223 }
224 name = null;
225 metadata_element = null;
226 }
227 metadata_elements = null;
228 archive_element = null;
229 document = null;
230 }
231 catch (Exception error) {
232 Gatherer.printStackTrace(error);
233 }
234 }
235 document_file = null;
236 }
237 }
238 document_directories = null;
239 return extracted_metadata_elements;
240 }
241}
Note: See TracBrowser for help on using the repository browser.