source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java@ 24984

Last change on this file since 24984 was 24984, checked in by sjm84, 12 years ago

Reformatting this file ahead of some changes

  • Property svn:keywords set to Author Date Id Revision
File size: 34.6 KB
Line 
1/*
2 * GSXML.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.util;
20
21import org.w3c.dom.NamedNodeMap;
22import org.w3c.dom.Node;
23import org.w3c.dom.Element;
24import org.w3c.dom.NodeList;
25import org.w3c.dom.Document;
26import org.w3c.dom.Text;
27
28import javax.xml.transform.TransformerFactory;
29import javax.xml.transform.Transformer;
30import java.io.StringWriter;
31import javax.xml.transform.stream.StreamResult;
32import javax.xml.transform.dom.DOMSource;
33
34import java.util.Map;
35import java.util.Set;
36import java.util.HashMap;
37import java.util.Vector;
38import java.util.Iterator;
39import java.util.ArrayList;
40
41//import java.util.Locale;
42
43import org.apache.log4j.*;
44
45/** various functions for extracting info out of GS XML */
46public class GSXML
47{
48
49 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GSXML.class.getName());
50
51 // greenstone xml elements
52 public static final String MESSAGE_ELEM = "message";
53 public static final String REQUEST_ELEM = "request";
54 public static final String RESPONSE_ELEM = "response";
55 public static final String COLLECTION_ELEM = "collection";
56 public static final String SERVICE_ELEM = "service";
57 public static final String CLUSTER_ELEM = "serviceCluster";
58 public static final String SITE_ELEM = "site";
59 public static final String PARAM_ELEM = "param";
60 public static final String PARAM_OPTION_ELEM = "option";
61 public static final String CONTENT_ELEM = "content";
62 public static final String RESOURCE_ELEM = "resource";
63 public static final String DOCUMENT_ELEM = "document";
64 public static final String METADATA_ELEM = "metadata";
65 public static final String SERVICE_CLASS_ELEM = "serviceRack";
66 public static final String CLASSIFIER_ELEM = "classifier";
67 public static final String APPLET_ELEM = "applet";
68 public static final String APPLET_DATA_ELEM = "appletData";
69 public static final String CONFIGURE_ELEM = "configure";
70 public static final String STATUS_ELEM = "status";
71 public static final String ERROR_ELEM = "error";
72 public static final String DEFAULT_ELEM = "default";
73 public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem
74 public static final String FORMAT_ELEM = "format"; // config files use format - should we use this instead of stylesheet??
75 public static final String TERM_ELEM = "term";
76 public static final String STOPWORD_ELEM = "stopword";
77 public static final String SYSTEM_ELEM = "system";
78 public static final String FORMAT_STRING_ELEM = "formatString";
79
80 //config file elems
81 public static final String COLLECTION_CONFIG_ELEM = "collectionConfig";
82 public static final String COLLECTION_BUILD_ELEM = "buildConfig";
83 public static final String COLLECTION_INIT_ELEM = "collectionInit";
84 public static final String RECOGNISE_ELEM = "recognise";
85 public static final String DOC_TYPE_ELEM = "docType";
86 public static final String SEARCH_ELEM = "search";
87 public static final String INFODB_ELEM = "infodb";
88 public static final String INDEX_ELEM = "index";
89 public static final String INDEX_STEM_ELEM = "indexStem";
90 public static final String INDEX_OPTION_ELEM = "indexOption";
91 public static final String BROWSE_ELEM = "browse";
92 public static final String DISPLAY_ELEM = "display";
93 public static final String LEVEL_ELEM = "level";
94
95 public static final String DBINFO_ELEM = "dbInfo";
96 public static final String DBNAME_ATT = "dbname";
97 public static final String DBPATH_ATT = "dbpath";
98 public static final String SQLSTATE_ATT = "sqlstate";
99 public static final String DATABASE_TYPE_ELEM = "databaseType";
100 public static final String SHORTNAME_ATT = "shortname";
101 public static final String NOTIFY_ELEM = "notify";
102 public static final String NOTIFY_HOST_ATT = "host";
103
104 //doc.xml file elems
105 public static final String DOCXML_SECTION_ELEM = "Section";
106 public static final String DOCXML_DESCRIPTION_ELEM = "Description";
107 public static final String DOCXML_METADATA_ELEM = "Metadata";
108 public static final String DOCXML_CONTENT_ELEM = "Content";
109
110 // elems for the pages to be processed by xslt
111 public final static String PAGE_ELEM = "page";
112 public final static String CONFIGURATION_ELEM = "config";
113 public final static String PAGE_REQUEST_ELEM = "pageRequest";
114 public final static String PAGE_RESPONSE_ELEM = "pageResponse";
115 public final static String PAGE_EXTRA_ELEM = "pageExtra";
116
117 //public final static String DESCRIPTION_ELEM = "description";
118
119 public static final String ACTION_ELEM = "action";
120 public static final String SUBACTION_ELEM = "subaction";
121
122 // add on to another elem type to get a list of that type
123 public static final String LIST_MODIFIER = "List";
124
125 // greenstone xml attributes
126 public static final String COLLECTION_ATT = "collection";
127 public static final String NAME_ATT = "name";
128 public static final String TO_ATT = "to";
129 public static final String USER_ID_ATT = "uid";
130 public static final String FROM_ATT = "from";
131 public static final String LANG_ATT = "lang";
132 public static final String TYPE_ATT = "type";
133 public static final String DB_TYPE_ATT = "dbType";
134 public static final String VALUE_ATT = "value";
135 public static final String DEFAULT_ATT = "default";
136 public static final String INFO_ATT = "info";
137 public static final String ACTION_ATT = "action";
138 public static final String SUBACTION_ATT = "subaction";
139 public static final String OUTPUT_ATT = "output";
140 public static final String ADDRESS_ATT = "address";
141 public static final String LOCAL_SITE_ATT = "localSite";
142 public static final String LOCAL_SITE_NAME_ATT = "localSiteName";
143 public static final String STATUS_ERROR_CODE_ATT = "code";
144 public static final String STATUS_PROCESS_ID_ATT = "pid";
145 public static final String PARAM_SHORTNAME_ATT = "shortname";
146 public static final String PARAM_IGNORE_POS_ATT = "ignore";
147 public static final String CLASSIFIER_CONTENT_ATT = "content";
148 public static final String ERROR_TYPE_ATT = "type";
149 public static final String COLLECT_TYPE_ATT = "ct";
150 public static final String HIDDEN_ATT = "hidden";
151
152 // document stuff
153 public static final String DOC_TYPE_ATT = "docType";
154 public static final String DOC_NODE_ELEM = "documentNode";
155 public static final String NODE_CONTENT_ELEM = "nodeContent";
156 public static final String NODE_STRUCTURE_ELEM = "nodeStructure";
157 public static final String NODE_ID_ATT = "nodeID";
158 public static final String NODE_NAME_ATT = "nodeName";
159 public static final String NODE_TYPE_ATT = "nodeType";
160 public static final String NODE_RANK_ATT = "rank";
161 public static final String NODE_TYPE_ROOT = "root";
162 public static final String NODE_TYPE_INTERNAL = "internal";
163 public static final String NODE_TYPE_LEAF = "leaf";
164
165 public static final String DOC_TYPE_SIMPLE = "simple";
166 public static final String DOC_TYPE_PAGED = "paged";
167 public static final String DOC_TYPE_HIERARCHY = "hierarchy";
168
169 public static final String SESSION_EXPIRATION = "session_expiration";
170 public static final String USER_SESSION_CACHE_ATT = "user_session_cache";
171
172 // classifier stuff
173 public static final String CLASS_NODE_ELEM = "classifierNode";
174 public static final String CLASS_NODE_ORIENTATION_ATT = "orientation";
175
176 // parameter types
177 public static final String PARAM_TYPE_INTEGER = "integer";
178 public static final String PARAM_TYPE_BOOLEAN = "boolean";
179 public static final String PARAM_TYPE_ENUM_START = "enum";
180 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
181 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
182 public static final String PARAM_TYPE_STRING = "string";
183 public static final String PARAM_TYPE_TEXT = "text";
184 public static final String PARAM_TYPE_MULTI = "multi";
185 public static final String PARAM_TYPE_FILE = "file";
186 public static final String PARAM_TYPE_INVISIBLE = "invisible";
187 // stuff for text strings
188 public static final String DISPLAY_TEXT_ELEM = "displayItem";
189 // the following are used for the name attributes
190 public static final String DISPLAY_TEXT_NAME = "name";
191 public static final String DISPLAY_TEXT_SUBMIT = "submit";
192 public static final String DISPLAY_TEXT_DESCRIPTION = "description";
193
194 // request types
195 // get the module description
196 public static final String REQUEST_TYPE_DESCRIBE = "describe";
197 // startup a process
198 public static final String REQUEST_TYPE_PROCESS = "process";
199 // get the status of an ongoing process
200 public static final String REQUEST_TYPE_STATUS = "status";
201 // system type request - eg reload a collection
202 public static final String REQUEST_TYPE_SYSTEM = "system";
203 // page requests to the Receptionist/Actions
204 public static final String REQUEST_TYPE_PAGE = "page"; // used to be cgi
205 // get any format info for a service
206 public static final String REQUEST_TYPE_FORMAT = "format";
207 // modify the requests
208 public static final String REQUEST_TYPE_MESSAGING = "messaging";
209 // save the format string
210 public static final String REQUEST_TYPE_FORMAT_STRING = "formatString";
211
212 // service types
213 public static final String SERVICE_TYPE_QUERY = "query";
214 public static final String SERVICE_TYPE_RETRIEVE = "retrieve";
215 public static final String SERVICE_TYPE_BROWSE = "browse";
216 public static final String SERVICE_TYPE_APPLET = "applet";
217 public static final String SERVICE_TYPE_PROCESS = "process";
218 public static final String SERVICE_TYPE_ENRICH = "enrich";
219 public static final String SERVICE_TYPE_OAI = "oai";
220 public static final String FLAX_PAGE = "flaxPage";
221 public static final String FLAX_PAGE_GENERATION = "FlaxPageGeneration";
222
223 // system command types and attributes
224 public static final String SYSTEM_TYPE_CONFIGURE = "configure";
225 public static final String SYSTEM_TYPE_ACTIVATE = "activate";
226 public static final String SYSTEM_TYPE_DEACTIVATE = "deactivate";
227
228 public static final String SYSTEM_SUBSET_ATT = "subset";
229 public static final String SYSTEM_MODULE_TYPE_ATT = "moduleType";
230 public static final String SYSTEM_MODULE_NAME_ATT = "moduleName";
231
232 // communicator types
233 public static final String COMM_TYPE_SOAP_JAVA = "soap";
234
235 // error types
236 public static final String ERROR_TYPE_SYNTAX = "syntax";
237 public static final String ERROR_TYPE_SYSTEM = "system";
238 public static final String ERROR_TYPE_INVALID_ID = "invalid_id";
239 public static final String ERROR_TYPE_OTHER = "other";
240
241 // some system wide param names
242 public static final String SUBSET_PARAM = "subset";
243
244 //for plugin
245 public static final String PLUGIN_ELEM = "plugin";
246 public static final String IMPORT_ELEM = "import";
247
248 //for authentication
249 public static final String AUTHEN_NODE_ELEM = "authenticationNode";
250 public static final String USER_NODE_ELEM = "userNode";
251
252 //for configure action results
253 public static final String SUCCESS = "success";
254 public static final String ERROR = "error";
255
256 /**
257 * takes a list of elements, and returns an array of strings of the values
258 * of attribute att_name
259 */
260 public static String[] getAttributeValuesFromList(Element list, String att_name)
261 {
262
263 NodeList children = list.getChildNodes();
264
265 int num_nodes = children.getLength();
266 String[] ids = new String[num_nodes];
267 for (int i = 0; i < num_nodes; i++)
268 {
269 Element e = (Element) children.item(i);
270 String id = e.getAttribute(att_name);
271 ids[i] = id;
272 }
273
274 return ids;
275 }
276
277 public static HashMap extractParams(Element xml, boolean deep)
278 {
279 return extractParams(xml, deep, null);
280 }
281
282 /**
283 * takes a paramList element, and gets a HashMap of name-value pairs if
284 * deep=true, extracts embedded params, otherwise just top level params
285 */
286 public static HashMap extractParams(Element xml, boolean deep, String toFind)
287 {
288
289 if (!xml.getNodeName().equals(PARAM_ELEM + LIST_MODIFIER))
290 {
291 logger.error("paramList element should have been passed to extractParams, instead it was " + xml.getNodeName());
292 return null;
293 }
294
295 NodeList params = null;
296 if (deep)
297 { // get all the nested ones
298 params = xml.getElementsByTagName(PARAM_ELEM);
299 }
300 else
301 { // just get the top level ones
302 params = xml.getChildNodes();
303 }
304 HashMap param_map = new HashMap();
305 for (int i = 0; i < params.getLength(); i++)
306 {
307 if (params.item(i).getNodeName().equals(PARAM_ELEM))
308 {
309 Element param = (Element) params.item(i);
310 String name = param.getAttribute(NAME_ATT);
311 String value = getValue(param); //att or content
312
313 // For only one parameter
314 if (toFind != null && name.equals(toFind))
315 {
316 param_map.put(name, value);
317 return param_map;
318 }
319 else if (toFind != null)
320 continue;
321
322 int pos = name.indexOf('.');
323 if (pos == -1)
324 { // a base param
325 param_map.put(name, value);
326 }
327 else
328 { // a namespaced param
329
330 String namespace = name.substring(0, pos);
331 name = name.substring(pos + 1);
332 HashMap map = (HashMap) param_map.get(namespace);
333 if (map == null)
334 {
335 map = new HashMap();
336 param_map.put(namespace, map);
337 }
338 map.put(name, value);
339 }
340 }
341 }
342 return param_map;
343 }
344
345 /** gets the value att or the text content */
346 public static String getValue(Element e)
347 {
348 String val = e.getAttribute(VALUE_ATT);
349 if (val == null || val.equals(""))
350 {
351 // have to get it out of the text
352 val = getNodeText(e);
353
354 }
355 else
356 {
357 // unescape the xml stuff
358 val = unXmlSafe(val);
359 }
360 return val;
361 }
362
363 /** extracts the text out of a node */
364 public static Node getNodeTextNode(Element param)
365 {
366 param.normalize();
367 Node n = param.getFirstChild();
368 while (n != null && n.getNodeType() != Node.TEXT_NODE)
369 {
370 n = n.getNextSibling();
371 }
372 return n;
373 }
374
375 /** extracts the text out of a node */
376 public static String getNodeText(Element param)
377 {
378 Node text_node = getNodeTextNode(param);
379 if (text_node == null)
380 {
381 return "";
382 }
383 return text_node.getNodeValue();
384 }
385
386 public static void setNodeText(Element elem, String text)
387 {
388 Node old_text_node = getNodeTextNode(elem);
389 if (old_text_node != null)
390 {
391 elem.removeChild(old_text_node);
392 }
393 Text t = elem.getOwnerDocument().createTextNode(text);
394 elem.appendChild(t);
395 }
396
397 /** add text to a document/subsection element */
398 public static boolean addDocText(Document owner, Element doc, String text)
399 {
400
401 Element content = owner.createElement(NODE_CONTENT_ELEM);
402 Text t = owner.createTextNode(text);
403 content.appendChild(t);
404 doc.appendChild(content);
405 return true;
406 }
407
408 /** add an error message, unknown error type */
409 public static boolean addError(Document owner, Element doc, String text)
410 {
411 return addError(owner, doc, text, ERROR_TYPE_OTHER);
412 }
413
414 /** add an error message */
415 public static boolean addError(Document owner, Element doc, String text, String error_type)
416 {
417
418 Element content = owner.createElement(ERROR_ELEM);
419 content.setAttribute(ERROR_TYPE_ATT, error_type);
420 Text t = owner.createTextNode(text);
421 content.appendChild(t);
422 doc.appendChild(content);
423 return true;
424 }
425
426 /** add an error message */
427 public static boolean addError(Document owner, Element doc, Throwable error)
428 {
429 return addError(owner, doc, error, ERROR_TYPE_OTHER);
430 }
431
432 /** add an error message */
433 public static boolean addError(Document owner, Element doc, Throwable error, String error_type)
434 {
435 error.printStackTrace();
436 return addError(owner, doc, error.toString(), error_type);
437 }
438
439 public static Element createMetadataParamList(Document owner, Vector meta_values)
440 {
441
442 Element meta_param_list = owner.createElement(PARAM_ELEM + LIST_MODIFIER);
443 Iterator i = meta_values.iterator();
444 while (i.hasNext())
445 {
446 String next = (String) i.next();
447 Element meta_param = owner.createElement(PARAM_ELEM);
448 meta_param_list.appendChild(meta_param);
449 meta_param.setAttribute(NAME_ATT, "metadata");
450 meta_param.setAttribute(VALUE_ATT, next);
451 }
452 return meta_param_list;
453 }
454
455 /** adds a metadata elem to a list */
456 public static boolean addMetadata(Document owner, Element list, String meta_name, String meta_value)
457 {
458 if (meta_value == null || meta_value.equals(""))
459 {
460 return false;
461 }
462 Element data = owner.createElement(METADATA_ELEM);
463 data.setAttribute(NAME_ATT, meta_name);
464 Text t = owner.createTextNode(meta_value);
465 data.appendChild(t);
466 list.appendChild(data);
467 return true;
468
469 }
470
471 /**
472 * copies the metadata out of the metadataList of 'from' into the
473 * metadataList of 'to'
474 */
475 public static boolean mergeMetadataLists(Node to, Node from)
476 {
477 Node from_meta = getChildByTagName(from, METADATA_ELEM + LIST_MODIFIER);
478 if (from_meta == null)
479 { // nothing to copy
480 return true;
481 }
482 return mergeMetadataFromList(to, from_meta);
483 }
484
485 /**
486 * copies the metadata out of the meta_list metadataList into the
487 * metadataList of 'to'
488 */
489 public static boolean mergeMetadataFromList(Node to, Node meta_list)
490 {
491 if (meta_list == null)
492 return false;
493 Node to_meta = getChildByTagName(to, METADATA_ELEM + LIST_MODIFIER);
494 Document to_owner = to.getOwnerDocument();
495 if (to_meta == null)
496 {
497 to.appendChild(to_owner.importNode(meta_list, true));
498 return true;
499 }
500 // copy individual metadata elements
501 NodeList meta_items = ((Element) meta_list).getElementsByTagName(METADATA_ELEM);
502 for (int i = 0; i < meta_items.getLength(); i++)
503 {
504 to_meta.appendChild(to_owner.importNode(meta_items.item(i), true));
505 }
506 return true;
507 }
508
509 /** copies all the children from from to to */
510 public static boolean mergeElements(Element to, Element from)
511 {
512
513 Document owner = to.getOwnerDocument();
514 Node child = from.getFirstChild();
515 while (child != null)
516 {
517 to.appendChild(owner.importNode(child, true));
518 child = child.getNextSibling();
519 }
520 return true;
521 }
522
523 /** returns the (first) element child of the node n */
524 public static Element getFirstElementChild(Node n)
525 {
526
527 Node child = n.getFirstChild();
528 while (child != null)
529 {
530 if (child.getNodeType() == Node.ELEMENT_NODE)
531 {
532 return (Element) child;
533 }
534 child = child.getNextSibling();
535 }
536 return null; //no element child found
537 }
538
539 /** returns the (first) child element with the given name */
540 public static Node getChildByTagName(Node n, String name)
541 {
542 if (n != null)
543 { // this line is an attempted solution to the NullPointerException mentioned
544 // in trac bug ticket #225. If n is null can't do n.getFirstChild() below. As per bug #225:
545 // GSXML.getNodeByPath() is called by GS2BrowseAction, which then calls this method.
546 // If n is null, null will be returned which GS2BrowseAction already checks for. It's here
547 // that the NullPointerException was thrown.
548
549 Node child = n.getFirstChild();
550 while (child != null)
551 {
552 if (child.getNodeName().equals(name))
553 {
554 return child;
555 }
556 child = child.getNextSibling();
557 }
558 }
559 return null; //not found
560 }
561
562 /**
563 * returns the (nth) child element with the given name index numbers start
564 * at 0
565 */
566 public static Node getChildByTagNameIndexed(Node n, String name, int index)
567 {
568 if (index == -1)
569 {
570 return getChildByTagName(n, name);
571 }
572 int count = 0;
573 Node child = n.getFirstChild();
574 while (child != null)
575 {
576 if (child.getNodeName().equals(name))
577 {
578 if (count == index)
579 {
580 return child;
581 }
582 else
583 {
584 count++;
585 }
586 }
587 child = child.getNextSibling();
588 }
589 return null; //not found
590 }
591
592 /**
593 * takes an xpath type expression of the form name/name/... and returns the
594 * first node that matches, or null if not found
595 */
596 public static Node getNodeByPath(Node n, String path)
597 {
598
599 String link = GSPath.getFirstLink(path);
600 path = GSPath.removeFirstLink(path);
601 while (!link.equals(""))
602 {
603 n = getChildByTagName(n, link);
604 if (n == null)
605 {
606 return null;
607 }
608 link = GSPath.getFirstLink(path);
609 path = GSPath.removeFirstLink(path);
610 }
611 return n;
612 }
613
614 /**
615 * takes an xpath type expression of the form name/name/... and returns the
616 * first node that matches, or null if not found can include [i] indices.
617 * index numbers start at 0
618 */
619 public static Node getNodeByPathIndexed(Node n, String path)
620 {
621
622 String link = GSPath.getFirstLink(path);
623 int index = GSPath.getIndex(link);
624 if (index != -1)
625 {
626 link = GSPath.removeIndex(link);
627 }
628 path = GSPath.removeFirstLink(path);
629 while (!link.equals(""))
630 {
631 n = getChildByTagNameIndexed(n, link, index);
632 if (n == null)
633 {
634 return null;
635 }
636 link = GSPath.getFirstLink(path);
637 index = GSPath.getIndex(link);
638 if (index != -1)
639 {
640 link = GSPath.removeIndex(link);
641 }
642 path = GSPath.removeFirstLink(path);
643 }
644 return n;
645 }
646
647 public static HashMap getChildrenMap(Node n)
648 {
649
650 HashMap map = new HashMap();
651 Node child = n.getFirstChild();
652 while (child != null)
653 {
654 String name = child.getNodeName();
655 map.put(name, child);
656 child = child.getNextSibling();
657 }
658 return map;
659 }
660
661 public static NodeList getChildrenByTagName(Node n, String name)
662 {
663 MyNodeList node_list = new MyNodeList();
664 Node child = n.getFirstChild();
665 while (child != null)
666 {
667 if (child.getNodeName().equals(name))
668 {
669 node_list.addNode(child);
670 }
671 child = child.getNextSibling();
672 }
673 return node_list;
674 }
675
676 /** Duplicates an element, but gives it a new name */
677 public static Element duplicateWithNewName(Document owner, Element element, String element_name, boolean with_attributes)
678 {
679 return duplicateWithNewNameNS(owner, element, element_name, null, with_attributes);
680 }
681
682 /** Duplicates an element, but gives it a new name */
683 public static Element duplicateWithNewNameNS(Document owner, Element element, String element_name, String namespace_uri, boolean with_attributes)
684 {
685 Element duplicate;
686 if (namespace_uri == null)
687 {
688 duplicate = owner.createElement(element_name);
689 }
690 else
691 {
692 duplicate = owner.createElementNS(namespace_uri, element_name);
693 }
694 // Copy element attributes
695 if (with_attributes)
696 {
697 NamedNodeMap attributes = element.getAttributes();
698 for (int i = 0; i < attributes.getLength(); i++)
699 {
700 Node attribute = attributes.item(i);
701 duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
702 }
703 }
704
705 // Copy element children
706 NodeList children = element.getChildNodes();
707 for (int i = 0; i < children.getLength(); i++)
708 {
709 Node child = children.item(i);
710 duplicate.appendChild(owner.importNode(child, true));
711 }
712
713 return duplicate;
714 }
715
716 public static void copyAllChildren(Element to, Element from)
717 {
718
719 Document to_doc = to.getOwnerDocument();
720 Node child = from.getFirstChild();
721 while (child != null)
722 {
723 to.appendChild(to_doc.importNode(child, true));
724 child = child.getNextSibling();
725 }
726 }
727
728 /** returns a basic request message */
729 public static Element createBasicRequest(Document owner, String request_type, String to, String lang, String uid)
730 {
731 Element request = owner.createElement(REQUEST_ELEM);
732 request.setAttribute(TYPE_ATT, request_type);
733 request.setAttribute(LANG_ATT, lang);
734 request.setAttribute(TO_ATT, to);
735 request.setAttribute(USER_ID_ATT, uid);
736 return request;
737 }
738
739 public static Element createBasicResponse(Document owner, String from)
740 {
741 Element response = owner.createElement(GSXML.RESPONSE_ELEM);
742 response.setAttribute(GSXML.FROM_ATT, from);
743 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
744 return response;
745 }
746
747 public static Element createMetadataElement(Document owner, String name, String value)
748 {
749 Element metaElem = owner.createElement(GSXML.METADATA_ELEM);
750 metaElem.setAttribute(GSXML.NAME_ATT, name);
751 metaElem.setAttribute(GSXML.VALUE_ATT, value);
752 return metaElem;
753 }
754
755 public static Element createTextElement(Document owner, String elem_name, String text)
756 {
757 Element e = owner.createElement(elem_name);
758 Text t = owner.createTextNode(text);
759 e.appendChild(t);
760 return e;
761
762 }
763
764 public static Element createTextElement(Document owner, String elem_name, String text, String att_name, String att_value)
765 {
766 Element e = owner.createElement(elem_name);
767 e.setAttribute(att_name, att_value);
768 Text t = owner.createTextNode(text);
769 e.appendChild(t);
770 return e;
771
772 }
773
774 public static Element createDisplayTextElement(Document owner, String text_name, String text)
775 {
776 Element e = owner.createElement(DISPLAY_TEXT_ELEM);
777 e.setAttribute(NAME_ATT, text_name);
778 Text t = owner.createTextNode(text);
779 e.appendChild(t);
780 return e;
781
782 }
783
784 public static Element createParameter(Document owner, String name, String value)
785 {
786 Element param = owner.createElement(PARAM_ELEM);
787 param.setAttribute(NAME_ATT, name);
788 param.setAttribute(VALUE_ATT, value);
789 return param;
790 }
791
792 public static void addParametersToList(Document owner, Element param_list, HashMap params)
793 {
794 if (params == null)
795 {
796 return;
797 }
798
799 Set items = params.entrySet();
800 Iterator i = items.iterator();
801 while (i.hasNext())
802 {
803 Map.Entry m = (Map.Entry) i.next();
804 param_list.appendChild(createParameter(owner, (String) m.getKey(), (String) m.getValue()));
805 }
806
807 }
808
809 public static Element createParameterDescription(Document owner, String id, String display_name, String type, String default_value, String[] option_ids, String[] option_names)
810 {
811
812 Element p = owner.createElement(PARAM_ELEM);
813 p.setAttribute(NAME_ATT, id);
814 p.setAttribute(TYPE_ATT, type);
815 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
816
817 if (default_value != null)
818 {
819 p.setAttribute(DEFAULT_ATT, default_value);
820 }
821 if (option_ids != null && option_names != null)
822 {
823 for (int i = 0; i < option_ids.length; i++)
824 {
825 Element e = owner.createElement(PARAM_OPTION_ELEM);
826 e.setAttribute(NAME_ATT, option_ids[i]);
827 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names[i]));
828 p.appendChild(e);
829 }
830 }
831 return p;
832 }
833
834 public static Element createParameterDescription2(Document owner, String id, String display_name, String type, String default_value, ArrayList option_ids, ArrayList option_names)
835 {
836
837 Element p = owner.createElement(PARAM_ELEM);
838 p.setAttribute(NAME_ATT, id);
839 p.setAttribute(TYPE_ATT, type);
840 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
841 if (default_value != null)
842 {
843 p.setAttribute(DEFAULT_ATT, default_value);
844 }
845 if (option_ids != null && option_names != null)
846 {
847 for (int i = 0; i < option_ids.size(); i++)
848 {
849 Element e = owner.createElement(PARAM_OPTION_ELEM);
850 e.setAttribute(NAME_ATT, (String) option_ids.get(i));
851 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, (String) option_names.get(i)));
852 p.appendChild(e);
853 }
854 }
855 return p;
856 }
857
858 /** returns the element parent/node_name[@attribute_name='attribute_value'] */
859 public static Element getNamedElement(Element parent, String node_name, String attribute_name, String attribute_value)
860 {
861
862 NodeList children = parent.getChildNodes();
863 for (int i = 0; i < children.getLength(); i++)
864 {
865 Node child = children.item(i);
866 if (child.getNodeName().equals(node_name))
867 {
868 if (((Element) child).getAttribute(attribute_name).equals(attribute_value))
869 return (Element) child;
870 }
871 }
872 // not found
873 return null;
874 }
875
876 /**
877 * returns a NodeList of elements:
878 * ancestor/node_name[@attribute_name='attribute_value']
879 */
880 public static NodeList getNamedElements(Element ancestor, String node_name, String attribute_name, String attribute_value)
881 {
882 MyNodeList node_list = new MyNodeList();
883 NodeList children = ancestor.getElementsByTagName(node_name);
884
885 if (children != null && children.getLength() > 0)
886 {
887
888 for (int i = 0; i < children.getLength(); i++)
889 {
890 Node child = children.item(i);
891 if (child.getNodeName().equals(node_name))
892 {
893 if (((Element) child).getAttribute(attribute_name).equals(attribute_value))
894 node_list.addNode(child);
895 }
896 }
897 }
898 return node_list;
899 }
900
901 public static int SORT_TYPE_STRING = 0;
902 public static int SORT_TYPE_INT = 1;
903 public static int SORT_TYPE_FLOAT = 2;
904
905 // sort type:
906 public static Element insertIntoOrderedList(Element parent_node, String node_name, Element start_from_elem, Element new_elem, String sort_att, boolean descending)
907 {
908 if (new_elem == null)
909 return null;
910 Element cloned_elem = (Element) parent_node.getOwnerDocument().importNode(new_elem, true);
911 if (start_from_elem == null)
912 {
913 parent_node.appendChild(cloned_elem);
914 return cloned_elem;
915 }
916
917 Node current_node = start_from_elem;
918 String insert_att = cloned_elem.getAttribute(sort_att);
919 String list_att = start_from_elem.getAttribute(sort_att);
920 while ((!descending && list_att.compareTo(insert_att) < 0) || (descending && list_att.compareTo(insert_att) > 0))
921 {
922 current_node = current_node.getNextSibling();
923 if (current_node == null)
924 break; // end of the list
925 if (!current_node.getNodeName().equals(node_name))
926 {
927 continue; // not a valid node
928 }
929 list_att = ((Element) current_node).getAttribute(sort_att);
930 }
931
932 parent_node.insertBefore(cloned_elem, current_node);
933 return cloned_elem;
934 }
935
936 /**
937 * Returns the appropriate language element from a display elem, display is
938 * the containing element, name is the name of the element to look for, lang
939 * is the preferred language, lang_default is the fall back lang if neither
940 * lang is found, will return the first one it finds
941 */
942 public static String getDisplayText(Element display, String name, String lang, String lang_default)
943 {
944
945 String def = null;
946 String first = null;
947 NodeList elems = display.getElementsByTagName(DISPLAY_TEXT_ELEM);
948 if (elems.getLength() == 0)
949 return "";
950 for (int i = 0; i < elems.getLength(); i++)
951 {
952 Element e = (Element) elems.item(i);
953 String n = e.getAttribute(NAME_ATT);
954 if (name.equals(n))
955 {
956 String l = e.getAttribute(LANG_ATT);
957 if (lang.equals(l))
958 {
959 return getNodeText(e);
960 }
961 else if (lang_default.equals(l))
962 {
963 def = getNodeText(e);
964 }
965 else if (first == null)
966 {
967 first = getNodeText(e);
968 }
969 }
970 else
971 {
972 continue;
973 }
974 }
975
976 if (def != null)
977 {
978 return def;
979 }
980 if (first != null)
981 {
982 return first;
983 }
984 return "";
985 }
986
987 // replaces < > " ' & in the original with their entities
988 public static String xmlSafe(String original)
989 {
990
991 StringBuffer filtered = new StringBuffer(original.length());
992 char c;
993 for (int i = 0; i < original.length(); i++)
994 {
995 c = original.charAt(i);
996 if (c == '>')
997 {
998 filtered.append("&gt;");
999 }
1000 else if (c == '<')
1001 {
1002 filtered.append("&lt;");
1003 }
1004 else if (c == '"')
1005 {
1006 filtered.append("&quot;");
1007 }
1008 else if (c == '&')
1009 {
1010 filtered.append("&amp;");
1011 }
1012 else if (c == '\'')
1013 {
1014 filtered.append("&apos;");
1015 }
1016 else
1017 {
1018 filtered.append(c);
1019 }
1020 }
1021 return filtered.toString();
1022 }
1023
1024 // replaces < > " ' & entities with their originals
1025 public static String unXmlSafe(String original)
1026 {
1027
1028 StringBuffer filtered = new StringBuffer(original.length());
1029 char c;
1030 for (int i = 0; i < original.length(); i++)
1031 {
1032 c = original.charAt(i);
1033 if (c == '&')
1034 {
1035 int pos = original.indexOf(";", i);
1036 String entity = original.substring(i + 1, pos);
1037 if (entity.equals("gt"))
1038 {
1039 filtered.append(">");
1040 }
1041 else if (entity.equals("lt"))
1042 {
1043 filtered.append("<");
1044 }
1045 else if (entity.equals("apos"))
1046 {
1047 filtered.append("'");
1048 }
1049 else if (entity.equals("amp"))
1050 {
1051 filtered.append("&");
1052 }
1053 else if (entity.equals("quot"))
1054 {
1055 filtered.append("\"");
1056 }
1057 else
1058 {
1059 filtered.append("&" + entity + ";");
1060 }
1061 i = pos;
1062 }
1063 else
1064 {
1065 filtered.append(c);
1066 }
1067 }
1068 return filtered.toString();
1069 }
1070
1071 public static void printXMLNode(Node e, boolean printText)
1072 {
1073 printXMLNode(e, 0, printText);
1074 }
1075
1076 public static String xmlNodeToString(Node e)
1077 {
1078 StringBuffer sb = new StringBuffer("");
1079 xmlNodeToString(sb, e, 0, true);
1080 return sb.toString();
1081 }
1082
1083 public static String xmlNodeToString(Node e, boolean printText)
1084 {
1085 StringBuffer sb = new StringBuffer("");
1086 xmlNodeToString(sb, e, 0, printText);
1087 return sb.toString();
1088 }
1089
1090 private static void xmlNodeToString(StringBuffer sb, Node e, int depth, boolean printText)
1091 {
1092
1093 for (int i = 0; i < depth; i++)
1094 sb.append(' ');
1095
1096 if (e.getNodeType() == Node.TEXT_NODE)
1097 {
1098 if (printText)
1099 {
1100 sb.append(e.getNodeValue());
1101 }
1102 else
1103 {
1104 sb.append("text");
1105 }
1106 return;
1107 }
1108
1109 sb.append('<');
1110 sb.append(e.getNodeName());
1111 NamedNodeMap attrs = e.getAttributes();
1112 if (attrs != null)
1113 {
1114 for (int i = 0; i < attrs.getLength(); i++)
1115 {
1116 Node attr = attrs.item(i);
1117 sb.append(' ');
1118 sb.append(attr.getNodeName());
1119 sb.append("=\"");
1120 sb.append(attr.getNodeValue());
1121 sb.append('"');
1122 }
1123 }
1124
1125 NodeList children = e.getChildNodes();
1126
1127 if (children == null || children.getLength() == 0)
1128 sb.append("/>\n");
1129 else
1130 {
1131
1132 sb.append(">\n");
1133
1134 int len = children.getLength();
1135 for (int i = 0; i < len; i++)
1136 {
1137 xmlNodeToString(sb, children.item(i), depth + 1, printText);
1138 }
1139
1140 for (int i = 0; i < depth; i++)
1141 sb.append(' ');
1142
1143 sb.append("</" + e.getNodeName() + ">\n");
1144 }
1145
1146 }
1147
1148 public static void printXMLNode(Node e, int depth, boolean printText)
1149 { //recursive method call using DOM API...
1150
1151 if (e == null)
1152 {
1153 return;
1154 }
1155
1156 for (int i = 0; i < depth; i++)
1157 System.out.print(' ');
1158
1159 if (e.getNodeType() == Node.TEXT_NODE)
1160 {
1161 if (printText)
1162 {
1163 System.out.println(e.getNodeValue());
1164 }
1165 else
1166 {
1167 System.out.println("text");
1168 }
1169 return;
1170 }
1171
1172 System.out.print('<');
1173 System.out.print(e.getNodeName());
1174 NamedNodeMap attrs = e.getAttributes();
1175
1176 if (attrs != null)
1177 {
1178 for (int i = 0; i < attrs.getLength(); i++)
1179 {
1180 Node attr = attrs.item(i);
1181 System.out.print(' ');
1182 System.out.print(attr.getNodeName());
1183 System.out.print("=\"");
1184 System.out.print(attr.getNodeValue());
1185 System.out.print('"');
1186 }
1187 }
1188
1189 NodeList children = e.getChildNodes();
1190
1191 if (children == null || children.getLength() == 0)
1192 System.out.println("/>");
1193 else
1194 {
1195
1196 System.out.println('>');
1197
1198 int len = children.getLength();
1199 for (int i = 0; i < len; i++)
1200 {
1201 printXMLNode(children.item(i), depth + 1, printText);
1202 }
1203
1204 for (int i = 0; i < depth; i++)
1205 System.out.print(' ');
1206
1207 System.out.println("</" + e.getNodeName() + ">");
1208 }
1209 }
1210
1211 public static void elementToLogAsString(Element e)
1212 {
1213 try
1214 {
1215 TransformerFactory tf = TransformerFactory.newInstance();
1216 Transformer trans = tf.newTransformer();
1217 StringWriter sw = new StringWriter();
1218 trans.transform(new DOMSource(e), new StreamResult(sw));
1219 System.err.println(sw.toString());
1220 }
1221 catch (Exception ex)
1222 {
1223 System.err.println("couldn't write " + e + " to log");
1224 }
1225 }
1226}
Note: See TracBrowser for help on using the repository browser.