source: trunk/gsdl3/src/java/org/greenstone/gsdl3/util/GSXML.java@ 8488

Last change on this file since 8488 was 8488, checked in by kjdon, 19 years ago

Added a couple of element names for config file elements

  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 KB
Line 
1package org.greenstone.gsdl3.util;
2
3import org.w3c.dom.NamedNodeMap;
4import org.w3c.dom.Node;
5import org.w3c.dom.Element;
6import org.w3c.dom.NodeList;
7import org.w3c.dom.Document;
8import org.w3c.dom.Text;
9
10import java.util.Map;
11import java.util.Set;
12import java.util.HashMap;
13import java.util.Vector;
14import java.util.Iterator;
15//import java.util.Locale;
16
17/** various functions for extracting info out of GS XML */
18public class GSXML {
19
20 // greenstone xml elements
21 public static final String MESSAGE_ELEM = "message";
22 public static final String REQUEST_ELEM = "request";
23 public static final String RESPONSE_ELEM = "response";
24 public static final String COLLECTION_ELEM = "collection";
25 public static final String SERVICE_ELEM = "service";
26 public static final String CLUSTER_ELEM = "serviceCluster";
27 public static final String SITE_ELEM = "site";
28 public static final String PARAM_ELEM = "param";
29 public static final String PARAM_OPTION_ELEM = "option";
30 public static final String CONTENT_ELEM = "content";
31 public static final String RESOURCE_ELEM = "resource";
32 public static final String DOCUMENT_ELEM = "document";
33 public static final String METADATA_ELEM = "metadata";
34 public static final String SERVICE_CLASS_ELEM = "serviceRack";
35 public static final String CLASSIFIER_ELEM = "classifier";
36 public static final String APPLET_ELEM = "applet";
37 public static final String APPLET_DATA_ELEM = "appletData";
38 public static final String CONFIGURE_ELEM = "configure";
39 public static final String STATUS_ELEM = "status";
40 public static final String ERROR_ELEM = "error";
41 public static final String DEFAULT_ELEM = "default";
42 public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem
43 public static final String FORMAT_ELEM = "format"; // config files use format - should we use this instead of stylesheet??
44 public static final String TERM_ELEM = "term";
45 public static final String SYSTEM_ELEM = "system";
46
47 //config file elems
48 public static final String COLLECTION_CONFIG_ELEM = "collectionConfig";
49 public static final String COLLECTION_BUILD_ELEM = "buildConfig";
50 public static final String COLLECTION_INIT_ELEM = "collectionInit";
51 public static final String RECOGNISE_ELEM = "recognise";
52 public static final String DOC_TYPE_ELEM = "docType";
53 public static final String SEARCH_ELEM = "search";
54 public static final String INDEX_ELEM = "index";
55 public static final String BROWSE_ELEM = "browse";
56 public static final String DISPLAY_ELEM = "display";
57 public static final String FIELD_ELEM = "field";
58 public static final String LEVEL_ELEM = "level";
59 public static final String SHORTNAME_ATT = "shortname";
60
61 // elems for the pages to be processed by xslt
62 public final static String PAGE_ELEM = "page";
63 public final static String CONFIGURATION_ELEM = "config";
64 public final static String PAGE_REQUEST_ELEM = "pageRequest";
65 public final static String PAGE_RESPONSE_ELEM = "pageResponse";
66 public final static String PAGE_EXTRA_ELEM = "pageExtra";
67
68 //public final static String DESCRIPTION_ELEM = "description";
69
70 public static final String SITE_NAME_ELEM = "localSiteName";
71 public static final String SITE_HTTP_ADDRESS_ELEM = "httpAddress";
72 public static final String ACTION_ELEM = "action";
73 public static final String SUBACTION_ELEM = "subaction";
74
75 // add on to another elem type to get a list of that type
76 public static final String LIST_MODIFIER = "List";
77
78 // greenstone xml attributes
79 public static final String NAME_ATT = "name";
80 public static final String TO_ATT = "to";
81 public static final String USER_ID_ATT = "uid";
82 public static final String FROM_ATT = "from";
83 public static final String LANG_ATT = "lang";
84 public static final String TYPE_ATT = "type";
85 public static final String VALUE_ATT = "value";
86 public static final String DEFAULT_ATT = "default";
87 public static final String INFO_ATT = "info";
88 public static final String ACTION_ATT = "action";
89 public static final String SUBACTION_ATT = "subaction";
90 public static final String OUTPUT_ATT = "output";
91 public static final String ADDRESS_ATT = "address";
92 public static final String STATUS_ERROR_CODE_ATT = "code";
93 public static final String STATUS_PROCESS_ID_ATT = "pid";
94 public static final String PARAM_SHORTNAME_ATT = "shortname";
95 public static final String PARAM_IGNORE_POS_ATT = "ignore";
96 public static final String CLASSIFIER_CONTENT_ATT = "content";
97
98 // document stuff
99 public static final String DOC_TYPE_ATT = "docType";
100 public static final String DOC_NODE_ELEM = "documentNode";
101 public static final String NODE_CONTENT_ELEM = "nodeContent";
102 public static final String NODE_STRUCTURE_ELEM = "nodeStructure";
103 public static final String NODE_ID_ATT = "nodeID";
104 public static final String NODE_NAME_ATT = "nodeName";
105 public static final String NODE_TYPE_ATT = "nodeType";
106
107 public static final String NODE_TYPE_ROOT = "root";
108 public static final String NODE_TYPE_INTERIOR = "interior";
109 public static final String NODE_TYPE_LEAF = "leaf";
110
111 // classifier stuff
112 public static final String CLASS_NODE_ELEM = "classifierNode";
113 public static final String CLASS_NODE_ORIENTATION_ATT = "orientation";
114
115 // parameter types
116 public static final String PARAM_TYPE_INTEGER = "integer";
117 public static final String PARAM_TYPE_BOOLEAN = "boolean";
118 public static final String PARAM_TYPE_ENUM_START = "enum";
119 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
120 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
121 public static final String PARAM_TYPE_STRING = "string";
122 public static final String PARAM_TYPE_TEXT = "text";
123 public static final String PARAM_TYPE_MULTI = "multi";
124 public static final String PARAM_TYPE_FILE = "file";
125 public static final String PARAM_TYPE_INVISIBLE = "invisible";
126 // stuff for text strings
127 public static final String DISPLAY_TEXT_ELEM = "displayItem";
128 // the following are used for the name attributes
129 public static final String DISPLAY_TEXT_NAME = "name";
130 public static final String DISPLAY_TEXT_SUBMIT = "submit";
131 public static final String DISPLAY_TEXT_DESCRIPTION = "description";
132
133 // request types
134 // get the module description
135 public static final String REQUEST_TYPE_DESCRIBE = "describe";
136 // startup a process
137 public static final String REQUEST_TYPE_PROCESS = "process";
138 // get the status of an ongoing process
139 public static final String REQUEST_TYPE_STATUS = "status";
140 // system type request - eg reload a collection
141 public static final String REQUEST_TYPE_SYSTEM = "system";
142 // page requests to the Receptionist/Actions
143 public static final String REQUEST_TYPE_PAGE = "page"; // used to be cgi
144 // get any format info for a service
145 public static final String REQUEST_TYPE_FORMAT = "format";
146
147 // service types
148 public static final String SERVICE_TYPE_QUERY = "query";
149 public static final String SERVICE_TYPE_RETRIEVE = "retrieve";
150 public static final String SERVICE_TYPE_BROWSE = "browse";
151 public static final String SERVICE_TYPE_APPLET = "applet";
152 public static final String SERVICE_TYPE_PROCESS = "process";
153 public static final String SERVICE_TYPE_ENRICH = "enrich";
154
155 // system command types and attributes
156 public static final String SYSTEM_TYPE_CONFIGURE = "configure";
157 public static final String SYSTEM_TYPE_ACTIVATE = "activate";
158 public static final String SYSTEM_TYPE_DEACTIVATE = "deactivate";
159
160 public static final String SYSTEM_SUBSET_ATT = "subset";
161 public static final String SYSTEM_MODULE_TYPE_ATT = "moduleType";
162 public static final String SYSTEM_MODULE_NAME_ATT = "moduleName";
163
164 // communicator types
165 public static final String COMM_TYPE_SOAP_JAVA = "soap";
166
167 // some system wide param names
168 public static final String SUBSET_PARAM = "subset";
169
170 /** takes a list of elements, and returns an array of strings
171 * of the values of attribute att_name */
172 public static String [] getAttributeValuesFromList(Element list,
173 String att_name) {
174
175 NodeList children = list.getChildNodes();
176
177 int num_nodes = children.getLength();
178 String []ids = new String[num_nodes];
179 for (int i=0; i<num_nodes; i++) {
180 Element e = (Element)children.item(i);
181 String id = e.getAttribute(att_name);
182 ids[i] = id;
183 }
184
185 return ids;
186 }
187
188 /** takes a paramList element, and gets a HashMap of name-value pairs
189 * if deep=true, extracts embedded params, otherwise just top level
190 * params*/
191 public static HashMap extractParams(Element xml, boolean deep) {
192
193 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
194 System.err.println("GSXML:paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
195 return null;
196 }
197
198 NodeList params = null;
199 if (deep) { // get all the nested ones
200 params = xml.getElementsByTagName(PARAM_ELEM);
201 } else { // just get the top level ones
202 params = xml.getChildNodes();
203 }
204 HashMap param_map = new HashMap();
205 for (int i=0; i<params.getLength(); i++) {
206 if (params.item(i).getNodeName().equals(PARAM_ELEM)) {
207 Element param = (Element)params.item(i);
208 String name=param.getAttribute(NAME_ATT);
209 String value=getValue(param); //att or content
210 int pos = name.indexOf('.');
211 if (pos == -1) { // a base param
212 param_map.put(name, value);
213 } else { // a namespaced param
214
215 String namespace = name.substring(0, pos);
216 name = name.substring(pos+1);
217 HashMap map = (HashMap)param_map.get(namespace);
218 if (map == null) {
219 map = new HashMap();
220 param_map.put(namespace, map);
221 }
222 map.put(name, value);
223 }
224 }
225 }
226 return param_map;
227 }
228
229 /** gets the value att or the text content */
230 public static String getValue(Element e) {
231 String val = e.getAttribute(VALUE_ATT);
232 if (val ==null || val.equals("")) {
233 // have to get it out of the text
234 val=getNodeText(e);
235
236 }
237 return val;
238 }
239
240 /** extracts the text out of a node */
241 public static Node getNodeTextNode(Element param) {
242 param.normalize();
243 Node n = param.getFirstChild();
244 while (n!=null && n.getNodeType() !=Node.TEXT_NODE) {
245 n=n.getNextSibling();
246 }
247 return n;
248 }
249
250 /** extracts the text out of a node */
251 public static String getNodeText(Element param) {
252 Node text_node = getNodeTextNode(param);
253 if (text_node == null) {
254 return "";
255 }
256 return text_node.getNodeValue();
257 }
258
259
260 /** add text to a document/subsection element */
261 public static boolean addDocText(Document owner, Element doc, String text) {
262
263 Element content = owner.createElement(NODE_CONTENT_ELEM);
264 Text t = owner.createTextNode(text);
265 content.appendChild(t);
266 doc.appendChild(content);
267 return true;
268 }
269
270 /** add an error message */
271 public static boolean addError(Document owner, Element doc, String text) {
272
273 Element content = owner.createElement(ERROR_ELEM);
274 Text t = owner.createTextNode(text);
275 content.appendChild(t);
276
277 return true;
278 }
279
280 /** add an error message */
281 public static boolean addError(Document owner, Element doc, Throwable error) {
282 error.printStackTrace();
283 return addError(owner, doc, error.toString());
284 }
285
286 public static Element createMetadataParamList(Document owner, Vector meta_values) {
287
288 Element meta_param_list = owner.createElement(PARAM_ELEM+LIST_MODIFIER);
289 Iterator i = meta_values.iterator();
290 while(i.hasNext()) {
291 String next = (String)i.next();
292 Element meta_param = owner.createElement(PARAM_ELEM);
293 meta_param_list.appendChild(meta_param);
294 meta_param.setAttribute(NAME_ATT, "metadata");
295 meta_param.setAttribute(VALUE_ATT, next);
296 }
297 return meta_param_list;
298 }
299
300 /** adds a metadata elem to a list */
301 public static boolean addMetadata(Document owner, Element list,
302 String meta_name, String meta_value) {
303 if (meta_value==null || meta_value.equals("")) {
304 return false;
305 }
306 Element data = owner.createElement(METADATA_ELEM);
307 data.setAttribute(NAME_ATT, meta_name);
308 Text t = owner.createTextNode(meta_value);
309 data.appendChild(t);
310 list.appendChild(data);
311 return true;
312
313 }
314
315 /** copies the metadata out of teh metadataList of 'from' into
316 * the metadataList of 'to' */
317 public static boolean mergeMetadataLists(Node to, Node from) {
318 Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER);
319 Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER);
320
321 if (from_meta == null) { // nothing to copy
322 return true;
323 }
324 Document to_owner = to.getOwnerDocument();
325 Node new_from = to_owner.importNode(from_meta, true);
326
327 if (to_meta == null) { // just copy the whole list
328 to.appendChild(new_from);
329 return true;
330 }
331
332 // copy individual elements
333 Node child = new_from.getFirstChild();
334 while ( child != null) {
335 to_meta.appendChild(child);
336 child = child.getNextSibling();
337 }
338 return true;
339 }
340
341 /** copies all the children from from to to */
342 public static boolean mergeElements(Element to, Element from) {
343
344 Document owner = to.getOwnerDocument();
345 Node child = from.getFirstChild();
346 while (child != null) {
347 to.appendChild(owner.importNode(child, true));
348 child = child.getNextSibling();
349 }
350 return true;
351 }
352 /** returns the (first) child element with the given name */
353 public static Node getChildByTagName(Node n, String name) {
354
355 Node child = n.getFirstChild();
356 while (child!=null) {
357 if (child.getNodeName().equals(name)) {
358 return child;
359 }
360 child = child.getNextSibling();
361 }
362 return null; //not found
363 }
364
365 /** takes an xpath type expression of the form name/name/...
366 and returns the first node that matches, or null if not found */
367 public static Node getNodeByPath(Node n, String path) {
368
369 String link = GSPath.getFirstLink(path);
370 path = GSPath.removeFirstLink(path);
371 while (!link.equals("")) {
372 n = getChildByTagName(n, link);
373 if (n==null) {
374 return null;
375 }
376 link = GSPath.getFirstLink(path);
377 path = GSPath.removeFirstLink(path);
378 }
379 return n;
380 }
381 public static HashMap getChildrenMap(Node n) {
382
383 HashMap map= new HashMap();
384 Node child = n.getFirstChild();
385 while (child!=null) {
386 String name = child.getNodeName();
387 map.put(name, child);
388 child = child.getNextSibling();
389 }
390 return map;
391 }
392
393
394 /** Duplicates an element, but gives it a new name */
395 public static Element duplicateWithNewName(Document owner, Element element,
396 String element_name, boolean with_attributes)
397 {
398 Element duplicate = owner.createElement(element_name);
399
400 // Copy element attributes
401 if (with_attributes) {
402 NamedNodeMap attributes = element.getAttributes();
403 for (int i = 0; i < attributes.getLength(); i++) {
404 Node attribute = attributes.item(i);
405 duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
406 }
407 }
408
409 // Copy element children
410 NodeList children = element.getChildNodes();
411 for (int i = 0; i < children.getLength(); i++) {
412 Node child = children.item(i);
413 duplicate.appendChild(owner.importNode(child, true));
414 }
415
416 return duplicate;
417 }
418
419 public static void copyAllChildren(Element to, Element from) {
420
421 Document to_doc = to.getOwnerDocument();
422 Node child = from.getFirstChild();
423 while (child != null) {
424 to.appendChild(to_doc.importNode(child, true));
425 child = child.getNextSibling();
426 }
427 }
428 /** returns a basic request message */
429 public static Element createBasicRequest(Document owner,
430 String request_type, String to,
431 String lang,
432 String uid) {
433 Element request = owner.createElement(REQUEST_ELEM);
434 request.setAttribute(TYPE_ATT, request_type);
435 request.setAttribute(LANG_ATT, lang);
436 request.setAttribute(TO_ATT, to);
437 request.setAttribute(USER_ID_ATT, uid);
438 return request;
439 }
440
441 public static Element createTextElement(Document owner, String elem_name,
442 String text) {
443 Element e = owner.createElement(elem_name);
444 Text t = owner.createTextNode(text);
445 e.appendChild(t);
446 return e;
447
448 }
449
450 public static Element createDisplayTextElement(Document owner,
451 String text_name,
452 String text) {
453 Element e = owner.createElement(DISPLAY_TEXT_ELEM);
454 e.setAttribute(NAME_ATT, text_name);
455 Text t = owner.createTextNode(text);
456 e.appendChild(t);
457 return e;
458
459 }
460
461
462 public static Element createParameter(Document owner, String name,
463 String value) {
464 Element param = owner.createElement(PARAM_ELEM);
465 param.setAttribute(NAME_ATT, name);
466 param.setAttribute(VALUE_ATT, value);
467 return param;
468 }
469
470 public static Element createParameterList(Document owner,
471 HashMap params) {
472
473 Element list = owner.createElement(PARAM_ELEM+LIST_MODIFIER);
474 Set items = params.entrySet();
475 Iterator i = items.iterator();
476 while(i.hasNext()) {
477 Map.Entry m = (Map.Entry)i.next();
478 list.appendChild(createParameter(owner, (String)m.getKey(), (String)m.getValue()));
479 }
480 return list;
481 }
482
483 public static Element createParameterDescription(Document owner,
484 String id,
485 String display_name,
486 String type,
487 String default_value,
488 String []option_ids,
489 String []option_names) {
490
491
492 Element p = owner.createElement(PARAM_ELEM);
493 p.setAttribute(NAME_ATT, id);
494 p.setAttribute(TYPE_ATT, type);
495 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name));
496 if (default_value != null) {
497 p.setAttribute(DEFAULT_ATT, default_value);
498 }
499 if (option_ids!=null && option_names!=null) {
500 for (int i=0; i<option_ids.length; i++) {
501 Element e = owner.createElement(PARAM_OPTION_ELEM);
502 e.setAttribute(NAME_ATT, option_ids[i]);
503 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names[i]));
504 p.appendChild(e);
505 }
506 }
507 return p;
508 }
509
510
511 /** returns the element parent/node_name[@attribute_name='attribute_value']
512 */
513 public static Element getNamedElement(Element parent, String node_name,
514 String attribute_name,
515 String attribute_value) {
516
517 NodeList children = parent.getChildNodes();
518 for (int i=0; i<children.getLength(); i++) {
519 Node child = children.item(i);
520 ///ystem.out.println("getnamed elem, node nmae="+child.getNodeName());
521 if (child.getNodeName().equals(node_name)) {
522 if (((Element)child).getAttribute(attribute_name).equals(attribute_value))
523 return (Element)child;
524 }
525 }
526 // not found
527 return null;
528 }
529
530
531
532 /** Returns the appropriate language element from a display elem,
533 display is the containing element, name is the name of the element to
534 look for, lang is the preferred language, lang_default is the fall back
535 lang if neither lang is found, will return the first one it finds*/
536 public static String getDisplayText(Element display, String name,
537 String lang, String lang_default) {
538
539 String def = null;
540 String first = null;
541 NodeList elems = display.getElementsByTagName(DISPLAY_TEXT_ELEM);
542 if (elems.getLength() == 0) return "";
543 for (int i=0; i<elems.getLength(); i++) {
544 Element e = (Element)elems.item(i);
545 String n = e.getAttribute(NAME_ATT);
546 if (name.equals(n)) {
547 String l = e.getAttribute(LANG_ATT);
548 if (lang.equals(l)) {
549 return getNodeText(e);
550 } else if (lang_default.equals(l)) {
551 def = getNodeText(e);
552 } else if (first == null) {
553 first = getNodeText(e);
554 }
555 } else {
556 continue;
557 }
558 }
559
560 if (def != null) {
561 return def;
562 }
563 if (first != null) {
564 return first;
565 }
566 return "";
567 }
568
569 // replaces < > " ' & in the original with their entities
570 public static String xmlSafe(String original) {
571
572 StringBuffer filtered = new StringBuffer(original.length());
573 char c;
574 for (int i=0; i<original.length(); i++) {
575 c = original.charAt(i);
576 if (c == '>') {
577 filtered.append("&gt;");
578 } else if (c == '<') {
579 filtered.append("&lt;");
580 } else if (c == '"') {
581 filtered.append("&quot;");
582 } else if (c == '&') {
583 filtered.append("&amp;");
584 } else if (c == '\'') {
585 filtered.append("&apos;");
586 } else {
587 filtered.append(c);
588 }
589 }
590 return filtered.toString();
591 }
592
593
594// // replaces < > " ' & in the original with their entities
595// public static String unXmlSafe(String original) {
596
597// StringBuffer filtered = new StringBuffer(original.length());
598// char c;
599// for (int i=0; i<original.length(); i++) {
600// c = original.charAt(i);
601// if (c == '&') {
602// int pos = original.indexOf(";"), i);
603// String entity = original.substring(i+1, pos);
604// if (entity.equals("gt")) {
605// filtered.append(">");
606// } else if (entity.equals("lt")) {
607// filtered.append("<");
608// } else if (entity.equals("apos")) {
609// filtered.append(
610// while (c != ';') {
611
612// // process the entity
613// } else {
614// filtered.append(c);
615// }
616// }
617// return filtered.toString();
618// }
619}
Note: See TracBrowser for help on using the repository browser.