source: trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfiguration.java@ 12467

Last change on this file since 12467 was 12416, checked in by shaoqun, 18 years ago

fixed bugs that causes DefaultIndex not to be parsed properly for mgpp

  • Property svn:keywords set to Author Date Id Revision
File size: 69.9 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 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.io.*;
32import java.util.*;
33import javax.swing.*;
34import org.greenstone.gatherer.Configuration;
35import org.greenstone.gatherer.DebugStream;
36import org.greenstone.gatherer.Gatherer;
37import org.greenstone.gatherer.gui.GLIButton;
38import org.greenstone.gatherer.metadata.MetadataElement;
39import org.greenstone.gatherer.metadata.MetadataSetManager;
40import org.greenstone.gatherer.metadata.MetadataTools;
41import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
42import org.greenstone.gatherer.util.DOMTree;
43import org.greenstone.gatherer.util.Codec;
44import org.greenstone.gatherer.util.StaticStrings;
45import org.greenstone.gatherer.util.XMLTools;
46import org.greenstone.gatherer.util.ZipTools;
47import org.w3c.dom.*;
48
49/** This class provides access to an xml-type view of the collect.cfg file. This is useful as it allows the manipulation and free form editing of a collect.cfg file while still allowing the various CDM data managers to base themselves directly on this model (whereas they used to be independant ListModels which clobbered the ordering of unparsed commands).
50 * @author John Thompson, Greenstone Digital Library, University of Waikato
51 * @version 2.3d
52 */
53public class CollectionConfiguration
54 extends StaticStrings {
55
56 static final public String ENCODING = "UTF-8";
57
58 static public Document document;
59
60 /** Find the best insertion position for the given DOM Element. This should try to match command tag, and if found should then try to group by name or type (eg CollectionMeta), or append to end is no such grouping exists (eg Plugins). Failing a command match it will check against the command order for the best insertion location.
61 * @param target_element the command Element to be inserted
62 * @return the Element which the given command should be inserted before, or null to append to end of list
63 */
64 static public Node findInsertionPoint(Element target_element) {
65 ///ystem.err.println("Find insertion point: " + target_element.getNodeName());
66 String target_element_name = target_element.getNodeName();
67 Element document_element = document.getDocumentElement();
68 // Try to find commands with the same tag.
69 NodeList matching_elements = document_element.getElementsByTagName(target_element_name);
70 // If we found matching elements, then we have our most likely insertion location, so check within for groupings
71 if(matching_elements.getLength() != 0) {
72 ///ystem.err.println("Found matching elements.");
73 // Only CollectionMeta are grouped.
74 if(target_element_name.equals(COLLECTIONMETADATA_ELEMENT)) {
75 ///ystem.err.println("Dealing with collection metadata");
76 // Special case: CollectionMeta can be added at either the start or end of a collection configuration file. However the start position is reserved for special metadata, so if no non-special metadata can be found we must append to the end.
77 // So if the command to be added is special add it immediately after any other special command
78 if(target_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
79 int index = 0;
80 Element matched_element = (Element) matching_elements.item(index);
81 Element sibling_element = (Element) matched_element.getNextSibling();
82 while(sibling_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
83 index++;
84 matched_element = (Element) matching_elements.item(index);
85 sibling_element = (Element) matched_element.getNextSibling();
86 }
87 if(sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
88 Element newline_element = document.createElement(NEWLINE_ELEMENT);
89 document_element.insertBefore(newline_element, sibling_element);
90 }
91 return sibling_element;
92 }
93 // Otherwise try to find a matching 'name' and add after the last one in that group.
94 else {
95 int index = 0;
96 target_element_name = target_element.getAttribute(NAME_ATTRIBUTE);
97 boolean found = false;
98 // Skip all of the special metadata
99 Element matched_element = (Element) matching_elements.item(index);
100 while(matched_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
101 index++;
102 matched_element = (Element) matching_elements.item(index);
103 }
104 // Begin search
105 while(!found && matched_element != null) {
106 if(matched_element.getAttribute(NAME_ATTRIBUTE).equals(target_element_name)) {
107 found = true;
108 }
109 else {
110 index++;
111 matched_element = (Element) matching_elements.item(index);
112 }
113 }
114 // If we found a match, we need to continue checking until we find the last name match.
115 if(found) {
116 index++;
117 Element previous_sibling = matched_element;
118 Element sibling_element = (Element) matching_elements.item(index);
119 while(sibling_element != null && sibling_element.getAttribute(NAME_ATTRIBUTE).equals(target_element_name)) {
120 previous_sibling = sibling_element;
121 index++;
122 sibling_element = (Element) matching_elements.item(index);
123 }
124 // Previous sibling now holds the command immediately before where we want to add, so find its next sibling and add to that. In this one case we can ignore new lines!
125 return previous_sibling.getNextSibling();
126 }
127 // If not found we just add after last metadata element
128 else {
129 Element last_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
130 return last_element.getNextSibling();
131 }
132 }
133
134 }
135 else {
136 ///ystem.err.println("Not dealing with collection meta.");
137 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
138 // One final quick test. If the matched element is immediately followed by a NewLine command, then we insert another NewLine after the matched command, then return the NewLine instead (thus the about to be inserted command will be placed between the two NewLines)
139 Node sibling_element = matched_element.getNextSibling();
140 if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
141 Element newline_element = document.createElement(NEWLINE_ELEMENT);
142 document_element.insertBefore(newline_element, sibling_element);
143 }
144 return sibling_element; // Note that this may be null
145 }
146 }
147 ///ystem.err.println("No matching elements found.");
148 // Locate where this command is in the ordering
149 int command_index = -1;
150 for(int i = 0; command_index == -1 && i < COMMAND_ORDER.length; i++) {
151 if(COMMAND_ORDER[i].equals(target_element_name)) {
152 command_index = i;
153 }
154 }
155 ///ystem.err.println("Command index is: " + command_index);
156 // Now move forward, checking for existing elements in each of the preceeding command orders.
157 int preceeding_index = command_index - 1;
158 ///ystem.err.println("Searching before the target command.");
159 while(preceeding_index >= 0) {
160 matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[preceeding_index]);
161 // If we've found a match
162 if(matching_elements.getLength() > 0) {
163 // We add after the last element
164 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
165 // One final quick test. If the matched element is immediately followed by a NewLine command, then we insert another NewLine after the matched command, then return the NewLine instead (thus the about to be inserted command will be placed between the two NewLines)
166 Node sibling_element = matched_element.getNextSibling();
167 if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
168 Element newline_element = document.createElement(NEWLINE_ELEMENT);
169 document_element.insertBefore(newline_element, sibling_element);
170 }
171 return sibling_element; // Note that this may be null
172 }
173 preceeding_index--;
174 }
175 // If all that fails, we now move backwards through the commands
176 int susceeding_index = command_index + 1;
177 ///ystem.err.println("Searching after the target command.");
178 while(susceeding_index < COMMAND_ORDER.length) {
179 matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[susceeding_index]);
180 // If we've found a match
181 if(matching_elements.getLength() > 0) {
182 // We add before the first element
183 Element matched_element = (Element) matching_elements.item(0);
184 // One final quick test. If the matched element is immediately preceeded by a NewLine command, then we insert another NewLine before the matched command, then return this new NewLine instead (thus the about to be inserted command will be placed between the two NewLines)
185 Node sibling_element = matched_element.getPreviousSibling();
186 if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
187 Element newline_element = document.createElement(NEWLINE_ELEMENT);
188 document_element.insertBefore(newline_element, sibling_element);
189 }
190 return sibling_element; // Note that this may be null
191 }
192 susceeding_index++;
193 }
194 // Well. Apparently there are no other commands in this collection configuration. So append away...
195 return null;
196 }
197
198 static public String toString(Element command_element, boolean show_extracted_namespace) {
199 String command_element_name = command_element.getNodeName();
200 if(command_element_name.equals(CLASSIFY_ELEMENT)) {
201 return classifyToString(command_element, show_extracted_namespace);
202 }
203 else if(command_element_name.equals(FORMAT_ELEMENT)) {
204 return formatToString(command_element, show_extracted_namespace);
205 }
206 else if(command_element_name.equals(INDEXES_ELEMENT)) {
207 return indexesToString(command_element, show_extracted_namespace);
208 }
209 else if(command_element_name.equals(INDEX_DEFAULT_ELEMENT)) {
210 return indexDefaultToString(command_element, show_extracted_namespace);
211 }
212 else if(command_element_name.equals(LANGUAGES_ELEMENT)) {
213 return languagesToString(command_element);
214 }
215 else if(command_element_name.equals(LANGUAGE_DEFAULT_ELEMENT)) {
216 return languageDefaultToString(command_element);
217 }
218 else if (command_element_name.equals(LANGUAGE_METADATA_ELEMENT)) {
219 return languageMetadataToString(command_element, show_extracted_namespace);
220 }
221 else if(command_element_name.equals(LEVELS_ELEMENT)) {
222 return levelsToString(command_element);
223 }
224 else if(command_element_name.equals(LEVEL_DEFAULT_ELEMENT)) {
225 return levelDefaultToString(command_element);
226 }
227 else if(command_element_name.equals(COLLECTIONMETADATA_ELEMENT)) {
228 return metadataToString(command_element, show_extracted_namespace);
229 }
230 else if(command_element_name.equals(COLLECTIONMETADATA_CREATOR_ELEMENT)) {
231 return metadataToString(command_element, show_extracted_namespace);
232 }
233 else if(command_element_name.equals(COLLECTIONMETADATA_MAINTAINER_ELEMENT)) {
234 return metadataToString(command_element, show_extracted_namespace);
235 }
236 else if(command_element_name.equals(COLLECTIONMETADATA_PUBLIC_ELEMENT)) {
237 return metadataToString(command_element, show_extracted_namespace);
238 }
239 else if (command_element_name.equals(BUILDTYPE_ELEMENT)) {
240 return metadataToString(command_element, show_extracted_namespace);
241 }
242 else if(command_element_name.equals(PLUGIN_ELEMENT)) {
243 return pluginToString(command_element, show_extracted_namespace);
244 }
245// else if(command_element_name.equals(SEARCHTYPE_ELEMENT)) {
246// return searchtypeToString(command_element);
247// }
248 else if(command_element_name.equals(SUBCOLLECTION_ELEMENT)) {
249 return subcollectionToString(command_element, show_extracted_namespace);
250 }
251 else if(command_element_name.equals(SUBCOLLECTION_DEFAULT_INDEX_ELEMENT)) {
252 return subcollectionDefaultIndexToString(command_element);
253 }
254 else if(command_element_name.equals(SUBCOLLECTION_INDEXES_ELEMENT)) {
255 return subcollectionIndexesToString(command_element);
256 }
257 else if(command_element_name.equals(SUPERCOLLECTION_ELEMENT)) {
258 return supercollectionToString(command_element);
259 }
260 else if(command_element_name.equals(UNKNOWN_ELEMENT)) {
261 return unknownToString(command_element);
262 }
263 return "";
264 }
265
266 /** Parses arguments from a tokenizer and returns a HashMap of mappings. The tricky bit here is that not all entries in the HashMap are name->value pairs, as some arguments are boolean and are turned on by their presence. Arguments are denoted by a '-' prefix.
267 * @param tokenizer a CommandTokenizer based on the unconsumed portion of a command string
268 * @return a HashMap containing the arguments parsed
269 */
270 static public HashMap parseArguments(CommandTokenizer tokenizer) {
271 HashMap arguments = new HashMap();
272 String name = null;
273 String value = null;
274 while(tokenizer.hasMoreTokens() || name != null) {
275 // First we retrieve a name if we need one.
276 if(name == null) {
277 name = tokenizer.nextToken();
278 }
279 // Now we attempt to retrieve a value
280 if(tokenizer.hasMoreTokens()) {
281 value = tokenizer.nextToken();
282 // Test if the value is actually a name, and if so add the name by itself, then put value into name so that it is parsed correctly during the next loop.
283 if(value.startsWith(StaticStrings.MINUS_CHARACTER)) {
284 arguments.put(name, null);
285 name = value;
286 }
287 // Otherwise we have a typical name->value pair ready to go
288 else {
289 arguments.put(name, value);
290 name = null;
291 }
292 }
293 // Otherwise its a binary flag
294 else {
295 arguments.put(name, null);
296 name = null;
297 }
298 }
299 return arguments;
300 }
301
302 static private ArrayList known_metadata;
303
304 /** Gives the preferred ordering of commands */
305 static final private String[] COMMAND_ORDER = {StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT, StaticStrings.BUILDTYPE_ELEMENT, StaticStrings.PLUGIN_ELEMENT, StaticStrings.INDEXES_ELEMENT, StaticStrings.INDEX_DEFAULT_ELEMENT, StaticStrings.LEVELS_ELEMENT, StaticStrings.LEVEL_DEFAULT_ELEMENT, StaticStrings.LANGUAGES_ELEMENT, StaticStrings.LANGUAGE_DEFAULT_ELEMENT, StaticStrings.LANGUAGE_METADATA_ELEMENT, StaticStrings.SUBCOLLECTION_ELEMENT, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT, StaticStrings.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT, StaticStrings.SUPERCOLLECTION_ELEMENT, StaticStrings.CLASSIFY_ELEMENT, StaticStrings.FORMAT_ELEMENT, StaticStrings.COLLECTIONMETADATA_ELEMENT};
306
307 /** ************************** Public Data Members ***************************/
308
309 /** ************************** Private Data Members ***************************/
310
311 private File collect_cfg_file;
312
313 /** ************************** Public Methods ***************************/
314
315 public CollectionConfiguration(File collect_cfg_file)
316 {
317 this.collect_cfg_file = collect_cfg_file;
318 // parse the XML template
319 document = XMLTools.parseXMLFile("xml/CollectionConfig.xml", true);
320 parse(collect_cfg_file);
321
322 }
323
324 /** This debug facility shows the currently loaded collect.cfg or CollectConfig.xml file as a DOM tree. */
325 public void display() {
326 JDialog dialog = new JDialog(Gatherer.g_man, "Collection Configuration", false);
327 dialog.setSize(400,400);
328 JPanel content_pane = (JPanel) dialog.getContentPane();
329 final DOMTree tree = new DOMTree(document);
330 JButton refresh_button = new GLIButton("Refresh Tree");
331 refresh_button.addActionListener(new ActionListener() {
332 public void actionPerformed(ActionEvent event) {
333 tree.setDocument(document);
334 }
335 });
336 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
337 content_pane.setLayout(new BorderLayout());
338 content_pane.add(new JScrollPane(tree), BorderLayout.CENTER);
339 content_pane.add(refresh_button, BorderLayout.SOUTH);
340 dialog.setVisible(true);
341 }
342
343
344 public Element getCreator() {
345 Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_CREATOR_ELEMENT, null, null);
346 element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_CREATOR_STR);
347 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
348 return element;
349 }
350
351 public Element getDocumentElement() {
352 return document.getDocumentElement();
353 }
354
355 public File getFile() {
356 return collect_cfg_file;
357 }
358
359 /** Retrieve or create the languages Element. */
360 public Element getLanguages() {
361 return getOrCreateElementByTagName(LANGUAGES_ELEMENT, null, null);
362 }
363
364 public Element getLanguageMetadata() {
365 return getOrCreateElementByTagName(LANGUAGE_METADATA_ELEMENT, null, null);
366 }
367
368 public Element getLevels() {
369 return getOrCreateElementByTagName(LEVELS_ELEMENT, null, null);
370 }
371
372 public Element getMaintainer() {
373 Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_MAINTAINER_ELEMENT, null, null);
374 element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_MAINTAINER_STR);
375 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
376 return element;
377 }
378
379 /** Retrieve or create the indexes Element. Note that this method behaves differently from the other getBlah methods, in that it also has to keep in mind that indexes come in two flavours, MG and MGPP. */
380 public Element getMGIndexes() {
381 return getOrCreateElementByTagName(INDEXES_ELEMENT, MGPP_ATTRIBUTE, FALSE_STR);
382 }
383
384 public Element getMGPPIndexes() {
385 return getOrCreateElementByTagName(INDEXES_ELEMENT, MGPP_ATTRIBUTE, TRUE_STR);
386 }
387
388 public Element getPublic() {
389 Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_PUBLIC_ELEMENT, null, null);
390 element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_PUBLIC_STR);
391 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
392 return element;
393 }
394
395 public Element getBuildType() {
396 Element element = getOrCreateElementByTagName(BUILDTYPE_ELEMENT, null, null);
397 element.setAttribute(NAME_ATTRIBUTE, BUILDTYPE_STR);
398 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
399 return element;
400
401 }
402
403 /** Retrieve or create the subindexes Element. */
404 public Element getSubIndexes() {
405 return getOrCreateElementByTagName(SUBCOLLECTION_INDEXES_ELEMENT, null, null);
406 }
407
408 /** Retrieve or create the supercollections Element. */
409 public Element getSuperCollection() {
410 return getOrCreateElementByTagName(SUPERCOLLECTION_ELEMENT, null, null);
411 }
412
413 public boolean ready() {
414 return document != null;
415 }
416
417 public void save() {
418 if(collect_cfg_file.exists()) {
419 File original_file = new File(collect_cfg_file.getParentFile(), COLLECT_CFG);
420 File backup_file = new File(collect_cfg_file.getParentFile(), "collect.bak");
421 if(backup_file.exists()) {
422 backup_file.delete();
423 }
424 if(!original_file.renameTo(backup_file)) {
425 DebugStream.println("Can't rename collect.cfg");
426 }
427 }
428
429 try {
430 OutputStream ostream = new FileOutputStream(collect_cfg_file);
431 Writer file_writer = new OutputStreamWriter(ostream, ENCODING);
432 //FileWriter file_writer = new FileWriter(collect_cfg_file, false);
433 BufferedWriter buffered_writer = new BufferedWriter(file_writer);
434 Element collect_config_element = document.getDocumentElement();
435 NodeList command_elements = collect_config_element.getChildNodes();
436 boolean just_wrote_newline = false; // Prevent two or more newlines in a row
437 for(int i = 0; i < command_elements.getLength(); i++) {
438 Node command_node = command_elements.item(i);
439 if(command_node instanceof Element) {
440 Element command_element = (Element) command_node;
441 // The only thing left are NewLine elements
442 if(command_element.getNodeName().equals(NEWLINE_ELEMENT) && !just_wrote_newline) {
443 buffered_writer.newLine();
444 just_wrote_newline = true;
445 }
446 // Anything else we write to file, but only if it has been assigned, the exception being the Indexes element which just get commented if unassigned (a side effect of MG && MGPP compatibility)
447 else if(!command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR) || command_element.getNodeName().equals(INDEXES_ELEMENT) || command_element.getNodeName().equals(INDEX_DEFAULT_ELEMENT) || command_element.getNodeName().equals(LEVELS_ELEMENT) || command_element.getNodeName().equals(LEVEL_DEFAULT_ELEMENT)){
448 String command;
449 // format statements we write out with ex. still present
450 if (command_element.getNodeName().equals(FORMAT_ELEMENT)) {
451 command = toString(command_element, true);
452 } else {
453 command = toString(command_element, false);
454 }
455 if(command != null && command.length()> 0 ) {
456 write(buffered_writer, command);
457 buffered_writer.newLine();
458 just_wrote_newline = false;
459 }
460 }
461 }
462 }
463 buffered_writer.close();
464
465 // If we're using a remote Greenstone server, upload the new collect.cfg file
466 if (Gatherer.isGsdlRemote) {
467 String collection_name = Gatherer.c_man.getCollection().getName();
468 RemoteGreenstoneServer.uploadCollectionFile(collection_name, collect_cfg_file);
469 }
470 }
471 catch (Exception exception) {
472 DebugStream.println("Error in CollectionConfiguration.save(boolean): " + exception);
473 DebugStream.printStackTrace(exception);
474 }
475
476 }
477
478 /** ************************** Private Methods ***************************/
479
480 static private String classifyToString(Element command_element, boolean show_extracted_namespace)
481 {
482 StringBuffer text = new StringBuffer(CLASSIFY_STR);
483 text.append(TAB_CHARACTER);
484 text.append(command_element.getAttribute(TYPE_ATTRIBUTE));
485 text.append(SPACE_CHARACTER);
486 NodeList option_elements = command_element.getElementsByTagName(OPTION_ELEMENT);
487 int option_elements_length = option_elements.getLength();
488 for(int j = 0; j < option_elements_length; j++) {
489 Element option_element = (Element) option_elements.item(j);
490 if(option_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
491 text.append(StaticStrings.MINUS_CHARACTER);
492 text.append(option_element.getAttribute(NAME_ATTRIBUTE));
493 String value_str = XMLTools.getValue(option_element);
494
495 // Convert metadata element names to internal names, and remove extracted metadata namespaces
496 if (value_str.length() > 0) {
497 StringTokenizer string_tokenizer = new StringTokenizer(value_str, ",");
498 StringBuffer value_buffer = new StringBuffer();
499 while (string_tokenizer.hasMoreElements()) {
500 String raw_token = (String) string_tokenizer.nextElement();
501 String token = raw_token.trim();
502 MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(token);
503 if (metadata_element != null) {
504 token = metadata_element.getFullName();
505 }
506
507 if (token.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
508 token = token.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
509 }
510 value_buffer.append(token);
511 if (string_tokenizer.hasMoreElements()) {
512 value_buffer.append(",");
513 }
514 }
515 value_str = value_buffer.toString();
516 }
517
518 text.append(SPACE_CHARACTER);
519 if (value_str.indexOf(SPACE_CHARACTER) == -1) {
520 text.append(value_str);
521 }
522 else {
523 text.append(SPEECH_CHARACTER);
524 text.append(value_str);
525 text.append(SPEECH_CHARACTER);
526 }
527 value_str = null;
528 if(j < option_elements_length - 1) {
529 text.append(SPACE_CHARACTER);
530 }
531 }
532 option_element = null;
533 }
534 option_elements = null;
535 return text.toString();
536 }
537
538 static private String formatToString(Element command_element, boolean show_extracted_namespace) {
539 StringBuffer text = new StringBuffer(FORMAT_STR);
540 text.append(SPACE_CHARACTER);
541 text.append(command_element.getAttribute(NAME_ATTRIBUTE));
542 text.append(SPACE_CHARACTER);
543 String value_str = command_element.getAttribute(VALUE_ATTRIBUTE);
544 if(value_str.length() != 0) {
545 text.append(value_str);
546 }
547 else {
548 // Remember to encode format string to Greenstone specification
549 value_str = Codec.transform(XMLTools.getValue(command_element), Codec.DOM_TO_GREENSTONE);
550 // Remove any references to a namespace for extracted metadata
551 if (!show_extracted_namespace) {
552 String match_string = "\\[" + MetadataSetManager.EXTRACTED_METADATA_NAMESPACE + "\\.";
553 value_str = value_str.replaceAll(match_string, "[");
554 }
555
556 text.append(SPEECH_CHARACTER);
557 text.append(value_str);
558 text.append(SPEECH_CHARACTER);
559 }
560 value_str = null;
561 return text.toString();
562 }
563
564 /** Retrieve or create the indexes Element. */
565 static private Element getOrCreateElementByTagName(String name, String conditional_attribute, String required_value) {
566 Element document_element = document.getDocumentElement();
567 NodeList elements = document_element.getElementsByTagName(name);
568 int elements_length = elements.getLength();
569 if(elements_length > 0) {
570 if(conditional_attribute == null) {
571 document_element = null;
572 return (Element) elements.item(0);
573 }
574 else {
575 for(int i = 0; i < elements_length; i++) {
576 Element element = (Element) elements.item(i);
577 if(element.getAttribute(conditional_attribute).equals(required_value)) {
578 document_element = null;
579 return element;
580 }
581 element = null;
582 }
583 }
584 }
585 // Create the element
586 Element element = document.createElement(name);
587 // If there was a property set it
588 if(conditional_attribute != null) {
589 element.setAttribute(conditional_attribute, required_value);
590 }
591 Node target_node = findInsertionPoint(element);
592 if(target_node != null) {
593 document_element.insertBefore(element, target_node);
594 }
595 else {
596 document_element.appendChild(element);
597 }
598 document_element = null;
599 return element;
600 }
601
602 static private String indexesToString(Element command_element, boolean show_extracted_namespace) {
603 boolean comment_only = false;
604 StringBuffer text = new StringBuffer("");
605 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
606 text.append("#");
607 comment_only = true;
608 }
609 text.append(INDEX_STR);
610 text.append(TAB_CHARACTER);
611 if(!comment_only) {
612 text.append(TAB_CHARACTER);
613 }
614 NodeList index_elements = command_element.getElementsByTagName(INDEX_ELEMENT);
615 if (index_elements.getLength() == 0) { // no indexes
616 return "";
617 }
618 // For each index, write its level, a colon, then concatenate its child content elements into a single comma separated list
619 int index_elements_length = index_elements.getLength();
620 for(int j = 0; j < index_elements_length; j++) {
621 Element index_element = (Element) index_elements.item(j);
622 String level_str = index_element.getAttribute(LEVEL_ATTRIBUTE);
623 if(level_str.length() > 0) {
624 text.append(level_str);
625 text.append(StaticStrings.COLON_CHARACTER);
626 }
627 NodeList content_elements = index_element.getElementsByTagName(CONTENT_ELEMENT);
628 int content_elements_length = content_elements.getLength();
629 // Don't output anything if no indexes are set
630 if(content_elements_length == 0) {
631 return null;
632 }
633 for(int k = 0; k < content_elements_length; k++) {
634 Element content_element = (Element) content_elements.item(k);
635 String name_str = content_element.getAttribute(NAME_ATTRIBUTE);
636 if(!show_extracted_namespace && name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
637 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
638 }
639 text.append(name_str);
640 name_str = null;
641 if(k < content_elements_length - 1) {
642 text.append(StaticStrings.COMMA_CHARACTER);
643 }
644 content_element = null;
645 }
646 if(j < index_elements_length - 1) {
647 text.append(SPACE_CHARACTER);
648 }
649 content_elements = null;
650 index_element = null;
651 }
652 index_elements = null;
653 return text.toString();
654 }
655
656 static private String indexDefaultToString(Element command_element, boolean show_extracted_namespace) {
657 StringBuffer text = new StringBuffer("");
658 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
659 text.append("#");
660 }
661 text.append(INDEX_DEFAULT_STR);
662 text.append(TAB_CHARACTER);
663 if (!command_element.getAttribute(LEVEL_ATTRIBUTE).equals("")) {
664 text.append(command_element.getAttribute(LEVEL_ATTRIBUTE));
665 text.append(StaticStrings.COLON_CHARACTER);
666 }
667 NodeList content_elements = command_element.getElementsByTagName(CONTENT_ELEMENT);
668 int content_elements_length = content_elements.getLength();
669 for(int j = 0; j < content_elements_length; j++) {
670 Element content_element = (Element) content_elements.item(j);
671 String name_str = content_element.getAttribute(NAME_ATTRIBUTE);
672 if(!show_extracted_namespace && name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
673 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
674 }
675 text.append(name_str);
676 name_str = null;
677 if(j < content_elements_length - 1) {
678 text.append(StaticStrings.COMMA_CHARACTER);
679 }
680 content_element = null;
681 }
682 content_elements = null;
683 return text.toString();
684 }
685
686 static private String languagesToString(Element command_element) {
687 StringBuffer text = new StringBuffer(LANGUAGES_STR);
688 text.append(TAB_CHARACTER);
689 // Retrieve all the languages and write them out in a space separated list
690 NodeList language_elements = command_element.getElementsByTagName(LANGUAGE_ELEMENT);
691 int language_elements_length = language_elements.getLength();
692 if(language_elements_length == 0) {
693 return null;
694 }
695 for(int j = 0; j < language_elements_length; j++) {
696 Element language_element = (Element) language_elements.item(j);
697 text.append(language_element.getAttribute(NAME_ATTRIBUTE));
698 if(j < language_elements_length - 1) {
699 text.append(SPACE_CHARACTER);
700 }
701 }
702 return text.toString();
703 }
704
705 static private String languageDefaultToString(Element command_element) {
706 StringBuffer text = new StringBuffer(LANGUAGE_DEFAULT_STR);
707 text.append(TAB_CHARACTER);
708 text.append(command_element.getAttribute(NAME_ATTRIBUTE));
709 return text.toString();
710 }
711
712 static private String languageMetadataToString(Element command_element, boolean show_extracted_namespace) {
713 StringBuffer text = new StringBuffer(LANGUAGE_METADATA_STR);
714 text.append(TAB_CHARACTER);
715 String name_str = command_element.getAttribute(NAME_ATTRIBUTE);
716 if(!show_extracted_namespace && name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
717 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
718 }
719 text.append(name_str);
720 return text.toString();
721 }
722
723 static private String levelsToString(Element command_element) {
724 StringBuffer text = new StringBuffer("");
725 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
726 text.append("#");
727 }
728 text.append(LEVELS_STR);
729 text.append(TAB_CHARACTER);
730 text.append(TAB_CHARACTER);
731 NodeList content_elements = command_element.getElementsByTagName(LEVEL_ELEMENT);
732 int content_elements_length = content_elements.getLength();
733 // Don't output anything if no levels are set.
734 if(content_elements_length == 0) {
735 return null;
736 }
737 for(int i = 0; i < content_elements_length; i++) {
738 Element content_element = (Element) content_elements.item(i);
739 text.append(content_element.getAttribute(NAME_ATTRIBUTE));
740 text.append(SPACE_CHARACTER);
741 }
742 return text.substring(0, text.length() - 1);
743 }
744
745 static private String levelDefaultToString(Element command_element) {
746 StringBuffer text = new StringBuffer("");
747 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
748 text.append("#");
749 }
750 text.append(LEVEL_DEFAULT_STR);
751 text.append(TAB_CHARACTER);
752 text.append(command_element.getAttribute(NAME_ATTRIBUTE));
753 return text.toString();
754 }
755
756
757
758 static private String metadataToString(Element command_element, boolean text_value) {
759 // lets first check the value - if its empty, don't bother sticking it in the config file
760 String value_str = XMLTools.getValue(command_element);
761 if (value_str.equals("")) {
762 return "";
763 }
764 boolean special = false;
765
766 StringBuffer text = new StringBuffer("");
767 String name_str = command_element.getAttribute(NAME_ATTRIBUTE);
768 // If the name is one of the special four, we don't write the collectionmeta first. Note maintainer and buildtype are singled out for 'prittying' reasons.
769 if(name_str.equals(COLLECTIONMETADATA_MAINTAINER_STR)|| name_str.equals(BUILDTYPE_STR) ) {
770 text.append(name_str);
771 text.append(TAB_CHARACTER);
772 special = true;
773 }
774 else if (name_str.equals(COLLECTIONMETADATA_CREATOR_STR) || name_str.equals(COLLECTIONMETADATA_PUBLIC_STR) ) {
775 text.append(name_str);
776 text.append(TAB_CHARACTER);
777 text.append(TAB_CHARACTER);
778 special = true;
779 }
780 else {
781 text.append(COLLECTIONMETADATA_STR);
782 text.append(TAB_CHARACTER);
783 text.append(name_str);
784 text.append(SPACE_CHARACTER);
785 String language_str = command_element.getAttribute(LANGUAGE_ATTRIBUTE);
786 text.append(LBRACKET_CHARACTER);
787 text.append(LANGUAGE_ARGUMENT);
788 text.append(language_str);
789 text.append(RBRACKET_CHARACTER);
790 text.append(SPACE_CHARACTER);
791
792 if(known_metadata != null) {
793 known_metadata.add(name_str);
794 }
795 language_str = null;
796 }
797 name_str = null;
798
799 // The value string we retrieved will be encoded for xml, so we now decode it - to text if text_value set. This parameter was originally show_extracted_namespace, but sincethis is only true for 'toString()' commands from within the CDM, its good enough to determine if this toString() will be used to display on screen, or write to collect.cfg
800 if(text_value == CollectionMeta.TEXT) {
801 value_str = Codec.transform(value_str, Codec.DOM_TO_TEXT);
802 }
803 else {
804 value_str = Codec.transform(value_str, Codec.DOM_TO_GREENSTONE);
805 }
806
807 // We don't wrap the email addresses in quotes, nor the other special metadata
808 if(special) {
809 text.append(value_str);
810 }
811 else {
812 text.append(SPEECH_CHARACTER);
813 text.append(value_str);
814 text.append(SPEECH_CHARACTER);
815 }
816 value_str = null;
817 return text.toString();
818 }
819
820 /** Parse a collect.cfg into a DOM model representation.
821 * note we are ignoring 2.39 compatibility now. */
822 private void parse(File collect_cfg_file) {
823 // hack for pre 2.71 compatibility - we need to add in a
824 // build type if there is not one there
825 boolean search_types_parsed = false;
826 boolean build_types_parsed = false;
827 try {
828
829 Element collect_cfg_element = document.getDocumentElement();
830 // Read in the file one command at a time.
831 InputStream istream = new FileInputStream(collect_cfg_file);
832 Reader in_reader = new InputStreamReader(istream, ENCODING);
833 BufferedReader in = new BufferedReader(in_reader);
834 String command_str = null;
835 while((command_str = in.readLine()) != null) {
836 boolean append_element = true;
837 Element command_element = null;
838 // A command may be broken over several lines.
839 command_str = command_str.trim();
840 boolean eof = false;
841 while(!eof && command_str.endsWith(NEWLINE_CHARACTER)) {
842 String next_line = in.readLine();
843 if(next_line != null) {
844 next_line = next_line.trim();
845 if(next_line.length() > 0) {
846 // Remove the new line character
847 command_str = command_str.substring(0, command_str.lastIndexOf(NEWLINE_CHARACTER));
848 // And append the next line, which due to the test above must be non-zero length
849 command_str = command_str + next_line;
850 }
851 next_line = null;
852 }
853 // If we've reached the end of the file theres nothing more we can do
854 else {
855 eof = true;
856 }
857 }
858 // If there is still a new line character, then we remove it and hope for the best
859 if(command_str.endsWith(NEWLINE_CHARACTER)) {
860 command_str = command_str.substring(0, command_str.lastIndexOf(NEWLINE_CHARACTER));
861 }
862 // Now we've either got a command to parse...
863 if(command_str.length() != 0) {
864 // Start trying to figure out what it is
865 //StringTokenizer tokenizer = new StringTokenizer(command_str);
866 // Instead of a standard string tokenizer I'm going to use the new version of CommandTokenizer, which is not only smart enough to correctly notice speech marks and correctly parse them out, but now also takes the input stream so it can rebuild tokens that stretch over several lines.
867 CommandTokenizer tokenizer = new CommandTokenizer(command_str, in);
868 String command_type = tokenizer.nextToken().toLowerCase();
869 // Why can't you switch on strings eh? We pass it to the various subparsers who each have a bash at parsing the command. If none can parse the command, an unknown element is created
870 if(command_element == null && command_type.equals(CLASSIFY_STR)) {
871 command_element = parseClassify(command_str);
872 }
873 if(command_element == null && command_type.equals(FORMAT_STR)) {
874 command_element = parseFormat(tokenizer); // Revised to handle multiple lines
875 }
876 if(command_element == null && (command_type.equals(INDEX_STR) || command_type.equals(COMMENTED_INDEXES_STR))) {
877 command_element = parseIndex(command_str);
878 }
879 if(command_element == null && (command_type.equals(INDEX_DEFAULT_STR) || command_type.equals(COMMENTED_INDEX_DEFAULT_STR))) {
880
881 command_element = parseIndexDefault(command_str);
882 }
883 if(command_element == null && command_type.equals(LANGUAGES_STR)) {
884 command_element = parseLanguage(command_str);
885 }
886 if(command_element == null && command_type.equals(LANGUAGE_DEFAULT_STR)) {
887 command_element = parseLanguageDefault(command_str);
888 }
889 if (command_element == null && command_type.equals(LANGUAGE_METADATA_STR)) {
890 command_element = parseLanguageMetadata(command_str);
891 }
892 if(command_element == null && (command_type.equals(LEVELS_STR) || command_type.equals(COMMENTED_LEVELS_STR))) {
893 command_element = parseLevels(command_str);
894 }
895 if(command_element == null && (command_type.equals(LEVEL_DEFAULT_STR) || command_type.equals(COMMENTED_LEVEL_DEFAULT_STR))) {
896
897 command_element = parseLevelDefault(command_str);
898 }
899
900 if(command_element == null && command_type.equals(COLLECTIONMETADATA_STR)) {
901 command_element = parseMetadata(tokenizer); // Revised to handle multiple lines
902 }
903 if(command_element == null && (command_type.equals(COLLECTIONMETADATA_PUBLIC_STR) || command_type.equals(COLLECTIONMETADATA_CREATOR_STR) || command_type.equals(COLLECTIONMETADATA_MAINTAINER_STR) || command_type.equals(BUILDTYPE_STR))) {
904 command_element = parseMetadataSpecial(command_str);
905 // pre 2.71 hack
906 if (command_type.equals(BUILDTYPE_STR)) {
907 build_types_parsed = true;
908 }
909 }
910 if(command_element == null && command_type.equals(PLUGIN_STR)) {
911 command_element = parsePlugin(command_str);
912 }
913 // leave here for backwards compatibility
914 if(command_element == null && command_type.equals(SEARCHTYPE_STR)) {
915 command_element = parseSearchType(command_str);
916 // pre 2.71 hack
917 search_types_parsed = true;
918
919 }
920 if(command_element == null && command_type.equals(SUBCOLLECTION_STR)) {
921 command_element = parseSubCollection(command_str);
922 }
923 if(command_element == null && command_type.equals(SUBCOLLECTION_DEFAULT_INDEX_STR)) {
924 command_element = parseSubCollectionDefaultIndex(command_str);
925 }
926 if(command_element == null && command_type.equals(SUBCOLLECTION_INDEX_STR)) {
927 command_element = parseSubCollectionIndex(command_str);
928 }
929 if(command_element == null && (command_type.equals(SUPERCOLLECTION_STR) || command_type.equals(CCS_STR))) {
930 command_element = parseSuperCollection(command_str);
931 }
932 // Doesn't match any known type
933 command_type = null;
934 if(command_element == null) {
935 // No-one knows what to do with this command, so we create an Unknown command element
936 command_element = document.createElement(UNKNOWN_ELEMENT);
937 XMLTools.setValue(command_element, command_str);
938 }
939 }
940 // Or an empty line to remember for later
941 else {
942 command_element = document.createElement(NEWLINE_ELEMENT);
943 }
944 // Now command element shouldn't be null so we append it to the collection config DOM, but only if we haven't been told not to add it
945 //if(append_element) {
946 collect_cfg_element.appendChild(command_element);
947 //}
948 }
949 if (!build_types_parsed) {
950 String buildtype_type = BuildTypeManager.BUILD_TYPE_MG;
951 if (search_types_parsed) {
952 buildtype_type = BuildTypeManager.BUILD_TYPE_MGPP;
953 }
954 Element command_element = parseMetadataSpecial(BUILDTYPE_STR+" "+buildtype_type);
955 Node target_node = findInsertionPoint(command_element);
956 if(target_node != null) {
957 collect_cfg_element.insertBefore(command_element, target_node);
958 }
959 else {
960 collect_cfg_element.appendChild(command_element);
961 }
962
963 }
964 }
965 catch(Exception exception) {
966 DebugStream.println("Error in CollectionConfiguration.parse(java.io.File): " + exception);
967 DebugStream.printStackTrace(exception);
968 }
969 }
970
971
972 private Element parseClassify(String command_str) {
973 Element command_element = null;
974 try {
975 CommandTokenizer tokenizer = new CommandTokenizer(command_str);
976 // Check the token count. The token count from a command tokenizer isn't guarenteed to be correct, but it does give the maximum number of available tokens according to the underlying StringTokenizer (some of which may actually be append together by the CommandTokenizer as being a single argument).
977 if(tokenizer.countTokens() >= 2) { // Must support "classify Phind" (no args)
978 command_element = document.createElement(CLASSIFY_ELEMENT);
979 // First token is classify
980 tokenizer.nextToken();
981 // The next token is the classifier type
982 command_element.setAttribute(TYPE_ATTRIBUTE, tokenizer.nextToken());
983 // Now we parse out the remaining arguments into a hashmapping from name to value
984 HashMap arguments = parseArguments(tokenizer);
985 // Assign the arguments as Option elements, but watch out for the metadata argument as we treat that differently
986 Iterator names = arguments.keySet().iterator();
987 while(names.hasNext()) {
988 String name = (String) names.next();
989 String value = (String) arguments.get(name); // Can be null
990 // The metadata argument gets added as the content attribute
991 if (name.equals(METADATA_ARGUMENT) && value != null) {
992 // Add the extracted namespace onto un-namespaced metadata names
993 StringTokenizer string_tokenizer = new StringTokenizer(value, ",");
994 value = "";
995 while (string_tokenizer.hasMoreElements()) {
996 String token = (String) string_tokenizer.nextElement();
997
998 if (token.indexOf(StaticStrings.NS_SEP) == -1) {
999 token = StaticStrings.EXTRACTED_NAMESPACE + token;
1000 }
1001 else {
1002 MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(token);
1003 if (metadata_element != null) {
1004 token = metadata_element.getDisplayName();
1005 }
1006 }
1007
1008 if (!value.equals("")) {
1009 value = value + ",";
1010 }
1011 value = value + token;
1012 }
1013 }
1014 // Everything else is an Option Element
1015 Element option_element = document.createElement(OPTION_ELEMENT);
1016 option_element.setAttribute(NAME_ATTRIBUTE, name.substring(1));
1017 if(value != null) {
1018 // Remove any speech marks appended in strings containing whitespace
1019 if(value.startsWith(SPEECH_CHARACTER) && value.endsWith(SPEECH_CHARACTER)) {
1020 value = value.substring(1, value.length() - 1);
1021 }
1022 XMLTools.setValue(option_element, value);
1023 }
1024 option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
1025 command_element.appendChild(option_element);
1026 option_element = null;
1027 name = null;
1028 value = null;
1029 }
1030 names = null;
1031 arguments = null;
1032 }
1033 tokenizer = null;
1034 }
1035 catch(Exception error) {
1036 }
1037 return command_element;
1038 }
1039
1040 private Element parseFormat(CommandTokenizer tokenizer) {
1041 Element command_element = null;
1042 try {
1043 command_element = document.createElement(FORMAT_ELEMENT);
1044 String name_str = tokenizer.nextToken();
1045 String value_str = tokenizer.nextToken();
1046 if(name_str != null && value_str != null) {
1047 command_element.setAttribute(NAME_ATTRIBUTE, name_str);
1048 // If the value is true or false we add it as an attribute
1049 if(value_str.equalsIgnoreCase(TRUE_STR) || value_str.equalsIgnoreCase(FALSE_STR)) {
1050 command_element.setAttribute(VALUE_ATTRIBUTE, value_str.toLowerCase());
1051 }
1052 // Otherwise it gets added as a text node
1053 else {
1054 // Ready the value str (which can contain all sorts of funky characters) for writing as a DOM value
1055 value_str = Codec.transform(value_str, Codec.GREENSTONE_TO_DOM);
1056 XMLTools.setValue(command_element, value_str);
1057 }
1058 }
1059 else {
1060 command_element = null;
1061 }
1062 name_str = null;
1063 value_str = null;
1064 }
1065 catch (Exception exception) {
1066 DebugStream.printStackTrace(exception);
1067 command_element = null;
1068 }
1069 return command_element;
1070 }
1071
1072 private Element parseIndex(String command_str) {
1073 Element command_element = null;
1074 try {
1075 StringTokenizer tokenizer = new StringTokenizer(command_str);
1076 String command = tokenizer.nextToken();
1077 command_element = document.createElement(INDEXES_ELEMENT);
1078 command_element.setAttribute(ASSIGNED_ATTRIBUTE, (command.equals(INDEX_STR) ? TRUE_STR : FALSE_STR));
1079 command = null;
1080 if(!tokenizer.hasMoreTokens()) {
1081
1082 // there are no indexes
1083 command_element.setAttribute(ASSIGNED_ATTRIBUTE, FALSE_STR);
1084 command_element.setAttribute(MGPP_ATTRIBUTE, FALSE_STR); // for now
1085 tokenizer = null;
1086 return command_element;
1087 }
1088
1089 while(tokenizer.hasMoreTokens()) {
1090 Element index_element = document.createElement(INDEX_ELEMENT);
1091 String index_str = tokenizer.nextToken();
1092 // There are two types of index we have to consider. Old G2.38 and earlier use level:source tuplets while G2.39+ have just a single, non-comma separated list where order is important.
1093 boolean old_index;
1094 if(index_str.indexOf(COLON_CHARACTER) != -1) {
1095 old_index = true;
1096 index_element.setAttribute(LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
1097 index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
1098 command_element.setAttribute(MGPP_ATTRIBUTE, FALSE_STR);
1099 }
1100 else {
1101 command_element.setAttribute(MGPP_ATTRIBUTE, TRUE_STR);
1102 old_index = false;
1103 }
1104 StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
1105 while(content_tokenizer.hasMoreTokens()) {
1106 Element content_element = document.createElement(CONTENT_ELEMENT);
1107 String content_str = content_tokenizer.nextToken();
1108 // Since the contents of indexes have to be certain keywords, or metadata elements, if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace.
1109 if(content_str.indexOf(StaticStrings.NS_SEP) == -1) {
1110 if(content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR))) {
1111 // Our special strings are OK.
1112 }
1113 else {
1114 content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
1115 }
1116 }
1117 content_element.setAttribute(NAME_ATTRIBUTE, content_str);
1118 index_element.appendChild(content_element);
1119 content_element = null;
1120 }
1121 content_tokenizer = null;
1122 index_str = null;
1123 command_element.appendChild(index_element);
1124 index_element = null;
1125 }
1126 tokenizer = null;
1127 }
1128 catch (Exception exception) {
1129 exception.printStackTrace();
1130 }
1131 return command_element;
1132 }
1133
1134 private Element parseIndexDefault(String command_str) {
1135 Element command_element = null;
1136 try {
1137 StringTokenizer tokenizer = new StringTokenizer(command_str);
1138 if(tokenizer.countTokens() >= 2) {
1139 command_element = document.createElement(INDEX_DEFAULT_ELEMENT);
1140 command_element.setAttribute(ASSIGNED_ATTRIBUTE, ((tokenizer.nextToken()).equals(INDEX_DEFAULT_STR) ? TRUE_STR : FALSE_STR));
1141 String index_str = tokenizer.nextToken();
1142 String level="";
1143 if (index_str.indexOf(StaticStrings.COLON_CHARACTER) !=-1){
1144 level = index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER));
1145 }
1146
1147 command_element.setAttribute(LEVEL_ATTRIBUTE,level);
1148
1149 String content_str = index_str;
1150
1151 if (index_str.indexOf(StaticStrings.COLON_CHARACTER) !=-1){
1152 content_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
1153 }
1154
1155 StringTokenizer content_tokenizer = new StringTokenizer(content_str, StaticStrings.COMMA_CHARACTER);
1156 while(content_tokenizer.hasMoreTokens()) {
1157 Element content_element = document.createElement(CONTENT_ELEMENT);
1158 content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
1159 command_element.appendChild(content_element);
1160 content_element = null;
1161 }
1162 content_tokenizer = null;
1163 content_str = null;
1164 content_str = null;
1165 index_str = null;
1166 }
1167 tokenizer = null;
1168 }
1169 catch (Exception exception) {
1170 }
1171 return command_element;
1172 }
1173
1174 private Element parseLanguage(String command_str) {
1175 Element command_element = null;
1176 try {
1177 StringTokenizer tokenizer = new StringTokenizer(command_str);
1178 tokenizer.nextToken();
1179 if(tokenizer.hasMoreTokens()) {
1180 command_element = document.createElement(LANGUAGES_ELEMENT);
1181 while(tokenizer.hasMoreTokens()) {
1182 Element language_element = document.createElement(LANGUAGE_ELEMENT);
1183 language_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
1184 command_element.appendChild(language_element);
1185 language_element = null;
1186 }
1187 }
1188 tokenizer = null;
1189 }
1190 catch (Exception exception) {
1191 }
1192 return command_element;
1193 }
1194
1195 private Element parseLanguageDefault(String command_str) {
1196 Element command_element = null;
1197 try {
1198 StringTokenizer tokenizer = new StringTokenizer(command_str);
1199 if(tokenizer.countTokens() >= 2) {
1200 command_element = document.createElement(LANGUAGE_DEFAULT_ELEMENT);
1201 tokenizer.nextToken();
1202 String default_language_str = tokenizer.nextToken();
1203 command_element.setAttribute(NAME_ATTRIBUTE, default_language_str);
1204 command_element.setAttribute(ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
1205 default_language_str = null;
1206 }
1207 tokenizer = null;
1208 }
1209 catch (Exception exception) {
1210 }
1211 return command_element;
1212 }
1213
1214 private Element parseLanguageMetadata(String command_str) {
1215 Element command_element = null;
1216 try {
1217 StringTokenizer tokenizer = new StringTokenizer(command_str);
1218 if(tokenizer.countTokens() >= 2) {
1219 command_element = document.createElement(LANGUAGE_METADATA_ELEMENT);
1220 tokenizer.nextToken();
1221 String language_metadata_str = tokenizer.nextToken();
1222 if (language_metadata_str.indexOf(StaticStrings.NS_SEP) == -1) {
1223 language_metadata_str = StaticStrings.EXTRACTED_NAMESPACE + language_metadata_str;
1224 }
1225 command_element.setAttribute(NAME_ATTRIBUTE, language_metadata_str);
1226 command_element.setAttribute(ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
1227 language_metadata_str = null;
1228 }
1229 tokenizer = null;
1230
1231 }
1232 catch (Exception exception) {
1233 }
1234 return command_element;
1235 }
1236
1237 private Element parseLevels(String command_str) {
1238 Element command_element = null;
1239 try {
1240 StringTokenizer tokenizer = new StringTokenizer(command_str);
1241 // First token is command type (levels)
1242 String command = tokenizer.nextToken();
1243 if(tokenizer.hasMoreTokens()) {
1244 command_element = document.createElement(LEVELS_ELEMENT);
1245 command_element.setAttribute(ASSIGNED_ATTRIBUTE, (command.equals(LEVELS_STR) ? TRUE_STR : FALSE_STR));
1246 while(tokenizer.hasMoreTokens()) {
1247 Element level_element = document.createElement(LEVEL_ELEMENT);
1248 level_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
1249 command_element.appendChild(level_element);
1250 level_element = null;
1251 }
1252 }
1253 command = null;
1254 }
1255 catch(Exception exception) {
1256 }
1257 return command_element;
1258 }
1259
1260 private Element parseLevelDefault(String command_str) {
1261 Element command_element = null;
1262 try {
1263 StringTokenizer tokenizer = new StringTokenizer(command_str);
1264 if(tokenizer.countTokens() >= 2) {
1265 command_element = document.createElement(LEVEL_DEFAULT_ELEMENT);
1266 command_element.setAttribute(ASSIGNED_ATTRIBUTE, ((tokenizer.nextToken()).equals(LEVEL_DEFAULT_STR) ? TRUE_STR : FALSE_STR)); // is it commented out or not?
1267 command_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
1268 }
1269
1270 tokenizer = null;
1271 }
1272 catch (Exception exception) {
1273 }
1274 return command_element;
1275 }
1276
1277 private Element parseMetadata(CommandTokenizer tokenizer) {
1278 Element command_element = null;
1279 try {
1280 command_element = document.createElement(COLLECTIONMETADATA_ELEMENT);
1281 String name_str = tokenizer.nextToken();
1282 String value_str = tokenizer.nextToken();
1283 if(name_str != null && value_str != null) {
1284 String language_str = Configuration.getLanguage();
1285 // Check if the value string is actually a language string
1286 if(value_str.startsWith(LBRACKET_CHARACTER) && value_str.endsWith(RBRACKET_CHARACTER)) {
1287 language_str = value_str.substring(value_str.indexOf(LANGUAGE_ARGUMENT) + 2, value_str.length() - 1);
1288 value_str = tokenizer.nextToken();
1289 }
1290 if(value_str != null) {
1291 // Ready the value str (which can contain all sorts of funky characters) for writing as a DOM value
1292 value_str = Codec.transform(value_str, Codec.GREENSTONE_TO_DOM);
1293 command_element.setAttribute(NAME_ATTRIBUTE, name_str);
1294 command_element.setAttribute(LANGUAGE_ATTRIBUTE, language_str);
1295 command_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
1296 XMLTools.setValue(command_element, value_str);
1297 }
1298 else {
1299 command_element = null;
1300 }
1301 language_str = null;
1302 }
1303 else {
1304 command_element = null;
1305 }
1306 name_str = null;
1307 value_str = null;
1308 }
1309 catch (Exception exception) {
1310 DebugStream.printStackTrace(exception);
1311 command_element = null;
1312 }
1313 return command_element;
1314 }
1315
1316 private Element parseMetadataSpecial(String command_str) {
1317 Element command_element = null;
1318 try {
1319 StringTokenizer tokenizer = new StringTokenizer(command_str);
1320 if(tokenizer.countTokens() >= 2) {
1321 String name_str = tokenizer.nextToken();
1322 String value_str = tokenizer.nextToken();
1323 if (name_str.equals(COLLECTIONMETADATA_CREATOR_STR)) {
1324 command_element = document.createElement(COLLECTIONMETADATA_CREATOR_ELEMENT);
1325 }
1326 else if(name_str.equals(COLLECTIONMETADATA_MAINTAINER_STR)) {
1327 command_element = document.createElement(COLLECTIONMETADATA_MAINTAINER_ELEMENT);
1328 }
1329 else if(name_str.equals(COLLECTIONMETADATA_PUBLIC_STR)) {
1330 command_element = document.createElement(COLLECTIONMETADATA_PUBLIC_ELEMENT);
1331 }
1332 else if (name_str.equals(BUILDTYPE_STR)) {
1333 command_element = document.createElement(BUILDTYPE_ELEMENT);
1334 }
1335 if(command_element != null) {
1336 command_element.setAttribute(NAME_ATTRIBUTE, name_str);
1337 command_element.setAttribute(LANGUAGE_ATTRIBUTE, ENGLISH_LANGUAGE_STR);
1338 command_element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
1339 command_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
1340 if(value_str.startsWith(SPEECH_CHARACTER) && value_str.endsWith(SPEECH_CHARACTER)) {
1341 value_str = value_str.substring(1, value_str.length() - 1);
1342 }
1343 XMLTools.setValue(command_element, value_str);
1344 }
1345 value_str = null;
1346 name_str = null;
1347 }
1348 tokenizer = null;
1349 }
1350 catch (Exception exception) {
1351 }
1352 return command_element;
1353 }
1354
1355 private Element parsePlugin(String command_str) {
1356 Element command_element = null;
1357 boolean use_metadata_files = false;
1358 try {
1359 CommandTokenizer tokenizer = new CommandTokenizer(command_str);
1360 // Check the token count. The token count from a command tokenizer isn't guarenteed to be correct, but it does give the maximum number of available tokens according to the underlying StringTokenizer (some of which may actually be append together by the CommandTokenizer as being a single argument).
1361 if(tokenizer.countTokens() >= 2) {
1362 command_element = document.createElement(PLUGIN_ELEMENT);
1363 // First token is plugin
1364 tokenizer.nextToken();
1365 // The next token is the type
1366 String type = tokenizer.nextToken();
1367 command_element.setAttribute(TYPE_ATTRIBUTE, type);
1368 // Now we parse out the remaining arguments into a hashmapping from name to value
1369 HashMap arguments = parseArguments(tokenizer);
1370 // Assign the arguments as Option elements, but watch out for the metadata argument as we treat that differently
1371 Iterator names = arguments.keySet().iterator();
1372 while(names.hasNext()) {
1373 String name = (String) names.next();
1374 String value = (String) arguments.get(name); // Can be null
1375 Element option_element = document.createElement(OPTION_ELEMENT);
1376 if(name.substring(1).equals(USE_METADATA_FILES_ARGUMENT)) {
1377 use_metadata_files = true;
1378 }
1379 option_element.setAttribute(NAME_ATTRIBUTE, name.substring(1));
1380 option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
1381 if(value != null) {
1382 // Remove any speech marks appended in strings containing whitespace
1383 if(value.startsWith(SPEECH_CHARACTER) && value.endsWith(SPEECH_CHARACTER)) {
1384 value = value.substring(1, value.length() - 1);
1385 }
1386 if(name.equals(METADATA_ARGUMENT)) {
1387 // The metadata argument must be the fully qualified name of a metadata element, so if it doesn't yet have a namespace, append the extracted metadata namespace.
1388 if(value.indexOf(StaticStrings.NS_SEP) == -1) {
1389 value = StaticStrings.EXTRACTED_NAMESPACE + value;
1390 }
1391 }
1392 XMLTools.setValue(option_element, value);
1393 }
1394 command_element.appendChild(option_element);
1395 option_element = null;
1396 name = null;
1397 value = null;
1398 }
1399
1400 // We must have some RecPlug options: use_metadata_files
1401 if (type.equals(RECPLUG_STR)) {
1402 if (!use_metadata_files) {
1403 Element option_element = document.createElement(OPTION_ELEMENT);
1404 option_element.setAttribute(NAME_ATTRIBUTE, USE_METADATA_FILES_ARGUMENT);
1405 option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
1406 command_element.appendChild(option_element);
1407 option_element = null;
1408 }
1409 }
1410 type = null;
1411 names = null;
1412 arguments = null;
1413 }
1414 tokenizer = null;
1415 }
1416 catch(Exception exception) {
1417 }
1418 return command_element;
1419 }
1420
1421 /* search types are now handled as formats - leave this here to convert in case we have an old config file */
1422 private Element parseSearchType(String command_str) {
1423 Element command_element = null;
1424 try {
1425 StringTokenizer tokenizer = new StringTokenizer(command_str);
1426 // First token is command type (searchtype)
1427 tokenizer.nextToken();
1428 if(tokenizer.hasMoreTokens()) {
1429 command_element = document.createElement(FORMAT_ELEMENT);
1430 command_element.setAttribute(NAME_ATTRIBUTE, "SearchTypes");
1431 String value = tokenizer.nextToken();
1432 while(tokenizer.hasMoreTokens()) {
1433 value += ","+tokenizer.nextToken();
1434 }
1435 value = Codec.transform(value, Codec.GREENSTONE_TO_DOM);
1436 XMLTools.setValue(command_element, value);
1437 }
1438 }
1439 catch(Exception exception) {
1440 }
1441 return command_element;
1442 }
1443
1444 private Element parseSubCollection(String command_str) {
1445 Element command_element = null;
1446 try {
1447 CommandTokenizer tokenizer = new CommandTokenizer(command_str);
1448 if(tokenizer.countTokens() >= 3) {
1449 command_element = document.createElement(SUBCOLLECTION_ELEMENT);
1450 // First token is command type
1451 tokenizer.nextToken();
1452 // Then subcollection identifier
1453 command_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
1454 // Then finally the pattern used to build the subcollection partition
1455 String full_pattern_str = tokenizer.nextToken();
1456 // Set inclusion/exclusion flag and remove any exclamation mark
1457 boolean exclusion = full_pattern_str.startsWith(EXCLAMATION_CHARACTER);
1458 if (exclusion) {
1459 full_pattern_str = full_pattern_str.substring(1, full_pattern_str.length());
1460 command_element.setAttribute(TYPE_ATTRIBUTE, EXCLUDE_STR);
1461 }
1462 else {
1463 command_element.setAttribute(TYPE_ATTRIBUTE, INCLUDE_STR);
1464 }
1465 StringTokenizer pattern_tokenizer = new StringTokenizer(full_pattern_str, SEPARATOR_CHARACTER);
1466 if(pattern_tokenizer.countTokens() >= 2) {
1467 String content_str = pattern_tokenizer.nextToken();
1468 // Since the contents of indexes have to be certain keywords, or metadata elements, if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace.
1469 if(!content_str.equals(StaticStrings.FILENAME_STR) && content_str.indexOf(StaticStrings.NS_SEP) == -1) {
1470 content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
1471 }
1472 command_element.setAttribute(CONTENT_ATTRIBUTE, content_str);
1473 XMLTools.setValue(command_element, pattern_tokenizer.nextToken());
1474 if(pattern_tokenizer.hasMoreTokens()) {
1475 command_element.setAttribute(OPTIONS_ATTRIBUTE, pattern_tokenizer.nextToken());
1476 }
1477 }
1478 pattern_tokenizer = null;
1479 }
1480 }
1481 catch(Exception exception) {
1482 exception.printStackTrace();
1483 }
1484 return command_element;
1485 }
1486
1487 private Element parseSubCollectionDefaultIndex(String command_str) {
1488 Element command_element = null;
1489 try {
1490 StringTokenizer tokenizer = new StringTokenizer(command_str);
1491 if(tokenizer.countTokens() == 2) {
1492 command_element = document.createElement(SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
1493 tokenizer.nextToken();
1494 //command_element.setAttribute(CONTENT_ATTRIBUTE, tokenizer.nextToken());
1495 String content_str = tokenizer.nextToken();
1496 StringTokenizer content_tokenizer = new StringTokenizer(content_str, StaticStrings.COMMA_CHARACTER);
1497 while(content_tokenizer.hasMoreTokens()) {
1498 Element content_element = document.createElement(CONTENT_ELEMENT);
1499 content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
1500 command_element.appendChild(content_element);
1501 content_element = null;
1502 }
1503 content_tokenizer = null;
1504 content_str = null;
1505 }
1506 tokenizer = null;
1507 }
1508 catch(Exception exception) {
1509 }
1510 return command_element;
1511 }
1512
1513 private Element parseSubCollectionIndex(String command_str) {
1514 Element command_element = null;
1515 try {
1516 StringTokenizer tokenizer = new StringTokenizer(command_str);
1517 tokenizer.nextToken();
1518 if(tokenizer.hasMoreTokens()) {
1519 command_element = document.createElement(SUBCOLLECTION_INDEXES_ELEMENT);
1520 }
1521 while(tokenizer.hasMoreTokens()) {
1522 Element subcollectionindex_element = document.createElement(INDEX_ELEMENT);
1523 //command_element.setAttribute(CONTENT_ATTRIBUTE, tokenizer.nextToken());
1524 String content_str = tokenizer.nextToken();
1525 StringTokenizer content_tokenizer = new StringTokenizer(content_str, StaticStrings.COMMA_CHARACTER);
1526 while(content_tokenizer.hasMoreTokens()) {
1527 Element content_element = document.createElement(CONTENT_ELEMENT);
1528 content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
1529 subcollectionindex_element.appendChild(content_element);
1530 content_element = null;
1531 }
1532 content_tokenizer = null;
1533 content_str = null;
1534 command_element.appendChild(subcollectionindex_element);
1535 subcollectionindex_element = null;
1536 }
1537 tokenizer = null;
1538 }
1539 catch (Exception exception) {
1540 }
1541 return command_element;
1542 }
1543
1544 private Element parseSuperCollection(String command_str) {
1545 Element command_element = null;
1546 try {
1547 StringTokenizer tokenizer = new StringTokenizer(command_str);
1548 if(tokenizer.countTokens() >= 3) {
1549 command_element = document.createElement(SUPERCOLLECTION_ELEMENT);
1550 tokenizer.nextToken();
1551 while(tokenizer.hasMoreTokens()) {
1552 Element collection_element = document.createElement(COLLECTION_ELEMENT);
1553 collection_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
1554 command_element.appendChild(collection_element);
1555 collection_element = null;
1556 }
1557 }
1558 tokenizer = null;
1559 }
1560 catch(Exception exception) {
1561 }
1562 return command_element;
1563 }
1564
1565 static private String pluginToString(Element command_element, boolean show_extracted_namespace) {
1566 StringBuffer text = new StringBuffer();
1567 if(!command_element.getAttribute(SEPARATOR_ATTRIBUTE).equals(TRUE_STR)) {
1568 text.append(PLUGIN_STR);
1569 text.append(TAB_CHARACTER);
1570 text.append(TAB_CHARACTER);
1571 text.append(command_element.getAttribute(TYPE_ATTRIBUTE));
1572 // Retrieve, and output, the arguments
1573 NodeList option_elements = command_element.getElementsByTagName(OPTION_ELEMENT);
1574 int option_elements_length = option_elements.getLength();
1575 if(option_elements_length > 0) {
1576 text.append(SPACE_CHARACTER);
1577 for(int j = 0; j < option_elements_length; j++) {
1578 Element option_element = (Element) option_elements.item(j);
1579 if(option_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
1580 text.append(StaticStrings.MINUS_CHARACTER);
1581 text.append(option_element.getAttribute(NAME_ATTRIBUTE));
1582 String value_str = XMLTools.getValue(option_element);
1583 if(!show_extracted_namespace && value_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
1584 value_str = value_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
1585 }
1586 if(value_str.length() > 0) {
1587 text.append(SPACE_CHARACTER);
1588 if(value_str.indexOf(SPACE_CHARACTER) == -1) {
1589 text.append(value_str);
1590 }
1591 else {
1592 text.append(SPEECH_CHARACTER);
1593 text.append(value_str);
1594 text.append(SPEECH_CHARACTER);
1595 }
1596 }
1597 value_str = null;
1598 if(j < option_elements_length - 1) {
1599 text.append(SPACE_CHARACTER);
1600 }
1601 }
1602 option_element = null;
1603 }
1604 }
1605 option_elements = null;
1606 }
1607 return text.toString();
1608 }
1609
1610 static private String searchtypeToString(Element command_element) {
1611 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
1612 StringBuffer text = new StringBuffer(SEARCHTYPE_STR);
1613 text.append(TAB_CHARACTER);
1614 NodeList search_elements = command_element.getElementsByTagName(CONTENT_ELEMENT);
1615 int search_elements_length = search_elements.getLength();
1616 for(int i = 0; i < search_elements_length; i++) {
1617 Element search_element = (Element) search_elements.item(i);
1618 text.append(search_element.getAttribute(NAME_ATTRIBUTE));
1619 text.append(SPACE_CHARACTER);
1620 }
1621 return text.substring(0, text.length() - 1);
1622 }
1623 else {
1624 return null;
1625 }
1626 }
1627
1628 static private String subcollectionToString(Element command_element, boolean show_extracted_namespace) {
1629 StringBuffer text = new StringBuffer(SUBCOLLECTION_STR);
1630 text.append(SPACE_CHARACTER);
1631 text.append(command_element.getAttribute(NAME_ATTRIBUTE));
1632 text.append(SPACE_CHARACTER);
1633 text.append(TAB_CHARACTER);
1634 text.append(SPEECH_CHARACTER);
1635 if(command_element.getAttribute(TYPE_ATTRIBUTE).equals(EXCLUDE_STR)) {
1636 text.append(EXCLAMATION_CHARACTER);
1637 }
1638 String content_str = command_element.getAttribute(CONTENT_ATTRIBUTE);
1639 if(!show_extracted_namespace && content_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
1640 content_str = content_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
1641 }
1642 text.append(content_str);
1643 content_str = null;
1644 text.append(SEPARATOR_CHARACTER);
1645 text.append(XMLTools.getValue(command_element));
1646 text.append(SEPARATOR_CHARACTER);
1647 String options_str = command_element.getAttribute(OPTIONS_ATTRIBUTE);
1648 if(options_str.length() > 0) {
1649 text.append(options_str);
1650 }
1651 options_str = null;
1652 text.append(SPEECH_CHARACTER);
1653 return text.toString();
1654 }
1655
1656 static private String subcollectionDefaultIndexToString(Element command_element) {
1657 StringBuffer text = new StringBuffer(SUBCOLLECTION_DEFAULT_INDEX_STR);
1658 text.append(TAB_CHARACTER);
1659 NodeList content_elements = command_element.getElementsByTagName(CONTENT_ELEMENT);
1660 int content_elements_length = content_elements.getLength();
1661 for(int j = 0; j < content_elements_length; j++) {
1662 Element content_element = (Element) content_elements.item(j);
1663 text.append(content_element.getAttribute(NAME_ATTRIBUTE));
1664 if(j < content_elements_length - 1) {
1665 text.append(StaticStrings.COMMA_CHARACTER);
1666 }
1667 }
1668 return text.toString();
1669 }
1670
1671 static private String subcollectionIndexesToString(Element command_element) {
1672 StringBuffer text = new StringBuffer(SUBCOLLECTION_INDEX_STR);
1673 text.append(TAB_CHARACTER);
1674 // Retrieve all of the subcollection index partitions
1675 NodeList subcollectionindex_elements = command_element.getElementsByTagName(INDEX_ELEMENT);
1676 int subcollectionindex_elements_length = subcollectionindex_elements.getLength();
1677 if(subcollectionindex_elements_length == 0) {
1678 return null;
1679 }
1680 for(int j = 0; j < subcollectionindex_elements_length; j++) {
1681 Element subcollectionindex_element = (Element) subcollectionindex_elements.item(j);
1682 NodeList content_elements = subcollectionindex_element.getElementsByTagName(CONTENT_ELEMENT);
1683 int content_elements_length = content_elements.getLength();
1684 for(int k = 0; k < content_elements_length; k++) {
1685 Element content_element = (Element) content_elements.item(k);
1686 text.append(content_element.getAttribute(NAME_ATTRIBUTE));
1687 if(k < content_elements_length - 1) {
1688 text.append(StaticStrings.COMMA_CHARACTER);
1689 }
1690 }
1691 if(j < subcollectionindex_elements_length - 1) {
1692 text.append(SPACE_CHARACTER);
1693 }
1694 }
1695 return text.toString();
1696 }
1697
1698 static private String supercollectionToString(Element command_element) {
1699 NodeList content_elements = command_element.getElementsByTagName(COLLECTION_ELEMENT);
1700 int content_elements_length = content_elements.getLength();
1701 if(content_elements_length > 1) {
1702 StringBuffer text = new StringBuffer(SUPERCOLLECTION_STR);
1703 text.append(TAB_CHARACTER);
1704 for(int j = 0; j < content_elements_length; j++) {
1705 Element content_element = (Element) content_elements.item(j);
1706 text.append(content_element.getAttribute(NAME_ATTRIBUTE));
1707 if(j < content_elements_length - 1) {
1708 text.append(SPACE_CHARACTER);
1709 }
1710 }
1711 return text.toString();
1712 }
1713 return null;
1714 }
1715
1716 static private String unknownToString(Element command_element) {
1717 return XMLTools.getValue(command_element);
1718 }
1719
1720 /** Write the text to the buffer. This is used so we don't have to worry about storing intermediate String values just so we can calaulate length and offset.
1721 * @param writer the BufferedWriter to which the str will be written
1722 * @param str the String to be written
1723 */
1724 private void write(BufferedWriter writer, String str)
1725 throws IOException {
1726 writer.write(str, 0, str.length());
1727 }
1728}
Note: See TracBrowser for help on using the repository browser.