source: trunk/gli/src/org/greenstone/gatherer/metadata/MetadataXMLFileManager.java@ 13586

Last change on this file since 13586 was 13586, checked in by mdewsnip, 17 years ago

Added a static getLoadedCollectionName() function into CollectionManager, as part of making CollectionManager fully static.

  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1/**
2 *############################################################################
3 * A component of the Greenstone Librarian Interface, part of the Greenstone
4 * digital library suite from the New Zealand Digital Library Project at the
5 * University of Waikato, New Zealand.
6 *
7 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
8 *
9 * Copyright (C) 2005 New Zealand Digital Library Project
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *############################################################################
25 */
26
27package org.greenstone.gatherer.metadata;
28
29
30import java.io.*;
31import java.util.*;
32import org.greenstone.gatherer.DebugStream;
33import org.greenstone.gatherer.Gatherer;
34import org.greenstone.gatherer.collection.CollectionManager;
35import org.greenstone.gatherer.collection.CollectionTreeNode;
36import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
37import org.greenstone.gatherer.util.XMLTools;
38
39
40/** This class is a static class that manages the metadata.xml files */
41public class MetadataXMLFileManager
42{
43 static private ArrayList metadata_xml_files = new ArrayList();
44 /** The objects listening for MetadataChanged events. */
45 static private ArrayList metadata_changed_listeners = new ArrayList();
46 /** Keep track of which metadata.xml files have been modified so we can upload them to the server */
47 static private ArrayList modified_metadata_xml_files = new ArrayList();
48
49
50 static public void addMetadata(CollectionTreeNode file_node, ArrayList metadata_values)
51 {
52 addMetadata(new CollectionTreeNode[] { file_node }, metadata_values);
53 }
54
55
56 static public void addMetadata(CollectionTreeNode[] file_nodes, MetadataValue metadata_value)
57 {
58 ArrayList metadata_values = new ArrayList();
59 metadata_values.add(metadata_value);
60 addMetadata(file_nodes, metadata_values);
61 }
62
63
64 static public void addMetadata(CollectionTreeNode[] file_nodes, ArrayList metadata_values)
65 {
66 // Check the list of metadata values is non-empty
67 if (metadata_values.isEmpty()) {
68 return;
69 }
70
71 // Add the metadata to each file node in turn
72 for (int i = 0; i < file_nodes.length; i++) {
73 File current_file = file_nodes[i].getFile();
74 DebugStream.println("Adding metadata to " + current_file.getAbsolutePath());
75
76 // Find which metadata.xml file needs editing
77 boolean applicable_metadata_xml_file_found = false;
78 File current_file_directory = (current_file.isDirectory() ? current_file : current_file.getParentFile());
79 String current_file_directory_path = current_file_directory.getAbsolutePath();
80 for (int j = 0; j < metadata_xml_files.size(); j++) {
81 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(j);
82
83 // This metadata.xml file is only applicable if it is at the same level as the file
84 if (current_file_directory_path.equals(metadata_xml_file.getParentFile().getAbsolutePath())) {
85 applicable_metadata_xml_file_found = true;
86 metadata_xml_file.addMetadata(current_file, metadata_values);
87 if (!modified_metadata_xml_files.contains(metadata_xml_file)) {
88 modified_metadata_xml_files.add(metadata_xml_file);
89 }
90 }
91 }
92
93 // If no applicable metadata.xml file exists, we have to create a new one
94 if (!applicable_metadata_xml_file_found) {
95 // Create a new (empty) metadata.xml file in the file's directory...
96 File new_metadata_xml_file_file = new File(current_file_directory, "metadata.xml");
97 XMLTools.writeXMLFile(new_metadata_xml_file_file, XMLTools.parseXMLFile("xml/metadata.xml", true));
98
99 // ...load it...
100 MetadataXMLFile new_metadata_xml_file = loadMetadataXMLFile(new_metadata_xml_file_file);
101
102 // ...and add the metadata
103 new_metadata_xml_file.addMetadata(current_file, metadata_values);
104 if (!modified_metadata_xml_files.contains(new_metadata_xml_file)) {
105 modified_metadata_xml_files.add(new_metadata_xml_file);
106 }
107 }
108 }
109
110 // Let any listeners know that the metadata has changed
111 fireMetadataChangedEvent(file_nodes);
112 }
113
114
115 static public void addMetadataChangedListener(MetadataChangedListener metadata_changed_listener)
116 {
117 metadata_changed_listeners.add(metadata_changed_listener);
118 }
119
120
121 static public void clearMetadataXMLFiles()
122 {
123 metadata_xml_files.clear();
124 }
125
126
127 static private void fireMetadataChangedEvent(CollectionTreeNode[] file_nodes)
128 {
129 // Send the event off to all the MetadataChangedListeners
130 for (int i = 0; i < metadata_changed_listeners.size(); i++) {
131 ((MetadataChangedListener) metadata_changed_listeners.get(i)).metadataChanged(file_nodes);
132 }
133 }
134
135
136 /** Returns the metadata assigned to a file outside the collection, excluding folder-level/inherited metadata. */
137 static public ArrayList getMetadataAssignedDirectlyToExternalFile(File file)
138 {
139 DebugStream.println("Getting metadata assigned directly to external file " + file + "...");
140
141 // Build up a list of applicable metadata.xml files
142 ArrayList applicable_metadata_xml_files = new ArrayList();
143
144 File directory = (file.isDirectory() ? file : file.getParentFile());
145 while (directory != null) {
146 File metadata_xml_file = new File(directory, "metadata.xml");
147 if (metadata_xml_file.exists() && !metadata_xml_file.isDirectory()) {
148 // It is very important that shallower files come before deeper ones
149 applicable_metadata_xml_files.add(0, new MetadataXMLFile(metadata_xml_file.getAbsolutePath()));
150 }
151
152 directory = directory.getParentFile();
153 }
154
155 // Get the metadata assigned to the specified file from the applicable metadata.xml files
156 ArrayList assigned_metadata = getMetadataAssignedToFile(file, applicable_metadata_xml_files);
157
158 // Remove any folder-level metadata
159 for (int i = assigned_metadata.size() - 1; i >= 0; i--) {
160 if (((MetadataValue) assigned_metadata.get(i)).isInheritedMetadata()) {
161 assigned_metadata.remove(i);
162 }
163 }
164
165 return assigned_metadata;
166 }
167
168
169 /** Returns the metadata assigned to a file inside the collection, excluding folder-level/inherited metadata. */
170 static public ArrayList getMetadataAssignedDirectlyToFile(File file)
171 {
172 // Get all the metadata assigned to the specified file...
173 ArrayList assigned_metadata = getMetadataAssignedToFile(file);
174
175 // ...then remove any folder-level metadata
176 for (int i = assigned_metadata.size() - 1; i >= 0; i--) {
177 if (((MetadataValue) assigned_metadata.get(i)).isInheritedMetadata()) {
178 assigned_metadata.remove(i);
179 }
180 }
181
182 return assigned_metadata;
183 }
184
185
186 /** Returns all the metadata assigned to a file inside the collection. */
187 static public ArrayList getMetadataAssignedToFile(File file)
188 {
189 // Build up a list of applicable metadata.xml files
190 ArrayList applicable_metadata_xml_files = new ArrayList();
191
192 // Look at each loaded metadata.xml file to see if it is potentially applicable
193 String file_directory_path = (file.isDirectory() ? file : file.getParentFile()).getAbsolutePath() + File.separator;
194 for (int i = 0; i < metadata_xml_files.size(); i++) {
195 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(i);
196
197 // This metadata.xml file is only potentially applicable if it is above or at the same level as the file
198 if (file_directory_path.startsWith(metadata_xml_file.getParentFile().getAbsolutePath() + File.separator)) {
199 applicable_metadata_xml_files.add(metadata_xml_file);
200 }
201 }
202
203 // Return the metadata assigned to the specified file from the applicable metadata.xml files
204 return getMetadataAssignedToFile(file, applicable_metadata_xml_files);
205 }
206
207
208 static private ArrayList getMetadataAssignedToFile(File file, ArrayList applicable_metadata_xml_files)
209 {
210 // Build up a list of metadata values assigned to this file
211 ArrayList metadata_values_all = new ArrayList();
212
213 // Look at each applicable metadata.xml file to see if it assigns metadata to this file
214 for (int i = 0; i < applicable_metadata_xml_files.size(); i++) {
215 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) applicable_metadata_xml_files.get(i);
216 DebugStream.println("Applicable metadata.xml file: " + metadata_xml_file);
217
218 ArrayList metadata_values = metadata_xml_file.getMetadataAssignedToFile(file);
219 for (int j = 0; j < metadata_values.size(); j++) {
220 MetadataValue metadata_value = (MetadataValue) metadata_values.get(j);
221
222 // Overriding metadata: remove any values with this metadata element
223 if (metadata_value.isAccumulatingMetadata() == false) {
224 for (int k = metadata_values_all.size() - 1; k >= 0; k--) {
225 if (((MetadataValue) metadata_values_all.get(k)).getMetadataElement().equals(metadata_value.getMetadataElement())) {
226 metadata_values_all.remove(k);
227 }
228 }
229 }
230
231 metadata_values_all.add(metadata_value);
232 }
233 }
234
235 return metadata_values_all;
236 }
237
238
239 static public void loadMetadataXMLFiles(File directory)
240 {
241 // Make sure the directory (import) exists
242 if (directory.exists() == false) {
243 return;
244 }
245
246 // Look recursively at each subfile of the directory for metadata.xml files
247 File[] directory_files = directory.listFiles();
248 for (int i = 0; i < directory_files.length; i++) {
249 File child_file = directory_files[i];
250 if (child_file.isDirectory()) {
251 loadMetadataXMLFiles(child_file);
252 }
253 else if (child_file.getName().equals("metadata.xml")) {
254 loadMetadataXMLFile(child_file);
255 }
256 }
257 }
258
259
260 static private MetadataXMLFile loadMetadataXMLFile(File metadata_xml_file_file)
261 {
262 MetadataXMLFile metadata_xml_file = new MetadataXMLFile(metadata_xml_file_file.getAbsolutePath());
263 if (metadata_xml_files.contains(metadata_xml_file)) {
264 // This metadata.xml file has already been loaded, so return the loaded object
265 return (MetadataXMLFile) metadata_xml_files.get(metadata_xml_files.indexOf(metadata_xml_file));
266 }
267
268 metadata_xml_file.skimFile();
269 metadata_xml_files.add(metadata_xml_file);
270 return metadata_xml_file;
271 }
272
273
274 static public void removeMetadata(CollectionTreeNode file_node, ArrayList metadata_values)
275 {
276 removeMetadata(new CollectionTreeNode[] { file_node }, metadata_values);
277 }
278
279
280 static public void removeMetadata(CollectionTreeNode[] file_nodes, MetadataValue metadata_value)
281 {
282 ArrayList metadata_values = new ArrayList();
283 metadata_values.add(metadata_value);
284 removeMetadata(file_nodes, metadata_values);
285 }
286
287
288 static public void removeMetadata(CollectionTreeNode[] file_nodes, ArrayList metadata_values)
289 {
290 // Check the list of metadata values is non-empty
291 if (metadata_values.isEmpty()) {
292 return;
293 }
294
295 // Remove the metadata from each file node in turn
296 for (int i = 0; i < file_nodes.length; i++) {
297 File current_file = file_nodes[i].getFile();
298 DebugStream.println("Removing metadata from " + current_file.getAbsolutePath());
299
300 // Find which metadata.xml file needs editing
301 File current_file_directory = (current_file.isDirectory() ? current_file : current_file.getParentFile());
302 String current_file_directory_path = current_file_directory.getAbsolutePath();
303 for (int j = 0; j < metadata_xml_files.size(); j++) {
304 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(j);
305
306 // This metadata.xml file is only potentially applicable if it is above or at the same level as the file
307 if (current_file_directory_path.startsWith(metadata_xml_file.getParentFile().getAbsolutePath())) {
308 metadata_xml_file.removeMetadata(current_file, metadata_values);
309 if (!modified_metadata_xml_files.contains(metadata_xml_file)) {
310 modified_metadata_xml_files.add(metadata_xml_file);
311 }
312 }
313 }
314 }
315
316 // Let any listeners know that the metadata has changed
317 fireMetadataChangedEvent(file_nodes);
318 }
319
320
321 static public void removeMetadataChangedListener(MetadataChangedListener metadata_changed_listener)
322 {
323 metadata_changed_listeners.remove(metadata_changed_listener);
324 }
325
326
327 static public void replaceMetadata(CollectionTreeNode[] file_nodes, MetadataValue old_metadata_value, MetadataValue new_metadata_value)
328 {
329 // Replace the metadata in each file node in turn
330 for (int i = 0; i < file_nodes.length; i++) {
331 File current_file = file_nodes[i].getFile();
332 DebugStream.println("Replacing metadata in " + current_file.getAbsolutePath());
333
334 // Find which metadata.xml file needs editing
335 File current_file_directory = (current_file.isDirectory() ? current_file : current_file.getParentFile());
336 String current_file_directory_path = current_file_directory.getAbsolutePath();
337 for (int j = 0; j < metadata_xml_files.size(); j++) {
338 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(j);
339
340 // This metadata.xml file is only applicable if it is at the same level as the file
341 if (current_file_directory_path.equals(metadata_xml_file.getParentFile().getAbsolutePath())) {
342 metadata_xml_file.replaceMetadata(current_file, old_metadata_value, new_metadata_value);
343 if (!modified_metadata_xml_files.contains(metadata_xml_file)) {
344 modified_metadata_xml_files.add(metadata_xml_file);
345 }
346 }
347 }
348 }
349
350 // Let any listeners know that the metadata has changed
351 fireMetadataChangedEvent(file_nodes);
352 }
353
354
355 static public void unloadMetadataXMLFile(File metadata_xml_file_file)
356 {
357 DebugStream.println("Unloading metadata.xml file " + metadata_xml_file_file);
358
359 // Find the metadata.xml file in the list of loaded files, and remove it
360 for (int i = 0; i < metadata_xml_files.size(); i++) {
361 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(i);
362 if (metadata_xml_file_file.getAbsolutePath().equals(metadata_xml_file.getAbsolutePath())) {
363 metadata_xml_files.remove(i);
364 break;
365 }
366 }
367 }
368
369
370 static public void uploadModifiedMetadataXMLFiles()
371 {
372 // This is only necessary when the collection is stored on a remote server
373 if (Gatherer.isGsdlRemote) {
374 if (modified_metadata_xml_files.isEmpty()) {
375 DebugStream.println("No modified metadata.xml files to upload.");
376 return;
377 }
378
379 // Upload the files modified since last time, then reset the list
380 RemoteGreenstoneServer.uploadCollectionFiles(CollectionManager.getLoadedCollectionName(), (File[]) modified_metadata_xml_files.toArray(new File[0]));
381 modified_metadata_xml_files.clear();
382 }
383 }
384}
Note: See TracBrowser for help on using the repository browser.