comparison WebServiceExtensionsV1.1/WebServiceToolWorkflow_REST_SOAP/lib/SAWADLParser/src/edu/uga/cs/lsdis/meteors/wadls/util/xml/DOMUtils.java @ 0:049760c677de default tip

Galaxy WSExtensions added successfully
author uga-galaxy-group
date Tue, 05 Jul 2011 19:34:18 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:049760c677de
1 /*
2 * (c) Copyright IBM Corp 2001, 2005
3 */
4
5 package edu.uga.cs.lsdis.meteors.wadls.util.xml;
6
7 import java.io.*;
8 import java.util.*;
9 import org.w3c.dom.*;
10
11 import javax.wadls.*;
12 import javax.xml.namespace.*;
13
14 public class DOMUtils {
15 /**
16 * The namespaceURI represented by the prefix <code>xmlns</code>.
17 */
18 private static String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
19
20 private static final String ATTR_XMLNS = "xmlns";
21
22 /**
23 * Returns a list of attributes of an element. Returns an
24 * empty list if the element has no attributes. Does not
25 * include namespace declarations.
26 *
27 * @param el Element whose attributes are returned
28 * @return the List of Attr
29 */
30 static public List getAttributes (Element el) {
31 String nodename, prefix = null;
32 List attrs = new Vector();
33 NamedNodeMap attrMap = el.getAttributes();
34 for(int i = 0; i < attrMap.getLength(); i++)
35 {
36 nodename = attrMap.item(i).getNodeName();
37 prefix = attrMap.item(i).getPrefix();
38
39 if (ATTR_XMLNS.equals(nodename) || ATTR_XMLNS.equals(prefix))
40 {
41 //ignore namespace declarations
42 continue;
43 }
44 else
45 {
46 attrs.add(attrMap.item(i));
47 }
48 }
49
50 return attrs;
51 }
52
53 /**
54 * Returns the value of an attribute of an element. Returns null
55 * if the attribute is not found (whereas Element.getAttribute
56 * returns "" if an attrib is not found). This method should be
57 * used for elements that support extension attributes because it
58 * does not track unexpected attributes.
59 *
60 * @param el Element whose attrib is looked for
61 * @param attrName name of attribute to look for
62 * @return the attribute value
63 */
64 static public String getAttribute (Element el, String attrName) {
65 String sRet = null;
66 Attr attr = el.getAttributeNode(attrName);
67
68 if (attr != null) {
69 sRet = attr.getValue();
70 }
71 return sRet;
72 }
73
74 /**
75 * Returns the value of an attribute of an element. Returns null
76 * if the attribute is not found (whereas Element.getAttribute
77 * returns "" if an attrib is not found). This method should be
78 * used for elements that do not support extension attributes
79 * because it tracks the element's remaining attributes so that
80 * eventually any unexpected attributes can be identified.
81 *
82 * @param el Element whose attrib is looked for
83 * @param attrName name of attribute to look for
84 * @param remainingAttrs List of remaining attributes
85 * @return the attribute value
86 */
87 static public String getAttribute (Element el, String attrName, List remainingAttrs) {
88 String sRet = null;
89 Attr attr = el.getAttributeNode(attrName);
90
91 if (attr != null) {
92 sRet = attr.getValue();
93 remainingAttrs.remove(attr);
94 }
95 return sRet;
96 }
97
98 /**
99 * Returns the value of an attribute of an element. Returns null
100 * if the attribute is not found (whereas Element.getAttributeNS
101 * returns "" if an attrib is not found).
102 *
103 * @param el Element whose attrib is looked for
104 * @param namespaceURI namespace URI of attribute to look for
105 * @param localPart local part of attribute to look for
106 * @return the attribute value
107 */
108 static public String getAttributeNS (Element el,
109 String namespaceURI,
110 String localPart) {
111 String sRet = null;
112 Attr attr = el.getAttributeNodeNS (namespaceURI, localPart);
113
114 if (attr != null) {
115 sRet = attr.getValue ();
116 }
117
118 return sRet;
119 }
120
121 /**
122 * Returns the value of an attribute of an element. Returns null
123 * if the attribute is not found (whereas Element.getAttributeNS
124 * returns "" if an attrib is not found).
125 *
126 * @param el Element whose attrib is looked for
127 * @param namespaceURI namespace URI of attribute to look for
128 * @param localPart local part of attribute to look for
129 * @return the attribute value
130 */
131 static public String getAttributeNS (Element el,
132 String namespaceURI,
133 String localPart,
134 List remainingAttrs) {
135 String sRet = null;
136 Attr attr = el.getAttributeNodeNS (namespaceURI, localPart);
137
138 if (attr != null) {
139 sRet = attr.getValue();
140 remainingAttrs.remove(attr);
141 }
142
143 return sRet;
144 }
145
146 /**
147 * Concat all the text and cdata node children of this elem and return
148 * the resulting text.
149 *
150 * @param parentEl the element whose cdata/text node values are to
151 * be combined.
152 * @return the concatanated string.
153 */
154 static public String getChildCharacterData (Element parentEl) {
155 if (parentEl == null) {
156 return null;
157 }
158 Node tempNode = parentEl.getFirstChild();
159 StringBuffer strBuf = new StringBuffer();
160 CharacterData charData;
161
162 while (tempNode != null) {
163 switch (tempNode.getNodeType()) {
164 case Node.TEXT_NODE :
165 case Node.CDATA_SECTION_NODE : charData = (CharacterData)tempNode;
166 strBuf.append(charData.getData());
167 break;
168 }
169 tempNode = tempNode.getNextSibling();
170 }
171 return strBuf.toString();
172 }
173
174 /**
175 * Return the first child element of the given element. Null if no
176 * children are found.
177 *
178 * @param elem Element whose child is to be returned
179 * @return the first child element.
180 */
181 public static Element getFirstChildElement (Element elem) {
182 for (Node n = elem.getFirstChild (); n != null; n = n.getNextSibling ()) {
183 if (n.getNodeType () == Node.ELEMENT_NODE) {
184 return (Element) n;
185 }
186 }
187 return null;
188 }
189
190 /**
191 * Return the next sibling element of the given element. Null if no
192 * more sibling elements are found.
193 *
194 * @param elem Element whose sibling element is to be returned
195 * @return the next sibling element.
196 */
197 public static Element getNextSiblingElement (Element elem) {
198 for (Node n = elem.getNextSibling (); n != null; n = n.getNextSibling ()) {
199 if (n.getNodeType () == Node.ELEMENT_NODE) {
200 return (Element) n;
201 }
202 }
203 return null;
204 }
205
206 /**
207 * Return the first child element of the given element which has the
208 * given attribute with the given value.
209 *
210 * @param elem the element whose children are to be searched
211 * @param attrName the attrib that must be present
212 * @param attrValue the desired value of the attribute
213 *
214 * @return the first matching child element.
215 */
216 public static Element findChildElementWithAttribute (Element elem,
217 String attrName,
218 String attrValue) {
219 for (Node n = elem.getFirstChild (); n != null; n = n.getNextSibling ()) {
220 if (n.getNodeType () == Node.ELEMENT_NODE) {
221 if (attrValue.equals (DOMUtils.getAttribute ((Element) n, attrName))) {
222 return (Element) n;
223 }
224 }
225 }
226 return null;
227 }
228
229 /**
230 * Count number of children of a certain type of the given element.
231 *
232 * @param elem the element whose kids are to be counted
233 *
234 * @return the number of matching kids.
235 */
236 public static int countKids (Element elem, short nodeType) {
237 int nkids = 0;
238 for (Node n = elem.getFirstChild (); n != null; n = n.getNextSibling ()) {
239 if (n.getNodeType () == nodeType) {
240 nkids++;
241 }
242 }
243 return nkids;
244 }
245
246 /**
247 * Given a prefix and a node, return the namespace URI that the prefix
248 * has been associated with. This method is useful in resolving the
249 * namespace URI of attribute values which are being interpreted as
250 * QNames. If prefix is null, this method will return the default
251 * namespace.
252 *
253 * @param context the starting node (looks up recursively from here)
254 * @param prefix the prefix to find an xmlns:prefix=uri for
255 *
256 * @return the namespace URI or null if not found
257 */
258 public static String getNamespaceURIFromPrefix (Node context,
259 String prefix) {
260 short nodeType = context.getNodeType ();
261 Node tempNode = null;
262
263 switch (nodeType)
264 {
265 case Node.ATTRIBUTE_NODE :
266 {
267 tempNode = ((Attr) context).getOwnerElement ();
268 break;
269 }
270 case Node.ELEMENT_NODE :
271 {
272 tempNode = context;
273 break;
274 }
275 default :
276 {
277 tempNode = context.getParentNode ();
278 break;
279 }
280 }
281
282 while (tempNode != null && tempNode.getNodeType () == Node.ELEMENT_NODE)
283 {
284 Element tempEl = (Element) tempNode;
285 String namespaceURI = null;
286 if (prefix == null){
287 namespaceURI = getAttribute (tempEl, "xmlns");
288 if (namespaceURI == null)
289 namespaceURI = getAttribute (tempEl, "targetNamespace");
290 }
291 else
292 namespaceURI = getAttributeNS (tempEl, NS_URI_XMLNS, prefix);
293
294 if (namespaceURI != null)
295 {
296 return namespaceURI;
297 }
298 else
299 {
300 tempNode = tempEl.getParentNode ();
301 }
302 }
303
304 return null;
305 }
306
307 public static QName getQName(String prefixedValue,
308 Element contextEl,
309 Application app)
310 throws WADLSException
311 {
312 int index = prefixedValue.indexOf(':');
313 String prefix = (index != -1)
314 ? prefixedValue.substring(0, index)
315 : null;
316 String localPart = prefixedValue.substring(index + 1);
317 String namespaceURI = getNamespaceURIFromPrefix(contextEl, prefix);
318
319 if (namespaceURI != null)
320 {
321 registerUniquePrefix(prefix, namespaceURI, app);
322
323 return new QName(namespaceURI, localPart);
324 }
325 else
326 {
327 String faultCode = (prefix == null)
328 ? WADLSException.NO_PREFIX_SPECIFIED
329 : WADLSException.UNBOUND_PREFIX;
330
331 WADLSException wsdlExc = new WADLSException(faultCode,
332 "Unable to determine " +
333 "namespace of '" +
334 prefixedValue + "'.");
335
336 wsdlExc.setLocation(XPathUtils.getXPathExprFromNode(contextEl));
337
338 throw wsdlExc;
339 }
340 }
341
342 public static void registerUniquePrefix(String prefix,
343 String namespaceURI,
344 Application app)
345 {
346 String tempNSUri = app.getNamespace(prefix);
347
348 if (tempNSUri != null && tempNSUri.equals(namespaceURI))
349 {
350 return;
351 }
352
353 while (tempNSUri != null && !tempNSUri.equals(namespaceURI))
354 {
355 prefix += "_";
356 tempNSUri = app.getNamespace(prefix);
357 }
358
359 app.addNamespace(prefix, namespaceURI);
360 }
361
362 /**
363 * This method should be used for elements that support extension attributes
364 * because it does not track the remaining attributes to test for unexpected
365 * attributes.
366 */
367 public static QName getQualifiedAttributeValue(Element el,
368 String attrName,
369 String elDesc,
370 boolean isRequired,
371 Application app)
372 throws WADLSException
373 {
374 String attrValue = DOMUtils.getAttribute(el, attrName);
375
376 if (attrValue != null)
377 {
378 return getQName(attrValue, el, app);
379 }
380 else if (isRequired)
381 {
382 WADLSException wsdlExc = new WADLSException(WADLSException.INVALID_WADL,
383 "The '" + attrName +
384 "' attribute must be " +
385 "specified for every " +
386 elDesc + " element.");
387
388 wsdlExc.setLocation(XPathUtils.getXPathExprFromNode(el));
389
390 throw wsdlExc;
391 }
392 else
393 {
394 return null;
395 }
396 }
397
398 /**
399 * This method should be used for elements that do not support extension attributes
400 * because it tracks the remaining attributes so that eventually any
401 * unexpected attributes can be identified.
402 */
403 public static QName getQualifiedAttributeValue(Element el,
404 String attrName,
405 String elDesc,
406 boolean isRequired,
407 Application app,
408 List remainingAttrs)
409 throws WADLSException
410 {
411 String attrValue = null;
412
413 attrValue = DOMUtils.getAttribute(el, attrName, remainingAttrs);
414
415 if (attrValue != null)
416 {
417 return getQName(attrValue, el, app);
418 }
419 else if (isRequired)
420 {
421 WADLSException wsdlExc = new WADLSException(WADLSException.INVALID_WADL,
422 "The '" + attrName +
423 "' attribute must be " +
424 "specified for every " +
425 elDesc + " element.");
426
427 wsdlExc.setLocation(XPathUtils.getXPathExprFromNode(el));
428
429 throw wsdlExc;
430 }
431 else
432 {
433 return null;
434 }
435 }
436
437 public static void throwWADLException(Element location) throws WADLSException
438 {
439 String elName = QNameUtils.newQName(location).toString();
440
441 WADLSException wsdlExc = new WADLSException(WADLSException.INVALID_WADL,
442 "Encountered unexpected element '" +
443 elName + "'.");
444
445 wsdlExc.setLocation(XPathUtils.getXPathExprFromNode(location));
446
447 throw wsdlExc;
448 }
449
450 public static void throwWADLException(Element location, List remainingAttrs) throws WADLSException
451 {
452 String elName = QNameUtils.newQName(location).toString();
453
454 StringBuffer sb = new StringBuffer();
455 ListIterator i = remainingAttrs.listIterator();
456 while (i.hasNext())
457 {
458 String attrName = QNameUtils.newQName((Attr)i.next()).toString();
459 sb.append(attrName);
460 sb.append( i.hasNext() ? " " : "");
461 }
462
463 WADLSException wsdlExc = new WADLSException(WADLSException.INVALID_WADL,
464 "Element '" +
465 elName +
466 "' contained unexpected attributes: '" +
467 sb.toString() +
468 "'");
469
470 wsdlExc.setLocation(XPathUtils.getXPathExprFromNode(location));
471
472 throw wsdlExc;
473 }
474
475 public static void printAttribute(String name,
476 String value,
477 PrintWriter pw)
478 {
479 if (value != null)
480 {
481 pw.print(' ' + name + "=\"" + cleanString(value) + '\"');
482 }
483 }
484
485 /**
486 * Prints attributes with qualified names.
487 */
488 public static void printQualifiedAttribute(QName name,
489 String value,
490 Application app,
491 PrintWriter pw)
492 throws WADLSException
493 {
494 if (name != null)
495 {
496 printAttribute(getQualifiedValue(name.getNamespaceURI(),
497 name.getLocalPart(),
498 app),
499 value,
500 pw);
501 }
502 }
503
504 public static void printQualifiedAttribute(QName name,
505 QName value,
506 Application app,
507 PrintWriter pw)
508 throws WADLSException
509 {
510 if (value != null)
511 {
512 printAttribute(getQualifiedValue(name.getNamespaceURI(),
513 name.getLocalPart(),
514 app),
515 getQualifiedValue(value.getNamespaceURI(),
516 value.getLocalPart(),
517 app),
518 pw);
519 }
520 }
521
522 public static void printQualifiedAttribute(String name,
523 QName value,
524 Application app,
525 PrintWriter pw)
526 throws WADLSException
527 {
528 if (value != null)
529 {
530 printAttribute(name,
531 getQualifiedValue(value.getNamespaceURI(),
532 value.getLocalPart(),
533 app),
534 pw);
535 }
536 }
537
538 public static String getQualifiedValue(String namespaceURI,
539 String localPart,
540 Application app)
541 throws WADLSException
542 {
543 String prefix = null;
544
545 if (namespaceURI != null && !namespaceURI.equals(""))
546 {
547 prefix = getPrefix(namespaceURI, app);
548 }
549
550 return ((prefix != null && !prefix.equals(""))
551 ? prefix + ":"
552 : "") + localPart;
553 }
554
555 public static String getPrefix(String namespaceURI,
556 Application app)
557 throws WADLSException
558 {
559 String prefix = app.getPrefix(namespaceURI);
560
561 if (prefix == null)
562 {
563 throw new WADLSException(WADLSException.OTHER_ERROR,
564 "Can't find prefix for '" + namespaceURI +
565 "'. Namespace prefixes must be set on the" +
566 " Definition object using the " +
567 "addNamespace(...) method.");
568 }
569
570 return prefix;
571 }
572
573 public static String cleanString(String orig)
574 {
575 if (orig == null)
576 {
577 return "";
578 }
579
580 StringBuffer strBuf = new StringBuffer();
581 char[] chars = orig.toCharArray();
582 boolean inCDATA = false;
583
584 for (int i = 0; i < chars.length; i++)
585 {
586 if (!inCDATA)
587 {
588 switch (chars[i])
589 {
590 case '&' : strBuf.append("&amp;");
591 break;
592 case '\"' : strBuf.append("&quot;");
593 break;
594 case '\'' : strBuf.append("&apos;");
595 break;
596 case '<' :
597 {
598 if (chars.length >= i + 9)
599 {
600 String tempStr = new String(chars, i, 9);
601
602 if (tempStr.equals("<![CDATA["))
603 {
604 strBuf.append(tempStr);
605 i += 8;
606 inCDATA = true;
607 }
608 else
609 {
610 strBuf.append("&lt;");
611 }
612 }
613 else
614 {
615 strBuf.append("&lt;");
616 }
617 }
618 break;
619 case '>' : strBuf.append("&gt;");
620 break;
621 default : strBuf.append(chars[i]);
622 break;
623 }
624 }
625 else
626 {
627 strBuf.append(chars[i]);
628
629 if (chars[i] == '>'
630 && chars[i - 1] == ']'
631 && chars[i - 2] == ']')
632 {
633 inCDATA = false;
634 }
635 }
636 }
637
638 return strBuf.toString();
639 }
640 }
641