Move catalog handling to parser API from config API.
[shibboleth/cpp-xmltooling.git] / xmltooling / XMLObject.h
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * @file xmltooling/XMLObject.h
23  * 
24  * Abstract interface to objects that can be manipulated in and out of XML form. 
25  */
26
27 #ifndef __xmltooling_xmlobj_h__
28 #define __xmltooling_xmlobj_h__
29
30 #include <xmltooling/Namespace.h>
31 #include <xmltooling/util/XMLConstants.h>
32
33 #include <set>
34 #include <list>
35 #include <vector>
36 #include <xercesc/dom/DOM.hpp>
37
38 #ifndef XMLTOOLING_NO_XMLSEC
39 namespace xmlsignature {
40     class XMLTOOL_API Signature;
41 };
42 #endif
43
44 #if defined (_MSC_VER)
45     #pragma warning( push )
46     #pragma warning( disable : 4250 4251 )
47 #endif
48
49 namespace xmltooling {
50
51 #ifndef XMLTOOLING_NO_XMLSEC
52     class XMLTOOL_API Credential;
53 #endif
54     class XMLTOOL_API QName;
55
56     /**
57      * Object that represents an XML Element that has been unmarshalled into this C++ object.
58      */
59     class XMLTOOL_API XMLObject
60     {
61     public:
62         virtual ~XMLObject();
63         
64         /**
65          * Creates a copy of the object, along with all of its children.
66          * 
67          * The new object tree will be completely distinct and independent of
68          * the original in all respects.
69          */
70         virtual XMLObject* clone() const=0;
71         
72         /**
73          * Specialized function for detaching a child object from its parent
74          * <strong>while disposing of the parent</strong>.
75          *
76          * This is not a generic way of detaching any child object, but only of
77          * pruning a single child from the root of an XMLObject tree. If the
78          * detached XMLObject's parent is itself a child, an exception will be
79          * thrown. It's mainly useful for turning a child into the new root of
80          * the tree without having to clone the child.
81          */
82         virtual void detach()=0;
83
84         /**
85          * Gets the QName for this element.  This QName <strong>MUST</strong> 
86          * contain the namespace URI, namespace prefix, and local element name.
87          * 
88          * @return constant reference to the QName for this object
89          */
90         virtual const QName& getElementQName() const=0;
91         
92         /**
93          * Gets the namespaces that are scoped to this element.
94          * 
95          * The caller MUST NOT modify the set returned, but may use any
96          * non-modifying operations or algorithms on it. Iterators will
97          * remain valid unless the set member referenced is removed using
98          * the removeNamespace method.
99          * 
100          * @return the namespaces that are scoped to this element
101          */
102         virtual const std::set<Namespace>& getNamespaces() const=0;
103         
104         /**
105          * Adds a namespace to the ones already scoped to this element
106          * 
107          * @param ns the namespace to add
108          */
109         virtual void addNamespace(const Namespace& ns) const=0;
110         
111         /**
112          * Removes a namespace from this element
113          * 
114          * @param ns the namespace to remove
115          */
116         virtual void removeNamespace(const Namespace& ns)=0;
117         
118         /**
119          * Gets the XML schema type of this element.  This translates to contents the xsi:type
120          * attribute for the element.
121          * 
122          * @return XML schema type of this element
123          */
124         virtual const QName* getSchemaType() const=0;
125         
126         /**
127          * Gets the value of the ID attribute set on this object, if any.
128          * 
129          * @return an ID value or nullptr 
130          */
131         virtual const XMLCh* getXMLID() const=0;
132
133         /**
134          * Returns the xsi:nil property of the object, or false if not set.
135          * 
136          * @return      the xsi:nil property
137          */
138         bool nil() const {
139             switch (getNil()) {
140                 case xmlconstants::XML_BOOL_TRUE:
141                 case xmlconstants::XML_BOOL_ONE:
142                     return true;
143                 case xmlconstants::XML_BOOL_FALSE:
144                 case xmlconstants::XML_BOOL_ZERO:
145                 default:
146                     return false; 
147             }
148         }
149
150         /**
151          * Returns the xsi:nil property as an explicit enumerated value.
152          * 
153          * @return the xsi:nil property
154          */
155         virtual xmlconstants::xmltooling_bool_t getNil() const=0;
156         
157         /**
158          * Sets the xsi:nil property using an enumerated value.
159          * 
160          * @param value value to set
161          */
162         virtual void nil(xmlconstants::xmltooling_bool_t value)=0;
163         
164         /**
165          * Sets the xsi:nil property.
166          * 
167          * @param value value to set
168          */
169         void nil(bool value) {
170             nil(value ? xmlconstants::XML_BOOL_ONE : xmlconstants::XML_BOOL_ZERO);
171         }
172         
173         /**
174          * Sets the xsi:nil property using a string constant.
175          * 
176          * @param value value to set
177          */
178         void setNil(const XMLCh* value);
179         
180         /**
181          * Checks to see if this object has a parent.
182          * 
183          * @return true if the object has a parent, false if not
184          */
185         virtual bool hasParent() const=0;
186         
187         /**
188          * Gets the parent of this element or null if there is no parent.
189          * 
190          * @return the parent of this element or null
191          */
192         virtual XMLObject* getParent() const=0;
193         
194         /**
195          * Sets the parent of this element.
196          * 
197          * @param parent the parent of this element
198          */
199         virtual void setParent(XMLObject* parent)=0;
200         
201         /**
202          * Checks if this XMLObject has children.
203          * 
204          * @return true if this XMLObject has children, false if not
205          */
206         virtual bool hasChildren() const=0;
207         
208         /**
209          * Returns an unmodifiable list of child objects in the order that they
210          * should appear in the serialized representation.
211          * 
212          * The validity of the returned list is not maintained if any non-const
213          * operations are performed on the parent object. 
214          * 
215          * @return the list of children
216          */
217         virtual const std::list<XMLObject*>& getOrderedChildren() const=0;
218
219         /**
220          * Used by a child's detach method to isolate the child from
221          * this parent object in preparation for destroying the parent
222          * (this object).
223          * 
224          * @param child the child object to remove
225          */
226         virtual void removeChild(XMLObject* child)=0;
227
228         /**
229          * Returns the text content at the specified position relative to
230          * any child elements. A zero represents leading text, 1 comes after
231          * the first child, and so forth.
232          *
233          * @param position  the relative child element position of the text  
234          * @return the designated text value
235          */
236         virtual const XMLCh* getTextContent(unsigned int position=0) const=0;
237
238         /**
239          * Sets (or clears) text content relative to a child element's position. 
240          * 
241          * @param value         value to set, or nullptr to clear
242          * @param position      position relative to child element 
243          */
244         virtual void setTextContent(const XMLCh* value, unsigned int position=0)=0;
245
246         /**
247          * Gets the DOM representation of this XMLObject, if one exists.
248          * 
249          * @return the DOM representation of this XMLObject
250          */
251         virtual xercesc::DOMElement* getDOM() const=0;
252         
253         /**
254          * Sets the DOM representation of this XMLObject.
255          * 
256          * @param dom       DOM representation of this XMLObject
257          * @param bindDocument  true if the object should take ownership of the associated Document
258          */
259         virtual void setDOM(xercesc::DOMElement* dom, bool bindDocument=false) const=0;
260     
261         /**
262          * Assigns ownership of a DOM document to the XMLObject.
263          * This binds the lifetime of the document to the lifetime of the object.
264          * 
265          * @param doc DOM document bound to this object 
266          */
267         virtual void setDocument(xercesc::DOMDocument* doc) const=0;
268
269         /**
270          * Releases the DOM representation of this XMLObject, if there is one.
271          */
272         virtual void releaseDOM() const=0;
273         
274         /**
275          * Releases the DOM representation of this XMLObject's parent.
276          * 
277          * @param propagateRelease true if all ancestors of this element should release their DOM
278          */
279         virtual void releaseParentDOM(bool propagateRelease=true) const=0;
280         
281         /**
282          * Releases the DOM representation of this XMLObject's children.
283          * 
284          * @param propagateRelease true if all descendants of this element should release their DOM
285          */
286         virtual void releaseChildrenDOM(bool propagateRelease=true) const=0;
287
288         /**
289          * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true).
290          */
291         void releaseThisandParentDOM() const;
292     
293         /**
294          * A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM().
295          */
296         void releaseThisAndChildrenDOM() const;
297
298         /**
299          * Marshalls the XMLObject, and its children, into a DOM element.
300          * If a document is supplied, then it will be used to create the resulting elements.
301          * If the document does not have a Document Element set, then the resulting
302          * element will be set as the Document Element. If no document is supplied, then
303          * a new document will be created and bound to the lifetime of the root object being
304          * marshalled, unless an existing DOM can be reused without creating a new document. 
305          * 
306          * @param document  the DOM document the marshalled element will be placed in, or nullptr
307          * @param sigs      ordered array of signatures to create after marshalling is complete
308          * @param credential    optional credential to supply signing key and related info
309          * @return the DOM element representing this XMLObject
310          * 
311          * @throws MarshallingException thrown if there is a problem marshalling the given object
312          * @throws SignatureException thrown if a problem occurs during signature creation 
313          */
314         virtual xercesc::DOMElement* marshall(
315             xercesc::DOMDocument* document=nullptr
316 #ifndef XMLTOOLING_NO_XMLSEC
317             ,const std::vector<xmlsignature::Signature*>* sigs=nullptr
318             ,const Credential* credential=nullptr
319 #endif
320             ) const=0;
321         
322         /**
323          * Marshalls the XMLObject and appends it as a child of the given parent element.
324          * 
325          * <strong>NOTE:</strong> The given Element must be within a DOM tree rooted in 
326          * the Document owning the given Element.
327          * 
328          * @param parentElement the parent element to append the resulting DOM tree
329          * @param sigs          ordered array of signatures to create after marshalling is complete
330          * @param credential    optional credential to supply signing key and related info
331          * @return the marshalled element tree
332
333          * @throws MarshallingException thrown if the given XMLObject can not be marshalled.
334          * @throws SignatureException thrown if a problem occurs during signature creation 
335          */
336         virtual xercesc::DOMElement* marshall(
337             xercesc::DOMElement* parentElement
338 #ifndef XMLTOOLING_NO_XMLSEC
339             ,const std::vector<xmlsignature::Signature*>* sigs=nullptr
340             ,const Credential* credential=nullptr
341 #endif
342             ) const=0;
343
344         /**
345          * Unmarshalls the given W3C DOM element into the XMLObject.
346          * The root of a given XML construct should be unmarshalled with the bindDocument parameter
347          * set to true.
348          * 
349          * @param element       the DOM element to unmarshall
350          * @param bindDocument  true iff the resulting XMLObject should take ownership of the DOM's Document 
351          * 
352          * @return the unmarshalled XMLObject
353          * 
354          * @throws UnmarshallingException thrown if an error occurs unmarshalling the DOM element into the XMLObject
355          */
356         virtual XMLObject* unmarshall(xercesc::DOMElement* element, bool bindDocument=false)=0;
357
358     protected:
359         XMLObject();
360     private:
361         XMLObject& operator=(const XMLObject& src);
362     };
363
364 };
365
366 #if defined (_MSC_VER)
367     #pragma warning( pop )
368 #endif
369
370 #endif /* __xmltooling_xmlobj_h__ */