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

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

Fixing Greenstone 3's use (or lack thereof) of generics, this was done automatically so we may want to change it over time. This change will also auto-format any files that have not already been formatted.

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