Major revamp of credential and trust handling code, PKIX engine still needs work.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / XMLHelper.h
1 /*
2  *  Copyright 2001-2007 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file XMLHelper.h
19  * 
20  * A helper class for working with W3C DOM objects. 
21  */
22
23 #ifndef __xmltooling_xmlhelper_h__
24 #define __xmltooling_xmlhelper_h__
25
26 #include <xmltooling/XMLObject.h>
27 #include <xercesc/dom/DOM.hpp>
28
29 #include <iostream>
30
31 using namespace xercesc;
32
33 namespace xmltooling {
34     
35     /**
36      * RAII wrapper for Xerces resources.
37      */
38     template<class T> class XercesJanitor
39     {
40         MAKE_NONCOPYABLE(XercesJanitor);
41         T* m_held;
42     public:
43         /**
44          * Constructor
45          * 
46          * @param resource  object to release when leaving scope
47          */
48         XercesJanitor(T* resource) : m_held(resource) {}
49         
50         ~XercesJanitor() {
51             if (m_held)
52                 m_held->release();
53         }
54         
55         /**
56          * Returns resource held by this object.
57          * 
58          * @return  the resource held or NULL
59          */
60         T* get() {
61             return m_held;
62         }
63
64         /**
65          * Returns resource held by this object.
66          * 
67          * @return  the resource held or NULL
68          */
69         T* operator->() {
70             return m_held;
71         }
72
73         /**
74          * Returns resource held by this object and releases it to the caller.
75          * 
76          * @return  the resource held or NULL
77          */
78         T* release() {
79             T* ret=m_held;
80             m_held=NULL;
81             return ret;
82         }
83     };
84     
85     /**
86      * A helper class for working with W3C DOM objects. 
87      */
88     class XMLTOOL_API XMLHelper
89     {
90     public:
91         /**
92          * Checks if the given element has an xsi:type defined for it
93          * 
94          * @param e the DOM element
95          * @return true if there is a type, false if not
96          */
97         static bool hasXSIType(const DOMElement* e);
98
99         /**
100          * Gets the XSI type for a given element if it has one.
101          * 
102          * @param e the element
103          * @return the type or null
104          */
105         static QName* getXSIType(const DOMElement* e);
106
107         /**
108          * Gets the ID attribute of a DOM element.
109          * 
110          * @param domElement the DOM element
111          * @return the ID attribute or null if there isn't one
112          */
113         static DOMAttr* getIdAttribute(const DOMElement* domElement);
114
115         /**
116          * Attempts to locate an XMLObject from this point downward in the tree whose
117          * XML ID matches the supplied value.
118          * 
119          * @param tree  root of tree to search
120          * @param id    ID value to locate
121          * @return XMLObject in the tree with a matching ID value, or NULL
122          */
123         static const XMLObject* getXMLObjectById(const XMLObject& tree, const XMLCh* id);
124         
125
126         /**
127          * Gets the QName for the given DOM node.
128          * 
129          * @param domNode the DOM node
130          * @return the QName for the element or null if the element was null
131          */
132         static QName* getNodeQName(const DOMNode* domNode);
133
134         /**
135          * Constructs a QName from an attribute's value.
136          * 
137          * @param attribute the attribute with a QName value
138          * @return a QName from an attribute's value, or null if the given attribute is null
139          */
140         static QName* getAttributeValueAsQName(const DOMAttr* attribute);
141
142         /**
143          * Appends the child Element to the parent Element,
144          * importing the child Element into the parent's Document if needed.
145          * 
146          * @param parentElement the parent Element
147          * @param childElement the child Element
148          * @return the child Element that was added (may be an imported copy)
149          */
150         static DOMElement* appendChildElement(DOMElement* parentElement, DOMElement* childElement);
151         
152         /**
153          * Checks the qualified name of a node.
154          * 
155          * @param n     node to check
156          * @param ns    namespace to compare with
157          * @param local local name to compare with
158          * @return  true iff the node's qualified name matches the other parameters
159          */
160         static bool isNodeNamed(const DOMNode* n, const XMLCh* ns, const XMLCh* local) {
161             return (n && XMLString::equals(local,n->getLocalName()) && XMLString::equals(ns,n->getNamespaceURI()));
162         }
163
164         /**
165          * Returns the first matching child element of the node if any.
166          * 
167          * @param n         node to check
168          * @param localName local name to compare with or NULL for any match
169          * @return  the first matching child node of type Element, or NULL
170          */
171         static DOMElement* getFirstChildElement(const DOMNode* n, const XMLCh* localName=NULL);
172         
173         /**
174          * Returns the last matching child element of the node if any.
175          * 
176          * @param n     node to check
177          * @param localName local name to compare with or NULL for any match
178          * @return  the last matching child node of type Element, or NULL
179          */
180         static DOMElement* getLastChildElement(const DOMNode* n, const XMLCh* localName=NULL);
181         
182         /**
183          * Returns the next matching sibling element of the node if any.
184          * 
185          * @param n     node to check
186          * @param localName local name to compare with or NULL for any match
187          * @return  the next matching sibling node of type Element, or NULL
188          */
189         static DOMElement* getNextSiblingElement(const DOMNode* n, const XMLCh* localName=NULL);
190         
191         /**
192          * Returns the previous matching sibling element of the node if any.
193          * 
194          * @param n     node to check
195          * @param localName local name to compare with or NULL for any match
196          * @return  the previous matching sibling node of type Element, or NULL
197          */
198         static DOMElement* getPreviousSiblingElement(const DOMNode* n, const XMLCh* localName=NULL);
199         
200         /**
201          * Returns the first matching child element of the node if any.
202          * 
203          * @param n         node to check
204          * @param ns        namespace to compare with
205          * @param localName local name to compare with
206          * @return  the first matching child node of type Element, or NULL
207          */
208         static DOMElement* getFirstChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
209         
210         /**
211          * Returns the last matching child element of the node if any.
212          * 
213          * @param n         node to check
214          * @param ns        namespace to compare with
215          * @param localName local name to compare with
216          * @return  the last matching child node of type Element, or NULL
217          */
218         static DOMElement* getLastChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
219         
220         /**
221          * Returns the next matching sibling element of the node if any.
222          * 
223          * @param n         node to check
224          * @param ns        namespace to compare with
225          * @param localName local name to compare with
226          * @return  the next matching sibling node of type Element, or NULL
227          */
228         static DOMElement* getNextSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
229         
230         /**
231          * Returns the previous matching sibling element of the node if any.
232          * 
233          * @param n         node to check
234          * @param ns        namespace to compare with
235          * @param localName local name to compare with
236          * @return  the previous matching sibling node of type Element, or NULL
237          */
238         static DOMElement* getPreviousSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
239
240         /**
241          * Returns the content of the first Text node found in the element, if any.
242          * This is roughly similar to the DOM getTextContent function, but only
243          * examples the immediate children of the element.
244          *
245          * @param e     element to examine
246          * @return the content of the first Text node found, or NULL
247          */
248         static const XMLCh* getTextContent(const DOMElement* e);
249
250         /**
251          * Serializes the DOM node provided into a buffer using UTF-8 encoding and
252          * the default XML serializer available. No manipulation or formatting is applied.
253          * 
254          * @param n     node to serialize
255          * @param buf   buffer to serialize element into
256          */
257         static void serialize(const DOMNode* n, std::string& buf);
258
259         /**
260          * Serializes the DOM node provided to a stream using UTF-8 encoding and
261          * the default XML serializer available. No manipulation or formatting is applied.
262          * 
263          * @param n     node to serialize
264          * @param out   stream to serialize element into
265          * @return reference to output stream
266          */
267         static std::ostream& serialize(const DOMNode* n, std::ostream& out);
268     };
269
270     /**
271      * Serializes the DOM node provided to a stream using UTF-8 encoding and
272      * the default XML serializer available. No manipulation or formatting is applied.
273      * 
274      * @param n      node to serialize
275      * @param ostr   stream to serialize element into
276      * @return reference to output stream
277      */
278     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const DOMNode& n);
279
280     /**
281      * Marshalls and serializes the XMLObject provided to a stream using UTF-8 encoding and
282      * the default XML serializer available. No manipulation or formatting is applied.
283      * 
284      * <p>The marshaller operation takes no parameters.
285      * 
286      * @param obj    object to serialize
287      * @param ostr   stream to serialize object into
288      * @return reference to output stream
289      */
290     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const XMLObject& obj);
291 };
292
293 #endif /* __xmltooling_xmlhelper_h__ */