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

Last change on this file since 3600 was 3600, checked in by kjdon, 22 years ago

added some new methods for xml-safeing, and handling multiparams

  • Property svn:keywords set to Author Date Id Revision
File size: 14.4 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 METADATA_ELEM = "metadata";
28 public static final String SERVICE_IMPL_ELEM = "servicesImpl";
29 public static final String CLASSIFIER_ELEM = "classifier";
30 public static final String APPLET_ELEM = "applet";
31 public static final String APPLET_DATA_ELEM = "appletData";
32 public static final String CONFIGURE_ELEM = "configure";
33 public static final String STATUS_ELEM = "status";
34 public static final String DEFAULT_ELEM = "default";
35 // elems for the pages to be processed by xslt
36 public final static String PAGE_ELEM = "page";
37 public final static String TRANSLATION_ELEM = "translate";
38 public final static String CONFIGURATION_ELEM = "config";
39 public final static String DESCRIPTION_ELEM = "description";
40
41 public static final String SITE_NAME_ELEM = "localSiteName";
42 // add on to another elem type to get a list of that type
43 public static final String LIST_MODIFIER = "List";
44
45 //public static final String
46 //public static final String
47
48 // greenstone xml attributes
49 public static final String NAME_ATT = "name";
50 public static final String TO_ATT = "to";
51 public static final String FROM_ATT = "from";
52 public static final String LANG_ATT = "lang";
53 public static final String TYPE_ATT = "type";
54 public static final String VALUE_ATT = "value";
55 public static final String DEFAULT_ATT = "default";
56 public static final String INFO_ATT = "info";
57 public static final String ACTION_ATT = "action";
58 public static final String SUBACTION_ATT = "subaction";
59 public static final String ADDRESS_ATT = "address";
60 public static final String PARAM_SHORTNAME_ATT = "shortname";
61 public static final String PARAM_IGNORE_POS_ATT = "ignore";
62
63 // parameter types
64 public static final String PARAM_TYPE_INTEGER = "integer";
65 public static final String PARAM_TYPE_BOOLEAN = "boolean";
66 public static final String PARAM_TYPE_ENUM = "enum";
67 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single";
68 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi";
69 public static final String PARAM_TYPE_STRING = "string";
70 public static final String PARAM_TYPE_MULTI = "multi";
71
72 // stuff for text strings
73 public static final String DISPLAY_ELEM = "display";
74 public static final String DISPLAY_NAME_ELEM = "name";
75 public static final String DISPLAY_SUBMIT_ELEM = "submit";
76
77 // request types
78 public static final String REQUEST_TYPE_DESCRIBE = "describe";
79 public static final String REQUEST_TYPE_CONFIGURE = "configure";
80 public static final String REQUEST_TYPE_QUERY = "query";
81 public static final String REQUEST_TYPE_ACTION = "action";
82 public static final String REQUEST_TYPE_BUILD = "build";
83
84 // service types
85 public static final String SERVICE_TYPE_QUERY = "query";
86 public static final String SERVICE_TYPE_BUILD = "build";
87
88 // configure types
89 public static final String CONFIG_ACTION_ACTIVATE = "activate";
90 public static final String CONFIG_ACTION_DEACTIVATE = "deactivate";
91
92 // communicator types
93 public static final String COMM_TYPE_SOAP_JAVA = "soap";
94
95 // takes a node with a resource elements inside it and extracts all the
96 // HASh oids - name att for resource
97 public static String [] getResourceNameList(Element content) {
98
99 Node n = content.getFirstChild();
100 while (n!=null && !n.getNodeName().equals(RESOURCE_ELEM+LIST_MODIFIER)) {
101 n = n.getNextSibling();
102 }
103 if (n==null) { // no docs found
104 return null;
105 }
106
107 NodeList docs = n.getChildNodes();
108
109 int numdocs = docs.getLength();
110 String []ids = new String[numdocs];
111 for (int i=0; i<numdocs; i++) {
112 Element e = (Element)docs.item(i);
113 String id = e.getAttribute(NAME_ATT);
114 // check that its a valid id - ie starts with HASH
115 // need to change this if use different ids
116
117 ids[i] = id;
118
119 }
120
121 return ids;
122 }
123
124 /** extracts metadata names out of an element */
125 public static String [] getMetaNameList(Element content) {
126 Node n = content.getFirstChild();
127 while (n!=null &&
128 !n.getNodeName().equals(METADATA_ELEM+LIST_MODIFIER)) {
129 n = n.getNextSibling();
130 }
131 if (n==null) { // no metadatas found
132 return null;
133 }
134 NodeList elems = n.getChildNodes();
135
136 int numelems = elems.getLength();
137 String []ids = new String[numelems];
138 for (int i=0; i<numelems; i++) {
139 Element e = (Element)elems.item(i);
140 String id = e.getAttribute(NAME_ATT);
141 ids[i] = id;
142 }
143
144 return ids;
145 }
146
147 /** takes a paramList element, and gets a HashMap of name-value pairs */
148 public static HashMap extractParams(Element xml) {
149
150 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
151 System.err.println("GSXML:paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
152 return null;
153 }
154 NodeList params = xml.getChildNodes();
155 HashMap param_map = new HashMap();
156 for (int i=0; i<params.getLength(); i++) {
157 Element param = (Element)params.item(i);
158 String name=param.getAttribute(NAME_ATT);
159 String value=param.getAttribute(VALUE_ATT);
160 if (value.equals("")) { // the value is in the content of the param
161 value=getNodeText(param);
162 }
163 param_map.put(name, value);
164
165 }
166 return param_map;
167 }
168 /** takes a paramList element, and gets a HashMap of name-value pairs */
169 public static HashMap extractAllParams(Element xml) {
170
171 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
172 System.err.println("GSXML:paramList element should have been passed to extractParams, instead it was "+xml.getNodeName());
173 return null;
174 }
175 NodeList params = xml.getElementsByTagName(PARAM_ELEM);
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=param.getAttribute(VALUE_ATT);
181 if (value.equals("")) { // the value is in the content of the param
182 value=getNodeText(param);
183 }
184 param_map.put(name, value);
185
186 }
187 return param_map;
188 }
189
190 public static String getValue(Element e) {
191 String val = e.getAttribute(VALUE_ATT);
192 if (val ==null || val.equals("")) {
193 // have to get it out of the text
194 val=getNodeText(e);
195
196 }
197 return val;
198 }
199 /** extracts the text out of a node */
200 public static String getNodeText(Element param) {
201 param.normalize();
202 Node n = param.getFirstChild();
203 while (n!=null && n.getNodeType() !=Node.TEXT_NODE) {
204 n=n.getNextSibling();
205 }
206 if (n==null) { // no text node
207 return "";
208 }
209 return n.getNodeValue();
210 }
211 /** creates a new document Element */
212 public static Element createResourceElement(Document owner, String oid) {
213 Element e = owner.createElement(RESOURCE_ELEM);
214 e.setAttribute(NAME_ATT, oid);
215
216 return e;
217 }
218
219 /** add text to a document/subsection element */
220 public static boolean addDocText(Document owner, Element doc, String text) {
221
222 Element content = owner.createElement(CONTENT_ELEM);
223 Text t = owner.createTextNode(text);
224 content.appendChild(t);
225 doc.appendChild(content);
226 return true;
227 }
228 /** adds an empty MetadataList elem to a doc, and returns a ref to it*/
229 public static Element addMetaList(Document owner, Element doc) {
230 Element list = owner.createElement(METADATA_ELEM+LIST_MODIFIER);
231 doc.appendChild(list);
232 return list;
233 }
234 /** adds a metadata elem to a list */
235 public static boolean addMetadata(Document owner, Element list,
236 String meta_name, String meta_value) {
237 if (meta_value==null || meta_value.equals("")) {
238 return false;
239 }
240 Element data = owner.createElement(METADATA_ELEM);
241 data.setAttribute(NAME_ATT, meta_name);
242 Text t = owner.createTextNode(meta_value);
243 data.appendChild(t);
244 list.appendChild(data);
245 return true;
246
247 }
248
249 public static boolean mergeMetadataLists(Node to, Node from) {
250 Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER);
251 Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER);
252
253 if (from_meta == null) { // nothing to copy
254 return true;
255 }
256 Document to_owner = to.getOwnerDocument();
257 Node new_from = to_owner.importNode(from_meta, true);
258
259 if (to_meta == null) { // just copy the whole list
260 to.appendChild(new_from);
261 return true;
262 }
263
264 // copy individual elements
265 Node child = new_from.getFirstChild();
266 while ( child != null) {
267 to_meta.appendChild(child);
268 child = child.getNextSibling();
269 }
270 return true;
271 }
272
273 /** takes two nodes - should have the same node type, tag name, etc
274 * copies the info from 'from' into 'to'
275 -- not finished haven't thought through the algo yet.*/
276 /*
277 public static boolean mergeElements(Element to, Element from) {
278
279 if (to.getNodeName()!=from.getNodeName()) {
280 System.err.println("cant merge two nodes with different names");
281 return false;
282 }
283
284 // copy any atts over - ignore for now
285
286 // copy the children
287 if (!from.hasChildNodes()) {
288 return true;
289 }
290
291 // check if they belong to the same document
292 Document to_doc = to.getOwnerDocument();
293 Document from_doc = from.getOwnerDocument();
294 Element newfrom;
295 if (to_doc != from_doc) {
296 nfrom = to_doc.importNode(from, true);
297 } else {
298 newfrom = from;
299 }
300
301 if (!to.hasChildNodes()) {
302 // just copy all the children over
303 Node child = newfrom.getFirstChild();
304 while (child !=null) {
305 to.appendChild(child);
306 child = child.getNextSibling();
307 }
308 return true;
309 }
310
311 // have to check each one to see if already present or not
312 HashMap children = getChildrenMap(to);
313
314 Node child = newfrom.getFirstChild();
315 while (child !=null) {
316 String name = child.getNodeName();
317 Node n = map.get(name);
318 if (n==null) { // there is no elem by that name in to
319 to.appendChild(child);
320 }
321 else {
322 }
323 return true;
324 }
325 */
326 /** returns the (first) child element with the given name */
327 public static Node getChildByTagName(Node n, String name) {
328
329 Node child = n.getFirstChild();
330 while (child!=null) {
331 if (child.getNodeName().equals(name)) {
332 return child;
333 }
334 child = child.getNextSibling();
335 }
336 return null; //not found
337 }
338
339 /** takes an xpath type expression of the form name/name/...
340 and returns the first node that matches, or null if not found */
341 public static Node getNodeByPath(Node n, String path) {
342
343 String link = GSPath.getFirstLink(path);
344 path = GSPath.removeFirstLink(path);
345 while (!link.equals("")) {
346 n = getChildByTagName(n, link);
347 if (n==null) {
348 return null;
349 }
350 link = GSPath.getFirstLink(path);
351 path = GSPath.removeFirstLink(path);
352 }
353 return n;
354 }
355 public static HashMap getChildrenMap(Node n) {
356
357 HashMap map= new HashMap();
358 Node child = n.getFirstChild();
359 while (child!=null) {
360 String name = child.getNodeName();
361 map.put(name, child);
362 child = child.getNextSibling();
363 }
364 return map;
365 }
366
367 public static Element createTextElement(Document owner, String elem_name,
368 String text) {
369 Element e = owner.createElement(elem_name);
370 Text t = owner.createTextNode(text);
371 e.appendChild(t);
372 return e;
373
374 }
375
376
377 public static Element createParameter(Document owner, String name,
378 String type, String default_value,
379 String []options) {
380
381
382 Element p = owner.createElement(PARAM_ELEM);
383 p.setAttribute(NAME_ATT, name);
384 p.setAttribute(TYPE_ATT, type);
385 if (default_value != null) {
386 p.setAttribute(DEFAULT_ATT, default_value);
387 }
388 if (type.startsWith(PARAM_TYPE_ENUM) && options!=null) {
389 for (int i=0; i<options.length; i++) {
390 Element e = owner.createElement(PARAM_OPTION_ELEM);
391 e.setAttribute(NAME_ATT, options[i]);
392 p.appendChild(e);
393 }
394 }
395 return p;
396 }
397
398 /** creates a parm elem containing the text strings
399 * <param><name>xxx<name><option name='x'>yyy</option><option name='y'>zzz</option></param>
400 */
401 public static Element createParameterDisplay(Document owner, String name,
402 String name_text,
403 String []options,
404 String []option_texts) {
405
406
407 Element param = owner.createElement(PARAM_ELEM);
408 param.setAttribute(NAME_ATT, name);
409 param.appendChild(createTextElement(owner, DISPLAY_NAME_ELEM, name_text));
410 if (options != null) {
411 for (int i=0; i<options.length; i++) {
412 Element e = GSXML.createTextElement(owner, PARAM_OPTION_ELEM, option_texts[i]);
413 e.setAttribute(NAME_ATT, options[i]);
414 param.appendChild(e);
415 }
416 }
417
418 return param;
419 }
420
421 /** returns the element parent/node_name[@attribute_name='attribute_value']
422 */
423 public static Element getNamedElement(Element parent, String node_name,
424 String attribute_name,
425 String attribute_value) {
426
427 NodeList children = parent.getChildNodes();
428 for (int i=0; i<children.getLength(); i++) {
429 Node child = children.item(i);
430 if (child.getNodeName().equals(node_name)) {
431 if (((Element)child).getAttribute(attribute_name).equals(attribute_value))
432 return (Element)child;
433 }
434 }
435 // not found
436 return null;
437 }
438
439 // replaces < > " ' & in the original with their entities
440 public static String xmlSafe(String original) {
441
442 StringBuffer filtered = new StringBuffer(original.length());
443 char c;
444 for (int i=0; i<original.length(); i++) {
445 c = original.charAt(i);
446 if (c == '>') {
447 filtered.append("&gt;");
448 } else if (c == '<') {
449 filtered.append("&lt;");
450 } else if (c == '"') {
451 filtered.append("&quot;");
452 } else if (c == '&') {
453 filtered.append("&amp;");
454 } else if (c == '\'') {
455 filtered.append("&apos;");
456 } else {
457 filtered.append(c);
458 }
459 }
460 return filtered.toString();
461 }
462}
Note: See TracBrowser for help on using the repository browser.