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

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

doc node atts now have generic names so can be shared by documents and classifiers

  • Property svn:keywords set to Author Date Id Revision
File size: 15.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 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
120 public static final String REQUEST_TYPE_CONFIGURE = "configure"; // ?
121 public static final String REQUEST_TYPE_CGI = "cgi"; // ?
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 public static Element createTextElement(Document owner, String elem_name,
321 String text) {
322 Element e = owner.createElement(elem_name);
323 Text t = owner.createTextNode(text);
324 e.appendChild(t);
325 return e;
326
327 }
328
329
330 public static Element createParameter(Document owner, String name,
331 String type, String default_value,
332 String []options) {
333
334
335 Element p = owner.createElement(PARAM_ELEM);
336 p.setAttribute(NAME_ATT, name);
337 p.setAttribute(TYPE_ATT, type);
338 if (default_value != null) {
339 p.setAttribute(DEFAULT_ATT, default_value);
340 }
341 if (type.startsWith(PARAM_TYPE_ENUM_START) && options!=null) {
342 for (int i=0; i<options.length; i++) {
343 Element e = owner.createElement(PARAM_OPTION_ELEM);
344 e.setAttribute(NAME_ATT, options[i]);
345 p.appendChild(e);
346 }
347 }
348 return p;
349 }
350
351 /** creates a parm elem containing the text strings
352 * <param><name>xxx<name><option name='x'>yyy</option><option name='y'>zzz</option></param>
353 */
354 public static Element createParameterDisplay(Document owner, String name,
355 String name_text,
356 String []options,
357 String []option_texts) {
358
359
360 Element param = owner.createElement(PARAM_ELEM);
361 param.setAttribute(NAME_ATT, name);
362 param.appendChild(createTextElement(owner, DISPLAY_NAME_ELEM, name_text));
363 if (options != null) {
364 for (int i=0; i<options.length; i++) {
365 Element e = GSXML.createTextElement(owner, PARAM_OPTION_ELEM, option_texts[i]);
366 e.setAttribute(NAME_ATT, options[i]);
367 param.appendChild(e);
368 }
369 }
370
371 return param;
372 }
373
374 /** returns the element parent/node_name[@attribute_name='attribute_value']
375 */
376 public static Element getNamedElement(Element parent, String node_name,
377 String attribute_name,
378 String attribute_value) {
379
380 NodeList children = parent.getChildNodes();
381 for (int i=0; i<children.getLength(); i++) {
382 Node child = children.item(i);
383 if (child.getNodeName().equals(node_name)) {
384 if (((Element)child).getAttribute(attribute_name).equals(attribute_value))
385 return (Element)child;
386 }
387 }
388 // not found
389 return null;
390 }
391
392
393 /** Returns the appropriate language element from a display elem,
394 display is the containing element, name is the name of the element to
395 look for, lang is the preferred language, lang_default is the fall back
396 lang if neither lang is found, will return the first one it finds*/
397 public static String getDisplayText(Element display, String name,
398 String lang, String lang_default) {
399 Element item = getNamedElement(display, name, GSXML.LANG_ATT, lang);
400 if (item==null) {
401 item = getNamedElement(display, name, GSXML.LANG_ATT, lang_default);
402 }
403 if (item ==null) {
404 item = (Element)getChildByTagName(display, name); // just get the first one
405 }
406 if (item==null) {
407 return ""; // should we return an empty string? or null?
408 }
409 return getNodeText(item);
410
411 }
412 // replaces < > " ' & in the original with their entities
413 public static String xmlSafe(String original) {
414
415 StringBuffer filtered = new StringBuffer(original.length());
416 char c;
417 for (int i=0; i<original.length(); i++) {
418 c = original.charAt(i);
419 if (c == '>') {
420 filtered.append("&gt;");
421 } else if (c == '<') {
422 filtered.append("&lt;");
423 } else if (c == '"') {
424 filtered.append("&quot;");
425 } else if (c == '&') {
426 filtered.append("&amp;");
427 } else if (c == '\'') {
428 filtered.append("&apos;");
429 } else {
430 filtered.append(c);
431 }
432 }
433 return filtered.toString();
434 }
435}
Note: See TracBrowser for help on using the repository browser.