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

Last change on this file since 3867 was 3867, checked in by kjdon, 21 years ago

more stuff

  • Property svn:keywords set to Author Date Id Revision
File size: 19.1 KB
Line 
1package org.greenstone.gsdl3.util;
2
3import org.w3c.dom.Node;
4import org.w3c.dom.Element;
5import org.w3c.dom.NodeList;
6import org.w3c.dom.Document;
7import org.w3c.dom.Text;
8
9import java.util.HashMap;
10//import java.util.Locale;
11
12/** various functions for extracting info out of GS XML */
13public class GSXML {
14
15 // greenstone xml elements
16 public static final String MESSAGE_ELEM = "message";
17 public static final String REQUEST_ELEM = "request";
18 public static final String RESPONSE_ELEM = "response";
19 public static final String COLLECTION_ELEM = "collection";
20 public static final String SERVICE_ELEM = "service";
21 public static final String CLUSTER_ELEM = "serviceCluster";
22 public static final String SITE_ELEM = "site";
23 public static final String PARAM_ELEM = "param";
24 public static final String PARAM_OPTION_ELEM = "option";
25 public static final String CONTENT_ELEM = "content";
26 public static final String RESOURCE_ELEM = "resource";
27 public static final String DOCUMENT_ELEM = "document";
28 public static final String METADATA_ELEM = "metadata";
29 public static final String SERVICE_CLASS_ELEM = "serviceRack";
30 public static final String CLASSIFIER_ELEM = "classifier";
31 public static final String APPLET_ELEM = "applet";
32 public static final String APPLET_DATA_ELEM = "appletData";
33 public static final String CONFIGURE_ELEM = "configure";
34 public static final String STATUS_ELEM = "status";
35 public static final String ERROR_ELEM = "error";
36 public static final String DEFAULT_ELEM = "default";
37 public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem
38 public static final String FORMAT_ELEM = "format"; // config files use format - shoudl we use this instead of stylesheet??
39 public static final String TERM_ELEM = "term";
40
41 //config file elems
42 public static final String INDEX_ELEM = "index";
43 public static final String SEARCH_ELEM = "search";
44 public static final String BROWSE_ELEM = "browse";
45 public static final String FIELD_ELEM = "field";
46 public static final String DISPLAYNAME_ELEM = "displayName";
47 public static final String SHORTNAME_ATT = "shortname";
48 // elems for the pages to be processed by xslt
49 public final static String PAGE_ELEM = "page";
50 public final static String TRANSLATION_ELEM = "translate";
51 public final static String CONFIGURATION_ELEM = "config";
52 public final static String DESCRIPTION_ELEM = "description";
53
54 public static final String SITE_NAME_ELEM = "localSiteName";
55
56 // add on to another elem type to get a list of that type
57 public static final String LIST_MODIFIER = "List";
58
59 // greenstone xml attributes
60 public static final String NAME_ATT = "name";
61 public static final String TO_ATT = "to";
62 public static final String FROM_ATT = "from";
63 public static final String LANG_ATT = "lang";
64 public static final String TYPE_ATT = "type";
65 public static final String VALUE_ATT = "value";
66 public static final String DEFAULT_ATT = "default";
67 public static final String INFO_ATT = "info";
68 public static final String ACTION_ATT = "action";
69 public static final String SUBACTION_ATT = "subaction";
70 public static final String OUTPUT_ATT = "output";
71 public static final String ADDRESS_ATT = "address";
72 public static final String STATUS_ERROR_CODE_ATT = "code";
73 public static final String STATUS_PROCESS_ID_ATT = "handle";
74 public static final String PARAM_SHORTNAME_ATT = "shortname";
75 public static final String PARAM_IGNORE_POS_ATT = "ignore";
76 public static final String CLASSIFIER_CONTENT_ATT = "content";
77
78 // document stuff
79 public static final String DOC_NODE_ELEM = "documentNode";
80 public static final String DOC_NODE_CONTENT_ELEM = "documentNodeContent";
81 public static final String DOC_NODE_STRUCTURE_ELEM = "documentNodeStructure";
82 public static final String DOC_NODE_ID_ATT = "documentID";
83 public static final String DOC_NODE_NAME_ATT = "documentNodeName";
84 public static final String DOC_NODE_TYPE_ATT = "documentNodeType";
85
86 public static final String NODE_TYPE_ROOT = "root";
87 public static final String NODE_TYPE_INTERIOR = "interior";
88 public static final String NODE_TYPE_LEAF = "leaf";
89
90 // classifier stuff
91 public static final String CLASS_NODE_ELEM = "classifierNode";
92 public static final String CLASS_NODE_ID_ATT = "classifierID";
93
94 // parameter types
95 public static final String PARAM_TYPE_INTEGER = "integer";
96 public static final String PARAM_TYPE_BOOLEAN = "boolean";
97 public static final String PARAM_TYPE_ENUM_START = "enum";
98 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
99 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
100 public static final String PARAM_TYPE_STRING = "string";
101 public static final String PARAM_TYPE_TEXT = "text";
102 public static final String PARAM_TYPE_MULTI = "multi";
103 public static final String PARAM_TYPE_FILE = "file";
104 // stuff for text strings
105 public static final String DISPLAY_ELEM = "display";
106 public static final String DISPLAY_NAME_ELEM = "name";
107 public static final String DISPLAY_SUBMIT_ELEM = "submit";
108
109 // request types - do we need all these? or just
110 // describe, status, and one to say do teh request
111 public static final String REQUEST_TYPE_DESCRIBE = "describe";
112 public static final String REQUEST_TYPE_STATUS = "status";
113 public static final String REQUEST_TYPE_PROCESS = "process";
114
115 public static final String REQUEST_TYPE_CONFIGURE = "configure"; // ?
116 public static final String REQUEST_TYPE_CGI = "cgi"; // ?
117
118 public static final String REQUEST_TYPE_ACTION = "action"; // ??
119 public static final String REQUEST_TYPE_QUERY = "query"; // ??
120 public static final String REQUEST_TYPE_BUILD = "build"; // ??
121
122 // service types
123 public static final String SERVICE_TYPE_QUERY = "query";
124 public static final String SERVICE_TYPE_RETRIEVE = "retrieve";
125 public static final String SERVICE_TYPE_BROWSE = "browse";
126 public static final String SERVICE_TYPE_APPLET = "applet";
127 public static final String SERVICE_TYPE_PROCESS = "process";
128
129 // configure types
130 public static final String CONFIG_ACTION_ACTIVATE = "activate";
131 public static final String CONFIG_ACTION_DEACTIVATE = "deactivate";
132
133 // communicator types
134 public static final String COMM_TYPE_SOAP_JAVA = "soap";
135
136
137 /** takes a list of elements, and returns an array of strings
138 * of the values of attribute att_name */
139 public static String [] getAttributeValuesFromList(Element list,
140 String att_name) {
141
142 NodeList children = list.getChildNodes();
143
144 int num_nodes = children.getLength();
145 String []ids = new String[num_nodes];
146 for (int i=0; i<num_nodes; i++) {
147 Element e = (Element)children.item(i);
148 String id = e.getAttribute(att_name);
149 ids[i] = id;
150 }
151
152 return ids;
153 }
154
155
156 // takes a node with a resource elements inside it and extracts all the
157 // HASH oids - name att for resource
158 // generalise this for any element type? pass in the list, the element name, the att to extract
159 public static String [] getDocumentNameList(Element content) {
160
161 Node n = content.getFirstChild();
162 while (n!=null && !n.getNodeName().equals(DOCUMENT_ELEM+LIST_MODIFIER)) {
163 n = n.getNextSibling();
164 }
165 if (n==null) { // no docs found
166 return null;
167 }
168
169 NodeList docs = n.getChildNodes();
170
171 int numdocs = docs.getLength();
172 String []ids = new String[numdocs];
173 for (int i=0; i<numdocs; i++) {
174 Element e = (Element)docs.item(i);
175 String id = e.getAttribute(NAME_ATT);
176 // check that its a valid id - ie starts with HASH
177 // need to change this if use different ids
178
179 ids[i] = id;
180
181 }
182
183 return ids;
184 }
185
186 // same as above function
187 /** extracts metadata names out of an element */
188 public static String [] getMetaNameList(Element content) {
189 Node n = content.getFirstChild();
190 while (n!=null &&
191 !n.getNodeName().equals(METADATA_ELEM+LIST_MODIFIER)) {
192 n = n.getNextSibling();
193 }
194 if (n==null) { // no metadatas found
195 return null;
196 }
197 NodeList elems = n.getChildNodes();
198
199 int numelems = elems.getLength();
200 String []ids = new String[numelems];
201 for (int i=0; i<numelems; i++) {
202 Element e = (Element)elems.item(i);
203 String id = e.getAttribute(NAME_ATT);
204 ids[i] = id;
205 }
206
207 return ids;
208 }
209
210 // combine the next two??
211 /** takes a paramList element, and gets a HashMap of name-value pairs */
212 public static HashMap extractParams(Element xml) {
213
214 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
215 System.err.println("GSXML:paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
216 return null;
217 }
218 NodeList params = xml.getChildNodes();
219 HashMap param_map = new HashMap();
220 for (int i=0; i<params.getLength(); i++) {
221 Element param = (Element)params.item(i);
222 String name=param.getAttribute(NAME_ATT);
223 String value=param.getAttribute(VALUE_ATT);
224 if (value.equals("")) { // the value is in the content of the param
225 value=getNodeText(param);
226 }
227 param_map.put(name, value);
228
229 }
230 return param_map;
231 }
232 /** takes a paramList element, and gets a HashMap of name-value pairs */
233 public static HashMap extractAllParams(Element xml) {
234
235 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
236 System.err.println("GSXML:paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
237 return null;
238 }
239 NodeList params = xml.getElementsByTagName(PARAM_ELEM);
240 HashMap param_map = new HashMap();
241 for (int i=0; i<params.getLength(); i++) {
242 Element param = (Element)params.item(i);
243 String name=param.getAttribute(NAME_ATT);
244 String value=param.getAttribute(VALUE_ATT);
245 if (value.equals("")) { // the value is in the content of the param
246 value=getNodeText(param);
247 }
248 param_map.put(name, value);
249
250 }
251 return param_map;
252 }
253
254 /** gets the value att or the text content */
255 public static String getValue(Element e) {
256 String val = e.getAttribute(VALUE_ATT);
257 if (val ==null || val.equals("")) {
258 // have to get it out of the text
259 val=getNodeText(e);
260
261 }
262 return val;
263 }
264
265 /** extracts the text out of a node */
266 public static String getNodeText(Element param) {
267 param.normalize();
268 Node n = param.getFirstChild();
269 while (n!=null && n.getNodeType() !=Node.TEXT_NODE) {
270 n=n.getNextSibling();
271 }
272 if (n==null) { // no text node
273 return "";
274 }
275 return n.getNodeValue();
276 }
277 /** creates a new document Element */
278 public static Element createDocumentElement(Document owner, String oid) {
279 Element e = owner.createElement(DOCUMENT_ELEM);
280 e.setAttribute(NAME_ATT, oid);
281
282 return e;
283 }
284
285 /** add text to a document/subsection element */
286 public static boolean addDocText(Document owner, Element doc, String text) {
287
288 Element content = owner.createElement(DOC_NODE_CONTENT_ELEM);
289 Text t = owner.createTextNode(text);
290 content.appendChild(t);
291 doc.appendChild(content);
292 return true;
293 }
294
295 /** add an error message */
296 public static boolean addError(Document owner, Element doc, String text) {
297
298 Element content = owner.createElement(ERROR_ELEM);
299 Text t = owner.createTextNode(text);
300 content.appendChild(t);
301
302 return true;
303 }
304
305 /** add an error message */
306 public static boolean addError(Document owner, Element doc, Throwable error) {
307 error.printStackTrace();
308 return addError(owner, doc, error.toString());
309 }
310
311 /** adds an empty MetadataList elem to a doc, and returns a ref to it*/
312// public static Element addMetaList(Document owner, Element doc) {
313// Element list = owner.createElement(METADATA_ELEM+LIST_MODIFIER);
314// doc.appendChild(list);
315// return list;
316// }
317 /** adds a metadata elem to a list */
318 public static boolean addMetadata(Document owner, Element list,
319 String meta_name, String meta_value) {
320 if (meta_value==null || meta_value.equals("")) {
321 return false;
322 }
323 Element data = owner.createElement(METADATA_ELEM);
324 data.setAttribute(NAME_ATT, meta_name);
325 Text t = owner.createTextNode(meta_value);
326 data.appendChild(t);
327 list.appendChild(data);
328 return true;
329
330 }
331
332 /** copies the metadata out of teh metadataList of 'from' into
333 * the metadataList of 'to' */
334 public static boolean mergeMetadataLists(Node to, Node from) {
335 Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER);
336 Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER);
337
338 if (from_meta == null) { // nothing to copy
339 return true;
340 }
341 Document to_owner = to.getOwnerDocument();
342 Node new_from = to_owner.importNode(from_meta, true);
343
344 if (to_meta == null) { // just copy the whole list
345 to.appendChild(new_from);
346 return true;
347 }
348
349 // copy individual elements
350 Node child = new_from.getFirstChild();
351 while ( child != null) {
352 to_meta.appendChild(child);
353 child = child.getNextSibling();
354 }
355 return true;
356 }
357
358 /** takes two nodes - should have the same node type, tag name, etc
359 * copies the info from 'from' into 'to'
360 -- not finished haven't thought through the algo yet.*/
361 /*
362 public static boolean mergeElements(Element to, Element from) {
363
364 if (to.getNodeName()!=from.getNodeName()) {
365 System.err.println("cant merge two nodes with different names");
366 return false;
367 }
368
369 // copy any atts over - ignore for now
370
371 // copy the children
372 if (!from.hasChildNodes()) {
373 return true;
374 }
375
376 // check if they belong to the same document
377 Document to_doc = to.getOwnerDocument();
378 Document from_doc = from.getOwnerDocument();
379 Element newfrom;
380 if (to_doc != from_doc) {
381 nfrom = to_doc.importNode(from, true);
382 } else {
383 newfrom = from;
384 }
385
386 if (!to.hasChildNodes()) {
387 // just copy all the children over
388 Node child = newfrom.getFirstChild();
389 while (child !=null) {
390 to.appendChild(child);
391 child = child.getNextSibling();
392 }
393 return true;
394 }
395
396 // have to check each one to see if already present or not
397 HashMap children = getChildrenMap(to);
398
399 Node child = newfrom.getFirstChild();
400 while (child !=null) {
401 String name = child.getNodeName();
402 Node n = map.get(name);
403 if (n==null) { // there is no elem by that name in to
404 to.appendChild(child);
405 }
406 else {
407 }
408 return true;
409 }
410 */
411 /** returns the (first) child element with the given name */
412 public static Node getChildByTagName(Node n, String name) {
413
414 Node child = n.getFirstChild();
415 while (child!=null) {
416 if (child.getNodeName().equals(name)) {
417 return child;
418 }
419 child = child.getNextSibling();
420 }
421 return null; //not found
422 }
423
424 /** takes an xpath type expression of the form name/name/...
425 and returns the first node that matches, or null if not found */
426 public static Node getNodeByPath(Node n, String path) {
427
428 String link = GSPath.getFirstLink(path);
429 path = GSPath.removeFirstLink(path);
430 while (!link.equals("")) {
431 n = getChildByTagName(n, link);
432 if (n==null) {
433 return null;
434 }
435 link = GSPath.getFirstLink(path);
436 path = GSPath.removeFirstLink(path);
437 }
438 return n;
439 }
440 public static HashMap getChildrenMap(Node n) {
441
442 HashMap map= new HashMap();
443 Node child = n.getFirstChild();
444 while (child!=null) {
445 String name = child.getNodeName();
446 map.put(name, child);
447 child = child.getNextSibling();
448 }
449 return map;
450 }
451
452 public static Element createTextElement(Document owner, String elem_name,
453 String text) {
454 Element e = owner.createElement(elem_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 type, String default_value,
464 String []options) {
465
466
467 Element p = owner.createElement(PARAM_ELEM);
468 p.setAttribute(NAME_ATT, name);
469 p.setAttribute(TYPE_ATT, type);
470 if (default_value != null) {
471 p.setAttribute(DEFAULT_ATT, default_value);
472 }
473 if (type.startsWith(PARAM_TYPE_ENUM_START) && options!=null) {
474 for (int i=0; i<options.length; i++) {
475 Element e = owner.createElement(PARAM_OPTION_ELEM);
476 e.setAttribute(NAME_ATT, options[i]);
477 p.appendChild(e);
478 }
479 }
480 return p;
481 }
482
483 /** creates a parm elem containing the text strings
484 * <param><name>xxx<name><option name='x'>yyy</option><option name='y'>zzz</option></param>
485 */
486 public static Element createParameterDisplay(Document owner, String name,
487 String name_text,
488 String []options,
489 String []option_texts) {
490
491
492 Element param = owner.createElement(PARAM_ELEM);
493 param.setAttribute(NAME_ATT, name);
494 param.appendChild(createTextElement(owner, DISPLAY_NAME_ELEM, name_text));
495 if (options != null) {
496 for (int i=0; i<options.length; i++) {
497 Element e = GSXML.createTextElement(owner, PARAM_OPTION_ELEM, option_texts[i]);
498 e.setAttribute(NAME_ATT, options[i]);
499 param.appendChild(e);
500 }
501 }
502
503 return param;
504 }
505 /*
506 public static Element createClassifierDisplay(Document owner, String name,
507 String name_text) {
508 Element classifier = owner.createElement(CLASSIFIER_ELEM);
509 classifier.setAttribute(NAME_ATT, name);
510 classifier.appendChild(createTextElement(owner, DISPLAY_NAME_ELEM, name_text));
511
512 return classifier;
513 }
514
515 *
516 /** returns the element parent/node_name[@attribute_name='attribute_value']
517 */
518 public static Element getNamedElement(Element parent, String node_name,
519 String attribute_name,
520 String attribute_value) {
521
522 NodeList children = parent.getChildNodes();
523 for (int i=0; i<children.getLength(); i++) {
524 Node child = children.item(i);
525 if (child.getNodeName().equals(node_name)) {
526 if (((Element)child).getAttribute(attribute_name).equals(attribute_value))
527 return (Element)child;
528 }
529 }
530 // not found
531 return null;
532 }
533
534
535 /** Returns the appropriate language element from a display elem,
536 display is the containing element, name is the name of the element to
537 look for, lang is the preferred language, lang_default is the fall back
538 lang if neither lang is found, will return the first one it finds*/
539 public static String getDisplayText(Element display, String name,
540 String lang, String lang_default) {
541 Element item = getNamedElement(display, name, GSXML.LANG_ATT, lang);
542 if (item==null) {
543 item = getNamedElement(display, name, GSXML.LANG_ATT, lang_default);
544 }
545 if (item ==null) {
546 item = (Element)getChildByTagName(display, name); // just get the first one
547 }
548 if (item==null) {
549 return ""; // should we return an empty string? or null?
550 }
551 return getNodeText(item);
552
553 }
554 // replaces < > " ' & in the original with their entities
555 public static String xmlSafe(String original) {
556
557 StringBuffer filtered = new StringBuffer(original.length());
558 char c;
559 for (int i=0; i<original.length(); i++) {
560 c = original.charAt(i);
561 if (c == '>') {
562 filtered.append("&gt;");
563 } else if (c == '<') {
564 filtered.append("&lt;");
565 } else if (c == '"') {
566 filtered.append("&quot;");
567 } else if (c == '&') {
568 filtered.append("&amp;");
569 } else if (c == '\'') {
570 filtered.append("&apos;");
571 } else {
572 filtered.append(c);
573 }
574 }
575 return filtered.toString();
576 }
577}
Note: See TracBrowser for help on using the repository browser.