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

Last change on this file since 30584 was 30584, checked in by kjdon, 8 years ago

added GSLIB namespace to the list. Also created strings and methods for adding namespaces to XML (string or Node) so that all places get the same default namespaces

  • Property svn:keywords set to Author Date Id Revision
File size: 50.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 java.io.Serializable;
22import java.io.StringWriter;
23import java.util.ArrayList;
24import java.util.HashMap;
25import java.util.Iterator;
26import java.util.Map;
27import java.util.Set;
28import java.util.Vector;
29
30import javax.xml.transform.OutputKeys;
31import javax.xml.transform.Transformer;
32import javax.xml.transform.TransformerFactory;
33import javax.xml.transform.dom.DOMSource;
34import javax.xml.transform.stream.StreamResult;
35
36import org.apache.log4j.Logger;
37import org.w3c.dom.Document;
38import org.w3c.dom.Element;
39import org.w3c.dom.NamedNodeMap;
40import org.w3c.dom.Node;
41import org.w3c.dom.NodeList;
42import org.w3c.dom.Text;
43
44import org.greenstone.gsdl3.util.MyNodeList;
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 message 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 LIBRARY_PARAM_ELEM = "libraryParam";
62 public static final String CONTENT_ELEM = "content";
63 public static final String RESOURCE_ELEM = "resource";
64 public static final String DOCUMENT_ELEM = "document";
65 public static final String METADATA_ELEM = "metadata";
66 public static final String SERVICE_CLASS_ELEM = "serviceRack";
67 public static final String CLASSIFIER_ELEM = "classifier";
68 public static final String APPLET_ELEM = "applet";
69 public static final String APPLET_DATA_ELEM = "appletData";
70 public static final String CONFIGURE_ELEM = "configure";
71 public static final String STATUS_ELEM = "status";
72 public static final String ERROR_ELEM = "error";
73 public static final String DEFAULT_ELEM = "default";
74 public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem
75 public static final String FORMAT_ELEM = "format"; // config files use format - should we use this instead of stylesheet??
76 public static final String GLOBAL_FORMAT_ELEM = "globalFormat";
77 public static final String TERM_ELEM = "term";
78 public static final String STOPWORD_ELEM = "stopword";
79 public static final String FACET_ELEM = "facet";
80 public static final String COUNT_ELEM = "count";
81 public static final String SYSTEM_ELEM = "system";
82 public static final String FORMAT_STRING_ELEM = "formatString";
83 public static final String EXTRA_METADATA = "extraMetadata";
84
85 //config file elems
86 public static final String COLLECTION_CONFIG_ELEM = "collectionConfig";
87 public static final String COLLECTION_BUILD_ELEM = "buildConfig";
88 public static final String COLLECTION_INIT_ELEM = "collectionInit";
89 public static final String RECOGNISE_ELEM = "recognise";
90 public static final String DOC_TYPE_ELEM = "docType";
91 public static final String SEARCH_ELEM = "search";
92 public static final String INFODB_ELEM = "infodb";
93 public static final String INDEX_ELEM = "index";
94 public static final String INDEX_STEM_ELEM = "indexStem";
95 public static final String INDEX_OPTION_ELEM = "indexOption";
96 public static final String PARAM_DEFAULT_ELEM = "paramDefault";
97 public static final String BROWSE_ELEM = "browse";
98 public static final String DISPLAY_ELEM = "display";
99 public static final String LEVEL_ELEM = "level";
100 public static final String REPLACE_ELEM = "replace";
101 public static final String EXTRA_INFO_ELEM = "extraInfo";
102 public static final String DBINFO_ELEM = "dbInfo";
103 public static final String DBNAME_ATT = "dbname";
104 public static final String DBPATH_ATT = "dbpath";
105 public static final String SQLSTATE_ATT = "sqlstate";
106 public static final String DATABASE_TYPE_ELEM = "databaseType";
107 public static final String SHORTNAME_ATT = "shortname";
108 public static final String NOTIFY_ELEM = "notify";
109 public static final String NOTIFY_HOST_ATT = "host";
110
111 //doc.xml file elems
112 public static final String DOCXML_SECTION_ELEM = "Section";
113 public static final String DOCXML_DESCRIPTION_ELEM = "Description";
114 public static final String DOCXML_METADATA_ELEM = "Metadata";
115 public static final String DOCXML_CONTENT_ELEM = "Content";
116
117 // elems for the pages to be processed by xslt
118 public final static String PAGE_ELEM = "page";
119 public final static String CONFIGURATION_ELEM = "config";
120 public final static String PAGE_REQUEST_ELEM = "pageRequest";
121 public final static String PAGE_RESPONSE_ELEM = "pageResponse";
122 public final static String PAGE_EXTRA_ELEM = "pageExtra";
123
124 //public final static String DESCRIPTION_ELEM = "description";
125
126 public static final String ACTION_ELEM = "action";
127 public static final String SUBACTION_ELEM = "subaction";
128
129 // add on to another elem type to get a list of that type
130 public static final String LIST_MODIFIER = "List";
131 // used to refer back to another element type
132 public static final String REF_MODIFIER = "Ref";
133 // greenstone xml attributes
134 public static final String COLLECTION_ATT = "collection";
135 public static final String NAME_ATT = "name";
136 public static final String MATCH_ATT = "match";
137 public static final String TO_ATT = "to";
138 public static final String USER_ID_ATT = "uid";
139 public static final String FROM_ATT = "from";
140 public static final String LANG_ATT = "lang";
141 public static final String HREF_ATT = "href";
142 public static final String TYPE_ATT = "type";
143 public static final String DB_TYPE_ATT = "dbType";
144 public static final String VALUE_ATT = "value";
145 public static final String DEFAULT_ATT = "default";
146 public static final String INFO_ATT = "info";
147 public static final String ACTION_ATT = "action";
148 public static final String SUBACTION_ATT = "subaction";
149 public static final String OUTPUT_ATT = "output";
150 public static final String ADDRESS_ATT = "address";
151 public static final String LOCAL_SITE_ATT = "localSite";
152 public static final String LOCAL_SITE_NAME_ATT = "localSiteName";
153 public static final String STATUS_ERROR_CODE_ATT = "code";
154 public static final String STATUS_PROCESS_ID_ATT = "pid";
155 public static final String PARAM_SHORTNAME_ATT = "shortname";
156 public static final String PARAM_IGNORE_POS_ATT = "ignore";
157 public static final String CLASSIFIER_CONTENT_ATT = "content";
158 public static final String ERROR_TYPE_ATT = "type";
159 public static final String COLLECT_TYPE_ATT = "ct";
160 public static final String HIDDEN_ATT = "hidden";
161 public static final String FACET_ATT = "facet";
162
163 // document stuff
164 public static final String DOC_TYPE_ATT = "docType";
165 public static final String DOC_NODE_ELEM = "documentNode";
166 public static final String NODE_CONTENT_ELEM = "nodeContent";
167 public static final String NODE_STRUCTURE_ELEM = "nodeStructure";
168 public static final String NODE_ID_ATT = "nodeID";
169 public static final String HREF_ID_ATT = "hrefId"; // for ids that need translating
170 public static final String HL_SNIPPET_ELEM = "highlightSnippet";
171 public static final String ID_MOD_ATT = "idMod"; // might hold .rt etc for hrefIds
172 public static final String NODE_OID = "oid";
173 public static final String NODE_NAME_ATT = "nodeName";
174 public static final String NODE_TYPE_ATT = "nodeType";
175 public static final String NODE_RANK_ATT = "rank";
176 public static final String NODE_TYPE_ROOT = "root";
177 public static final String NODE_TYPE_INTERNAL = "internal";
178 public static final String NODE_TYPE_LEAF = "leaf";
179
180 public static final String DOC_TYPE_SIMPLE = "simple";
181 public static final String DOC_TYPE_PAGED = "paged";
182 public static final String DOC_TYPE_HIERARCHY = "hierarchy";
183 public static final String DOC_TYPE_PAGED_HIERARCHY = "pagedhierarchy";
184
185 public static final String SESSION_EXPIRATION = "session_expiration";
186 public static final String USER_SESSION_CACHE_ATT = "user_session_cache";
187
188 // classifier stuff
189 public static final String CLASS_NODE_ELEM = "classifierNode";
190 public static final String CLASS_NODE_ORIENTATION_ATT = "orientation";
191
192 // parameter types
193 public static final String PARAM_TYPE_INTEGER = "integer";
194 public static final String PARAM_TYPE_BOOLEAN = "boolean";
195 public static final String PARAM_TYPE_ENUM_START = "enum";
196 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
197 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
198 public static final String PARAM_TYPE_STRING = "string";
199 public static final String PARAM_TYPE_TEXT = "text";
200 public static final String PARAM_TYPE_MULTI = "multi";
201 public static final String PARAM_TYPE_FILE = "file";
202 public static final String PARAM_TYPE_INVISIBLE = "invisible";
203 public static final String PARAM_TYPE_CHECKBOX_LIST = "checkbox_list";
204 // stuff for text strings
205 public static final String DISPLAY_TEXT_ELEM = "displayItem";
206 // the following are used for the name attributes
207 public static final String DISPLAY_TEXT_NAME = "name";
208 public static final String DISPLAY_TEXT_SUBMIT = "submit";
209 public static final String DISPLAY_TEXT_DESCRIPTION = "description";
210
211 // request types
212 // get the module description
213 public static final String REQUEST_TYPE_DESCRIBE = "describe";
214 // startup a process
215 public static final String REQUEST_TYPE_PROCESS = "process";
216 // get the status of an ongoing process
217 public static final String REQUEST_TYPE_STATUS = "status";
218 // system type request - eg reload a collection
219 public static final String REQUEST_TYPE_SYSTEM = "system";
220 // page requests to the Receptionist/Actions
221 public static final String REQUEST_TYPE_PAGE = "page"; // used to be cgi
222 // get any format info for a service
223 public static final String REQUEST_TYPE_FORMAT = "format";
224 // modify the requests
225 public static final String REQUEST_TYPE_MESSAGING = "messaging";
226 // save the format string
227 public static final String REQUEST_TYPE_FORMAT_STRING = "formatString";
228 // check credentials
229 public static final String REQUEST_TYPE_SECURITY = "security";
230
231 // service types
232 public static final String SERVICE_TYPE_QUERY = "query";
233 public static final String SERVICE_TYPE_RETRIEVE = "retrieve";
234 public static final String SERVICE_TYPE_BROWSE = "browse";
235 public static final String SERVICE_TYPE_GROUPINFO = "groupinfo";
236 public static final String SERVICE_TYPE_APPLET = "applet";
237 public static final String SERVICE_TYPE_PROCESS = "process";
238 public static final String SERVICE_TYPE_ENRICH = "enrich";
239 public static final String SERVICE_TYPE_OAI = "oai";
240 public static final String FLAX_PAGE = "flaxPage";
241 public static final String FLAX_PAGE_GENERATION = "FlaxPageGeneration";
242
243 // system command types and attributes
244 public static final String SYSTEM_TYPE_CONFIGURE = "configure";
245 public static final String SYSTEM_TYPE_ACTIVATE = "activate";
246 public static final String SYSTEM_TYPE_DEACTIVATE = "deactivate";
247 public static final String SYSTEM_TYPE_PING = "ping";
248 public static final String SYSTEM_TYPE_AUTHENTICATED_PING = "authenticated-ping";
249 //public static final String SYSTEM_TYPE_ISPERSISTENT = "is-persistent";
250
251 public static final String SYSTEM_SUBSET_ATT = "subset";
252 public static final String SYSTEM_MODULE_TYPE_ATT = "moduleType";
253 public static final String SYSTEM_MODULE_NAME_ATT = "moduleName";
254
255 // communicator types
256 public static final String COMM_TYPE_SOAP_JAVA = "soap";
257
258 // error types
259 public static final String ERROR_TYPE_SYNTAX = "syntax";
260 public static final String ERROR_TYPE_SYSTEM = "system";
261 public static final String ERROR_TYPE_INVALID_ID = "invalid_id";
262 public static final String ERROR_TYPE_OTHER = "other";
263
264 // some system wide param names
265 public static final String SUBSET_PARAM = "subset";
266
267 //for plugin
268 public static final String PLUGIN_ELEM = "plugin";
269 public static final String IMPORT_ELEM = "import";
270
271 //for authentication
272 public static final String AUTHEN_NODE_ELEM = "authenticationNode";
273 public static final String USER_NODE_ELEM = "userNode";
274
275 //for configure action results
276 public static final String SUCCESS = "success";
277 public static final String ERROR = "error";
278
279 //security tags and attributes
280 public static final String SECURITY_ELEM = "security";
281 public static final String DISABLED_ATT = "disabled";
282 public static final String SCOPE_ATT = "scope";
283 public static final String DEFAULT_ACCESS_ATT = "default_access";
284 public static final String EXCEPTION_ELEM = "exception";
285 public static final String DOCUMENT_SET_ELEM = "documentSet";
286 public static final String GROUP_ELEM = "group";
287 public static final String MATCH_ELEM = "match";
288 public static final String FIELD_ATT = "field";
289 public static final String USER_INFORMATION_ELEM = "userInformation";
290 public static final String USERNAME_ATT = "username";
291 public static final String GROUPS_ATT = "groups";
292 public static final String BASE_URL = "baseURL";
293
294 // only for authenticated-ping
295 public static final String PASSWORD_ATT = "password";
296
297 //for classifiers
298 public static final String CHILD_TYPE_ATT = "childType";
299 public static final String CLASSIFIER_STYLE_ATT = "classifierStyle";
300 public static final String HLIST = "HList";
301 public static final String VLIST = "VList";
302
303 //for namespaces
304 public static final String XSL_NAMESPACE = "http://www.w3.org/1999/XSL/Transform";
305 public static final String GSF_NAMESPACE = "http://www.greenstone.org/greenstone3/schema/ConfigFormat";
306 public static final String GSLIB_NAMESPACE = "http://www.greenstone.org/skinning";
307 public static final String JAVA_NAMESPACE = "http://xml.apache.org/xslt/java";
308 public static final String UTIL_NAMESPACE = "xalan://org.greenstone.gsdl3.util.XSLTUtil";
309
310 // all the namespaces in a string for easy addition to a string
311 public static final String ALL_NAMESPACES_ATTS = "xmlns:gsf='" + GSF_NAMESPACE + "' xmlns:xsl='" + XSL_NAMESPACE + "' xmlns:gslib='" + GSLIB_NAMESPACE + "' xmlns:java='" + JAVA_NAMESPACE + "' xmlns:util='" + UTIL_NAMESPACE +"' ";
312 public static final String STD_NAMESPACES_ATTS = "xmlns:gsf='" + GSF_NAMESPACE + "' xmlns:xsl='" + XSL_NAMESPACE + "' xmlns:gslib='" + GSLIB_NAMESPACE +"' ";
313
314 //Groups configuration
315 public static final String HIERARCHY_ELEM = "hierarchy";
316 public static final String GROUP_DESC_ELEM = "groupDescriptions";
317 public static final String TITLE_ELEM = "title";
318 public static final String DESCRIPTION_ELEM = "description";
319 public static final String SHORT_DESCRIPTION_ELEM = "shortDescription";
320 public static final String BACKGROUND_IMAGE_ELEM = "backgroundImage";
321 public static final String POSITION_ATT = "position";
322
323 /**
324 * takes a list of elements, and returns an array of strings of the values
325 * of attribute att_name
326 */
327 public static String[] getAttributeValuesFromList(Element list, String att_name)
328 {
329
330 NodeList children = list.getChildNodes();
331
332 int num_nodes = children.getLength();
333 String[] ids = new String[num_nodes];
334 for (int i = 0; i < num_nodes; i++)
335 {
336 Element e = (Element) children.item(i);
337 String id = e.getAttribute(att_name);
338 ids[i] = id;
339 }
340
341 return ids;
342 }
343
344 public static HashMap<String, String> getParamMap(NodeList params) {
345 HashMap<String, String> map = new HashMap<String, String>();
346 for(int i=0; i<params.getLength(); i++) {
347 Element param = (Element)params.item(i);
348 String param_name = param.getAttribute(NAME_ATT);
349 String param_value = param.getAttribute(VALUE_ATT);
350 map.put(param_name, param_value);
351 }
352 return map;
353 }
354
355 public static HashMap<String, Serializable> extractParams(Element xml, boolean deep)
356 {
357 return extractParams(xml, deep, null);
358 }
359
360 /**
361 * takes a paramList element, and gets a HashMap of name-value pairs if
362 * deep=true, extracts embedded params, otherwise just top level params
363 */
364 public static HashMap<String, Serializable> extractParams(Element xml, boolean deep, String toFind)
365 {
366 if (xml == null)
367 {
368 return null;
369 }
370
371 if (!xml.getNodeName().equals(PARAM_ELEM + LIST_MODIFIER))
372 {
373 logger.error("paramList element should have been passed to extractParams, instead it was " + xml.getNodeName());
374 return null;
375 }
376
377 NodeList params = null;
378 if (deep)
379 { // get all the nested ones
380 params = xml.getElementsByTagName(PARAM_ELEM);
381 }
382 else
383 { // just get the top level ones
384 params = xml.getChildNodes();
385 }
386 HashMap<String, Serializable> param_map = new HashMap<String, Serializable>();
387 for (int i = 0; i < params.getLength(); i++)
388 {
389 if (params.item(i).getNodeName().equals(PARAM_ELEM))
390 {
391 Element param = (Element) params.item(i);
392 String name = param.getAttribute(NAME_ATT);
393 String value = getValue(param); //att or content
394
395 // For only one parameter
396 if (toFind != null && name.equals(toFind))
397 {
398 param_map.put(name, value);
399 return param_map;
400 }
401 else if (toFind != null)
402 continue;
403
404 int pos = name.indexOf('.');
405 if (pos == -1)
406 { // a base param
407 param_map.put(name, value);
408 }
409 else
410 { // a namespaced param
411
412 String namespace = name.substring(0, pos);
413 name = name.substring(pos + 1);
414 HashMap<String, String> map = (HashMap<String, String>) param_map.get(namespace);
415 if (map == null)
416 {
417 map = new HashMap<String, String>();
418 param_map.put(namespace, map);
419 }
420 map.put(name, value);
421 }
422 }
423 }
424 return param_map;
425 }
426
427 /** gets the value att or the text content */
428 public static String getValue(Element e)
429 {
430 String val = e.getAttribute(VALUE_ATT);
431 if (val == null || val.equals(""))
432 {
433 // have to get it out of the text
434 val = getNodeText(e);
435
436 }
437 else
438 {
439 // unescape the xml stuff
440 val = unXmlSafe(val);
441 }
442 return val;
443 }
444
445 /** extracts the text out of a node */
446 public static Node getNodeTextNode(Element param)
447 {
448 param.normalize();
449 Node n = param.getFirstChild();
450 while (n != null && n.getNodeType() != Node.TEXT_NODE)
451 {
452 n = n.getNextSibling();
453 }
454 return n;
455 }
456
457 /** extracts the text out of a node */
458 public static String getNodeText(Element param)
459 {
460 Node text_node = getNodeTextNode(param);
461 if (text_node == null)
462 {
463 return "";
464 }
465 return text_node.getNodeValue();
466 }
467
468 public static void setNodeText(Element elem, String text)
469 {
470 Node old_text_node = getNodeTextNode(elem);
471 if (old_text_node != null)
472 {
473 elem.removeChild(old_text_node);
474 }
475 Text t = elem.getOwnerDocument().createTextNode(text);
476 elem.appendChild(t);
477 }
478
479 /** add text to a document/subsection element */
480 public static boolean addDocText(Element doc, String text)
481 {
482
483 Element content = doc.getOwnerDocument().createElement(NODE_CONTENT_ELEM);
484 Text t = doc.getOwnerDocument().createTextNode(text);
485 content.appendChild(t);
486 doc.appendChild(content);
487 return true;
488 }
489
490 /** add an error message, unknown error type */
491 public static boolean addError(Element doc, String text)
492 {
493 return addError(doc, text, ERROR_TYPE_OTHER);
494 }
495
496 /** add an error message */
497 public static boolean addError(Element doc, String text, String error_type)
498 {
499
500 Element content = doc.getOwnerDocument().createElement(ERROR_ELEM);
501 content.setAttribute(ERROR_TYPE_ATT, error_type);
502 Text t = doc.getOwnerDocument().createTextNode(text);
503 content.appendChild(t);
504 doc.appendChild(content);
505 return true;
506 }
507
508 /** add an error message */
509 public static boolean addError(Element doc, Throwable error)
510 {
511 return addError(doc, error, ERROR_TYPE_OTHER);
512 }
513
514 /** add an error message */
515 public static boolean addError(Element doc, Throwable error, String error_type)
516 {
517 error.printStackTrace();
518 return addError(doc, error.toString(), error_type);
519 }
520
521 public static boolean addGSNamespaces(Element elem, boolean include_extension_ns) {
522 if (elem == null) {
523 return false;
524 }
525 elem.setAttribute("xmlns:gsf", GSF_NAMESPACE);
526 elem.setAttribute("xmlns:xsl", XSL_NAMESPACE);
527 elem.setAttribute("xmlns:gslib", GSLIB_NAMESPACE);
528 if (include_extension_ns) {
529 elem.setAttribute("xmlns:util", UTIL_NAMESPACE);
530 elem.setAttribute("xmlns:java", JAVA_NAMESPACE);
531 }
532 return true;
533 }
534 public static Element createMetadataParamList(Document owner, Vector meta_values)
535 {
536
537 Element meta_param_list = owner.createElement(PARAM_ELEM + LIST_MODIFIER);
538 Iterator i = meta_values.iterator();
539 while (i.hasNext())
540 {
541 String next = (String) i.next();
542 Element meta_param = owner.createElement(PARAM_ELEM);
543 meta_param_list.appendChild(meta_param);
544 meta_param.setAttribute(NAME_ATT, "metadata");
545 meta_param.setAttribute(VALUE_ATT, next);
546 }
547 return meta_param_list;
548 }
549
550 /** adds a metadata elem to a list */
551 public static boolean addMetadata(Element list, String meta_name, String meta_value)
552 {
553 if (meta_value == null || meta_value.equals(""))
554 {
555 return false;
556 }
557 Document owner = list.getOwnerDocument();
558 Element data = owner.createElement(METADATA_ELEM);
559 data.setAttribute(NAME_ATT, meta_name);
560 Text t = owner.createTextNode(meta_value);
561 data.appendChild(t);
562 list.appendChild(data);
563 return true;
564
565 }
566
567 /**
568 * copies the metadata out of the metadataList of 'from' into the
569 * metadataList of 'to'
570 */
571 public static boolean mergeMetadataLists(Node to, Node from)
572 {
573 Node from_meta = getChildByTagName(from, METADATA_ELEM + LIST_MODIFIER);
574 if (from_meta == null)
575 { // nothing to copy
576 return true;
577 }
578 return mergeMetadataFromList(to, from_meta);
579 }
580
581 /**
582 * copies the metadata out of the meta_list metadataList into the
583 * metadataList of 'to'
584 */
585 public static boolean mergeMetadataFromList(Node to, Node meta_list)
586 {
587 if (meta_list == null)
588 return false;
589 Node to_meta = getChildByTagName(to, METADATA_ELEM + LIST_MODIFIER);
590 Document to_owner = to.getOwnerDocument();
591 if (to_meta == null)
592 {
593 to.appendChild(to_owner.importNode(meta_list, true));
594 return true;
595 }
596 // copy individual metadata elements
597 NodeList meta_items = ((Element) meta_list).getElementsByTagName(METADATA_ELEM);
598 for (int i = 0; i < meta_items.getLength(); i++)
599 {
600 to_meta.appendChild(to_owner.importNode(meta_items.item(i), true));
601 }
602 return true;
603 }
604
605 /** copies all the children from from to to */
606 public static boolean mergeElements(Element to, Element from)
607 {
608
609 Document owner = to.getOwnerDocument();
610 Node child = from.getFirstChild();
611 while (child != null)
612 {
613 to.appendChild(owner.importNode(child, true));
614 child = child.getNextSibling();
615 }
616 return true;
617 }
618
619 /** returns the (first) element child of the node n */
620 public static Element getFirstElementChild(Node n)
621 {
622
623 Node child = n.getFirstChild();
624 while (child != null)
625 {
626 if (child.getNodeType() == Node.ELEMENT_NODE)
627 {
628 return (Element) child;
629 }
630 child = child.getNextSibling();
631 }
632 return null; //no element child found
633 }
634
635 /** returns the (first) child element with the given name */
636 public static Node getChildByTagName(Node n, String name)
637 {
638 if (n != null)
639 { // this line is an attempted solution to the NullPointerException mentioned
640 // in trac bug ticket #225. If n is null can't do n.getFirstChild() below. As per bug #225:
641 // GSXML.getNodeByPath() is called by GS2BrowseAction, which then calls this method.
642 // If n is null, null will be returned which GS2BrowseAction already checks for. It's here
643 // that the NullPointerException was thrown.
644
645 Node child = n.getFirstChild();
646 while (child != null)
647 {
648 if (child.getNodeName().equals(name))
649 {
650 return child;
651 }
652 child = child.getNextSibling();
653 }
654 }
655 return null; //not found
656 }
657
658 /**
659 * returns the (nth) child element with the given name index numbers start
660 * at 0
661 */
662 public static Node getChildByTagNameIndexed(Node n, String name, int index)
663 {
664 if (index == -1)
665 {
666 return getChildByTagName(n, name);
667 }
668 int count = 0;
669 Node child = n.getFirstChild();
670 while (child != null)
671 {
672 if (child.getNodeName().equals(name))
673 {
674 if (count == index)
675 {
676 return child;
677 }
678 else
679 {
680 count++;
681 }
682 }
683 child = child.getNextSibling();
684 }
685 return null; //not found
686 }
687
688 /**
689 * takes an xpath type expression of the form name/name/... and returns the
690 * first node that matches, or null if not found
691 */
692 public static Node getNodeByPath(Node n, String path)
693 {
694
695 String link = GSPath.getFirstLink(path);
696 path = GSPath.removeFirstLink(path);
697 while (!link.equals(""))
698 {
699 n = getChildByTagName(n, link);
700 if (n == null)
701 {
702 return null;
703 }
704 link = GSPath.getFirstLink(path);
705 path = GSPath.removeFirstLink(path);
706 }
707 return n;
708 }
709
710 /**
711 * takes an xpath type expression of the form name/name/... and returns the
712 * first node that matches, or null if not found can include [i] indices.
713 * index numbers start at 0
714 */
715 public static Node getNodeByPathIndexed(Node n, String path)
716 {
717
718 String link = GSPath.getFirstLink(path);
719 int index = GSPath.getIndex(link);
720 if (index != -1)
721 {
722 link = GSPath.removeIndex(link);
723 }
724 path = GSPath.removeFirstLink(path);
725 while (!link.equals(""))
726 {
727 n = getChildByTagNameIndexed(n, link, index);
728 if (n == null)
729 {
730 return null;
731 }
732 link = GSPath.getFirstLink(path);
733 index = GSPath.getIndex(link);
734 if (index != -1)
735 {
736 link = GSPath.removeIndex(link);
737 }
738 path = GSPath.removeFirstLink(path);
739 }
740 return n;
741 }
742
743 public static HashMap<String, Node> getChildrenMap(Node n)
744 {
745
746 HashMap<String, Node> map = new HashMap<String, Node>();
747 Node child = n.getFirstChild();
748 while (child != null)
749 {
750 String name = child.getNodeName();
751 map.put(name, child);
752 child = child.getNextSibling();
753 }
754 return map;
755 }
756
757 public static NodeList getChildrenByTagName(Node n, String name)
758 {
759 MyNodeList node_list = new MyNodeList();
760 Node child = n.getFirstChild();
761 while (child != null)
762 {
763 if (child.getNodeName().equals(name))
764 {
765 node_list.addNode(child);
766 }
767 child = child.getNextSibling();
768 }
769 return node_list;
770 }
771
772 public static NodeList getChildrenByTagNameNS(Node n, String namespace, String local_name)
773 {
774 MyNodeList node_list = new MyNodeList();
775 Node child = n.getFirstChild();
776 while (child != null)
777 {
778 if (child.getNodeType() == Node.ELEMENT_NODE && child.getNamespaceURI() != null && child.getNamespaceURI().equals(namespace) && child.getLocalName() != null && child.getLocalName().equals(local_name))
779 {
780 node_list.addNode(child);
781 }
782 child = child.getNextSibling();
783 }
784 return node_list;
785 }
786
787 /** Duplicates an element, but gives it a new name */
788 public static Element duplicateWithNewName(Document owner, Element element, String element_name, boolean with_attributes)
789 {
790 return duplicateWithNewNameNS(owner, element, element_name, null, with_attributes);
791 }
792
793 /** Duplicates an element, but gives it a new name */
794 public static Element duplicateWithNewNameNS(Document owner, Element element, String element_name, String namespace_uri, boolean with_attributes)
795 {
796 Element duplicate;
797 if (namespace_uri == null)
798 {
799 duplicate = owner.createElement(element_name);
800 }
801 else
802 {
803 duplicate = owner.createElementNS(namespace_uri, element_name);
804 }
805
806 // Copy element attributes
807 if (with_attributes)
808 {
809 NamedNodeMap attributes = element.getAttributes();
810 for (int i = 0; i < attributes.getLength(); i++)
811 {
812 Node attribute = attributes.item(i);
813 duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
814 }
815 }
816
817 // Copy element children
818 NodeList children = element.getChildNodes();
819 for (int i = 0; i < children.getLength(); i++)
820 {
821 Node child = children.item(i);
822 duplicate.appendChild(owner.importNode(child, true));
823 }
824
825 return duplicate;
826 }
827
828 public static void copyAllChildren(Element to, Element from)
829 {
830
831 Document to_doc = to.getOwnerDocument();
832 Node child = from.getFirstChild();
833 while (child != null)
834 {
835 to.appendChild(to_doc.importNode(child, true));
836 child = child.getNextSibling();
837 }
838 }
839
840 public static void copyNode(Element to_elem, Node original_element) {
841 to_elem.appendChild(to_elem.getOwnerDocument().importNode(original_element, true));
842
843 }
844
845 public static void copyNamedElement(Element to, Element from, String elem_name) {
846
847 Document to_doc = to.getOwnerDocument();
848 Node child = from.getFirstChild();
849 while (child != null) {
850 if (child.getNodeName().equals(elem_name)) {
851 to.appendChild(to_doc.importNode(child, true));
852 return;
853 }
854 child = child.getNextSibling();
855 }
856 }
857
858 /**
859 * Given a Node representing an Element or Document, will return the
860 * Element/docroot Element. Returns null if the Node was not an element.
861 */
862 public static Element nodeToElement(Node node)
863 {
864 if (node == null)
865 {
866 return null;
867 }
868 short nodeType = node.getNodeType();
869
870 if (nodeType == Node.DOCUMENT_NODE)
871 {
872 Document docNode = (Document) node;
873 return docNode.getDocumentElement();
874 }
875 else if (nodeType == Node.ELEMENT_NODE)
876 {
877 return (Element) node;
878 }
879 else
880 {
881 String message = "Expecting Document or Element node type but got " + node.getNodeName() + "\nReturning null";
882 System.err.println(message);
883 logger.warn(message);
884 return null;
885 }
886 }
887
888
889 /** returns a basic request message */
890 public static Element createBasicRequest(Document owner, String request_type, String to, UserContext userContext)
891 {
892 Element request = owner.createElement(REQUEST_ELEM);
893 request.setAttribute(TO_ATT, to);
894 request.setAttribute(TYPE_ATT, request_type);
895 if (userContext != null) { // should we allow this??
896 request.setAttribute(LANG_ATT, userContext._lang);
897 Element userContextElem = owner.createElement("userContext");
898 request.appendChild(userContextElem);
899 userContextElem.setAttribute(LANG_ATT, userContext._lang);
900 userContextElem.setAttribute(USERNAME_ATT, userContext._username);
901 userContextElem.setAttribute(USER_ID_ATT, userContext._userID);
902
903 if (userContext._groups != null)
904 {
905 String groupString = "";
906 for (int i = 0; i < userContext._groups.length; i++)
907 {
908 groupString += userContext._groups[i];
909 if (i != userContext._groups.length - 1)
910 {
911 groupString += ",";
912 }
913 }
914
915 if (groupString.length() > 0)
916 {
917 userContextElem.setAttribute(GROUPS_ATT, groupString);
918 }
919 }
920 }
921 return request;
922 }
923
924 public static Element createBasicResponse(Document owner, String from)
925 {
926 Element response = owner.createElement(GSXML.RESPONSE_ELEM);
927 response.setAttribute(GSXML.FROM_ATT, from);
928 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
929 return response;
930 }
931
932 public static Element createMetadataElement(Document owner, String name, String value)
933 {
934 Element metaElem = owner.createElement(GSXML.METADATA_ELEM);
935 metaElem.setAttribute(GSXML.NAME_ATT, name);
936 metaElem.setAttribute(GSXML.VALUE_ATT, value);
937 return metaElem;
938 }
939
940 public static Element createTextElement(Document owner, String elem_name, String text)
941 {
942 Element e = owner.createElement(elem_name);
943 Text t = owner.createTextNode(text);
944 e.appendChild(t);
945 return e;
946
947 }
948
949 public static Element createTextElement(Document owner, String elem_name, String text, String att_name, String att_value)
950 {
951 Element e = owner.createElement(elem_name);
952 e.setAttribute(att_name, att_value);
953 Text t = owner.createTextNode(text);
954 e.appendChild(t);
955 return e;
956
957 }
958
959 public static Element createDisplayTextElement(Document owner, String text_name, String text)
960 {
961 Element e = owner.createElement(DISPLAY_TEXT_ELEM);
962 e.setAttribute(NAME_ATT, text_name);
963 Text t = owner.createTextNode(text);
964 e.appendChild(t);
965 return e;
966
967 }
968
969 public static Element createParameter(Document owner, String name, String value)
970 {
971 Element param = owner.createElement(PARAM_ELEM);
972 param.setAttribute(NAME_ATT, name);
973 param.setAttribute(VALUE_ATT, value);
974 return param;
975 }
976
977 public static void addParameterToList(Element param_list, String name, String value) {
978 Element p = createParameter(param_list.getOwnerDocument(), name, value);
979 param_list.appendChild(p);
980 }
981 public static void addParametersToList(Element param_list, HashMap params)
982 {
983 if (params == null)
984 {
985 return;
986 }
987
988 Set items = params.entrySet();
989 Iterator i = items.iterator();
990 Document owner = param_list.getOwnerDocument();
991 while (i.hasNext())
992 {
993 Map.Entry m = (Map.Entry) i.next();
994 param_list.appendChild(createParameter(owner, (String) m.getKey(), (String) m.getValue()));
995 }
996
997 }
998
999 public static Element createParameterDescription(Document owner, String id, String display_name, String type, String default_value, String[] option_ids, String[] option_names)
1000 {
1001
1002 Element p = owner.createElement(PARAM_ELEM);
1003 p.setAttribute(NAME_ATT, id);
1004 p.setAttribute(TYPE_ATT, type);
1005 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
1006
1007 if (default_value != null)
1008 {
1009 p.setAttribute(DEFAULT_ATT, default_value);
1010 }
1011 if (option_ids != null && option_names != null)
1012 {
1013 for (int i = 0; i < option_ids.length; i++)
1014 {
1015 Element e = owner.createElement(PARAM_OPTION_ELEM);
1016 e.setAttribute(NAME_ATT, option_ids[i]);
1017 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names[i]));
1018 p.appendChild(e);
1019 }
1020 }
1021 return p;
1022 }
1023
1024 public static Element createParameterDescription2(Document owner, String id, String display_name, String type, String default_value, ArrayList<String> option_ids, ArrayList<String> option_names)
1025 {
1026
1027 Element p = owner.createElement(PARAM_ELEM);
1028 p.setAttribute(NAME_ATT, id);
1029 p.setAttribute(TYPE_ATT, type);
1030 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
1031 if (default_value != null)
1032 {
1033 p.setAttribute(DEFAULT_ATT, default_value);
1034 }
1035 if (option_ids != null && option_names != null)
1036 {
1037 for (int i = 0; i < option_ids.size(); i++)
1038 {
1039 Element e = owner.createElement(PARAM_OPTION_ELEM);
1040 e.setAttribute(NAME_ATT, option_ids.get(i));
1041 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names.get(i)));
1042 p.appendChild(e);
1043 }
1044 }
1045 return p;
1046 }
1047
1048 /** returns the element parent/node_name[@attribute_name='attribute_value'] */
1049 public static Element getNamedElement(Element parent, String node_name, String attribute_name, String attribute_value)
1050 {
1051
1052 NodeList children = parent.getChildNodes();
1053 for (int i = 0; i < children.getLength(); i++)
1054 {
1055 Node child = children.item(i);
1056 if (child.getNodeName().equals(node_name))
1057 {
1058 if (((Element) child).getAttribute(attribute_name).equals(attribute_value))
1059 return (Element) child;
1060 }
1061 }
1062 // not found
1063 return null;
1064 }
1065
1066 public static Element getNamedElementNS(Element parent, String namespace_uri, String node_local_name, String attribute_name, String attribute_value)
1067 {
1068 NodeList children = parent.getChildNodes();
1069 for (int i = 0; i < children.getLength(); i++)
1070 {
1071 Node child = children.item(i);
1072 if (child.getNodeType() == Node.ELEMENT_NODE && child.getNamespaceURI() != null && child.getNamespaceURI().equals(namespace_uri) && child.getLocalName().equals(node_local_name))
1073 {
1074 if (((Element) child).getAttribute(attribute_name).equals(attribute_value))
1075 return (Element) child;
1076 }
1077 }
1078 // not found
1079 return null;
1080 }
1081
1082 public static NodeList getNamedElementsNS(Element parent, String namespace_uri, String node_local_name, String attribute_name, String attribute_value)
1083 {
1084 MyNodeList result = new MyNodeList();
1085 NodeList children = parent.getChildNodes();
1086 for (int i = 0; i < children.getLength(); i++)
1087 {
1088 Node child = children.item(i);
1089 if (child.getNodeType() == Node.ELEMENT_NODE && child.getNamespaceURI() != null && child.getNamespaceURI().equals(namespace_uri) && child.getLocalName().equals(node_local_name))
1090 {
1091 if (((Element) child).getAttribute(attribute_name).equals(attribute_value))
1092 result.addNode(child);
1093 }
1094 }
1095 return result;
1096 }
1097
1098 public static NodeList getElementsWithAttributesNS(Element parent, String namespace_uri, String node_local_name, String[] attribute_names, String[] attribute_values)
1099 {
1100 if (attribute_names.length == 0 || attribute_names.length != attribute_values.length)
1101 {
1102 return new MyNodeList();
1103 }
1104
1105 MyNodeList result = new MyNodeList();
1106
1107 NodeList matchingNodes = GSXML.getNamedElementsNS(parent, namespace_uri, node_local_name, attribute_names[0], attribute_values[0]);
1108 for (int i = 0; i < matchingNodes.getLength(); i++)
1109 {
1110 Element current = (Element) matchingNodes.item(i);
1111 boolean nodeMatches = true;
1112 for (int j = 1; j < attribute_names.length; j++)
1113 {
1114 String currentName = attribute_names[j];
1115 String currentValue = attribute_values[j];
1116 if (!current.getAttribute(currentName).equals(currentValue))
1117 {
1118 nodeMatches = false;
1119 break;
1120 }
1121 }
1122
1123 if (nodeMatches)
1124 {
1125 result.addNode(current);
1126 }
1127 }
1128
1129 return result;
1130 }
1131
1132 public static void removeElementsWithAttributesNS(Element parent, String namespace_uri, String node_local_name, String[] attribute_names, String[] attribute_values)
1133 {
1134 NodeList matchingNodes = GSXML.getElementsWithAttributesNS(parent, namespace_uri, node_local_name, attribute_names, attribute_values);
1135 for (int i = 0; i < matchingNodes.getLength(); i++)
1136 {
1137 parent.removeChild(matchingNodes.item(i));
1138 }
1139 }
1140
1141 // In element main, tries to find any previous occurrence of elements with xsl-template-name=templateName,
1142 // and whose named attribute (attributeName) has the same value as the same attribute in node.
1143 // If this is the case, such a previous occurrence is removed from element main, since
1144 // the new node will contain a more specific redefinition of this element.
1145 public static void removeNamedElementNS(Element parent, String namespace_uri, String node_local_name, String attribute_name, String attribute_value)
1146 {
1147 if (attribute_value.equals(""))
1148 {
1149 // it has no identifying attribute, so we can't find any matches
1150 return;
1151 }
1152
1153 Element old_elem = GSXML.getNamedElementNS(parent, namespace_uri, node_local_name, attribute_name, attribute_value);
1154 if (old_elem != null)
1155 {
1156 parent.removeChild(old_elem);
1157 }
1158 }
1159
1160 public static void removeNamedElementsNS(Element parent, String namespace, String node_local_name, String attribute_name, String attribute_value)
1161 {
1162 if (attribute_value.equals(""))
1163 {
1164 // it has no identifying attribute, so we can't find any matches
1165 return;
1166 }
1167
1168 NodeList children = parent.getChildNodes();
1169 for (int i = children.getLength() - 1; i >= 0; i--)
1170 {
1171 Node child = children.item(i);
1172 if (child.getNodeType() == Node.ELEMENT_NODE && child.getNamespaceURI() != null && child.getNamespaceURI().equals(namespace) && child.getLocalName() != null && child.getLocalName().equals(node_local_name))
1173 {
1174 if (((Element) child).getAttribute(attribute_name).equals(attribute_value))
1175 parent.removeChild(child);
1176 }
1177 }
1178 }
1179
1180 /**
1181 * returns a NodeList of elements:
1182 * ancestor/node_name[@attribute_name='attribute_value']
1183 */
1184 public static NodeList getNamedElements(Element ancestor, String node_name, String attribute_name, String attribute_value)
1185 {
1186 MyNodeList node_list = new MyNodeList();
1187 NodeList children = ancestor.getElementsByTagName(node_name);
1188
1189 if (children != null && children.getLength() > 0)
1190 {
1191
1192 for (int i = 0; i < children.getLength(); i++)
1193 {
1194 Node child = children.item(i);
1195 if (child.getNodeName().equals(node_name))
1196 {
1197 if (((Element) child).getAttribute(attribute_name).equals(attribute_value))
1198 node_list.addNode(child);
1199 }
1200 }
1201 }
1202 return node_list;
1203 }
1204
1205 public static Element getLastElementByTagNameNS(Element main, String namespace, String node_name)
1206 {
1207 NodeList nodes = main.getElementsByTagNameNS(namespace, node_name);
1208 int len = nodes.getLength();
1209 if (len == 0)
1210 {
1211 return null;
1212 }
1213 return (Element) nodes.item(len - 1);
1214 }
1215
1216 public static int SORT_TYPE_STRING = 0;
1217 public static int SORT_TYPE_INT = 1;
1218 public static int SORT_TYPE_FLOAT = 2;
1219
1220 // sort type:
1221 public static Element insertIntoOrderedList(Element parent_node, String node_name, Element start_from_elem, Element new_elem, String sort_att, boolean descending)
1222 {
1223 if (new_elem == null)
1224 return null;
1225 Element cloned_elem = (Element) parent_node.getOwnerDocument().importNode(new_elem, true);
1226 if (start_from_elem == null)
1227 {
1228 parent_node.appendChild(cloned_elem);
1229 return cloned_elem;
1230 }
1231
1232 Node current_node = start_from_elem;
1233 String insert_att = cloned_elem.getAttribute(sort_att);
1234 String list_att = start_from_elem.getAttribute(sort_att);
1235 while ((!descending && list_att.compareTo(insert_att) < 0) || (descending && list_att.compareTo(insert_att) > 0))
1236 {
1237 current_node = current_node.getNextSibling();
1238 if (current_node == null)
1239 break; // end of the list
1240 if (!current_node.getNodeName().equals(node_name))
1241 {
1242 continue; // not a valid node
1243 }
1244 list_att = ((Element) current_node).getAttribute(sort_att);
1245 }
1246
1247 parent_node.insertBefore(cloned_elem, current_node);
1248 return cloned_elem;
1249 }
1250
1251 public static String getMetadataValue(Element metadata_list, String name) {
1252 Element meta = getNamedElement(metadata_list, METADATA_ELEM, NAME_ATT, name);
1253 if (meta == null) {
1254 return "";
1255 }
1256 String att_value = meta.getAttribute(VALUE_ATT);
1257 if (att_value.equals("")) {
1258 // try the text
1259 att_value = getNodeText(meta);
1260 }
1261 return att_value;
1262 }
1263 /**
1264 * Returns the appropriate language element from a display elem, display is
1265 * the containing element, name is the name of the element to look for, lang
1266 * is the preferred language, lang_default is the fall back lang if neither
1267 * lang is found, will return the first one it finds
1268 */
1269 public static String getDisplayText(Element display, String name, String lang, String lang_default)
1270 {
1271
1272 String def = null;
1273 String first = null;
1274 NodeList elems = display.getElementsByTagName(DISPLAY_TEXT_ELEM);
1275 if (elems.getLength() == 0)
1276 return "";
1277 for (int i = 0; i < elems.getLength(); i++)
1278 {
1279 Element e = (Element) elems.item(i);
1280 String n = e.getAttribute(NAME_ATT);
1281 if (name.equals(n))
1282 {
1283 String l = e.getAttribute(LANG_ATT);
1284 if (lang.equals(l))
1285 {
1286 return getNodeText(e);
1287 }
1288 else if (lang_default.equals(l))
1289 {
1290 def = getNodeText(e);
1291 }
1292 else if (first == null)
1293 {
1294 first = getNodeText(e);
1295 }
1296 }
1297 else
1298 {
1299 continue;
1300 }
1301 }
1302
1303 if (def != null)
1304 {
1305 return def;
1306 }
1307 if (first != null)
1308 {
1309 return first;
1310 }
1311 return "";
1312 }
1313
1314 // replaces < > " ' & in the original with their entities
1315 public static String xmlSafe(String original)
1316 {
1317
1318 StringBuffer filtered = new StringBuffer(original.length());
1319 char c;
1320 for (int i = 0; i < original.length(); i++)
1321 {
1322 c = original.charAt(i);
1323 if (c == '>')
1324 {
1325 filtered.append("&gt;");
1326 }
1327 else if (c == '<')
1328 {
1329 filtered.append("&lt;");
1330 }
1331 else if (c == '"')
1332 {
1333 filtered.append("&quot;");
1334 }
1335 else if (c == '&')
1336 {
1337 filtered.append("&amp;");
1338 }
1339 else if (c == '\'')
1340 {
1341 filtered.append("&apos;");
1342 }
1343 else
1344 {
1345 filtered.append(c);
1346 }
1347 }
1348 return filtered.toString();
1349 }
1350
1351 // replaces < > " ' & entities with their originals
1352 public static String unXmlSafe(String original)
1353 {
1354
1355 StringBuffer filtered = new StringBuffer(original.length());
1356 char c;
1357 for (int i = 0; i < original.length(); i++)
1358 {
1359 c = original.charAt(i);
1360 if (c == '&')
1361 {
1362 int pos = original.indexOf(";", i);
1363 String entity = original.substring(i + 1, pos);
1364 if (entity.equals("gt"))
1365 {
1366 filtered.append(">");
1367 }
1368 else if (entity.equals("lt"))
1369 {
1370 filtered.append("<");
1371 }
1372 else if (entity.equals("apos"))
1373 {
1374 filtered.append("'");
1375 }
1376 else if (entity.equals("amp"))
1377 {
1378 filtered.append("&");
1379 }
1380 else if (entity.equals("quot"))
1381 {
1382 filtered.append("\"");
1383 }
1384 else
1385 {
1386 filtered.append("&" + entity + ";");
1387 }
1388 i = pos;
1389 }
1390 else
1391 {
1392 filtered.append(c);
1393 }
1394 }
1395 return filtered.toString();
1396 }
1397
1398 public static void printXMLNode(Node e, boolean printText)
1399 {
1400 printXMLNode(e, 0, printText);
1401 }
1402
1403 public static String xmlNodeToString(Node e)
1404 {
1405 StringBuffer sb = new StringBuffer("");
1406 xmlNodeToString(sb, e, true, "\t", 0);
1407 return sb.toString();
1408 }
1409
1410 public static void xmlNodeToString(StringBuffer sb, Node e, boolean indent, String indentString, int depth)
1411 {
1412 if (e.getNodeType() == Node.TEXT_NODE)
1413 {
1414 if (e.getNodeValue() != "")
1415 {
1416 String text = e.getNodeValue();
1417 if (text != null)
1418 {
1419 text = text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("^[\\n\\r\\t\\s]*", "").replaceAll("[\\n\\r\\t\\s]*$", "");
1420 sb.append(text);
1421 }
1422 }
1423 return;
1424 }
1425
1426 if (e.getNodeType() == Node.COMMENT_NODE)
1427 {
1428 if (e.getNodeValue() != "")
1429 {
1430 sb.append("<!--" + e.getNodeValue() + "-->");
1431 }
1432 return;
1433 }
1434
1435 if (indent)
1436 {
1437 for (int i = 0; i < depth; i++)
1438 {
1439 sb.append(indentString);
1440 }
1441 }
1442
1443 sb.append('<');
1444 sb.append(e.getNodeName());
1445 NamedNodeMap attrs = e.getAttributes();
1446 if (attrs != null)
1447 {
1448 for (int i = 0; i < attrs.getLength(); i++)
1449 {
1450 Node attr = attrs.item(i);
1451 sb.append(' ');
1452 sb.append(attr.getNodeName());
1453 sb.append("=\"");
1454 sb.append(attr.getNodeValue().replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
1455 sb.append('"');
1456 }
1457 }
1458
1459 if (e.hasChildNodes())
1460 {
1461 boolean hasElements = false;
1462 boolean indentSwapped = false;
1463
1464 Node child = e.getFirstChild();
1465 do
1466 {
1467 if (child.getNodeType() == Node.ELEMENT_NODE)
1468 {
1469 hasElements = true;
1470 }
1471 if (child.getNodeType() == Node.TEXT_NODE && indent)
1472 {
1473 if (child.getNodeValue() != null && child.getNodeValue().trim().length() > 0)
1474 {
1475 indentSwapped = true;
1476 indent = false;
1477 }
1478 }
1479 } while ((child = child.getNextSibling()) != null);
1480
1481 sb.append(">");
1482 if (hasElements && indent)
1483 {
1484 sb.append("\n");
1485 }
1486
1487 child = e.getFirstChild();
1488 do
1489 {
1490 xmlNodeToString(sb, child, indent, indentString, depth + 1);
1491 } while ((child = child.getNextSibling()) != null);
1492
1493 if (indent)
1494 {
1495 for (int i = 0; i < depth; i++)
1496 {
1497 sb.append(indentString);
1498 }
1499 }
1500
1501 sb.append("</" + e.getNodeName() + ">");
1502
1503 if ((hasElements && indent) || indentSwapped)
1504 {
1505 sb.append("\n");
1506 }
1507 }
1508 else
1509 {
1510 sb.append("/>");
1511
1512 if (indent)
1513 {
1514 sb.append("\n");
1515 }
1516 }
1517
1518 /*
1519 boolean hasElements = false;
1520 boolean indentSwapped = false;
1521 for (int i = 0; i < children.getLength(); i++)
1522 {
1523 if (children.item(i).getNodeType() == Node.ELEMENT_NODE)
1524 {
1525 hasElements = true;
1526 }
1527 if (children.item(i).getNodeType() == Node.TEXT_NODE && indent)
1528 {
1529 if (children.item(i).getNodeValue() != null && children.item(i).getNodeValue().trim().length() > 0)
1530 {
1531 indentSwapped = true;
1532 indent = false;
1533 }
1534 }
1535 }
1536
1537 if (children == null || children.getLength() == 0)
1538 {
1539 sb.append("/>");
1540
1541 if (indent)
1542 {
1543 sb.append("\n");
1544 }
1545 }
1546 else
1547 {
1548 sb.append(">");
1549 if (hasElements && indent)
1550 {
1551 sb.append("\n");
1552 }
1553
1554 int len = children.getLength();
1555 for (int i = 0; i < len; i++)
1556 {
1557 xmlNodeToString(sb, children.item(i), indent, indentString, depth + 1);
1558 }
1559
1560 if (indent)
1561 {
1562 for (int i = 0; i < depth; i++)
1563 {
1564 sb.append(indentString);
1565 }
1566 }
1567
1568 sb.append("</" + e.getNodeName() + ">");
1569
1570 if ((hasElements && indent) || indentSwapped)
1571 {
1572 sb.append("\n");
1573 }
1574 }
1575 */
1576 }
1577
1578 public static void printXMLNode(Node e, int depth, boolean printText)
1579 { //recursive method call using DOM API...
1580
1581 if (e == null)
1582 {
1583 return;
1584 }
1585
1586 for (int i = 0; i < depth; i++)
1587 System.out.print(' ');
1588
1589 if (e.getNodeType() == Node.TEXT_NODE)
1590 {
1591 if (printText)
1592 {
1593 System.out.println(e.getNodeValue());
1594 }
1595 else
1596 {
1597 System.out.println("text");
1598 }
1599 return;
1600 }
1601
1602 System.out.print('<');
1603 System.out.print(e.getNodeName());
1604 NamedNodeMap attrs = e.getAttributes();
1605
1606 if (attrs != null)
1607 {
1608 for (int i = 0; i < attrs.getLength(); i++)
1609 {
1610 Node attr = attrs.item(i);
1611 System.out.print(' ');
1612 System.out.print(attr.getNodeName());
1613 System.out.print("=\"");
1614 System.out.print(attr.getNodeValue());
1615 System.out.print('"');
1616 }
1617 }
1618
1619 NodeList children = e.getChildNodes();
1620
1621 if (children == null || children.getLength() == 0)
1622 System.out.println("/>");
1623 else
1624 {
1625
1626 System.out.println('>');
1627
1628 int len = children.getLength();
1629 for (int i = 0; i < len; i++)
1630 {
1631 printXMLNode(children.item(i), depth + 1, printText);
1632 }
1633
1634 for (int i = 0; i < depth; i++)
1635 System.out.print(' ');
1636
1637 System.out.println("</" + e.getNodeName() + ">");
1638 }
1639 }
1640
1641 public static void elementToLogAsString(Element e, boolean indent)
1642 {
1643 String str = elementToString(e, indent);
1644 System.err.println(str);
1645 logger.error(str);
1646 }
1647
1648 public static String elementToString(Element e, boolean indent)
1649 {
1650 String str = "";
1651 try
1652 {
1653 TransformerFactory tf = TransformerFactory.newInstance();
1654 Transformer trans = tf.newTransformer();
1655 StringWriter sw = new StringWriter();
1656 if (indent)
1657 {
1658 trans.setOutputProperty(OutputKeys.INDENT, "yes");
1659 }
1660 else
1661 {
1662 trans.setOutputProperty(OutputKeys.INDENT, "no");
1663 }
1664 trans.transform(new DOMSource(e), new StreamResult(sw));
1665 str += sw.toString();
1666 }
1667 catch (Exception ex)
1668 {
1669 str += "Exception: couldn't write " + e + " to log";
1670 }
1671 finally
1672 {
1673 return str;
1674 }
1675 }
1676
1677 public static ArrayList<String> getGroupsFromSecurityResponse(Element securityResponse)
1678 {
1679 ArrayList<String> groups = new ArrayList<String>();
1680
1681 Element groupList = (Element) GSXML.getChildByTagName(securityResponse, GSXML.GROUP_ELEM + GSXML.LIST_MODIFIER);
1682 if (groupList == null)
1683 {
1684 return groups;
1685 }
1686
1687 NodeList groupElems = GSXML.getChildrenByTagName(groupList, GSXML.GROUP_ELEM);
1688
1689 for (int i = 0; i < groupElems.getLength(); i++)
1690 {
1691 Element groupElem = (Element) groupElems.item(i);
1692 groups.add(groupElem.getAttribute(GSXML.NAME_ATT));
1693 }
1694
1695 return groups;
1696 }
1697
1698}
Note: See TracBrowser for help on using the repository browser.