Remove catch(...) handler occurrences.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / XMLHelper.cpp
1 /*\r
2  *  Copyright 2001-2006 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * XMLHelper.cpp\r
19  * \r
20  * A helper class for working with W3C DOM objects. \r
21  */\r
22 \r
23 #include "internal.h"\r
24 #include "exceptions.h"\r
25 #include "util/XMLHelper.h"\r
26 #include "util/XMLConstants.h"\r
27 \r
28 #include <xercesc/framework/MemBufFormatTarget.hpp>\r
29 #include <xercesc/util/XMLUniDefs.hpp>\r
30 \r
31 using namespace xmltooling;\r
32 \r
33 static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };\r
34     \r
35 bool XMLHelper::hasXSIType(const DOMElement* e)\r
36 {\r
37     if (e) {\r
38         if (e->hasAttributeNS(XMLConstants::XSI_NS, type)) {\r
39             return true;\r
40         }\r
41     }\r
42 \r
43     return false;\r
44 }\r
45 \r
46 QName* XMLHelper::getXSIType(const DOMElement* e)\r
47 {\r
48     DOMAttr* attribute = e->getAttributeNodeNS(XMLConstants::XSI_NS, type);\r
49     if (attribute) {\r
50         const XMLCh* attributeValue = attribute->getTextContent();\r
51         if (attributeValue && *attributeValue) {\r
52             int i;\r
53             if ((i=XMLString::indexOf(attributeValue,chColon))>0) {\r
54                 XMLCh* prefix=new XMLCh[i+1];\r
55                 XMLString::subString(prefix,attributeValue,0,i);\r
56                 prefix[i]=chNull;\r
57                 QName* ret=new QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
58                 delete[] prefix;\r
59                 return ret;\r
60             }\r
61             else {\r
62                 return new QName(e->lookupNamespaceURI(&chNull), attributeValue);\r
63             }\r
64         }\r
65     }\r
66 \r
67     return NULL;\r
68 }\r
69 \r
70 DOMAttr* XMLHelper::getIdAttribute(const DOMElement* domElement)\r
71 {\r
72     if(!domElement->hasAttributes()) {\r
73         return NULL;\r
74     }\r
75     \r
76     DOMNamedNodeMap* attributes = domElement->getAttributes();\r
77     DOMAttr* attribute;\r
78     for(XMLSize_t i = 0; i < attributes->getLength(); i++) {\r
79         attribute = static_cast<DOMAttr*>(attributes->item(i));\r
80         if(attribute->isId()) {\r
81             return attribute;\r
82         }\r
83     }\r
84     \r
85     return NULL;\r
86 }\r
87 \r
88 QName* XMLHelper::getNodeQName(const DOMNode* domNode)\r
89 {\r
90     if (domNode)\r
91         return new QName(domNode->getNamespaceURI(), domNode->getLocalName(), domNode->getPrefix());\r
92     return NULL; \r
93 }\r
94 \r
95 QName* XMLHelper::getAttributeValueAsQName(const DOMAttr* attribute)\r
96 {\r
97     if (!attribute)\r
98         return NULL;\r
99     \r
100     int i;\r
101     const XMLCh* attributeValue=attribute->getTextContent();\r
102     if (attributeValue && (i=XMLString::indexOf(attributeValue,chColon))>0) {\r
103         XMLCh* prefix=new XMLCh[i+1];\r
104         XMLString::subString(prefix,attributeValue,0,i);\r
105         prefix[i]=chNull;\r
106         QName* ret=new QName(attribute->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
107         delete[] prefix;\r
108         return ret;\r
109     }\r
110     \r
111     return new QName(attribute->lookupNamespaceURI(NULL), attributeValue);\r
112 }\r
113 \r
114 DOMElement* XMLHelper::appendChildElement(DOMElement* parentElement, DOMElement* childElement)\r
115 {\r
116     DOMDocument* parentDocument = parentElement->getOwnerDocument();\r
117     if (childElement->getOwnerDocument() != parentDocument) {\r
118         childElement = static_cast<DOMElement*>(parentDocument->importNode(childElement, true));\r
119     }\r
120 \r
121     parentElement->appendChild(childElement);\r
122     return childElement;\r
123 }\r
124 \r
125 const XMLCh* XMLHelper::getTextContent(const DOMElement* e)\r
126 {\r
127     DOMNode* child=e->getFirstChild();\r
128     while (child) {\r
129         if (child->getNodeType()==DOMNode::TEXT_NODE)\r
130             return child->getNodeValue();\r
131         child=child->getNextSibling();\r
132     }\r
133     return NULL;\r
134 }\r
135 \r
136 DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n)\r
137 {\r
138     DOMNode* child = n->getFirstChild();\r
139     while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)\r
140         child = child->getNextSibling();\r
141     if (child)\r
142         return static_cast<DOMElement*>(child);\r
143     return NULL;\r
144 }    \r
145 \r
146 DOMElement* XMLHelper::getLastChildElement(const DOMNode* n)\r
147 {\r
148     DOMNode* child = n->getLastChild();\r
149     while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)\r
150         child = child->getPreviousSibling();\r
151     if (child)\r
152         return static_cast<DOMElement*>(child);\r
153     return NULL;\r
154 }    \r
155 \r
156 DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
157 {\r
158     DOMElement* e = getFirstChildElement(n);\r
159     while (e && !isNodeNamed(e, ns, localName))\r
160         e = getNextSiblingElement(e);\r
161     return e;\r
162 }\r
163 \r
164 DOMElement* XMLHelper::getLastChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
165 {\r
166     DOMElement* e = getLastChildElement(n);\r
167     while (e && !isNodeNamed(e, ns, localName))\r
168         e = getPreviousSiblingElement(e);\r
169     return e;\r
170 }\r
171 \r
172 DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n)\r
173 {\r
174     DOMNode* sib = n->getNextSibling();\r
175     while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)\r
176         sib = sib->getNextSibling();\r
177     if (sib)\r
178         return static_cast<DOMElement*>(sib);\r
179     return NULL;\r
180 }\r
181 \r
182 DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n)\r
183 {\r
184     DOMNode* sib = n->getPreviousSibling();\r
185     while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)\r
186         sib = sib->getPreviousSibling();\r
187     if (sib)\r
188         return static_cast<DOMElement*>(sib);\r
189     return NULL;\r
190 }\r
191 \r
192 DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
193 {\r
194     DOMElement* e = getNextSiblingElement(n);\r
195     while (e && !isNodeNamed(e, ns, localName))\r
196         e = getNextSiblingElement(e);\r
197     return e;\r
198 }\r
199 \r
200 DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
201 {\r
202     DOMElement* e = getPreviousSiblingElement(n);\r
203     while (e && !isNodeNamed(e, ns, localName))\r
204         e = getPreviousSiblingElement(e);\r
205     return e;\r
206 }\r
207 \r
208 void XMLHelper::serialize(const DOMElement* e, std::string& buf)\r
209 {\r
210     static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
211     static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
212     DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);\r
213     DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();\r
214     XercesJanitor<DOMWriter> janitor(serializer);\r
215     serializer->setEncoding(UTF8);\r
216     MemBufFormatTarget target;\r
217     if (!serializer->writeNode(&target,*e))\r
218         throw XMLParserException("unable to serialize XML");\r
219     buf.erase();\r
220     buf.append(reinterpret_cast<const char*>(target.getRawBuffer()),target.getLen());\r
221 }\r