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

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

added new method createBasicRequest

  • Property svn:keywords set to Author Date Id Revision
File size: 15.5 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 NODE_ID_ATT = "nodeID";
83 public static final String NODE_NAME_ATT = "nodeName";
84 public static final String NODE_TYPE_ATT = "nodeType";
85 // should we rename these to the above??
86 public static final String DOC_NODE_ID_ATT = "nodeID";
87 public static final String DOC_NODE_NAME_ATT = "nodeName";
88 public static final String DOC_NODE_TYPE_ATT = "nodeType";
89
90 public static final String NODE_TYPE_ROOT = "root";
91 public static final String NODE_TYPE_INTERIOR = "interior";
92 public static final String NODE_TYPE_LEAF = "leaf";
93
94 // classifier stuff
95 public static final String CLASS_NODE_ELEM = "classifierNode";
96 public static final String CLASS_NODE_ORIENTATION_ATT = "orientation";
97 //public static final String CLASS_NODE_ID_ATT = "classifierID";
98
99 // parameter types
100 public static final String PARAM_TYPE_INTEGER = "integer";
101 public static final String PARAM_TYPE_BOOLEAN = "boolean";
102 public static final String PARAM_TYPE_ENUM_START = "enum";
103 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
104 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
105 public static final String PARAM_TYPE_STRING = "string";
106 public static final String PARAM_TYPE_TEXT = "text";
107 public static final String PARAM_TYPE_MULTI = "multi";
108 public static final String PARAM_TYPE_FILE = "file";
109 // stuff for text strings
110 public static final String DISPLAY_ELEM = "display";
111 public static final String DISPLAY_NAME_ELEM = "name";
112 public static final String DISPLAY_SUBMIT_ELEM = "submit";
113
114 // request types - do we need all these? or just
115 // describe, status, and one to say do teh request
116 public static final String REQUEST_TYPE_DESCRIBE = "describe";
117 public static final String REQUEST_TYPE_STATUS = "status";
118 public static final String REQUEST_TYPE_PROCESS = "process";
119 public static final String REQUEST_TYPE_CONFIGURE = "configure";
120 public static final String REQUEST_TYPE_CGI = "cgi";
121 public static final String REQUEST_TYPE_FORMAT = "format";
122
123 public static final String REQUEST_TYPE_ACTION = "action"; // ??
124 public static final String REQUEST_TYPE_QUERY = "query"; // ??
125 public static final String REQUEST_TYPE_BUILD = "build"; // ??
126
127 // service types
128 public static final String SERVICE_TYPE_QUERY = "query";
129 public static final String SERVICE_TYPE_RETRIEVE = "retrieve";
130 public static final String SERVICE_TYPE_BROWSE = "browse";
131 public static final String SERVICE_TYPE_APPLET = "applet";
132 public static final String SERVICE_TYPE_PROCESS = "process";
133
134 // configure types
135 public static final String CONFIG_ACTION_ACTIVATE = "activate";
136 public static final String CONFIG_ACTION_DEACTIVATE = "deactivate";
137
138 // communicator types
139 public static final String COMM_TYPE_SOAP_JAVA = "soap";
140
141
142 /** takes a list of elements, and returns an array of strings
143 * of the values of attribute att_name */
144 public static String [] getAttributeValuesFromList(Element list,
145 String att_name) {
146
147 NodeList children = list.getChildNodes();
148
149 int num_nodes = children.getLength();
150 String []ids = new String[num_nodes];
151 for (int i=0; i<num_nodes; i++) {
152 Element e = (Element)children.item(i);
153 String id = e.getAttribute(att_name);
154 ids[i] = id;
155 }
156
157 return ids;
158 }
159
160 /** takes a paramList element, and gets a HashMap of name-value pairs
161 * if deep=true, extracts embedded params, otherwise just top level
162 * params*/
163 public static HashMap extractParams(Element xml, boolean deep) {
164
165 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
166 System.err.println("GSXML:paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
167 return null;
168 }
169
170 NodeList params = null;
171 if (deep) { // get all the nested ones
172 params = xml.getElementsByTagName(PARAM_ELEM);
173 } else { // just get the top level ones
174 params = xml.getChildNodes();
175 }
176 HashMap param_map = new HashMap();
177 for (int i=0; i<params.getLength(); i++) {
178 Element param = (Element)params.item(i);
179 String name=param.getAttribute(NAME_ATT);
180 String value=getValue(param); //att or content
181 param_map.put(name, value);
182
183 }
184 return param_map;
185 }
186
187 /** gets the value att or the text content */
188 public static String getValue(Element e) {
189 String val = e.getAttribute(VALUE_ATT);
190 if (val ==null || val.equals("")) {
191 // have to get it out of the text
192 val=getNodeText(e);
193
194 }
195 return val;
196 }
197
198 /** extracts the text out of a node */
199 public static String getNodeText(Element param) {
200 param.normalize();
201 Node n = param.getFirstChild();
202 while (n!=null && n.getNodeType() !=Node.TEXT_NODE) {
203 n=n.getNextSibling();
204 }
205 if (n==null) { // no text node
206 return "";
207 }
208 return n.getNodeValue();
209 }
210
211
212 /** add text to a document/subsection element */
213 public static boolean addDocText(Document owner, Element doc, String text) {
214
215 Element content = owner.createElement(DOC_NODE_CONTENT_ELEM);
216 Text t = owner.createTextNode(text);
217 content.appendChild(t);
218 doc.appendChild(content);
219 return true;
220 }
221
222 /** add an error message */
223 public static boolean addError(Document owner, Element doc, String text) {
224
225 Element content = owner.createElement(ERROR_ELEM);
226 Text t = owner.createTextNode(text);
227 content.appendChild(t);
228
229 return true;
230 }
231
232 /** add an error message */
233 public static boolean addError(Document owner, Element doc, Throwable error) {
234 error.printStackTrace();
235 return addError(owner, doc, error.toString());
236 }
237
238 /** adds a metadata elem to a list */
239 public static boolean addMetadata(Document owner, Element list,
240 String meta_name, String meta_value) {
241 if (meta_value==null || meta_value.equals("")) {
242 return false;
243 }
244 Element data = owner.createElement(METADATA_ELEM);
245 data.setAttribute(NAME_ATT, meta_name);
246 Text t = owner.createTextNode(meta_value);
247 data.appendChild(t);
248 list.appendChild(data);
249 return true;
250
251 }
252
253 /** copies the metadata out of teh metadataList of 'from' into
254 * the metadataList of 'to' */
255 public static boolean mergeMetadataLists(Node to, Node from) {
256 Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER);
257 Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER);
258
259 if (from_meta == null) { // nothing to copy
260 return true;
261 }
262 Document to_owner = to.getOwnerDocument();
263 Node new_from = to_owner.importNode(from_meta, true);
264
265 if (to_meta == null) { // just copy the whole list
266 to.appendChild(new_from);
267 return true;
268 }
269
270 // copy individual elements
271 Node child = new_from.getFirstChild();
272 while ( child != null) {
273 to_meta.appendChild(child);
274 child = child.getNextSibling();
275 }
276 return true;
277 }
278
279 /** returns the (first) child element with the given name */
280 public static Node getChildByTagName(Node n, String name) {
281
282 Node child = n.getFirstChild();
283 while (child!=null) {
284 if (child.getNodeName().equals(name)) {
285 return child;
286 }
287 child = child.getNextSibling();
288 }
289 return null; //not found
290 }
291
292 /** takes an xpath type expression of the form name/name/...
293 and returns the first node that matches, or null if not found */
294 public static Node getNodeByPath(Node n, String path) {
295
296 String link = GSPath.getFirstLink(path);
297 path = GSPath.removeFirstLink(path);
298 while (!link.equals("")) {
299 n = getChildByTagName(n, link);
300 if (n==null) {
301 return null;
302 }
303 link = GSPath.getFirstLink(path);
304 path = GSPath.removeFirstLink(path);
305 }
306 return n;
307 }
308 public static HashMap getChildrenMap(Node n) {
309
310 HashMap map= new HashMap();
311 Node child = n.getFirstChild();
312 while (child!=null) {
313 String name = child.getNodeName();
314 map.put(name, child);
315 child = child.getNextSibling();
316 }
317 return map;
318 }
319
320
321 /** returns a basic request message */
322 public static Element createBasicRequest(Document owner,
323 String request_type, String to,
324 String lang) {
325 Element request = owner.createElement(REQUEST_ELEM);
326 request.setAttribute(TYPE_ATT, request_type);
327 request.setAttribute(LANG_ATT, lang);
328 request.setAttribute(TO_ATT, to);
329 return request;
330 }
331 public static Element createTextElement(Document owner, String elem_name,
332 String text) {
333 Element e = owner.createElement(elem_name);
334 Text t = owner.createTextNode(text);
335 e.appendChild(t);
336 return e;
337
338 }
339
340
341 public static Element createParameter(Document owner, String name,
342 String type, String default_value,
343 String []options) {
344
345
346 Element p = owner.createElement(PARAM_ELEM);
347 p.setAttribute(NAME_ATT, name);
348 p.setAttribute(TYPE_ATT, type);
349 if (default_value != null) {
350 p.setAttribute(DEFAULT_ATT, default_value);
351 }
352 if (type.startsWith(PARAM_TYPE_ENUM_START) && options!=null) {
353 for (int i=0; i<options.length; i++) {
354 Element e = owner.createElement(PARAM_OPTION_ELEM);
355 e.setAttribute(NAME_ATT, options[i]);
356 p.appendChild(e);
357 }
358 }
359 return p;
360 }
361
362 /** creates a parm elem containing the text strings
363 * <param><name>xxx<name><option name='x'>yyy</option><option name='y'>zzz</option></param>
364 */
365 public static Element createParameterDisplay(Document owner, String name,
366 String name_text,
367 String []options,
368 String []option_texts) {
369
370
371 Element param = owner.createElement(PARAM_ELEM);
372 param.setAttribute(NAME_ATT, name);
373 param.appendChild(createTextElement(owner, DISPLAY_NAME_ELEM, name_text));
374 if (options != null) {
375 for (int i=0; i<options.length; i++) {
376 Element e = GSXML.createTextElement(owner, PARAM_OPTION_ELEM, option_texts[i]);
377 e.setAttribute(NAME_ATT, options[i]);
378 param.appendChild(e);
379 }
380 }
381
382 return param;
383 }
384
385 /** returns the element parent/node_name[@attribute_name='attribute_value']
386 */
387 public static Element getNamedElement(Element parent, String node_name,
388 String attribute_name,
389 String attribute_value) {
390
391 NodeList children = parent.getChildNodes();
392 for (int i=0; i<children.getLength(); i++) {
393 Node child = children.item(i);
394 if (child.getNodeName().equals(node_name)) {
395 if (((Element)child).getAttribute(attribute_name).equals(attribute_value))
396 return (Element)child;
397 }
398 }
399 // not found
400 return null;
401 }
402
403
404 /** Returns the appropriate language element from a display elem,
405 display is the containing element, name is the name of the element to
406 look for, lang is the preferred language, lang_default is the fall back
407 lang if neither lang is found, will return the first one it finds*/
408 public static String getDisplayText(Element display, String name,
409 String lang, String lang_default) {
410 Element item = getNamedElement(display, name, GSXML.LANG_ATT, lang);
411 if (item==null) {
412 item = getNamedElement(display, name, GSXML.LANG_ATT, lang_default);
413 }
414 if (item ==null) {
415 item = (Element)getChildByTagName(display, name); // just get the first one
416 }
417 if (item==null) {
418 return ""; // should we return an empty string? or null?
419 }
420 return getNodeText(item);
421
422 }
423 // replaces < > " ' & in the original with their entities
424 public static String xmlSafe(String original) {
425
426 StringBuffer filtered = new StringBuffer(original.length());
427 char c;
428 for (int i=0; i<original.length(); i++) {
429 c = original.charAt(i);
430 if (c == '>') {
431 filtered.append("&gt;");
432 } else if (c == '<') {
433 filtered.append("&lt;");
434 } else if (c == '"') {
435 filtered.append("&quot;");
436 } else if (c == '&') {
437 filtered.append("&amp;");
438 } else if (c == '\'') {
439 filtered.append("&apos;");
440 } else {
441 filtered.append(c);
442 }
443 }
444 return filtered.toString();
445 }
446}
Note: See TracBrowser for help on using the repository browser.