source: main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java@ 36305

Last change on this file since 36305 was 36305, checked in by kjdon, 21 months ago

major overhaul of this file. Tidied, reordered functions to make it easier to use, tried to get rid of as much duplicated code as possible, indented, etc. Sorry, will be impossible to see what changes I have made through svn diff.

File size: 107.6 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 * Methods to read collectionConfig.xml files into internal XML form, and write
9 * them back out again.
10 *
11 * Copyright (C) 1999 New Zealand Digital Library Project
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *########################################################################
27 */
28package org.greenstone.gatherer.cdm;
29
30import java.io.File;
31import java.util.ArrayList;
32import java.util.Arrays;
33import java.util.HashMap;
34import java.util.HashSet;
35import java.util.Iterator;
36import java.util.LinkedHashSet;
37import java.util.Map;
38import java.util.Set;
39import java.util.StringTokenizer;
40
41import org.greenstone.gatherer.DebugStream;
42import org.greenstone.gatherer.metadata.MetadataElement;
43import org.greenstone.gatherer.metadata.MetadataTools;
44import org.greenstone.gatherer.util.Codec;
45import org.greenstone.gatherer.util.StaticStrings;
46import org.greenstone.gatherer.util.Utility;
47import org.greenstone.gatherer.util.XMLTools;
48import org.w3c.dom.Document;
49import org.w3c.dom.Element;
50import org.w3c.dom.Node;
51import org.w3c.dom.NodeList;
52
53public class CollectionConfigXMLReadWrite
54{
55
56 // a list of all known top level elements; importOption and buildOPtion are commented out here as they are currently handled by unknown code
57 // /*StaticStrings.IMPORT_OPTION_STR, StaticStrings.BUILD_OPTION_STR,*/
58 static final private String known_element_names_array[] = { StaticStrings.SECURITY_STR, StaticStrings.METADATALIST_STR, StaticStrings.DISPLAYITEMLIST_STR, StaticStrings.FORMAT_STR, StaticStrings.SEARCH_STR, StaticStrings.INFODB_STR, StaticStrings.BROWSE_STR, StaticStrings.IMPORT_STR, StaticStrings.DISPLAY_STR, StaticStrings.REPLACELISTREF_STR, StaticStrings.REPLACELIST_STR, StaticStrings.SERVICE_RACK_LIST_ELEMENT };
59 static final private Set known_element_names = new HashSet(Arrays.asList(known_element_names_array));
60
61 /**
62 * *************************************************************************
63 * ******************************* The code in this file is used for
64 * greenstone 3 collection configuration, i.e., read ColletionConfig.xml
65 * into the internal DOM tree, and convert the internal DOM tree back to
66 * CollectionConfig.xml.
67 *
68 * The main methods are save - save internal DOM out to config file, and
69 * parse - read in the config file into the internal DOM tree.
70 *
71 * Methods named 'doXXXX' are for converting collectionConfig.xml into
72 * the internal configuration xml structure;
73 * Methods named 'convertXXXX' are for
74 * converting the internal configuration xml structure back to
75 * collectionConfig.xml.
76 ************************************************************************************************************ */
77
78 /** Generates a String version of the internal XML document */
79 static public String generateStringVersion(Document doc)
80 {
81 return XMLTools.xmlNodeToString(doc);
82 }
83
84
85 // From collectionConfig.xml to internal structure:add 'ex.' namespace (if none).
86 // From internal structure to collectionConfig.xml:always peel off 'ex.' namespace (if any), except for format statement
87
88 //This method parses 'xml_file_doc' into 'dOc'
89 static public void parse(File xml_file, Document dOc)
90 {
91
92 Document xml_file_doc = XMLTools.parseXMLFile(xml_file);
93 Element fromElement = xml_file_doc.getDocumentElement();
94 Element toElement = dOc.getDocumentElement();
95
96 // security element.
97 doSecurity(dOc, fromElement);
98
99 // metadataList - creator, maintainer, public, plus any custom metadata
100 doMetadataList(dOc, fromElement);
101
102 // top level display items
103 doDisplayItemList(dOc, fromElement);
104
105 // global format
106 doGlobalFormat(dOc, fromElement);
107 // infodb type
108 doDatabaseType(dOc, fromElement);
109
110 // searching. <search> index, level, subcolls etc
111 Node searchNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.SEARCH_STR, 0);
112 // return buildtype here as we use it later
113 String buildtype = doBuildType(dOc, (Element)searchNode);
114 if (buildtype.equalsIgnoreCase("mg")) {
115
116 doIndexes(dOc, searchNode, true);
117 }
118 else {
119
120 doIndexes(dOc, searchNode, false);
121 }
122
123 if(buildtype.equalsIgnoreCase("solr") || buildtype.equalsIgnoreCase("lucene")) {
124 doSorts(dOc, searchNode);
125 doDefaultSort(dOc, searchNode);
126 if (buildtype.equalsIgnoreCase("solr")) {
127 doFacets(dOc, searchNode);
128 }
129 // lucene will only have sort elements
130 }
131
132 doDefaultIndex(dOc, searchNode);
133 doDefaultLevel(dOc, searchNode);
134 doLevel(dOc, searchNode);
135 doIndexOption(dOc, searchNode);
136 doSubcollection(dOc, searchNode);
137 doIndexSubcollection(dOc, searchNode);
138 doIndexLanguage(dOc, searchNode);
139 doDefaultIndexLanguage(dOc, searchNode);
140 doLanguageMetadata(dOc, searchNode);
141 doSearchType(dOc, searchNode);
142 doSearchFormat(dOc, searchNode);
143
144 // importing
145 Node importNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.IMPORT_STR, 0);
146 if (importNode == null) {
147
148 System.out.println("There is no 'import' element.");
149 } else {
150
151 // plugins + plugout
152 doPluginsAndPlugout(dOc, importNode);
153
154 }
155
156 // import and build options are handled by unknown code at present,
157 // as can't be used in gli
158
159 // browsing
160
161 Node browseNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.BROWSE_STR, 0);
162 if (browseNode == null) {
163
164 System.out.println("There is no browse element.");
165 } else {
166 doClassifiers(dOc, browseNode);
167 }
168
169 // <display> - currently just has a format element?
170
171 doDisplayFormat(dOc, fromElement);
172
173 // lesser top level elements
174 doReplaceListRef(dOc, fromElement);
175 doReplaceList(dOc, fromElement);
176 doServiceRackList(dOc, fromElement);
177
178 // handle everything else
179 doUnknownElements(dOc, fromElement);
180
181 }
182
183 /** Saves the internal XML document out to the collectionConfig file */
184 static public void save(File collect_config_xml_file, Document doc)
185 {
186 Document collection_config_xml_document = convertInternalToCollectionConfig(doc);
187 String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR };
188 XMLTools.writeXMLFile(collect_config_xml_file, collection_config_xml_document, nonEscapingTagNames);
189 }
190
191
192 //Convert the internal XML DOM tree (dOc) into that of collectionConfig.xml (skeleton)
193 static private Document convertInternalToCollectionConfig(Document dOc)
194 {
195 //first parse an empty skeleton of xml config file
196 //The aim is to convert the internal structure into this skeleton
197 // This skeleton just has the CollectionConfig element and nothing else
198 Document skeleton = XMLTools.parseXMLFile("xml/CollectionConfig.xml", true);
199 convertSecurity(dOc, skeleton);
200 convertMetadataList(dOc, skeleton);
201 convertDisplayItemList(dOc, skeleton);
202 convertGlobalFormat(dOc, skeleton);
203 convertBuildType(dOc, skeleton); // creates the search elem
204 Element search = (Element) XMLTools.getChildByTagName(skeleton.getDocumentElement(), StaticStrings.SEARCH_STR);
205 String buildtype = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
206
207 if (buildtype.equals(StaticStrings.MG_STR)) {
208 // for mg, levels are included in index definition
209 convertIndexes(dOc, skeleton, search, true);
210 //Convert default index
211 convertDefaultIndex(dOc, skeleton, search, true);
212
213 } else {
214 convertIndexes(dOc, skeleton, search, false);
215 //Convert default index
216 convertDefaultIndex(dOc, skeleton, search, false);
217 // do the levels
218 convertLevels(dOc, skeleton, search);
219 convertDefaultLevel(dOc, skeleton, search);
220
221 }
222 // sortfields
223 if (buildtype.equals(StaticStrings.LUCENE_STR) || buildtype.equals(StaticStrings.SOLR_STR)) {
224 convertSorts(dOc, skeleton, search);
225 convertDefaultSort(dOc, skeleton, search);
226
227 }
228 // facet fields
229 if (buildtype.equals(StaticStrings.SOLR_STR)) {
230 convertFacets(dOc, skeleton, search);
231
232 }
233
234 convertIndexOptions(dOc, skeleton, search);
235 convertSubcollectionIndexes(dOc, skeleton, search);
236 convertLanguages(dOc, skeleton, search);
237 convertSubcollection(dOc, skeleton, search);
238 convertSearchType(dOc, skeleton, search);
239 convertSearchFormat(dOc, skeleton, search);
240
241 convertDatabaseType(dOc, skeleton);
242 convertPluginsAndPlugout(dOc, skeleton);// creates import/pluginList/plugin* + plugout if present (flax)
243 convertClassifier(dOc, skeleton); //creates browse/classifier*
244 convertDisplayFormat(dOc, skeleton);
245 convertReplaceListRef(dOc, skeleton);
246 convertReplaceList(dOc, skeleton);
247 convertServiceRackList(dOc, skeleton);
248 convertUnknownElements(dOc, skeleton); // try to catch everything GLI doesn't know about
249
250 return skeleton;
251 }
252 ///////////////////////////////
253 // Security
254 //////////////////////////////
255
256 /** Copy security element from config file to internal DOM */
257 static private void doSecurity(Document to, Element from) {
258 Node securityNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.SECURITY_STR,0);
259 if (securityNode != null) {
260 Element new_security = XMLTools.duplicateElement(to, (Element) securityNode, true);
261 to.getDocumentElement().appendChild(new_security);
262 }
263 }
264
265 /** Write out security element from internal DOM to config file */
266 static private void convertSecurity(Document from, Document to)
267 {
268 Node security = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.SECURITY_STR, 0);
269 if (security != null)
270 {
271 Element to_element = XMLTools.duplicateElement(to, (Element) security, true);
272 to.getDocumentElement().appendChild(to_element);
273
274 }
275 }
276
277
278 ///////////////////////////////////////////////////////
279 // metadataList - includes creator, maintainer, public
280 ///////////////////////////////////////////////////////
281
282 /** handle metadataList from config file. creator, maintainer, public get their own special elements in internal DOM, the rest just get copied to a metadataList, unused by GLI */
283 static private void doMetadataList(Document to, Element from)
284 {
285 Element toElement = to.getDocumentElement();
286 Element new_metadataList = to.createElement(StaticStrings.METADATALIST_STR);
287
288 Node metadataListNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.METADATALIST_STR, 0);
289 if (metadataListNode == null) {
290 return;
291 }
292 NodeList metas = ((Element)metadataListNode).getElementsByTagName(StaticStrings.METADATA_STR);
293 int num_children = (metas == null) ? 0: metas.getLength();
294 if (num_children == 0) {
295 return;
296 }
297 boolean has_meta = false;
298 for (int i=0; i < num_children; i++) {
299 Element m = (Element) metas.item(i);
300
301 String name = m.getAttribute(StaticStrings.NAME_ATTRIBUTE);
302 if (name.equals(StaticStrings.COLLECTIONMETADATA_CREATOR_STR)) {
303 // creator
304 doSpecialMetadata(to, m, StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT);
305 } else if (name.equals(StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR)) {
306 // maintainer
307 doSpecialMetadata(to, m, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT);
308 } else if (name.equals(StaticStrings.COLLECTIONMETADATA_PUBLIC_STR)) {
309 // public
310 doSpecialMetadata(to, m, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT);
311 } else {
312 // custom metadata - we just store it in the metadataList
313 Element new_m = XMLTools.duplicateElement(to, m, true);
314 new_metadataList.appendChild(new_m);
315 has_meta = true;
316 }
317 }
318 if (has_meta) {
319 toElement.appendChild(new_metadataList);
320 }
321 }
322
323 /** convert a special metadata element into internal DOM element */
324 static private void doSpecialMetadata(Document to, Element meta, String new_element_name) {
325 String text = XMLTools.getNodeText(meta);
326
327 //If there is nothing to display, don't bother creating the element
328 if (text.equals("")) return;
329
330 Element new_element = to.createElement(new_element_name);
331 new_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, meta.getAttribute(StaticStrings.NAME_ATTRIBUTE));
332 new_element.setAttribute(StaticStrings.LANG_ATTRIBUTE, meta.getAttribute(StaticStrings.LANG_ATTRIBUTE));
333 new_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
334 new_element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
335 XMLTools.setNodeText(new_element, text);
336 to.getDocumentElement().appendChild(new_element);
337 } // doMetadataList
338
339 /** output metadataList to config file. Comprises any custom metadata stored in metadataList in internal DOM, plus creator, maintainer, public elements converted back to metadataList */
340 static private void convertMetadataList(Document from, Document to)
341 {
342 // if we have existing metadataList (not used by GLI, just copied over)
343 // then we use that otherwise we create a new one
344 Node existing_metadataList = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.METADATALIST_STR, 0);
345 Element metadataList;
346 if (existing_metadataList != null) {
347 metadataList = XMLTools.duplicateElement(to, (Element)existing_metadataList, true);
348 } else {
349 metadataList = to.createElement(StaticStrings.METADATALIST_STR);
350 }
351
352 to.getDocumentElement().appendChild(metadataList);
353
354 // creator, maintainer, public are stored differently in internal DOM, but
355 // go into the metadataList for the config file
356
357 String[] ele_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT };
358 String[] att_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_STR, StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR, StaticStrings.COLLECTIONMETADATA_PUBLIC_STR };
359 for (int i = 0; i < ele_names.length; i++) {
360
361 Element e = XMLTools.getNamedElement(from.getDocumentElement(), ele_names[i], StaticStrings.NAME_ATTRIBUTE, att_names[i]);
362 if (e == null)
363 {
364 continue;
365 }
366 String text = XMLTools.getNodeText(e);
367 Element metadata = to.createElement(StaticStrings.METADATA_STR);
368 metadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, att_names[i]);
369 metadata.setAttribute(StaticStrings.LANG_STR, StaticStrings.ENGLISH_LANGUAGE_STR);
370 XMLTools.setNodeText(metadata, text);
371 metadataList.appendChild(metadata);
372 }
373
374 }// convertMetadataList
375
376
377 ////////////////////////////////////////////////
378 // display items (top level)
379 ///////////////////////////////////////////////
380
381 /** processes the top level displayItemList, and adds them all as
382 CollectionMeta to the internal doc. */
383 static private void doDisplayItemList(Document to, Element from) {
384 Element toElement = to.getDocumentElement();
385 Node displayItemListNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.DISPLAYITEMLIST_STR, 0);
386 if (displayItemListNode == null) {
387 return;
388 }
389 NodeList displayItems = ((Element)displayItemListNode).getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
390 for (int i=0; i<displayItems.getLength(); i++) {
391 Element item = (Element) displayItems.item(i);
392 String name = item.getAttribute(StaticStrings.NAME_ATTRIBUTE);
393 String internal_name = name; // unless mentioned below
394 if (name.equals(StaticStrings.NAME_STR)) {
395 internal_name = StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR;
396 } else if (name.equals(StaticStrings.DESCRIPTION_STR)) {
397 internal_name = StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR;
398 } else if (name.equals(StaticStrings.ICON_STR)) {
399 internal_name = StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR;
400 } else if (name.equals(StaticStrings.SMALLICON_STR)) {
401 internal_name = StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR;
402 }
403
404 Element coll_meta = processSingleDisplayItem(to, item, internal_name, null);
405 if (coll_meta != null) {
406 toElement.appendChild(coll_meta);
407 }
408 }
409
410
411 }
412
413
414 // create a displayItemList for config file, from CollectionMetadata
415 static private void convertDisplayItemList(Document from, Document to)
416 {
417 Element displayItemList = to.createElement(StaticStrings.DISPLAYITEMLIST_STR);
418 Element destination = to.getDocumentElement();
419
420 // certain special collectionmeta elements should have different names
421 // as displayItems in the collectionConfig.xml than they do in memory
422 Map attributeMap = new HashMap(4);
423 attributeMap.put(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR, StaticStrings.DESCRIPTION_STR);
424 attributeMap.put(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR, StaticStrings.NAME_STR);
425 attributeMap.put(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR, StaticStrings.SMALLICON_STR);
426 attributeMap.put(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR, StaticStrings.ICON_STR);
427
428 NodeList e_list = from.getDocumentElement().getElementsByTagName(StaticStrings.COLLECTIONMETADATA_ELEMENT);
429 // if such elements don't exist, don't bother
430 if (e_list != null) {
431
432
433 for (int j = 0; j < e_list.getLength(); j++) {
434
435 Element e = (Element) e_list.item(j);
436 if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) {
437
438 continue;
439 }
440
441 String name_value = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
442 String name_mapping = (String) attributeMap.get(name_value);
443 if (name_mapping != null) {
444 name_value = name_mapping;
445 }
446 Element displayItem = constructDisplayItem(e, to, name_value);
447
448 displayItemList.appendChild(displayItem);
449 }
450
451 }
452 destination.appendChild(displayItemList);
453 }
454
455 //////////////////////////////////////////////
456 // global (top level) format
457 /////////////////////////////////////////////
458
459 static private void doGlobalFormat(Document to, Element from)
460 {
461 // look for a top level format element
462 Element fe = (Element) XMLTools.getChildByTagName(from, StaticStrings.FORMAT_STR);
463 to.getDocumentElement().appendChild(doFormat(to, fe, StaticStrings.GLOBAL_STR));
464 }
465
466 // convert global format statement
467 static private void convertGlobalFormat(Document from, Document to)
468 {
469 Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.GLOBAL_STR);
470
471 to.getDocumentElement().appendChild(convertFormat(to, e));
472
473 }
474
475
476 ////////////////////////////////////////////////
477 // database type = infodb type
478 ////////////////////////////////////////////////
479
480 static private void doDatabaseType(Document to, Element from) {
481
482 Node databaseNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.INFODB_STR, 0);
483 String databasetype_value = "gdbm";
484 if (databaseNode != null) {
485
486 databasetype_value = ((Element) databaseNode).getAttribute(StaticStrings.TYPE_ATTRIBUTE);//might be gdbm|jdbm|sqlite OR not yet set (in which case it should default to gdbm)
487 }
488
489 Element element = to.createElement(StaticStrings.DATABASETYPE_ELEMENT);
490 element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR);
491 element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
492 element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
493 element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
494
495 XMLTools.setNodeText(element, databasetype_value);
496
497 appendProperly(to.getDocumentElement(), element);
498
499 }
500 static private void convertDatabaseType(Document from, Document to)
501 {
502 Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.DATABASETYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR);
503 if (e == null) {
504
505 return;
506 }
507 String db = XMLTools.getNodeText(e);
508 Element dbtype = to.createElement(StaticStrings.INFODB_STR);
509 dbtype.setAttribute(StaticStrings.TYPE_ATTRIBUTE, db);
510 to.getDocumentElement().appendChild(dbtype);
511 }
512
513 // search *************************************************************
514
515 ///////////////////////////////////////////////////
516 // build type
517 //////////////////////////////////////////////////
518
519 static private String doBuildType(Document to, Element searchNode)
520 {
521
522 String buildtype = ((Element) searchNode).getAttribute(StaticStrings.TYPE_ATTRIBUTE);//might be mg|mgpp|lucene|solr
523
524
525
526 //construct 'BuildType' element
527 Element element = to.createElement(StaticStrings.BUILDTYPE_ELEMENT);
528 element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR);
529 element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
530 element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
531 element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
532
533 XMLTools.setNodeText(element, buildtype);
534 appendProperly(to.getDocumentElement(), element);
535 return buildtype;
536 }
537
538 /** This uses the buildtype element in internal DOM, and creates the search element in the config file output, with type set to the indexer type */
539 static private void convertBuildType(Document from, Document to)
540 {
541 Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.BUILDTYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR);
542 if (e == null)
543 {
544 return;
545 }
546 String indexer = XMLTools.getNodeText(e);
547 Element search = to.createElement(StaticStrings.SEARCH_STR);
548 search.setAttribute(StaticStrings.TYPE_ATTRIBUTE, indexer);
549 to.getDocumentElement().appendChild(search);
550 }
551
552
553
554
555 /////////////////////////////////////////////
556 // indexes
557 ////////////////////////////////////////////
558
559 /**This converts indexes and their displayItems - set is_mg_index to true if dealing with mg, as that has slightly different format to the rest. */
560 static private void doIndexes(Document to, Node searchNode, boolean is_mg_index)
561 {
562 doBaseSearchPartInternal(to, searchNode, StaticStrings.INDEXES_ELEMENT, StaticStrings.INDEX_ELEMENT, StaticStrings.INDEX_LOW_STR, SearchMeta.TYPE_INDEX, is_mg_index);
563 Element toElement = to.getDocumentElement();
564 Element indexes_element = (Element) XMLTools.getChildByTagName(toElement, StaticStrings.INDEXES_ELEMENT);
565 indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, (is_mg_index? StaticStrings.FALSE_STR:StaticStrings.TRUE_STR));
566
567
568 boolean creating_mg_index = !is_mg_index;
569 // create another set of <indexes> which will be used when user switches to/from MG
570 // i.e. we build a default index set for a start
571 Element other_indexes = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes>
572 other_indexes.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
573 other_indexes.setAttribute(StaticStrings.MGPP_ATTRIBUTE, (creating_mg_index? StaticStrings.FALSE_STR:StaticStrings.TRUE_STR));
574
575 //put the namespace '.ex' as prefix to the indexes
576 String[] index_strs = { StaticStrings.TEXT_STR, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT };
577 for (int i = 0; i < index_strs.length; i++) {
578
579 Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index>
580 if (creating_mg_index) {
581 index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
582 }
583 Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
584 content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]);
585 index_element.appendChild(content_element);
586
587 other_indexes.appendChild(index_element);
588
589 } // foreach fake index
590 toElement.appendChild(other_indexes);
591
592 } // doIndexes
593
594
595 //construct 'DefaultIndex' element in the internal structure from collectionConfig.xml
596 // TODO
597
598 static private void doDefaultIndex(Document to, Node searchNode)
599 {
600 Element toElement = to.getDocumentElement();
601 Element default_index_element = to.createElement(StaticStrings.INDEX_DEFAULT_ELEMENT);
602 default_index_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
603
604 Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);//defaultIndex
605 if (e == null) {
606
607 return;
608 }
609 String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
610
611 boolean old_index = false;
612 if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1) {
613
614 //The index is 'level:source tuplets' which is for mg. Take out 'level'
615 old_index = true;
616 default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
617 index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
618 }
619 else {
620
621 default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, "");
622 }
623
624 //Each index may have a list of comma-separated strings.
625 //split them into 'content' elements in the internal structure
626 StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
627 while (content_tokenizer.hasMoreTokens()) {
628
629 Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
630 String content_str = content_tokenizer.nextToken();
631 // 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.
632 if (content_str.indexOf(StaticStrings.NS_SEP) == -1) {
633
634 if (content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR))) {
635
636 // in this case, do nothing
637 }
638 else {
639
640 content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
641 }
642 }
643
644 content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
645 default_index_element.appendChild(content_element);
646 content_element = null;
647 }
648 appendProperly(toElement, default_index_element);
649 } //doDefaultIndex
650
651 static private void convertIndexes(Document from, Document to, Element search, boolean is_mg_index) {
652
653 convertBaseSearchPartInternal(from, to, search, StaticStrings.INDEXES_ELEMENT, StaticStrings.INDEX_ELEMENT, StaticStrings.INDEX_LOW_STR, SearchMeta.TYPE_INDEX, is_mg_index);
654 }
655 static private void convertDefaultIndex(Document from, Document to, Element search, boolean is_mg_index) {
656 convertBaseDefaultSearchPartInternal(from, to, search, StaticStrings.INDEX_DEFAULT_ELEMENT, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE, is_mg_index);
657 }
658
659
660
661 ////////////////////////////////////////////////////////
662 // sortfields and facets
663 ////////////////////////////////////////////////////////
664
665 static private void doSorts(Document to, Node searchNode) {
666 doBaseSearchPartInternal(to, searchNode, StaticStrings.SORTS_ELEMENT, StaticStrings.SORT_ELEMENT, StaticStrings.SORT_LOW_STR, SearchMeta.TYPE_SORT, false);
667 }
668 static private void convertSorts(Document from, Document to, Element search) {
669 convertBaseSearchPartInternal(from, to, search, StaticStrings.SORTS_ELEMENT, StaticStrings.SORT_ELEMENT, StaticStrings.SORT_LOW_STR, SearchMeta.TYPE_SORT, false);
670 }
671
672 // TODO
673 static private void doDefaultSort(Document to, Node searchNode)
674 {
675 Element toElement = to.getDocumentElement();
676
677 Element from_e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.SORT_DEFAULT_ELEMENT);
678 if (from_e == null) {
679 return; // there is no default
680 }
681 Element default_sort = to.createElement(StaticStrings.SORT_DEFAULT_ELEMENT);
682
683 default_sort.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
684 String name = from_e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
685 default_sort.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
686 appendProperly(toElement, default_sort);
687 }
688 static private void convertDefaultSort(Document from, Document to, Element search) {
689 // todo - should this be combined with index? or write own code?
690 convertBaseDefaultSearchPartInternal(from, to, search, StaticStrings.SORT_DEFAULT_ELEMENT, StaticStrings.SORT_DEFAULT_ELEMENT, false);
691 }
692 static private void doFacets(Document to, Node searchNode) {
693 doBaseSearchPartInternal(to, searchNode, StaticStrings.FACETS_ELEMENT, StaticStrings.FACET_ELEMENT, StaticStrings.FACET_LOW_STR, SearchMeta.TYPE_FACET, false);
694 }
695 static private void convertFacets(Document from, Document to, Element search) {
696 convertBaseSearchPartInternal(from, to, search, StaticStrings.FACETS_ELEMENT, StaticStrings.FACET_ELEMENT, StaticStrings.FACET_LOW_STR, SearchMeta.TYPE_FACET, false);
697 }
698 //////////////////////////////////////////////////
699 // levels
700 /////////////////////////////////////////////////
701
702
703 //Handle levels (document, section). In the internal structure, the element is called 'IndexOption'
704 static private void doLevel(Document to, Node searchNode)
705 {
706 Element toElement = to.getDocumentElement();
707 NodeList level_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LEVEL_ATTRIBUTE);
708 int level_nodes = level_children.getLength();
709
710 // it's mg, there's no level. So we construct a default 'indexOption' in the internal structure
711 if (level_nodes < 1)
712 {
713 Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
714 index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
715 index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR);
716
717 Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
718 option_element.setAttribute(StaticStrings.NAME_STR, StaticStrings.DOCUMENT_STR);
719 index_option.appendChild(option_element);
720
721 appendProperly(toElement, index_option);
722
723 return;
724 }
725
726 Element index_options = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
727 index_options.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
728 index_options.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR);
729
730 for (int i = 0; i < level_nodes; i++)
731 {
732 Element level_element = (Element) level_children.item(i);
733 String level_str = level_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
734 Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
735 option_element.setAttribute(StaticStrings.NAME_STR, level_str);
736 index_options.appendChild(option_element);
737
738 // Contructing 'searchmetadata' elements from the 'displayItem' of this 'level' element
739 doSearchDisplayItems(to, level_element, level_str, SearchMeta.TYPE_LEVEL);
740 //ArrayList searchmetadata_list = doDisplayItemListForType(to, level_element, StaticStrings.NAME_STR, level_str, SearchMeta.TYPE_LEVEL);
741 //appendArrayList(toElement, searchmetadata_list);
742 }
743 appendProperly(toElement, index_options);
744 } // doLevel
745
746 // For mg, this method is still called, but make it 'assigned=false'
747 static private void doDefaultLevel(Document to, Node searchNode)
748 {
749 Element toElement = to.getDocumentElement();
750 Element default_index_option = to.createElement(StaticStrings.INDEXOPTION_DEFAULT_ELEMENT);
751 default_index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVEL_DEFAULT_STR);
752
753 Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.LEVEL_DEFAULT_ELEMENT);
754 if (e != null) {
755
756 default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
757 String level = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
758 default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, level);
759 }
760 else {
761
762 //In the case of mg, there's no level! build a default one using 'assigned=false value=document'
763 default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
764 default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
765 }
766 appendProperly(toElement, default_index_option);
767 }
768
769 // Convert levels for mgpp/lucene. This method is called by converIndex() when mgpp indexer is detected.
770 static private void convertLevels(Document from, Document to, Element search)
771 {
772 Element source = from.getDocumentElement();
773 Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVELS_STR);
774 if (index_option == null)
775 {
776 return;
777 }
778 //Debugging purposes
779 if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
780 {
781 DebugStream.println("For mgpp, there should be an IndexOption element for levels which is assigned 'true': possible bug.");
782 }
783
784 NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
785 int num_elements = option_elements.getLength();
786
787 // Don't output anything if no indexes are set
788 if (num_elements == 0)
789 {
790 return;//
791 }
792
793 for (int k = 0; k < num_elements; k++)
794 {
795 Element e = (Element) option_elements.item(k);
796 String name_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
797 Element level_element = to.createElement(StaticStrings.LEVEL_ELEMENT);
798 level_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
799
800 //Now construct displayItem for this level element from searchmetadata
801 // ** here
802 ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, name_str, SearchMeta.TYPE_LEVEL);
803 //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.SEARCHMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str);
804
805 if (searchmetadata_list != null)
806 {
807
808 for (int j = 0; j < searchmetadata_list.size(); j++)
809 {
810 Element searchmetadata = (Element) searchmetadata_list.get(j);
811
812 Element displayItem = constructDisplayItem(searchmetadata, to);
813 level_element.appendChild(displayItem);
814 }
815 }
816 search.appendChild(level_element);
817 }
818 }
819 static private void convertDefaultLevel(Document from, Document to, Element search) {
820 Element source = from.getDocumentElement();
821 Element default_index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTION_DEFAULT_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVEL_DEFAULT_STR);
822 if (default_index_option == null)
823 {
824 return;
825 }
826 Element default_level = to.createElement(StaticStrings.LEVEL_DEFAULT_ELEMENT);
827 String default_level_str = default_index_option.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
828 default_level.setAttribute(StaticStrings.NAME_ATTRIBUTE, default_level_str);
829 search.appendChild(default_level);
830
831 }
832
833 ////////////////////////////////////////////////
834 // index options
835 /////////////////////////////////////////////////
836
837 //Handle 'indexOption' (i.e. casefold, stem etc). In the internal structure, the element is called 'IndexOption'
838 static private void doIndexOption(Document to, Node searchNode)
839 {
840 Element toElement = to.getDocumentElement();
841 //Node index_option_node = XMLTools.getChildByTagName(searchNode, StaticStrings.INDEXOPTION_STR);
842 //if (index_option_node == null)
843 //{
844 // return;
845 //}
846 //NodeList option_children = ((Element) index_option_node).getElementsByTagName(StaticStrings.OPTION_STR);
847 NodeList option_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEXOPTION_STR);
848 int num_options = option_children.getLength();
849
850 // for lucene, there is no 'indexOption'. We build a default 'indexOption' and 'assigned=false' in case the user switches to mg or mgpp
851 if (num_options < 1)
852 {
853 Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
854 index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
855 index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR);
856 String[] option_str = { StaticStrings.CASEFOLD_OPTION_STR, StaticStrings.STEM_OPTION_STR };
857 for (int i = 0; i < option_str.length; i++)
858 {
859 Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
860 option_element.setAttribute(StaticStrings.NAME_STR, option_str[i]);
861 index_option.appendChild(option_element);
862 }
863 appendProperly(toElement, index_option);
864 return;
865 }
866
867 Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
868 index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
869 index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR);
870
871 for (int i = 0; i < num_options; i++)
872 {
873 String option_str = ((Element) option_children.item(i)).getAttribute(StaticStrings.NAME_ATTRIBUTE);
874 Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
875 option_element.setAttribute(StaticStrings.NAME_STR, option_str);
876 index_option.appendChild(option_element);
877 }
878 appendProperly(toElement, index_option);
879 }
880
881
882 // Convert indexoptions for mg/mgpp/lucene. This method is called by convertIndex().
883 static private void convertIndexOptions(Document from, Document to, Element search)
884 {
885 Element source = from.getDocumentElement();
886 Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.INDEXOPTIONS_STR);
887 if (index_option == null)
888 {
889 return;
890 }
891 //Debugging purposes
892 if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) {
893
894 DebugStream.println("There should be an IndexOption element which is assigned 'true': possible bug.");
895
896 // for lucene and solr collections, don't write out stemming, casefolding and accentfolding indexOptions
897 // since they are not meant to be editable: stemming and casefolding are always on in lucene
898 String buildtype_value = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE); //might be mg|mgpp|lucene|solr
899 if(buildtype_value.equalsIgnoreCase("solr") || buildtype_value.equalsIgnoreCase("lucene")) {
900 return;
901 }
902 }
903 //Element indexOptionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
904 NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
905 int num_elements = option_elements.getLength();
906 // Don't output anything if no index
907 if (num_elements == 0)
908 {
909 return;//
910 }
911 //search.appendChild(indexOptionEl);
912
913 for (int k = 0; k < num_elements; k++)
914 {
915 Element e = (Element) option_elements.item(k);
916 String name_att = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
917 Element optionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
918 optionEl.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_att);
919 // default value?? on/off
920 //indexOptionEl.appendChild(optionEl);
921 search.appendChild(optionEl);
922 }
923
924 }
925
926 //////////////////////////////////////////
927 // subcollections
928 //////////////////////////////////////////
929
930 // Handling 'subcollection' elements in 'search' element of 'collectionConfig.xml'
931 static private void doSubcollection(Document to, Node searchNode)
932 {
933 Element toElement = to.getDocumentElement();
934 NodeList sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_STR);
935 int sub_nodes = sub_children.getLength();
936
937 // There is no subcollection
938 if (sub_nodes < 1)
939 {
940 return;
941 }
942
943 for (int i = 0; i < sub_nodes; i++)
944 {
945 Element sub_child = (Element) sub_children.item(i);
946 String name_str = sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
947 String filter_str = sub_child.getAttribute(StaticStrings.FILTER_ATTRIBUTE);
948
949 // filter_str is in the form '<! (if set)><metadata>/<metadata value>/<flag (if any)>'
950
951 int pos = filter_str.indexOf(StaticStrings.SEPARATOR_CHARACTER);
952 String meta_str = "";
953 String meta_value_str = "";
954 String clude_str = "";
955 String flag_str = "";
956 if (pos == -1)
957 {
958
959 meta_str = meta_value_str = filter_str;
960 clude_str = StaticStrings.INCLUDE_STR;
961 }
962 else
963 {
964 clude_str = StaticStrings.INCLUDE_STR;
965 if (filter_str.startsWith(StaticStrings.EXCLAMATION_CHARACTER))
966 {
967 clude_str = StaticStrings.EXCLUDE_STR;
968 // Peel off "!"
969 filter_str = filter_str.substring(StaticStrings.EXCLAMATION_CHARACTER.length());
970 }
971
972 String[] strs = filter_str.split(StaticStrings.SEPARATOR_CHARACTER);
973 if (strs[0] != null && strs[0] != "")
974 {
975 meta_str = strs[0];
976 }
977 if (!meta_str.equals(StaticStrings.FILENAME_STR) && meta_str.indexOf(StaticStrings.NS_SEP) == -1)
978 {
979 meta_str = StaticStrings.EXTRACTED_NAMESPACE + meta_str;
980 }
981
982 if (strs[1] != null && strs[1] != "")
983 {
984 meta_value_str = strs[1];
985 }
986 if (strs.length > 2)
987 {
988 //This means there has been set a flag
989 if (strs[2] != null && strs[2] != "")
990 {
991 flag_str = strs[2];
992 }
993 }
994 }
995 Element subcollection_element = to.createElement(StaticStrings.SUBCOLLECTION_ELEMENT);
996 subcollection_element.setAttribute(StaticStrings.NAME_STR, name_str);
997 subcollection_element.setAttribute(StaticStrings.CONTENT_ATTRIBUTE, meta_str);
998 subcollection_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, clude_str);
999 if (flag_str != "")
1000 {
1001 subcollection_element.setAttribute(StaticStrings.OPTIONS_ATTRIBUTE, flag_str);
1002 }
1003 XMLTools.setNodeText(subcollection_element, meta_value_str);
1004
1005 toElement.appendChild(subcollection_element);
1006 }
1007 } // doSubCollection
1008
1009
1010 static private void convertSubcollection(Document from, Document to, Element search)
1011 {
1012 Element source = from.getDocumentElement();
1013 //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
1014 //Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
1015
1016 // Get the Subcollection element from the internal structure
1017 NodeList subcollection_elements = source.getElementsByTagName(StaticStrings.SUBCOLLECTION_ELEMENT);
1018 if (subcollection_elements == null)
1019 {
1020 return;
1021 }
1022 int subcollection_elements_length = subcollection_elements.getLength();
1023
1024 if (subcollection_elements_length == 0)
1025 { // no
1026 return;
1027 }
1028
1029 for (int j = 0; j < subcollection_elements_length; j++)
1030 {
1031
1032 Element e = (Element) subcollection_elements.item(j);
1033 if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
1034 {
1035 continue;
1036 }
1037 String content = e.getAttribute(StaticStrings.CONTENT_ATTRIBUTE);
1038 String name = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1039 String options = e.getAttribute(StaticStrings.OPTIONS_ATTRIBUTE);
1040 String type = e.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
1041 String text = XMLTools.getNodeText(e);
1042
1043 String filter = "";
1044 if (type.equals(StaticStrings.EXCLUDE_STR))
1045 {
1046 filter = StaticStrings.EXCLAMATION_CHARACTER;
1047 }
1048
1049 if (content.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && content.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
1050 {
1051 content = content.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
1052 }
1053 filter = filter + content + StaticStrings.SEPARATOR_CHARACTER + text;
1054 if (options != null && options != "")
1055 {
1056 filter = filter + StaticStrings.SEPARATOR_CHARACTER + options;
1057 }
1058 Element subcollection = to.createElement(StaticStrings.SUBCOLLECTION_STR);
1059 subcollection.setAttribute(StaticStrings.FILTER_ATTRIBUTE, filter);
1060 subcollection.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
1061
1062 search.appendChild(subcollection);
1063 }
1064 }
1065
1066 //Handle 'indexSubcollection' element of collectionConfig.xml, which is called 'SubcollectionIndexes' in the internal structure. These contain the subcollection indexes (i.e. the filter or filter combinations), and displayed words for the filter names.
1067 static private void doIndexSubcollection(Document to, Node searchNode)
1068 {
1069 Element toElement = to.getDocumentElement();
1070 NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT);
1071 int num_nodes = index_sub_children.getLength();
1072
1073 // there is no subcollection index
1074 if (num_nodes < 1)
1075 {
1076 return;
1077 }
1078
1079 Element subcollection_indexes = to.createElement(StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT);
1080
1081 for (int i = 0; i < num_nodes; i++)
1082 {
1083 Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);
1084 Element index_sub_child = (Element) index_sub_children.item(i);
1085 String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1086
1087 // name_str is in the form of comma separated strings, each of which is a subcollection filter name
1088 String[] filters = name_str.split(StaticStrings.COMMA_CHARACTER);
1089 for (int j = 0; j < filters.length; j++)
1090 {
1091
1092 Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
1093 content_element.setAttribute(StaticStrings.NAME_STR, filters[j]);
1094 index_element.appendChild(content_element);
1095 }
1096 subcollection_indexes.appendChild(index_element);
1097
1098 // Contructing 'searchmetadata' elements from the 'displayItem' of this 'indexSubcollection' element
1099 doSearchDisplayItems(to, index_sub_child, name_str, SearchMeta.TYPE_PARTITION);
1100 //ArrayList searchmetadata_list = doDisplayItemListForType(to, index_sub_child, StaticStrings.NAME_STR, name_str, SearchMeta.TYPE_PARTITION); // todo should be name_str???
1101 //appendArrayList(toElement, searchmetadata_list);
1102 }
1103 appendProperly(toElement, subcollection_indexes);
1104 } // doIndexSubCollection
1105
1106 static private void convertSubcollectionIndexes(Document from, Document to, Element search)
1107 {
1108 Element source = from.getDocumentElement();
1109 //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
1110 //Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
1111
1112 // Get the SubcollectionIndexes element from the internal structure
1113 Element subcollection_indexes = (Element) XMLTools.getChildByTagName(source, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT);
1114 if (subcollection_indexes == null)
1115 {
1116 return;
1117 }
1118 NodeList index_elements = subcollection_indexes.getElementsByTagName(StaticStrings.INDEX_ELEMENT);
1119 int index_elements_length = index_elements.getLength();
1120
1121 if (index_elements_length == 0)
1122 { // no indexes
1123 return;
1124 }
1125
1126 for (int j = 0; j < index_elements_length; j++)
1127 {
1128 Element index_element = (Element) index_elements.item(j);
1129 if (index_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
1130 {
1131 continue;
1132 }
1133
1134 Element index = to.createElement(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT);
1135
1136 String index_value = "";
1137
1138 NodeList content_elements = index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
1139 int content_elements_length = content_elements.getLength();
1140
1141 for (int k = 0; k < content_elements_length; k++)
1142 {
1143 Element content_element = (Element) content_elements.item(k);
1144 if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
1145 {
1146 continue;
1147 }
1148 String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1149 index_value += name_str;
1150 // Make it comma separated string
1151 if (k < content_elements_length - 1)
1152 {
1153 index_value += StaticStrings.COMMA_CHARACTER;
1154 }
1155 content_element = null;
1156 }//for loop ends
1157
1158 index.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_value);
1159
1160 // Now constructing 'displayItem' element for this 'indexSubcollection' element
1161 // from the searchmetadata element
1162 // *** here
1163 ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, index_value, SearchMeta.TYPE_PARTITION);
1164 //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, index_value);
1165
1166 if (searchmetadata_list != null)
1167 {
1168
1169 for (int k = 0; k < searchmetadata_list.size(); k++)
1170 {
1171 Element searchmetadata = (Element) searchmetadata_list.get(k);
1172 if (searchmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
1173 {
1174 continue;
1175 }
1176 Element displayItem = constructDisplayItem(searchmetadata, to);
1177 index.appendChild(displayItem);
1178 }
1179 }
1180
1181 search.appendChild(index);
1182
1183 } //for loop ends
1184 }
1185
1186 ///////////////////////////////////////////////
1187 // language partitions
1188 //////////////////////////////////////////////
1189
1190 //Handle 'indexLanguage' element of collectionConfig.xml, which is called 'Languages' in the internal structure. These contain the language indexes, and displayed words for those language index names.
1191 static private void doIndexLanguage(Document to, Node searchNode)
1192 {
1193 Element toElement = to.getDocumentElement();
1194 NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LANGUAGE_INDEX_ELEMENT);
1195 int num_nodes = index_sub_children.getLength();
1196
1197 // there is no subcollection index
1198 if (num_nodes < 1)
1199 {
1200 return;
1201 }
1202
1203 Element language_indexes = to.createElement(StaticStrings.LANGUAGES_ELEMENT);
1204
1205 for (int i = 0; i < num_nodes; i++)
1206 {
1207 Element language_element = to.createElement(StaticStrings.LANGUAGE_ELEMENT);
1208 Element index_sub_child = (Element) index_sub_children.item(i);
1209 String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1210 language_element.setAttribute(StaticStrings.NAME_STR, name_str);
1211 language_indexes.appendChild(language_element);
1212
1213 // Contructing 'searchmetadata' elements from the 'displayItem' of this 'indexLanguage' element
1214 doSearchDisplayItems(to, index_sub_child, name_str, SearchMeta.TYPE_LANGUAGE);
1215 }
1216 toElement.appendChild(language_indexes);
1217 } //doIndexLanguage
1218
1219
1220 static private void doDefaultIndexLanguage(Document to, Node searchNode)
1221 {
1222 Element toElement = to.getDocumentElement();
1223 String elementNameFrom = StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT;
1224 String elementNameTo = StaticStrings.LANGUAGE_DEFAULT_ELEMENT;
1225 Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom);
1226 if (from_element == null) return;
1227
1228 Element to_element = to.createElement(elementNameTo);
1229
1230 String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE);
1231 to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
1232 to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
1233
1234 toElement.appendChild(to_element);
1235 }
1236
1237 // Handling <languageMetadata> in collectionConfig.xml ('elementNameFrom'); in the internal structure, it is called 'LanguageMetadata' ('elementNameTo').
1238 // Converting from collectionConfig.xml to the internal xml structure.
1239 static private void doLanguageMetadata(Document to, Node searchNode)
1240 {
1241 Element toElement = to.getDocumentElement();
1242 String elementNameFrom = StaticStrings.LANGUAGE_METADATA_ELEMENT_STR;
1243 String elementNameTo = StaticStrings.LANGUAGE_METADATA_ELEMENT;
1244 Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom);
1245 if (from_element == null) return;
1246
1247 Element to_element = to.createElement(elementNameTo);
1248
1249 String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE);
1250 if (name_str.indexOf(StaticStrings.NS_SEP) == -1) {
1251
1252 name_str = StaticStrings.EXTRACTED_NAMESPACE + name_str;
1253 }
1254 to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
1255 to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
1256
1257 toElement.appendChild(to_element);
1258 }
1259
1260 /** language partitions - convert from internal DOM to config file,
1261 does <language>, <defaultLanguage>, <languageMetadata> plus the <displayItem>s inside <language>
1262 */
1263 static private void convertLanguages(Document from, Document to, Element search)
1264 {
1265 Element source = from.getDocumentElement();
1266
1267 // Get the Languages element from the internal structure
1268 Element languages = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGES_ELEMENT);
1269 if (languages == null) return;
1270
1271 NodeList language_elements = languages.getElementsByTagName(StaticStrings.LANGUAGE_ELEMENT);
1272 int language_elements_length = language_elements.getLength();
1273
1274 if (language_elements_length == 0) return;
1275
1276 for (int j = 0; j < language_elements_length; j++) {
1277
1278 Element element = (Element) language_elements.item(j);
1279 if (element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
1280
1281 // Create indexLanguage element
1282 Element index_language = to.createElement(StaticStrings.LANGUAGE_INDEX_ELEMENT);
1283
1284 String name_str = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1285 index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
1286
1287 // Now constructing 'displayItem' element for this 'indexLanguage' element
1288 // from the searchmetadata element
1289
1290 ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, name_str, SearchMeta.TYPE_LANGUAGE);
1291
1292 if (searchmetadata_list != null) {
1293 for (int k = 0; k < searchmetadata_list.size(); k++) {
1294
1295 Element searchmetadata = (Element) searchmetadata_list.get(k);
1296 if (searchmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
1297
1298 Element displayItem = constructDisplayItem(searchmetadata, to);
1299 index_language.appendChild(displayItem);
1300 }
1301 }
1302
1303 search.appendChild(index_language);
1304
1305 } //for loop ends
1306
1307 // Convert DefaultLanguage
1308 // Get the DefaultLanguage element from the internal structure
1309 Element default_language = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_DEFAULT_ELEMENT);
1310 if (default_language != null) {
1311
1312 String lang_name = default_language.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1313 Element default_index_language = to.createElement(StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT);
1314 default_index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, lang_name);
1315 search.appendChild(default_index_language);
1316 }
1317 // Convert LanguageMetadata
1318 // Get the LanguageMetadata element from the internal structure
1319 Element language_metadata = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_METADATA_ELEMENT);
1320 if (language_metadata != null) {
1321
1322 String meta_name = language_metadata.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1323 Element language_meta = to.createElement(StaticStrings.LANGUAGE_METADATA_ELEMENT_STR);
1324 if (meta_name.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && meta_name.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) {
1325
1326 meta_name = meta_name.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
1327 }
1328 language_meta.setAttribute(StaticStrings.NAME_ATTRIBUTE, meta_name);
1329 search.appendChild(language_meta);
1330 }
1331 }
1332
1333 ////////////////////////////////////////////////
1334 // search types
1335 //////////////////////////////////////////////////
1336
1337 // Handling search types
1338 static private void doSearchType(Document to, Node searchNode)
1339 {
1340 NodeList type_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SEARCHTYPE_ELEMENT);
1341 int num_types = type_children.getLength();
1342 String searchtype_str = "";
1343 if (num_types < 1) {
1344
1345 // not defined yet, add in default
1346 searchtype_str = "plain,simpleform,advancedform";
1347 }
1348 else {
1349
1350 for (int i = 0; i < num_types; i++) {
1351
1352 Node e = type_children.item(i);
1353 String t = ((Element) e).getAttribute(StaticStrings.NAME_ATTRIBUTE);
1354 if (i > 0) {
1355
1356 searchtype_str += ",";
1357 }
1358 searchtype_str += t;
1359 }
1360 }
1361 searchtype_str = searchtype_str.trim();
1362
1363 // pretend its a format statement
1364 Element search_type_element = to.createElement(StaticStrings.FORMAT_STR);
1365 search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT);
1366 XMLTools.setNodeText(search_type_element, searchtype_str);
1367 appendProperly(to.getDocumentElement(), search_type_element);
1368
1369 }
1370
1371
1372 //Handle 'searchType' of collectionConfig.xml. In the internal structure, its also called 'searchType', eg. plain, form
1373 static private void convertSearchType(Document from, Document to, Element search)
1374 {
1375 Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT);//searchType
1376
1377 if (e == null) return;
1378
1379 String searchtype_str = XMLTools.getNodeText(e).trim();
1380
1381 String[] types = searchtype_str.split(",");
1382 for (int i = 0; i < types.length; i++) {
1383
1384 Element search_type_element = to.createElement(StaticStrings.SEARCHTYPE_ELEMENT);
1385 search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, types[i]);
1386 search.appendChild(search_type_element);
1387 }
1388 }
1389
1390 /////////////////////////////////////////////
1391 // search format
1392 ///////////////////////////////////////////////
1393
1394
1395 // Handling search format statement
1396 static private void doSearchFormat(Document to, Node searchNode)
1397 {
1398 // THere is currently just one format element for search. HOwever, need to check for old config files which used to have <format name="searchTypes">
1399 NodeList format_children = ((Element) searchNode).getElementsByTagName(StaticStrings.FORMAT_STR);
1400 int format_nodes = format_children.getLength();
1401 if (format_nodes < 1) return;
1402
1403 Element format = null;
1404 for (int i = 0; i < format_nodes; i++) {
1405
1406 Node e = format_children.item(i);
1407 if (e.hasAttributes() == false) {
1408
1409 //The format element for format statement has no attribute
1410 format = (Element) e;
1411 }
1412 }
1413 //format statement for search
1414 if (format != null) {
1415
1416 (to.getDocumentElement()).appendChild(doFormat(to, format, StaticStrings.SEARCH_STR));
1417 }
1418 }
1419
1420 //convert format statement for search
1421 static private void convertSearchFormat(Document from, Document to, Element search)
1422 {
1423 Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCH_STR);
1424
1425 search.appendChild(convertFormat(to, e));
1426
1427 }
1428
1429 ///////////////////////////////////////////
1430 // plugins
1431 ///////////////////////////////////////////
1432
1433 // Transform plugins (pluginListNode) of collectionConfig.xml into the internal structure (i.e. Document to)
1434 static private void doPluginsAndPlugout(Document to, Node importNode)
1435 {
1436 Element toElement = to.getDocumentElement();
1437 Node pluginListNode = XMLTools.getChildByTagNameIndexed((Element) importNode, StaticStrings.PLUGINLIST_STR, 0);
1438 if (pluginListNode == null) {
1439
1440 System.out.println("There is no pluginlist set.");
1441
1442 } else {
1443 NodeList plugin_children = ((Element) pluginListNode).getElementsByTagName(StaticStrings.PLUGIN_STR);
1444 int plugin_nodes = plugin_children.getLength();
1445
1446 if (plugin_nodes >= 1) {
1447 for (int i = 0; i < plugin_nodes; i++)
1448 {
1449 Element e = (Element) plugin_children.item(i);
1450 String str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1451 str = Utility.ensureNewPluginName(str);
1452 Element plugin_element = to.createElement(StaticStrings.PLUGIN_ELEMENT);
1453 plugin_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, str);
1454
1455 NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
1456
1457 for (int j = 0; j < option_children.getLength(); j++)
1458 {
1459 Element el = (Element) option_children.item(j);
1460 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1461 if (name_str.startsWith(StaticStrings.MINUS_CHARACTER))
1462 {
1463 name_str = name_str.substring(1);
1464 }
1465 String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
1466 Element option_element = null;
1467
1468 if (name_str.equals("") && !value_str.equals(""))
1469 {
1470 continue;
1471 }
1472
1473 option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
1474 option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
1475 if (name_str.equals(StaticStrings.RECPLUG_STR) && value_str.equals(StaticStrings.USE_METADATA_FILES_ARGUMENT))
1476 {
1477 continue; // ignore this option
1478 }
1479
1480 if (value_str != null)
1481 {
1482 // Remove any speech marks appended in strings containing whitespace
1483 if (value_str.startsWith(StaticStrings.SPEECH_CHARACTER) && value_str.endsWith(StaticStrings.SPEECH_CHARACTER))
1484 {
1485 value_str = value_str.substring(1, value_str.length() - 1);
1486 }
1487 if (name_str.equals(StaticStrings.METADATA_STR))
1488 {
1489 // 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.
1490 String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
1491 value_str = "";
1492 for (int k = 0; k <= values.length - 1; k++)
1493 {
1494 if (values[k].indexOf(StaticStrings.NS_SEP) == -1)
1495 {
1496 values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k];
1497 }
1498
1499 if (k < values.length - 1)
1500 {
1501 value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
1502
1503 }
1504 else
1505 {
1506 value_str = value_str + values[k];
1507 }
1508 }
1509 }
1510 }
1511 if (!name_str.equals(""))
1512 {
1513 option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
1514 }
1515 if (!value_str.equals(""))
1516 {
1517 XMLTools.setNodeText(option_element, value_str);
1518 }
1519 plugin_element.appendChild(option_element);
1520
1521 }
1522
1523 appendProperly(toElement, plugin_element);
1524 }
1525 } // if we had plugin nodes
1526 }// else plguins not null
1527
1528 // do the plugout element if there is one (flax)
1529 Node plugout = XMLTools.getChildByTagNameIndexed((Element) importNode, StaticStrings.PLUGOUT_ELEMENT, 0);
1530 if (plugout != null)
1531 {
1532 Element to_element = XMLTools.duplicateElement(to, (Element) plugout, true);
1533 toElement.appendChild(to_element);
1534 }
1535
1536
1537 }
1538
1539
1540 // Convert plugins in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to)
1541 static private void convertPluginsAndPlugout(Document from, Document to)
1542 {
1543 Element import_element = to.createElement(StaticStrings.IMPORT_STR);
1544 Element plugin_list_element = to.createElement(StaticStrings.PLUGINLIST_STR);
1545
1546 NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.PLUGIN_ELEMENT);
1547 int num_children = (children == null) ? 0 : children.getLength();
1548 if (num_children == 0)
1549 {
1550 return;
1551 }
1552
1553 for (int i = 0; i < num_children; i++)
1554 {
1555
1556 Element child = (Element) children.item(i);
1557 if (child.getAttribute(StaticStrings.SEPARATOR_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
1558 {
1559 continue;
1560 }
1561 if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
1562 {
1563 continue;
1564 }
1565
1566 String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
1567 Element plugin_element = to.createElement(StaticStrings.PLUGIN_STR);
1568 plugin_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str);
1569
1570 NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
1571 for (int j = 0; j < option_children.getLength(); j++)
1572 {
1573 Element el = (Element) option_children.item(j);
1574 if (!el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
1575 {
1576 continue;
1577 }
1578 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1579 String value_str = XMLTools.getNodeText(el);
1580
1581 if (name_str == null && value_str == null)
1582 {
1583 continue;
1584 }
1585 Element option_element = to.createElement(StaticStrings.OPTION_STR);
1586 if (name_str != null && name_str.equals(StaticStrings.METADATA_STR))
1587 {
1588
1589 // The metadata argument is the fully qualified name of a metadata element, so if it contains a namespace, remove the extracted metadata namespace as the build process doesn't know about it, but ONLY if it is not embedded metadata (e.g. ex.dc.*)
1590 String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
1591 value_str = "";
1592 for (int k = 0; k <= values.length - 1; k++)
1593 {
1594 if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
1595 {
1596 values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length());
1597 }
1598
1599 if (k < values.length - 1)
1600 {
1601 value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
1602 }
1603 else
1604 {
1605 value_str = value_str + values[k];
1606 }
1607 }
1608 }
1609
1610 if (!name_str.equals(""))
1611 {
1612 if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER))
1613 {
1614 name_str = StaticStrings.MINUS_CHARACTER + name_str;
1615 }
1616 option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
1617 }
1618
1619 if (!value_str.equals(""))
1620 {
1621 option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);
1622 }
1623
1624 plugin_element.appendChild(option_element);
1625 }//for loop ends
1626
1627 plugin_list_element.appendChild(plugin_element);
1628 }//for loop ends
1629
1630 import_element.appendChild(plugin_list_element);
1631
1632 //do the plugout element (used by building flax collections)
1633 Node plugout = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.PLUGOUT_ELEMENT, 0);
1634 if (plugout != null)
1635 {
1636 Element to_element = XMLTools.duplicateElement(to, (Element) plugout, true);
1637 import_element.appendChild(to_element);
1638 }
1639
1640 to.getDocumentElement().appendChild(import_element);
1641 } // convertPlugins
1642
1643
1644 // Browse**********************************************************
1645
1646 ////////////////////////////////////////////////////
1647 // classifiers
1648 ////////////////////////////////////////////////////
1649
1650
1651 //Handle classifiers
1652 static private void doClassifiers(Document to, Node browseNode)
1653 {
1654 Element toElement = to.getDocumentElement();
1655 NodeList classifier_children = ((Element) browseNode).getElementsByTagName(StaticStrings.CLASSIFIER_STR);
1656 int num_nodes = classifier_children.getLength();
1657
1658 if (num_nodes < 1)
1659 {
1660 return;
1661 }
1662
1663 for (int i = 0; i < num_nodes; i++)
1664 {
1665 Element e = (Element) classifier_children.item(i);
1666 String str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1667 Element classify_element = to.createElement(StaticStrings.CLASSIFY_ELEMENT);
1668 classify_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, str);
1669
1670 String options_str = "";
1671 NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
1672 for (int j = 0; j < option_children.getLength(); j++)
1673 {
1674 Element el = (Element) option_children.item(j);
1675 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1676 options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str));
1677 if (name_str.startsWith(StaticStrings.MINUS_CHARACTER))
1678 {
1679 name_str = name_str.substring(1);
1680 }
1681 String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
1682 options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str));
1683 Element option_element = null;
1684
1685 if (name_str.equals("") && !value_str.equals(""))
1686 {
1687 continue; //invalid condition
1688 }
1689
1690 option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
1691 option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
1692
1693 if (!name_str.equals(""))
1694 {
1695 option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
1696 }
1697
1698 if (!value_str.equals("") && name_str.equals(StaticStrings.METADATA_STR))
1699 {
1700 // 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.
1701 String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
1702 value_str = "";
1703 for (int k = 0; k <= values.length - 1; k++)
1704 {
1705 if (values[k].indexOf(StaticStrings.NS_SEP) == -1)
1706 {
1707 values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k];
1708 }
1709 else
1710 {
1711 MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(values[k]);
1712 if (metadata_element != null)
1713 {
1714 values[k] = metadata_element.getDisplayName();
1715 }
1716 }
1717 if (k < values.length - 1)
1718 {
1719 value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
1720 }
1721 else
1722 {
1723 value_str = value_str + values[k];
1724 }
1725 }
1726 }
1727
1728 if (value_str != null && !value_str.equals(""))
1729 {
1730 XMLTools.setNodeText(option_element, value_str);
1731 }
1732 classify_element.appendChild(option_element);
1733
1734 } // for each option
1735
1736 //format element for this classifier
1737 Element format = (Element) XMLTools.getChildByTagName(e, StaticStrings.FORMAT_STR);
1738 if (format != null)
1739 {
1740 classify_element.appendChild(doFormat(to, format, null));
1741 }
1742
1743 // Handling 'displayItem' element of this 'classifier' element - for now, just copy in and out so they don't get deleted
1744 NodeList di_children = e.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
1745
1746 XMLTools.duplicateElementList(to, classify_element, di_children, true);
1747
1748 appendProperly(toElement, classify_element);
1749 }
1750
1751 // default format statement for all classifiers
1752 Element default_classifier_format = (Element) XMLTools.getChildByTagName(browseNode, StaticStrings.FORMAT_STR);
1753
1754 to.getDocumentElement().appendChild(doFormat(to, default_classifier_format, StaticStrings.BROWSE_STR));
1755 } // doClassifiers
1756
1757 // Convert classify in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to)
1758 static private void convertClassifier(Document from, Document to)
1759 {
1760 Element browse_element = to.createElement(StaticStrings.BROWSE_STR);
1761 NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.CLASSIFY_ELEMENT);
1762
1763 int num_children = (children == null) ? 0 : children.getLength();
1764
1765 if (num_children == 0) return;
1766
1767 for (int i = 0; i < num_children; i++)
1768 {
1769
1770 Element child = (Element) children.item(i);
1771 if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
1772
1773 String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
1774 Element classifier_element = to.createElement(StaticStrings.CLASSIFIER_STR);
1775 classifier_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str);
1776
1777 NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
1778 for (int j = 0; j < option_children.getLength(); j++)
1779 {
1780 Element el = (Element) option_children.item(j);
1781 if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
1782
1783 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
1784 String value_str = XMLTools.getNodeText(el);
1785
1786 if (name_str == null && value_str == null) continue;
1787
1788 Element option_element = to.createElement(StaticStrings.OPTION_STR);
1789 if (name_str != null && name_str.equals(StaticStrings.METADATA_STR))
1790 {
1791
1792 // The metadata argument is the fully qualified name of a metadata element, so if it contains a namespace, remove the extracted metadata namespace as the build process doesn't know about it.
1793 String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
1794 value_str = "";
1795 for (int k = 0; k <= values.length - 1; k++)
1796 {
1797 if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
1798 {
1799 values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length());
1800 }
1801 else
1802 {
1803 MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(values[k]);
1804 if (metadata_element != null)
1805 {
1806 values[k] = metadata_element.getFullName();
1807 }
1808 }
1809 if (k < values.length - 1)
1810 {
1811 value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
1812 }
1813 else
1814 {
1815 value_str = value_str + values[k];
1816 }
1817 }
1818 }
1819
1820 if (!name_str.equals(""))
1821 {
1822 if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER))
1823 {
1824 name_str = StaticStrings.MINUS_CHARACTER + name_str;
1825 }
1826 option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
1827 }
1828
1829 if (!value_str.equals(""))
1830 {
1831 option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);
1832 }
1833
1834 classifier_element.appendChild(option_element);
1835 }
1836
1837 //format element for this classifier
1838 Element e = (Element) XMLTools.getChildByTagName(child, StaticStrings.FORMAT_STR);
1839
1840 if (e != null)
1841 {
1842 classifier_element.appendChild(convertFormat(to, e));
1843 }
1844
1845 // Handling 'displayItem' element of this 'classifier' element - for now, just copy in and out so they don't get deleted
1846 NodeList di_children = child.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
1847
1848 XMLTools.duplicateElementList(to, classifier_element, di_children, true);
1849 browse_element.appendChild(classifier_element);
1850 }
1851
1852 //convert default classifier format
1853 Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BROWSE_STR);
1854 browse_element.appendChild(convertFormat(to, e));
1855
1856 to.getDocumentElement().appendChild(browse_element);
1857 } // convertClassifier
1858
1859 // Display ********************************************************
1860
1861 static private void doDisplayFormat(Document to, Element from)
1862 {
1863 //display element in the xml file
1864 Element de = (Element) XMLTools.getChildByTagName(from, StaticStrings.DISPLAY_STR);
1865 if (de == null) return;
1866
1867 //format element in the display element
1868 Element fe = (Element) XMLTools.getChildByTagName(de, StaticStrings.FORMAT_STR);
1869
1870 to.getDocumentElement().appendChild(doFormat(to, fe, StaticStrings.DISPLAY_STR));
1871 }
1872
1873 //convert format statement for display of the documents
1874 static private void convertDisplayFormat(Document from, Document to)
1875 {
1876 Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DISPLAY_STR);
1877 if (e == null) return;
1878
1879 Element display = to.createElement(StaticStrings.DISPLAY_STR);
1880 display.appendChild(convertFormat(to, e));
1881 to.getDocumentElement().appendChild(display);
1882 }
1883
1884
1885
1886 // Other top level elements *****************************************
1887
1888
1889 ////////////////////////////////////////////////////
1890 // replaceList and replaceListRef
1891 ///////////////////////////////////////////////////
1892
1893 /*
1894 * replacelist currently not editable in GLI, just copy it in and back out
1895 * again
1896 */
1897 static private void doReplaceList(Document to, Element from)
1898 {
1899 Element toElement = to.getDocumentElement();
1900
1901 Node rl_element = XMLTools.getChildByTagName(from, StaticStrings.REPLACELIST_STR);
1902 if (rl_element == null) return;
1903
1904 Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
1905 toElement.appendChild(to_element);
1906 }
1907
1908 static private void convertReplaceList(Document from, Document to)
1909 {
1910 Element toElement = to.getDocumentElement();
1911
1912 Node rl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.REPLACELIST_STR);
1913 if (rl_element == null) return;
1914
1915 Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
1916 toElement.appendChild(to_element);
1917 }
1918
1919 static private void doReplaceListRef(Document to, Element from)
1920 {
1921 Element toElement = to.getDocumentElement();
1922
1923 NodeList replace_elements = from.getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
1924 XMLTools.duplicateElementList(to, toElement, replace_elements, true);
1925 }
1926
1927
1928 static private void convertReplaceListRef(Document from, Document to)
1929 {
1930 Element toElement = to.getDocumentElement();
1931
1932 NodeList replace_elements = from.getDocumentElement().getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
1933 XMLTools.duplicateElementList(to, toElement, replace_elements, true);
1934 }
1935
1936 ///////////////////////////////////////////////
1937 // service racks
1938 ////////////////////////////////////////////////
1939
1940 /**
1941 * serviceRackList is currently not editable in GLI - just copy it in from
1942 * config file and write it out again.
1943 */
1944 static private void doServiceRackList(Document to, Element from)
1945 {
1946 Element toElement = to.getDocumentElement();
1947
1948 Node srl_element = XMLTools.getChildByTagName(from, StaticStrings.SERVICE_RACK_LIST_ELEMENT);
1949 if (srl_element == null) return;
1950
1951 Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true);
1952 toElement.appendChild(to_element);
1953 }
1954
1955 static private void convertServiceRackList(Document from, Document to)
1956 {
1957 Element toElement = to.getDocumentElement();
1958
1959 Node srl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.SERVICE_RACK_LIST_ELEMENT);
1960 if (srl_element == null) return;
1961
1962 Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true);
1963 toElement.appendChild(to_element);
1964 }
1965
1966
1967 ////////////////////////////////////////////////////
1968 // Unknown elements
1969 //////////////////////////////////////////////////////
1970
1971 // handle top level elements which GLI knows nothing about
1972 // we store them internally in a Unknown element for easy access when
1973 // we write them out.
1974 static private void doUnknownElements(Document to, Element from)
1975 {
1976 Element toElement = to.getDocumentElement();
1977 Element unknownElement = to.createElement(StaticStrings.UNKNOWN_ELEMENT);
1978 toElement.appendChild(unknownElement);
1979
1980 Node child = from.getFirstChild();
1981 while (child != null)
1982 {
1983 if (child.getNodeType() == Node.ELEMENT_NODE && !known_element_names.contains(child.getNodeName()))
1984 {
1985 unknownElement.appendChild(XMLTools.duplicateElement(to, (Element) child, true));
1986 }
1987 child = child.getNextSibling();
1988 }
1989
1990 }
1991
1992 // just copy all children of Unknown element into output doc.
1993 static private void convertUnknownElements(Document from, Document to)
1994 {
1995
1996 Element toElement = to.getDocumentElement();
1997 Node unknown_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.UNKNOWN_ELEMENT);
1998
1999 Node child = unknown_element.getFirstChild();
2000 while (child != null)
2001 {
2002 Element to_element = XMLTools.duplicateElement(to, (Element) child, true);
2003 toElement.appendChild(to_element);
2004
2005 child = child.getNextSibling();
2006 }
2007
2008 }
2009
2010
2011 //****************************************************************************
2012
2013 ///////////////////////////////////////////////////
2014 // Helper functions
2015 /////////////////////////////////////////////////
2016
2017
2018 // /////////////////////////////////////////////
2019 // base code for index/sort/facet
2020 ///////////////////////////////////////////////
2021
2022 static private void doBaseSearchPartInternal(Document to, Node searchNode, String new_parts_str, String new_part_str, String existing_part_str, String type, boolean is_mg_index) {
2023
2024 Element toElement = to.getDocumentElement();
2025 Element parts_element = to.createElement(new_parts_str);//<Indexes> / <Facets> / <Sorts>
2026 parts_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
2027
2028 NodeList part_children = ((Element) searchNode).getElementsByTagName(existing_part_str);//index/facet/sort
2029 int num_nodes = part_children.getLength();
2030
2031 for (int i = 0; i < num_nodes; i++)
2032 {
2033
2034 Element part_element = to.createElement(new_part_str);//<Index> INDEX_ELEMENT
2035 Element e = (Element) part_children.item(i);
2036 String part_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
2037 String part_str_display = part_str;//for creating searchmetadata for this index
2038 if (!is_mg_index) {
2039 // look for options inside the index, eg
2040 // <option name="solrfieldtype" value="text_ja" />
2041 String options_str = "";
2042 NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
2043 if(option_children != null) {
2044 for (int j = 0; j < option_children.getLength(); j++) {
2045 Element el = (Element) option_children.item(j);
2046
2047 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
2048 options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str));
2049
2050 String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
2051 options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str));
2052
2053 if (name_str.equals("") && !value_str.equals(""))
2054 {
2055 continue; //invalid condition
2056 }
2057
2058 Element option_element = null;
2059 option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
2060 option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
2061
2062 if (!name_str.equals(""))
2063 {
2064 option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
2065 }
2066 if (value_str != null && !value_str.equals(""))
2067 {
2068 XMLTools.setNodeText(option_element, value_str);
2069 }
2070 part_element.appendChild(option_element);
2071 }
2072 }
2073 }
2074
2075 // Handling 'index' element
2076 // Double check colon separated style
2077 int colon_index = part_str.indexOf(StaticStrings.COLON_CHARACTER);
2078 if (!is_mg_index && colon_index != -1 ) {
2079 System.err.println("Something is wrong! the "+existing_part_str+" should NOT be level:source tuplets style.");
2080 part_str = part_str.substring(colon_index + 1);
2081
2082 }
2083 if (is_mg_index) {
2084 if (colon_index == -1) {
2085
2086 // MG, and it doesn't contain ':' character
2087 System.err.println("Something is wrong! the index should be level:source tuplets.");
2088 // assume document level
2089 part_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
2090 }
2091 else {
2092 part_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, part_str.substring(0, colon_index));
2093
2094 part_str = part_str.substring(part_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
2095 }
2096 }
2097 //Each index/sort/facet may have a list of comma-separated strings.
2098 //split them into 'content' elements in the internal structure
2099 StringTokenizer content_tokenizer = new StringTokenizer(part_str, StaticStrings.COMMA_CHARACTER);
2100 while (content_tokenizer.hasMoreTokens())
2101 {
2102 // Replace part_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject.
2103
2104 Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
2105 String content_str = content_tokenizer.nextToken();
2106 // Since the contents of parts 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.
2107 if (content_str.indexOf(StaticStrings.NS_SEP) == -1 && !(content_str.equals(StaticStrings.TEXT_STR) || content_str.equals(StaticStrings.ALLFIELDS_STR) || content_str.equals(StaticStrings.NONE_STR) || content_str.equals(StaticStrings.RANK_STR)))
2108 {
2109 content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
2110 }
2111 content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
2112 part_element.appendChild(content_element);
2113 content_element = null;
2114 } //while ends
2115
2116 parts_element.appendChild(part_element);
2117
2118 part_element = null;
2119
2120 // Handling 'displayItem' element of this 'index' element
2121 // 'e' is the parent element 'index' of 'displayItem' element
2122 doSearchDisplayItems(to, e, part_str_display, type);
2123
2124 } // for loop ends
2125 toElement.appendChild(parts_element);
2126 //return toElement;
2127
2128 } // doBaseSearchPartInternal
2129
2130 // this code is used for indexes, sortfields, facets
2131 // internal_parts_str = Indexes/Sorts/Facets - internal doc
2132 // internal_part_str = Index/Sort/Facet - internal doc
2133 // output_part_str = index/sortfield/facet - what goes in collectionConfig
2134
2135 private static void convertBaseSearchPartInternal(Document from, Document to, Element search, String internal_parts_str, String internal_part_str, String output_part_str, String searchmeta_type, boolean is_mg_index)
2136 {
2137
2138 Element source = from.getDocumentElement();
2139 Element parts= XMLTools.getNamedElement(source, internal_parts_str, StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
2140 if (parts == null) return;
2141
2142 NodeList part_elements = parts.getElementsByTagName(internal_part_str);
2143 int part_elements_length = part_elements.getLength();
2144
2145 if (part_elements_length == 0) return;
2146
2147 for (int j = 0; j < part_elements_length; j++) {
2148
2149 Element part_element = (Element) part_elements.item(j);
2150 if (part_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
2151
2152 Element part_ele = to.createElement(output_part_str);//part
2153
2154 // Used for creating displayItem for this element 'part_ele' further below
2155 // full_part_names contain 'ex.'
2156 String full_part_name = ""; //why this string and below strin buffer??
2157 String level_str = "";
2158
2159 StringBuffer part_value = new StringBuffer();
2160 if (is_mg_index) {
2161 level_str = part_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
2162 part_value.append(level_str).append(StaticStrings.COLON_CHARACTER);
2163 full_part_name = level_str + StaticStrings.COLON_CHARACTER;
2164 }
2165
2166 NodeList content_elements = part_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
2167 int content_elements_length = content_elements.getLength();
2168
2169 for (int k = 0; k < content_elements_length; k++) {
2170
2171 Element content_element = (Element) content_elements.item(k);
2172 if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
2173
2174 String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
2175
2176 full_part_name = full_part_name + name_str;
2177 if (k < content_elements_length - 1) {
2178
2179 full_part_name = full_part_name + StaticStrings.COMMA_CHARACTER;
2180 }
2181
2182 if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) {
2183
2184 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
2185 }
2186
2187 part_value.append(name_str);
2188 name_str = null;
2189 // Make it comma separated string
2190 if (k < content_elements_length - 1) {
2191
2192 part_value.append(StaticStrings.COMMA_CHARACTER);
2193 }
2194 content_element = null;
2195 } //k for loop ends
2196
2197 // ok to here
2198 String temp_str = part_value.toString();
2199 part_ele.setAttribute(StaticStrings.NAME_ATTRIBUTE, temp_str);
2200
2201 // Now constructing 'displayItem' element for this 'part_ele' element
2202 // The part names in the searchmetadata elements in the internal structure are not the names that
2203 // are used in the content elements (i.e. ex.Source or dc.Subject and keywords), but the names that are
2204 // in the configuration files (i.e. Source or dc.Subject)
2205 ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, temp_str, searchmeta_type);
2206
2207 if (searchmetadata_list == null) {
2208
2209 //try the full name, i.e. with 'ex.'
2210 searchmetadata_list = getMatchingSearchMetaElements(source, full_part_name, searchmeta_type);
2211 }
2212
2213 if (searchmetadata_list != null) {
2214
2215
2216 for (int k = 0; k < searchmetadata_list.size(); k++) {
2217
2218 Element searchmetadata = (Element) searchmetadata_list.get(k);
2219 if (searchmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
2220
2221 Element displayItem = constructDisplayItem(searchmetadata, to);
2222
2223 part_ele.appendChild(displayItem);
2224 }
2225 }
2226
2227 if (!is_mg_index) {
2228 // deal with any <option name='' value=''> children of this part
2229 // e.g. <option name='solrfieldtype' value='text_es'>
2230 NodeList option_children = part_element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
2231 for (int k = 0; k < option_children.getLength(); k++) {
2232
2233 Element el = (Element) option_children.item(k);
2234 if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
2235
2236 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
2237 String value_str = XMLTools.getNodeText(el);
2238
2239 if (name_str == null && value_str == null) continue;
2240 Element option_element = to.createElement(StaticStrings.OPTION_STR);
2241 if (!name_str.equals("")) {
2242 option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
2243 }
2244 if (!value_str.equals("")) { // or no value attribute without name attribute?
2245 option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);
2246 }
2247 part_ele.appendChild(option_element);
2248 } // for each option
2249 }
2250 search.appendChild(part_ele);
2251
2252 } //for loop ends
2253
2254 } // convertBaseSearchPartInternal
2255
2256 // find searchMetas (which become display items) matching meta_name and meta_type
2257 static private ArrayList getMatchingSearchMetaElements(Element source, String meta_name, String meta_type) {
2258 return XMLTools.getNamedElementList(source, StaticStrings.SEARCHMETADATA_ELEMENT, new String[]{StaticStrings.NAME_ATTRIBUTE, StaticStrings.TYPE_ATTRIBUTE}, new String[]{ meta_name, meta_type});
2259
2260 }
2261
2262 //
2263 static private void convertBaseDefaultSearchPartInternal(Document from, Document to, Element search, String internal_default_part_str, String output_default_part_str, boolean is_mg_index)
2264 {
2265 Element source = from.getDocumentElement();
2266
2267 Element default_part_element = (Element) XMLTools.getChildByTagName(source, internal_default_part_str);
2268 if (default_part_element == null)
2269 {
2270 return;
2271 }
2272
2273 String level_str = "";
2274 if (is_mg_index) {
2275 level_str = default_part_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
2276 // Debugging purposes
2277 if (level_str.equals("")) {
2278
2279 System.out.println("Bug: DefaultIndex should have its level attribute not empty. Setting it to document");
2280 level_str = StaticStrings.DOCUMENT_STR;
2281 }
2282 }
2283 NodeList content_elements = default_part_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
2284 int content_elements_length = content_elements.getLength();
2285
2286 // Don't output anything if no parts are set
2287 if (content_elements_length == 0) return;
2288
2289 String part_str = "";
2290
2291 if (is_mg_index) {
2292
2293 //combine level with indexes
2294 part_str = level_str + StaticStrings.COLON_CHARACTER;
2295 }
2296
2297 for (int k = 0; k < content_elements_length; k++) {
2298
2299 Element content_element = (Element) content_elements.item(k);
2300 if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
2301
2302 String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
2303
2304 if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) {
2305
2306 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
2307 }
2308
2309 part_str = part_str + name_str;
2310
2311 // Make it comma separated string
2312 if (k < content_elements_length - 1) {
2313
2314 part_str = part_str + StaticStrings.COMMA_CHARACTER;
2315 }
2316 content_element = null;
2317 }//for loop ends
2318
2319 Element default_part = to.createElement(output_default_part_str);
2320 default_part.setAttribute(StaticStrings.NAME_ATTRIBUTE, part_str);
2321 search.appendChild(default_part);
2322
2323 } // convertBaseDefaultSearchPartInternal
2324
2325
2326 ////////////////////////////////
2327 // handling format statement code
2328 ////////////////////////////////
2329
2330 static private Element doFormat(Document to, Element format, String name_str)
2331 {
2332 Element format_element = to.createElement(StaticStrings.FORMAT_STR);
2333 if (name_str != null) {
2334
2335 format_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
2336 }
2337
2338 // Don't write out an empty format statement of <format/> (i.e. format has no child nodes)
2339 // as this will end up embedded in another format statement as <format><format/><format />
2340 // This doubling up of format stmts will then prevent GLI from opening the collection again.
2341 if (format != null && format.hasChildNodes()) {
2342 // not an empty format statement
2343 String gsf_text = XMLTools.xmlNodeToString(format);
2344
2345 //We don't want the <format> elements in the string
2346 int startFormatIndex = gsf_text.indexOf(StaticStrings.FORMAT_START_TAG) + StaticStrings.FORMAT_START_TAG.length();
2347 int endFormatIndex = gsf_text.lastIndexOf(StaticStrings.FORMAT_END_TAG);
2348 gsf_text = gsf_text.substring(startFormatIndex, endFormatIndex);
2349
2350 XMLTools.setNodeText(format_element, gsf_text);
2351 }
2352 return format_element;
2353 }
2354
2355 static private Element convertFormat(Document to, Element e)
2356 {
2357 String format_str = XMLTools.getNodeText(e);
2358 Element format = to.createElement(StaticStrings.FORMAT_STR);
2359 //XMLTools.copyAllChildren (format, e);
2360 XMLTools.setNodeText(format, format_str);
2361 return format;
2362 }
2363
2364 ///////////////////////////////////////////////////////////////
2365 // helper code for display items
2366 ///////////////////////////////////////////////////////////////
2367
2368
2369 static private void doSearchDisplayItems(Document to, Element from, String name, String type) {
2370 Element toElement = to.getDocumentElement();
2371 // Node displayItemListNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.DISPLAYITEMLIST_STR, 0);
2372 // if (displayItemListNode == null) {
2373 // return;
2374 // }
2375 NodeList displayItems = from.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
2376 for (int i=0; i<displayItems.getLength(); i++) {
2377 Element item = (Element) displayItems.item(i);
2378 Element search_meta = processSingleDisplayItem(to, item, name, type);
2379 if (search_meta == null) {
2380 System.err.println("search meta is null "+name+", "+type);
2381 }else {
2382 toElement.appendChild(search_meta);
2383 }
2384 }
2385 }
2386
2387 /** convert displayItem (item) into CollectionMeta (if type is null) or SearchMeta (if type is not null). Use new_name if not null. */
2388 static private Element processSingleDisplayItem(Document to, Element item, String new_name, String type) {
2389 // special case for collection description - is allowed html
2390 boolean isCollDescr = new_name.equals(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
2391
2392 // Sadly, XMLTools.getNodeText(item) returns empty for any HTML in displayItem
2393 // so we have to do it the hard way
2394 // We can't take a shortcut like format statements, which also need to keep their
2395 // tags intact in collConfig.xml, because we know in advance the format tag name
2396 // Can't guess at what html tag names the user uses, and there may be several at
2397 // the same level inside collDescription (e.g. multiple paragraphs)
2398 String text = isCollDescr ? preserveHTMLInDescriptionDisplayItem(item)
2399 : XMLTools.getNodeText(item); // else as before for all other displayItems
2400
2401 //If there is nothing to display, don't bother creating the element
2402 // Either lang or key should be set. If key set, no text node needed.
2403 // if lang set, should have textnode. Check if it's meaningful
2404 if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals("")) {
2405 return null;
2406 }
2407
2408 // get the value in 'lang=langcode' or 'key=keyname'
2409 // We can have either a key attribute (with optional dictionary attribute, else dictionary is implicit)
2410 // OR we can have a lang attr, with the nodetext containing the actual display string.
2411 String lang = item.getAttribute(StaticStrings.LANG_STR);
2412 String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
2413 String name;
2414 if (new_name != null) {
2415 name = new_name;
2416 } else {
2417 name = item.getAttribute(StaticStrings.NAME_ATTRIBUTE);
2418 }
2419
2420
2421 Element e;
2422 if (type ==null) {
2423 e = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
2424 } else {
2425 e = to.createElement(StaticStrings.SEARCHMETADATA_ELEMENT);
2426 }
2427 e.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
2428 e.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
2429
2430 if (type != null) {
2431 e.setAttribute(StaticStrings.TYPE_ATTRIBUTE, type);
2432 }
2433 if(!lang.equals("")) {
2434 e.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
2435 text = text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
2436 XMLTools.setNodeText(e, text);
2437
2438 } else if(!key.equals("")) {
2439 e.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
2440 String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
2441 if(!dictionary.equals("")) {
2442 e.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
2443 }
2444 }
2445 return e;
2446 }
2447
2448
2449 /** Construct s <displayItem> element from e which is a CollectionMeta or a SearchMeta
2450 i.e. internal DOM -> config file
2451 */
2452 static private Element constructDisplayItem(Element e, Document to, String name)
2453 {
2454 String lang_string = e.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE);
2455 String key_string = e.getAttribute(StaticStrings.KEY_ATTRIBUTE);
2456 String dictionary_string = e.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
2457 String text = XMLTools.getNodeText(e);
2458
2459 Element displayItem = to.createElement(StaticStrings.DISPLAYITEM_STR);
2460 displayItem.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
2461
2462 if(!lang_string.equals("")) {
2463 displayItem.setAttribute(StaticStrings.LANG_STR, lang_string);
2464 if (name.equals(StaticStrings.DESCRIPTION_STR)) {
2465 // special case for collection description string, which is allowed html tags
2466 text = Codec.transform(text, Codec.REINSTATE_HTML_TAGS);
2467 }
2468 XMLTools.setNodeText(displayItem, text);
2469 }
2470 if(!key_string.equals("")) {
2471 displayItem.setAttribute(StaticStrings.KEY_ATTRIBUTE, key_string);
2472 if(!dictionary_string.equals("")) {
2473 displayItem.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary_string);
2474 }
2475 }
2476 return displayItem;
2477 }
2478
2479 static private Element constructDisplayItem(Element e, Document to)
2480 {
2481 return constructDisplayItem(e, to, StaticStrings.NAME_ATTRIBUTE);
2482 }
2483
2484
2485
2486 ////////////////////////////////////////////////////////////////////
2487 // DOM tree manipulation
2488 ///////////////////////////////////////////////////////////////////
2489
2490 // Append the element son to the element mother in the appropriate position.
2491 static private void appendProperly(Element mother, Element son)
2492 {
2493 if (son == null)
2494 return;
2495
2496 Node reference_node = findInsertionPoint(mother, son);
2497 if (reference_node != null) {
2498 mother.insertBefore(son, reference_node);
2499 }
2500 else {
2501 mother.appendChild(son);
2502 }
2503 }
2504
2505 /**
2506 * Find the best insertion position for the given DOM Element
2507 * 'target_element' in the DOM Element 'document_element'. This should try
2508 * to match command tag, and if found should then try to group by name or
2509 * type (eg CollectionMeta), or append to end is no such grouping exists (eg
2510 * Plugins). Failing a command match it will check against the command order
2511 * for the best insertion location.
2512 *
2513 * @param target_element
2514 * the command Element to be inserted
2515 * @return the Element which the given command should be inserted before, or
2516 * null to append to end of list
2517 */
2518 static private Node findInsertionPoint(Element document_element, Element target_element)
2519 {
2520 ///ystem.err.println("Find insertion point: " + target_element.getNodeName());
2521 String target_element_name = target_element.getNodeName();
2522
2523 // Try to find commands with the same tag.
2524 NodeList matching_elements = document_element.getElementsByTagName(target_element_name);
2525 // If we found matching elements, then we have our most likely insertion location, so check within for groupings
2526 if (matching_elements.getLength() != 0) {
2527
2528 ///ystem.err.println("Found matching elements.");
2529 // Only CollectionMeta are grouped.
2530 if (target_element_name.equals(StaticStrings.COLLECTIONMETADATA_ELEMENT)) {
2531 ///ystem.err.println("Dealing with collection metadata");
2532 // 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.
2533 // So if the command to be added is special add it immediately after any other special command
2534 if (target_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) {
2535
2536 int index = 0;
2537 Element matched_element = (Element) matching_elements.item(index);
2538 Element sibling_element = (Element) matched_element.getNextSibling();
2539 while (sibling_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) {
2540
2541 index++;
2542 matched_element = (Element) matching_elements.item(index);
2543 sibling_element = (Element) matched_element.getNextSibling();
2544 }
2545 if (sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
2546
2547 Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
2548 document_element.insertBefore(newline_element, sibling_element);
2549 }
2550 return sibling_element;
2551 }
2552 // Otherwise try to find a matching 'name' and add after the last one in that group.
2553 else {
2554
2555 int index = 0;
2556 target_element_name = target_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
2557 boolean found = false;
2558 // Skip all of the special metadata
2559 Element matched_element = (Element) matching_elements.item(index);
2560 while (matched_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) {
2561
2562 index++;
2563 matched_element = (Element) matching_elements.item(index);
2564 }
2565 // Begin search
2566 while (!found && matched_element != null) {
2567
2568 if (matched_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name)) {
2569
2570 found = true;
2571 }
2572 else {
2573
2574 index++;
2575 matched_element = (Element) matching_elements.item(index);
2576 }
2577 }
2578 // If we found a match, we need to continue checking until we find the last name match.
2579 if (found) {
2580
2581 index++;
2582 Element previous_sibling = matched_element;
2583 Element sibling_element = (Element) matching_elements.item(index);
2584 while (sibling_element != null && sibling_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name)) {
2585
2586 previous_sibling = sibling_element;
2587 index++;
2588 sibling_element = (Element) matching_elements.item(index);
2589 }
2590 // 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!
2591 return previous_sibling.getNextSibling();
2592 }
2593 // If not found we just add after last metadata element
2594 else {
2595
2596 Element last_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
2597 return last_element.getNextSibling();
2598 }
2599 }
2600
2601 }
2602 else {
2603
2604 ///ystem.err.println("Not dealing with collection meta.");
2605 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
2606 // 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)
2607 Node sibling_element = matched_element.getNextSibling();
2608 if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
2609
2610 Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
2611 document_element.insertBefore(newline_element, sibling_element);
2612 }
2613 return sibling_element; // Note that this may be null
2614 }
2615 }
2616 ///ystem.err.println("No matching elements found.");
2617 // Locate where this command is in the ordering
2618 int command_index = -1;
2619 for (int i = 0; command_index == -1 && i < CollectionConfiguration.COMMAND_ORDER.length; i++) {
2620
2621 if (CollectionConfiguration.COMMAND_ORDER[i].equals(target_element_name)) {
2622
2623 command_index = i;
2624 }
2625 }
2626 ///ystem.err.println("Command index is: " + command_index);
2627 // Now move forward, checking for existing elements in each of the preceeding command orders.
2628 int preceeding_index = command_index - 1;
2629 ///ystem.err.println("Searching before the target command.");
2630 while (preceeding_index >= 0) {
2631
2632 matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[preceeding_index]);
2633 // If we've found a match
2634 if (matching_elements.getLength() > 0) {
2635
2636 // We add after the last element
2637 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
2638 // 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)
2639 Node sibling_element = matched_element.getNextSibling();
2640 if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
2641
2642 Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
2643 document_element.insertBefore(newline_element, sibling_element);
2644 }
2645 return sibling_element; // Note that this may be null
2646 }
2647 preceeding_index--;
2648 }
2649 // If all that fails, we now move backwards through the commands
2650 int susceeding_index = command_index + 1;
2651 ///ystem.err.println("Searching after the target command.");
2652 while (susceeding_index < CollectionConfiguration.COMMAND_ORDER.length) {
2653
2654 matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[susceeding_index]);
2655 // If we've found a match
2656 if (matching_elements.getLength() > 0) {
2657
2658 // We add before the first element
2659 Element matched_element = (Element) matching_elements.item(0);
2660 // 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)
2661 Node sibling_element = matched_element.getPreviousSibling();
2662 if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
2663
2664 Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
2665 document_element.insertBefore(newline_element, sibling_element);
2666 }
2667 return sibling_element; // Note that this may be null
2668 }
2669 susceeding_index++;
2670 }
2671 // Well. Apparently there are no other commands in this collection configuration. So append away...
2672 return null;
2673 }
2674
2675
2676 /**
2677 * For now it only makes sense to allow a collection's about page description to contain HTML.
2678 * Collection titles may go into a pre tag or text only context or into HTML headings,
2679 * where preserving any HTML in coll title would become meaningless or even a hindrance.
2680 * TODO: if users used HTML pre tags, they'll have wanted whitespace preserved.
2681 * TODO There's probably a better way to do this, but I'm unable to think of it. Messy but works.
2682 */
2683 static private String preserveHTMLInDescriptionDisplayItem(Element collDescription) {
2684 // First get the <displayItem> as text
2685 String text = XMLTools.elementToString(collDescription, true);
2686
2687 // We only want the contents, not the xml processing instruction or the
2688 // <displayItem></displayItem> or self-closing(!) <displayItem/> when no text for colldescr
2689 // Remove xml processing instr too by removing <displayItem until first > after that
2690 // This will also handle the self-closing tag case
2691 String lookFor = "<displayItem";
2692 int start = text.indexOf(lookFor);
2693 if(start != -1) {
2694 start += lookFor.length();
2695 start = text.indexOf(">", start);
2696 text = text.substring(start+1).trim(); // trim to ensure no empty lines to deceive us
2697 // especially after a self-closing tag
2698 }
2699 if ( text.equals("")) {
2700 //must have had self closing tag
2701 return "";
2702 }
2703 lookFor = "</displayItem>";
2704 int end = text.indexOf(lookFor);
2705 if (end == -1) {
2706 // there was no closing tag. something has gone wrong
2707 return "";
2708 }
2709 text = text.substring(0,end);
2710
2711 // in case opening the file has indented the text, we strip off whitespace for each line
2712 String[] lines = text.split("\\r?\\n");
2713 text = "";
2714 if(lines.length > 0) {
2715 for (int j = 0; j < lines.length; j++) {
2716 text += lines[j].trim() + "\n"; // Easiest solution:
2717 // trim white space of the one extra level of indentation
2718 // that became apparent when enclosing <dispItem> tags removed
2719 }
2720 }
2721
2722 text = text.replaceAll("&amp;", "&");
2723 return text;
2724
2725 }
2726
2727 // Append the elements, which are of Element type, in 'list' to Element 'to'
2728 static private void appendArrayList(Element to, ArrayList list)
2729 {
2730 if (list == null)
2731 return;
2732
2733 for (int i = 0; i < list.size(); i++) {
2734
2735 appendProperly(to, (Element) list.get(i));
2736 }
2737 }
2738
2739
2740}
Note: See TracBrowser for help on using the repository browser.