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

Last change on this file since 23627 was 23627, checked in by kjdon, 13 years ago

changed the mergeMetadataLists method so that it actually copied all metadata (was iterating through a changing list). Added a new method mergeMetadataFromList where you pass in the from metatadataList not the parent - needed if the parent hase more than one metadata list

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