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

Last change on this file since 13818 was 13818, checked in by shaoqun, 17 years ago

added code to allow disabling skimfile in collection's .col file

  • Property svn:keywords set to Author Date Id Revision
File size: 14.8 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,true);
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, boolean skimfile)
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,skimfile);
252 }
253 else if (child_file.getName().equals("metadata.xml")) {
254 loadMetadataXMLFile(child_file,skimfile);
255 }
256 }
257 }
258
259
260 static private MetadataXMLFile loadMetadataXMLFile(File metadata_xml_file_file, boolean skimfile)
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 if(skimfile){
268 metadata_xml_file.skimFile();
269 }
270 metadata_xml_files.add(metadata_xml_file);
271 return metadata_xml_file;
272 }
273
274
275 static public void removeMetadata(CollectionTreeNode file_node, ArrayList metadata_values)
276 {
277 removeMetadata(new CollectionTreeNode[] { file_node }, metadata_values);
278 }
279
280
281 static public void removeMetadata(CollectionTreeNode[] file_nodes, MetadataValue metadata_value)
282 {
283 ArrayList metadata_values = new ArrayList();
284 metadata_values.add(metadata_value);
285 removeMetadata(file_nodes, metadata_values);
286 }
287
288
289 static public void removeMetadata(CollectionTreeNode[] file_nodes, ArrayList metadata_values)
290 {
291 // Check the list of metadata values is non-empty
292 if (metadata_values.isEmpty()) {
293 return;
294 }
295
296 // Remove the metadata from each file node in turn
297 for (int i = 0; i < file_nodes.length; i++) {
298 File current_file = file_nodes[i].getFile();
299 DebugStream.println("Removing metadata from " + current_file.getAbsolutePath());
300
301 // Find which metadata.xml file needs editing
302 File current_file_directory = (current_file.isDirectory() ? current_file : current_file.getParentFile());
303 String current_file_directory_path = current_file_directory.getAbsolutePath();
304 for (int j = 0; j < metadata_xml_files.size(); j++) {
305 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(j);
306
307 // This metadata.xml file is only potentially applicable if it is above or at the same level as the file
308 if (current_file_directory_path.startsWith(metadata_xml_file.getParentFile().getAbsolutePath())) {
309 metadata_xml_file.removeMetadata(current_file, metadata_values);
310 if (!modified_metadata_xml_files.contains(metadata_xml_file)) {
311 modified_metadata_xml_files.add(metadata_xml_file);
312 }
313 }
314 }
315 }
316
317 // Let any listeners know that the metadata has changed
318 fireMetadataChangedEvent(file_nodes);
319 }
320
321
322 static public void removeMetadataChangedListener(MetadataChangedListener metadata_changed_listener)
323 {
324 metadata_changed_listeners.remove(metadata_changed_listener);
325 }
326
327
328 static public void replaceMetadata(CollectionTreeNode[] file_nodes, MetadataValue old_metadata_value, MetadataValue new_metadata_value)
329 {
330 // Replace the metadata in each file node in turn
331 for (int i = 0; i < file_nodes.length; i++) {
332 File current_file = file_nodes[i].getFile();
333 DebugStream.println("Replacing metadata in " + current_file.getAbsolutePath());
334
335 // Find which metadata.xml file needs editing
336 File current_file_directory = (current_file.isDirectory() ? current_file : current_file.getParentFile());
337 String current_file_directory_path = current_file_directory.getAbsolutePath();
338 for (int j = 0; j < metadata_xml_files.size(); j++) {
339 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(j);
340
341 // This metadata.xml file is only applicable if it is at the same level as the file
342 if (current_file_directory_path.equals(metadata_xml_file.getParentFile().getAbsolutePath())) {
343 metadata_xml_file.replaceMetadata(current_file, old_metadata_value, new_metadata_value);
344 if (!modified_metadata_xml_files.contains(metadata_xml_file)) {
345 modified_metadata_xml_files.add(metadata_xml_file);
346 }
347 }
348 }
349 }
350
351 // Let any listeners know that the metadata has changed
352 fireMetadataChangedEvent(file_nodes);
353 }
354
355
356 /** Ensures that all the metadata is written to metadata.xml files. */
357 static public void saveMetadataXMLFiles()
358 {
359 // Save the file currently loaded into memory out to disk
360 MetadataXMLFile.saveLoadedFile();
361
362 // If the collection is stored on a remote server, upload all the modified files now
363 if (Gatherer.isGsdlRemote) {
364 if (modified_metadata_xml_files.isEmpty()) {
365 DebugStream.println("No modified metadata.xml files to upload.");
366 return;
367 }
368
369 // Upload the files modified since last time, then reset the list
370 RemoteGreenstoneServer.uploadCollectionFiles(CollectionManager.getLoadedCollectionName(), (File[]) modified_metadata_xml_files.toArray(new File[0]));
371 modified_metadata_xml_files.clear();
372 }
373 }
374
375
376 static public void unloadMetadataXMLFile(File metadata_xml_file_file)
377 {
378 DebugStream.println("Unloading metadata.xml file " + metadata_xml_file_file);
379
380 // Find the metadata.xml file in the list of loaded files, and remove it
381 for (int i = 0; i < metadata_xml_files.size(); i++) {
382 MetadataXMLFile metadata_xml_file = (MetadataXMLFile) metadata_xml_files.get(i);
383 if (metadata_xml_file_file.getAbsolutePath().equals(metadata_xml_file.getAbsolutePath())) {
384 metadata_xml_files.remove(i);
385 break;
386 }
387 }
388 }
389}
Note: See TracBrowser for help on using the repository browser.