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

Last change on this file since 12799 was 12799, checked in by mdewsnip, 18 years ago

Removed an unused array.

  • Property svn:keywords set to Author Date Id Revision
File size: 69.8 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 private Document document;
59
60
61 static public Element createElement(String element_name)
62 {
63 return document.createElement(element_name);
64 }
65
66
67 /** 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.
68 * @param target_element the command Element to be inserted
69 * @return the Element which the given command should be inserted before, or null to append to end of list
70 */
71 static public Node findInsertionPoint(Element target_element) {
72 ///ystem.err.println("Find insertion point: " + target_element.getNodeName());
73 String target_element_name = target_element.getNodeName();
74 Element document_element = document.getDocumentElement();
75 // Try to find commands with the same tag.
76 NodeList matching_elements = document_element.getElementsByTagName(target_element_name);
77 // If we found matching elements, then we have our most likely insertion location, so check within for groupings
78 if(matching_elements.getLength() != 0) {
79 ///ystem.err.println("Found matching elements.");
80 // Only CollectionMeta are grouped.
81 if(target_element_name.equals(COLLECTIONMETADATA_ELEMENT)) {
82 ///ystem.err.println("Dealing with collection metadata");
83 // 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.
84 // So if the command to be added is special add it immediately after any other special command
85 if(target_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
86 int index = 0;
87 Element matched_element = (Element) matching_elements.item(index);
88 Element sibling_element = (Element) matched_element.getNextSibling();
89 while(sibling_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
90 index++;
91 matched_element = (Element) matching_elements.item(index);
92 sibling_element = (Element) matched_element.getNextSibling();
93 }
94 if(sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
95 Element newline_element = document.createElement(NEWLINE_ELEMENT);
96 document_element.insertBefore(newline_element, sibling_element);
97 }
98 return sibling_element;
99 }
100 // Otherwise try to find a matching 'name' and add after the last one in that group.
101 else {
102 int index = 0;
103 target_element_name = target_element.getAttribute(NAME_ATTRIBUTE);
104 boolean found = false;
105 // Skip all of the special metadata
106 Element matched_element = (Element) matching_elements.item(index);
107 while(matched_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
108 index++;
109 matched_element = (Element) matching_elements.item(index);
110 }
111 // Begin search
112 while(!found && matched_element != null) {
113 if(matched_element.getAttribute(NAME_ATTRIBUTE).equals(target_element_name)) {
114 found = true;
115 }
116 else {
117 index++;
118 matched_element = (Element) matching_elements.item(index);
119 }
120 }
121 // If we found a match, we need to continue checking until we find the last name match.
122 if(found) {
123 index++;
124 Element previous_sibling = matched_element;
125 Element sibling_element = (Element) matching_elements.item(index);
126 while(sibling_element != null && sibling_element.getAttribute(NAME_ATTRIBUTE).equals(target_element_name)) {
127 previous_sibling = sibling_element;
128 index++;
129 sibling_element = (Element) matching_elements.item(index);
130 }
131 // 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!
132 return previous_sibling.getNextSibling();
133 }
134 // If not found we just add after last metadata element
135 else {
136 Element last_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
137 return last_element.getNextSibling();
138 }
139 }
140
141 }
142 else {
143 ///ystem.err.println("Not dealing with collection meta.");
144 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
145 // 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)
146 Node sibling_element = matched_element.getNextSibling();
147 if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
148 Element newline_element = document.createElement(NEWLINE_ELEMENT);
149 document_element.insertBefore(newline_element, sibling_element);
150 }
151 return sibling_element; // Note that this may be null
152 }
153 }
154 ///ystem.err.println("No matching elements found.");
155 // Locate where this command is in the ordering
156 int command_index = -1;
157 for(int i = 0; command_index == -1 && i < COMMAND_ORDER.length; i++) {
158 if(COMMAND_ORDER[i].equals(target_element_name)) {
159 command_index = i;
160 }
161 }
162 ///ystem.err.println("Command index is: " + command_index);
163 // Now move forward, checking for existing elements in each of the preceeding command orders.
164 int preceeding_index = command_index - 1;
165 ///ystem.err.println("Searching before the target command.");
166 while(preceeding_index >= 0) {
167 matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[preceeding_index]);
168 // If we've found a match
169 if(matching_elements.getLength() > 0) {
170 // We add after the last element
171 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
172 // 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)
173 Node sibling_element = matched_element.getNextSibling();
174 if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
175 Element newline_element = document.createElement(NEWLINE_ELEMENT);
176 document_element.insertBefore(newline_element, sibling_element);
177 }
178 return sibling_element; // Note that this may be null
179 }
180 preceeding_index--;
181 }
182 // If all that fails, we now move backwards through the commands
183 int susceeding_index = command_index + 1;
184 ///ystem.err.println("Searching after the target command.");
185 while(susceeding_index < COMMAND_ORDER.length) {
186 matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[susceeding_index]);
187 // If we've found a match
188 if(matching_elements.getLength() > 0) {
189 // We add before the first element
190 Element matched_element = (Element) matching_elements.item(0);
191 // 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)
192 Node sibling_element = matched_element.getPreviousSibling();
193 if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
194 Element newline_element = document.createElement(NEWLINE_ELEMENT);
195 document_element.insertBefore(newline_element, sibling_element);
196 }
197 return sibling_element; // Note that this may be null
198 }
199 susceeding_index++;
200 }
201 // Well. Apparently there are no other commands in this collection configuration. So append away...
202 return null;
203 }
204
205 static public String toString(Element command_element, boolean show_extracted_namespace) {
206 String command_element_name = command_element.getNodeName();
207 if(command_element_name.equals(CLASSIFY_ELEMENT)) {
208 return classifyToString(command_element, show_extracted_namespace);
209 }
210 else if(command_element_name.equals(FORMAT_ELEMENT)) {
211 return formatToString(command_element, show_extracted_namespace);
212 }
213 else if(command_element_name.equals(INDEXES_ELEMENT)) {
214 return indexesToString(command_element, show_extracted_namespace);
215 }
216 else if(command_element_name.equals(INDEX_DEFAULT_ELEMENT)) {
217 return indexDefaultToString(command_element, show_extracted_namespace);
218 }
219 else if(command_element_name.equals(LANGUAGES_ELEMENT)) {
220 return languagesToString(command_element);
221 }
222 else if(command_element_name.equals(LANGUAGE_DEFAULT_ELEMENT)) {
223 return languageDefaultToString(command_element);
224 }
225 else if (command_element_name.equals(LANGUAGE_METADATA_ELEMENT)) {
226 return languageMetadataToString(command_element, show_extracted_namespace);
227 }
228 else if(command_element_name.equals(LEVELS_ELEMENT)) {
229 return levelsToString(command_element);
230 }
231 else if(command_element_name.equals(LEVEL_DEFAULT_ELEMENT)) {
232 return levelDefaultToString(command_element);
233 }
234 else if(command_element_name.equals(COLLECTIONMETADATA_ELEMENT)) {
235 return metadataToString(command_element, show_extracted_namespace);
236 }
237 else if(command_element_name.equals(COLLECTIONMETADATA_CREATOR_ELEMENT)) {
238 return metadataToString(command_element, show_extracted_namespace);
239 }
240 else if(command_element_name.equals(COLLECTIONMETADATA_MAINTAINER_ELEMENT)) {
241 return metadataToString(command_element, show_extracted_namespace);
242 }
243 else if(command_element_name.equals(COLLECTIONMETADATA_PUBLIC_ELEMENT)) {
244 return metadataToString(command_element, show_extracted_namespace);
245 }
246 else if (command_element_name.equals(BUILDTYPE_ELEMENT)) {
247 return metadataToString(command_element, show_extracted_namespace);
248 }
249 else if(command_element_name.equals(PLUGIN_ELEMENT)) {
250 return pluginToString(command_element, show_extracted_namespace);
251 }
252// else if(command_element_name.equals(SEARCHTYPE_ELEMENT)) {
253// return searchtypeToString(command_element);
254// }
255 else if(command_element_name.equals(SUBCOLLECTION_ELEMENT)) {
256 return subcollectionToString(command_element, show_extracted_namespace);
257 }
258 else if(command_element_name.equals(SUBCOLLECTION_DEFAULT_INDEX_ELEMENT)) {
259 return subcollectionDefaultIndexToString(command_element);
260 }
261 else if(command_element_name.equals(SUBCOLLECTION_INDEXES_ELEMENT)) {
262 return subcollectionIndexesToString(command_element);
263 }
264 else if(command_element_name.equals(SUPERCOLLECTION_ELEMENT)) {
265 return supercollectionToString(command_element);
266 }
267 else if(command_element_name.equals(UNKNOWN_ELEMENT)) {
268 return unknownToString(command_element);
269 }
270 return "";
271 }
272
273 /** 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.
274 * @param tokenizer a CommandTokenizer based on the unconsumed portion of a command string
275 * @return a HashMap containing the arguments parsed
276 */
277 static public HashMap parseArguments(CommandTokenizer tokenizer) {
278 HashMap arguments = new HashMap();
279 String name = null;
280 String value = null;
281 while(tokenizer.hasMoreTokens() || name != null) {
282 // First we retrieve a name if we need one.
283 if(name == null) {
284 name = tokenizer.nextToken();
285 }
286 // Now we attempt to retrieve a value
287 if(tokenizer.hasMoreTokens()) {
288 value = tokenizer.nextToken();
289 // 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.
290 if(value.startsWith(StaticStrings.MINUS_CHARACTER)) {
291 arguments.put(name, null);
292 name = value;
293 }
294 // Otherwise we have a typical name->value pair ready to go
295 else {
296 arguments.put(name, value);
297 name = null;
298 }
299 }
300 // Otherwise its a binary flag
301 else {
302 arguments.put(name, null);
303 name = null;
304 }
305 }
306 return arguments;
307 }
308
309 /** Gives the preferred ordering of commands */
310 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};
311
312 /** ************************** Public Data Members ***************************/
313
314 /** ************************** Private Data Members ***************************/
315
316 private File collect_cfg_file;
317
318 /** ************************** Public Methods ***************************/
319
320 public CollectionConfiguration(File collect_cfg_file)
321 {
322 this.collect_cfg_file = collect_cfg_file;
323 // parse the XML template
324 document = XMLTools.parseXMLFile("xml/CollectionConfig.xml", true);
325 parse(collect_cfg_file);
326
327 }
328
329 /** This debug facility shows the currently loaded collect.cfg or CollectConfig.xml file as a DOM tree. */
330 public void display() {
331 JDialog dialog = new JDialog(Gatherer.g_man, "Collection Configuration", false);
332 dialog.setSize(400,400);
333 JPanel content_pane = (JPanel) dialog.getContentPane();
334 final DOMTree tree = new DOMTree(document);
335 JButton refresh_button = new GLIButton("Refresh Tree");
336 refresh_button.addActionListener(new ActionListener() {
337 public void actionPerformed(ActionEvent event) {
338 tree.setDocument(document);
339 }
340 });
341 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
342 content_pane.setLayout(new BorderLayout());
343 content_pane.add(new JScrollPane(tree), BorderLayout.CENTER);
344 content_pane.add(refresh_button, BorderLayout.SOUTH);
345 dialog.setVisible(true);
346 }
347
348
349 public Element getCreator() {
350 Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_CREATOR_ELEMENT, null, null);
351 element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_CREATOR_STR);
352 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
353 return element;
354 }
355
356 public Element getDocumentElement() {
357 return document.getDocumentElement();
358 }
359
360 public File getFile() {
361 return collect_cfg_file;
362 }
363
364 /** Retrieve or create the languages Element. */
365 public Element getLanguages() {
366 return getOrCreateElementByTagName(LANGUAGES_ELEMENT, null, null);
367 }
368
369 public Element getLanguageMetadata() {
370 return getOrCreateElementByTagName(LANGUAGE_METADATA_ELEMENT, null, null);
371 }
372
373 public Element getLevels() {
374 return getOrCreateElementByTagName(LEVELS_ELEMENT, null, null);
375 }
376
377 public Element getMaintainer() {
378 Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_MAINTAINER_ELEMENT, null, null);
379 element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_MAINTAINER_STR);
380 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
381 return element;
382 }
383
384 /** 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. */
385 public Element getMGIndexes() {
386 return getOrCreateElementByTagName(INDEXES_ELEMENT, MGPP_ATTRIBUTE, FALSE_STR);
387 }
388
389 public Element getMGPPIndexes() {
390 return getOrCreateElementByTagName(INDEXES_ELEMENT, MGPP_ATTRIBUTE, TRUE_STR);
391 }
392
393 public Element getPublic() {
394 Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_PUBLIC_ELEMENT, null, null);
395 element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_PUBLIC_STR);
396 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
397 return element;
398 }
399
400 public Element getBuildType() {
401 Element element = getOrCreateElementByTagName(BUILDTYPE_ELEMENT, null, null);
402 element.setAttribute(NAME_ATTRIBUTE, BUILDTYPE_STR);
403 element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
404 return element;
405
406 }
407
408 /** Retrieve or create the subindexes Element. */
409 public Element getSubIndexes() {
410 return getOrCreateElementByTagName(SUBCOLLECTION_INDEXES_ELEMENT, null, null);
411 }
412
413 /** Retrieve or create the supercollections Element. */
414 public Element getSuperCollection() {
415 return getOrCreateElementByTagName(SUPERCOLLECTION_ELEMENT, null, null);
416 }
417
418 public boolean ready() {
419 return document != null;
420 }
421
422 public void save() {
423 if(collect_cfg_file.exists()) {
424 File original_file = new File(collect_cfg_file.getParentFile(), COLLECT_CFG);
425 File backup_file = new File(collect_cfg_file.getParentFile(), "collect.bak");
426 if(backup_file.exists()) {
427 backup_file.delete();
428 }
429 if(!original_file.renameTo(backup_file)) {
430 DebugStream.println("Can't rename collect.cfg");
431 }
432 }
433
434 try {
435 OutputStream ostream = new FileOutputStream(collect_cfg_file);
436 Writer file_writer = new OutputStreamWriter(ostream, ENCODING);
437 //FileWriter file_writer = new FileWriter(collect_cfg_file, false);
438 BufferedWriter buffered_writer = new BufferedWriter(file_writer);
439 Element collect_config_element = document.getDocumentElement();
440 NodeList command_elements = collect_config_element.getChildNodes();
441 boolean just_wrote_newline = false; // Prevent two or more newlines in a row
442 for(int i = 0; i < command_elements.getLength(); i++) {
443 Node command_node = command_elements.item(i);
444 if(command_node instanceof Element) {
445 Element command_element = (Element) command_node;
446 // The only thing left are NewLine elements
447 if(command_element.getNodeName().equals(NEWLINE_ELEMENT) && !just_wrote_newline) {
448 buffered_writer.newLine();
449 just_wrote_newline = true;
450 }
451 // 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)
452 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)){
453 String command;
454 // format statements we write out with ex. still present
455 if (command_element.getNodeName().equals(FORMAT_ELEMENT)) {
456 command = toString(command_element, true);
457 } else {
458 command = toString(command_element, false);
459 }
460 if(command != null && command.length()> 0 ) {
461 write(buffered_writer, command);
462 buffered_writer.newLine();
463 just_wrote_newline = false;
464 }
465 }
466 }
467 }
468 buffered_writer.close();
469
470 // If we're using a remote Greenstone server, upload the new collect.cfg file
471 if (Gatherer.isGsdlRemote) {
472 String collection_name = Gatherer.c_man.getCollection().getName();
473 RemoteGreenstoneServer.uploadCollectionFile(collection_name, collect_cfg_file);
474 }
475 }
476 catch (Exception exception) {
477 DebugStream.println("Error in CollectionConfiguration.save(boolean): " + exception);
478 DebugStream.printStackTrace(exception);
479 }
480
481 }
482
483 /** ************************** Private Methods ***************************/
484
485 static private String classifyToString(Element command_element, boolean show_extracted_namespace)
486 {
487 StringBuffer text = new StringBuffer(CLASSIFY_STR);
488 text.append(TAB_CHARACTER);
489 text.append(command_element.getAttribute(TYPE_ATTRIBUTE));
490 text.append(SPACE_CHARACTER);
491 NodeList option_elements = command_element.getElementsByTagName(OPTION_ELEMENT);
492 int option_elements_length = option_elements.getLength();
493 for(int j = 0; j < option_elements_length; j++) {
494 Element option_element = (Element) option_elements.item(j);
495 if(option_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
496 text.append(StaticStrings.MINUS_CHARACTER);
497 text.append(option_element.getAttribute(NAME_ATTRIBUTE));
498 String value_str = XMLTools.getValue(option_element);
499
500 // Convert metadata element names to internal names, and remove extracted metadata namespaces
501 if (value_str.length() > 0) {
502 StringTokenizer string_tokenizer = new StringTokenizer(value_str, ",");
503 StringBuffer value_buffer = new StringBuffer();
504 while (string_tokenizer.hasMoreElements()) {
505 String raw_token = (String) string_tokenizer.nextElement();
506 String token = raw_token.trim();
507 MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(token);
508 if (metadata_element != null) {
509 token = metadata_element.getFullName();
510 }
511
512 if (token.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
513 token = token.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
514 }
515 value_buffer.append(token);
516 if (string_tokenizer.hasMoreElements()) {
517 value_buffer.append(",");
518 }
519 }
520 value_str = value_buffer.toString();
521 }
522
523 text.append(SPACE_CHARACTER);
524 if (value_str.indexOf(SPACE_CHARACTER) == -1) {
525 text.append(value_str);
526 }
527 else {
528 text.append(SPEECH_CHARACTER);
529 text.append(value_str);
530 text.append(SPEECH_CHARACTER);
531 }
532 value_str = null;
533 if(j < option_elements_length - 1) {
534 text.append(SPACE_CHARACTER);
535 }
536 }
537 option_element = null;
538 }
539 option_elements = null;
540 return text.toString();
541 }
542
543 static private String formatToString(Element command_element, boolean show_extracted_namespace) {
544 StringBuffer text = new StringBuffer(FORMAT_STR);
545 text.append(SPACE_CHARACTER);
546 text.append(command_element.getAttribute(NAME_ATTRIBUTE));
547 text.append(SPACE_CHARACTER);
548 String value_str = command_element.getAttribute(VALUE_ATTRIBUTE);
549 if(value_str.length() != 0) {
550 text.append(value_str);
551 }
552 else {
553 // Remember to encode format string to Greenstone specification
554 value_str = Codec.transform(XMLTools.getValue(command_element), Codec.DOM_TO_GREENSTONE);
555 // Remove any references to a namespace for extracted metadata
556 if (!show_extracted_namespace) {
557 String match_string = "\\[" + MetadataSetManager.EXTRACTED_METADATA_NAMESPACE + "\\.";
558 value_str = value_str.replaceAll(match_string, "[");
559 }
560
561 text.append(SPEECH_CHARACTER);
562 text.append(value_str);
563 text.append(SPEECH_CHARACTER);
564 }
565 value_str = null;
566 return text.toString();
567 }
568
569 /** Retrieve or create the indexes Element. */
570 static private Element getOrCreateElementByTagName(String name, String conditional_attribute, String required_value) {
571 Element document_element = document.getDocumentElement();
572 NodeList elements = document_element.getElementsByTagName(name);
573 int elements_length = elements.getLength();
574 if(elements_length > 0) {
575 if(conditional_attribute == null) {
576 document_element = null;
577 return (Element) elements.item(0);
578 }
579 else {
580 for(int i = 0; i < elements_length; i++) {
581 Element element = (Element) elements.item(i);
582 if(element.getAttribute(conditional_attribute).equals(required_value)) {
583 document_element = null;
584 return element;
585 }
586 element = null;
587 }
588 }
589 }
590 // Create the element
591 Element element = document.createElement(name);
592 // If there was a property set it
593 if(conditional_attribute != null) {
594 element.setAttribute(conditional_attribute, required_value);
595 }
596 Node target_node = findInsertionPoint(element);
597 if(target_node != null) {
598 document_element.insertBefore(element, target_node);
599 }
600 else {
601 document_element.appendChild(element);
602 }
603 document_element = null;
604 return element;
605 }
606
607 static private String indexesToString(Element command_element, boolean show_extracted_namespace) {
608 boolean comment_only = false;
609 StringBuffer text = new StringBuffer("");
610 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
611 text.append("#");
612 comment_only = true;
613 }
614 text.append(INDEX_STR);
615 text.append(TAB_CHARACTER);
616 if(!comment_only) {
617 text.append(TAB_CHARACTER);
618 }
619 NodeList index_elements = command_element.getElementsByTagName(INDEX_ELEMENT);
620 if (index_elements.getLength() == 0) { // no indexes
621 return "";
622 }
623 // For each index, write its level, a colon, then concatenate its child content elements into a single comma separated list
624 int index_elements_length = index_elements.getLength();
625 for(int j = 0; j < index_elements_length; j++) {
626 Element index_element = (Element) index_elements.item(j);
627 String level_str = index_element.getAttribute(LEVEL_ATTRIBUTE);
628 if(level_str.length() > 0) {
629 text.append(level_str);
630 text.append(StaticStrings.COLON_CHARACTER);
631 }
632 NodeList content_elements = index_element.getElementsByTagName(CONTENT_ELEMENT);
633 int content_elements_length = content_elements.getLength();
634 // Don't output anything if no indexes are set
635 if(content_elements_length == 0) {
636 return null;
637 }
638 for(int k = 0; k < content_elements_length; k++) {
639 Element content_element = (Element) content_elements.item(k);
640 String name_str = content_element.getAttribute(NAME_ATTRIBUTE);
641 if(!show_extracted_namespace && name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
642 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
643 }
644 text.append(name_str);
645 name_str = null;
646 if(k < content_elements_length - 1) {
647 text.append(StaticStrings.COMMA_CHARACTER);
648 }
649 content_element = null;
650 }
651 if(j < index_elements_length - 1) {
652 text.append(SPACE_CHARACTER);
653 }
654 content_elements = null;
655 index_element = null;
656 }
657 index_elements = null;
658 return text.toString();
659 }
660
661 static private String indexDefaultToString(Element command_element, boolean show_extracted_namespace) {
662 StringBuffer text = new StringBuffer("");
663 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
664 text.append("#");
665 }
666 text.append(INDEX_DEFAULT_STR);
667 text.append(TAB_CHARACTER);
668 if (!command_element.getAttribute(LEVEL_ATTRIBUTE).equals("")) {
669 text.append(command_element.getAttribute(LEVEL_ATTRIBUTE));
670 text.append(StaticStrings.COLON_CHARACTER);
671 }
672 NodeList content_elements = command_element.getElementsByTagName(CONTENT_ELEMENT);
673 int content_elements_length = content_elements.getLength();
674 for(int j = 0; j < content_elements_length; j++) {
675 Element content_element = (Element) content_elements.item(j);
676 String name_str = content_element.getAttribute(NAME_ATTRIBUTE);
677 if(!show_extracted_namespace && name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
678 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
679 }
680 text.append(name_str);
681 name_str = null;
682 if(j < content_elements_length - 1) {
683 text.append(StaticStrings.COMMA_CHARACTER);
684 }
685 content_element = null;
686 }
687 content_elements = null;
688 return text.toString();
689 }
690
691 static private String languagesToString(Element command_element) {
692 StringBuffer text = new StringBuffer(LANGUAGES_STR);
693 text.append(TAB_CHARACTER);
694 // Retrieve all the languages and write them out in a space separated list
695 NodeList language_elements = command_element.getElementsByTagName(LANGUAGE_ELEMENT);
696 int language_elements_length = language_elements.getLength();
697 if(language_elements_length == 0) {
698 return null;
699 }
700 for(int j = 0; j < language_elements_length; j++) {
701 Element language_element = (Element) language_elements.item(j);
702 text.append(language_element.getAttribute(NAME_ATTRIBUTE));
703 if(j < language_elements_length - 1) {
704 text.append(SPACE_CHARACTER);
705 }
706 }
707 return text.toString();
708 }
709
710 static private String languageDefaultToString(Element command_element) {
711 StringBuffer text = new StringBuffer(LANGUAGE_DEFAULT_STR);
712 text.append(TAB_CHARACTER);
713 text.append(command_element.getAttribute(NAME_ATTRIBUTE));
714 return text.toString();
715 }
716
717 static private String languageMetadataToString(Element command_element, boolean show_extracted_namespace) {
718 StringBuffer text = new StringBuffer(LANGUAGE_METADATA_STR);
719 text.append(TAB_CHARACTER);
720 String name_str = command_element.getAttribute(NAME_ATTRIBUTE);
721 if(!show_extracted_namespace && name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
722 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
723 }
724 text.append(name_str);
725 return text.toString();
726 }
727
728 static private String levelsToString(Element command_element) {
729 StringBuffer text = new StringBuffer("");
730 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
731 text.append("#");
732 }
733 text.append(LEVELS_STR);
734 text.append(TAB_CHARACTER);
735 text.append(TAB_CHARACTER);
736 NodeList content_elements = command_element.getElementsByTagName(LEVEL_ELEMENT);
737 int content_elements_length = content_elements.getLength();
738 // Don't output anything if no levels are set.
739 if(content_elements_length == 0) {
740 return null;
741 }
742 for(int i = 0; i < content_elements_length; i++) {
743 Element content_element = (Element) content_elements.item(i);
744 text.append(content_element.getAttribute(NAME_ATTRIBUTE));
745 text.append(SPACE_CHARACTER);
746 }
747 return text.substring(0, text.length() - 1);
748 }
749
750 static private String levelDefaultToString(Element command_element) {
751 StringBuffer text = new StringBuffer("");
752 if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
753 text.append("#");
754 }
755 text.append(LEVEL_DEFAULT_STR);
756 text.append(TAB_CHARACTER);
757 text.append(command_element.getAttribute(NAME_ATTRIBUTE));
758 return text.toString();
759 }
760
761
762
763 static private String metadataToString(Element command_element, boolean text_value) {
764 // lets first check the value - if its empty, don't bother sticking it in the config file
765 String value_str = XMLTools.getValue(command_element);
766 if (value_str.equals("")) {
767 return "";
768 }
769 boolean special = false;
770
771 StringBuffer text = new StringBuffer("");
772 String name_str = command_element.getAttribute(NAME_ATTRIBUTE);
773 // 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.
774 if(name_str.equals(COLLECTIONMETADATA_MAINTAINER_STR)|| name_str.equals(BUILDTYPE_STR) ) {
775 text.append(name_str);
776 text.append(TAB_CHARACTER);
777 special = true;
778 }
779 else if (name_str.equals(COLLECTIONMETADATA_CREATOR_STR) || name_str.equals(COLLECTIONMETADATA_PUBLIC_STR) ) {
780 text.append(name_str);
781 text.append(TAB_CHARACTER);
782 text.append(TAB_CHARACTER);
783 special = true;
784 }
785 else {
786 text.append(COLLECTIONMETADATA_STR);
787 text.append(TAB_CHARACTER);
788 text.append(name_str);
789 text.append(SPACE_CHARACTER);
790 String language_str = command_element.getAttribute(LANGUAGE_ATTRIBUTE);
791 text.append(LBRACKET_CHARACTER);
792 text.append(LANGUAGE_ARGUMENT);
793 text.append(language_str);
794 text.append(RBRACKET_CHARACTER);
795 text.append(SPACE_CHARACTER);
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.