Update build revision
[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 xml:lang property of the object, if any.
135          *
136          * @return  an xml:lang value, or nullptr
137          */
138         virtual const XMLCh* getLang() const;
139
140         /**
141          * Returns the xsi:nil property of the object, or false if not set.
142          * 
143          * @return      the xsi:nil property
144          */
145         bool nil() const {
146             switch (getNil()) {
147                 case xmlconstants::XML_BOOL_TRUE:
148                 case xmlconstants::XML_BOOL_ONE:
149                     return true;
150                 case xmlconstants::XML_BOOL_FALSE:
151                 case xmlconstants::XML_BOOL_ZERO:
152                 default:
153                     return false; 
154             }
155         }
156
157         /**
158          * Returns the xsi:nil property as an explicit enumerated value.
159          * 
160          * @return the xsi:nil property
161          */
162         virtual xmlconstants::xmltooling_bool_t getNil() const=0;
163         
164         /**
165          * Sets the xsi:nil property using an enumerated value.
166          * 
167          * @param value value to set
168          */
169         virtual void nil(xmlconstants::xmltooling_bool_t value)=0;
170         
171         /**
172          * Sets the xsi:nil property.
173          * 
174          * @param value value to set
175          */
176         void nil(bool value) {
177             nil(value ? xmlconstants::XML_BOOL_ONE : xmlconstants::XML_BOOL_ZERO);
178         }
179         
180         /**
181          * Sets the xsi:nil property using a string constant.
182          * 
183          * @param value value to set
184          */
185         void setNil(const XMLCh* value);
186         
187         /**
188          * Checks to see if this object has a parent.
189          * 
190          * @return true if the object has a parent, false if not
191          */
192         virtual bool hasParent() const=0;
193         
194         /**
195          * Gets the parent of this element or null if there is no parent.
196          * 
197          * @return the parent of this element or null
198          */
199         virtual XMLObject* getParent() const=0;
200         
201         /**
202          * Sets the parent of this element.
203          * 
204          * @param parent the parent of this element
205          */
206         virtual void setParent(XMLObject* parent)=0;
207         
208         /**
209          * Checks if this XMLObject has children.
210          * 
211          * @return true if this XMLObject has children, false if not
212          */
213         virtual bool hasChildren() const=0;
214         
215         /**
216          * Returns an unmodifiable list of child objects in the order that they
217          * should appear in the serialized representation.
218          * 
219          * The validity of the returned list is not maintained if any non-const
220          * operations are performed on the parent object. 
221          * 
222          * @return the list of children
223          */
224         virtual const std::list<XMLObject*>& getOrderedChildren() const=0;
225
226         /**
227          * Used by a child's detach method to isolate the child from
228          * this parent object in preparation for destroying the parent
229          * (this object).
230          * 
231          * @param child the child object to remove
232          */
233         virtual void removeChild(XMLObject* child)=0;
234
235         /**
236          * Returns the text content at the specified position relative to
237          * any child elements. A zero represents leading text, 1 comes after
238          * the first child, and so forth.
239          *
240          * @param position  the relative child element position of the text  
241          * @return the designated text value
242          */
243         virtual const XMLCh* getTextContent(unsigned int position=0) const=0;
244
245         /**
246          * Sets (or clears) text content relative to a child element's position. 
247          * 
248          * @param value         value to set, or nullptr to clear
249          * @param position      position relative to child element 
250          */
251         virtual void setTextContent(const XMLCh* value, unsigned int position=0)=0;
252
253         /**
254          * Gets the DOM representation of this XMLObject, if one exists.
255          * 
256          * @return the DOM representation of this XMLObject
257          */
258         virtual xercesc::DOMElement* getDOM() const=0;
259         
260         /**
261          * Sets the DOM representation of this XMLObject.
262          * 
263          * @param dom       DOM representation of this XMLObject
264          * @param bindDocument  true if the object should take ownership of the associated Document
265          */
266         virtual void setDOM(xercesc::DOMElement* dom, bool bindDocument=false) const=0;
267     
268         /**
269          * Assigns ownership of a DOM document to the XMLObject.
270          * This binds the lifetime of the document to the lifetime of the object.
271          * 
272          * @param doc DOM document bound to this object 
273          */
274         virtual void setDocument(xercesc::DOMDocument* doc) const=0;
275
276         /**
277          * Releases the DOM representation of this XMLObject, if there is one.
278          */
279         virtual void releaseDOM() const=0;
280         
281         /**
282          * Releases the DOM representation of this XMLObject's parent.
283          * 
284          * @param propagateRelease true if all ancestors of this element should release their DOM
285          */
286         virtual void releaseParentDOM(bool propagateRelease=true) const=0;
287         
288         /**
289          * Releases the DOM representation of this XMLObject's children.
290          * 
291          * @param propagateRelease true if all descendants of this element should release their DOM
292          */
293         virtual void releaseChildrenDOM(bool propagateRelease=true) const=0;
294
295         /**
296          * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true).
297          */
298         void releaseThisandParentDOM() const;
299     
300         /**
301          * A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM().
302          */
303         void releaseThisAndChildrenDOM() const;
304
305         /**
306          * Marshalls the XMLObject, and its children, into a DOM element.
307          * If a document is supplied, then it will be used to create the resulting elements.
308          * If the document does not have a Document Element set, then the resulting
309          * element will be set as the Document Element. If no document is supplied, then
310          * a new document will be created and bound to the lifetime of the root object being
311          * marshalled, unless an existing DOM can be reused without creating a new document. 
312          * 
313          * @param document  the DOM document the marshalled element will be placed in, or nullptr
314          * @param sigs      ordered array of signatures to create after marshalling is complete
315          * @param credential    optional credential to supply signing key and related info
316          * @return the DOM element representing this XMLObject
317          * 
318          * @throws MarshallingException thrown if there is a problem marshalling the given object
319          * @throws SignatureException thrown if a problem occurs during signature creation 
320          */
321         virtual xercesc::DOMElement* marshall(
322             xercesc::DOMDocument* document=nullptr
323 #ifndef XMLTOOLING_NO_XMLSEC
324             ,const std::vector<xmlsignature::Signature*>* sigs=nullptr
325             ,const Credential* credential=nullptr
326 #endif
327             ) const=0;
328         
329         /**
330          * Marshalls the XMLObject and appends it as a child of the given parent element.
331          * 
332          * <strong>NOTE:</strong> The given Element must be within a DOM tree rooted in 
333          * the Document owning the given Element.
334          * 
335          * @param parentElement the parent element to append the resulting DOM tree
336          * @param sigs          ordered array of signatures to create after marshalling is complete
337          * @param credential    optional credential to supply signing key and related info
338          * @return the marshalled element tree
339
340          * @throws MarshallingException thrown if the given XMLObject can not be marshalled.
341          * @throws SignatureException thrown if a problem occurs during signature creation 
342          */
343         virtual xercesc::DOMElement* marshall(
344             xercesc::DOMElement* parentElement
345 #ifndef XMLTOOLING_NO_XMLSEC
346             ,const std::vector<xmlsignature::Signature*>* sigs=nullptr
347             ,const Credential* credential=nullptr
348 #endif
349             ) const=0;
350
351         /**
352          * Unmarshalls the given W3C DOM element into the XMLObject.
353          * The root of a given XML construct should be unmarshalled with the bindDocument parameter
354          * set to true.
355          * 
356          * @param element       the DOM element to unmarshall
357          * @param bindDocument  true iff the resulting XMLObject should take ownership of the DOM's Document 
358          * 
359          * @return the unmarshalled XMLObject
360          * 
361          * @throws UnmarshallingException thrown if an error occurs unmarshalling the DOM element into the XMLObject
362          */
363         virtual XMLObject* unmarshall(xercesc::DOMElement* element, bool bindDocument=false)=0;
364
365     protected:
366         XMLObject();
367     private:
368         XMLObject& operator=(const XMLObject& src);
369     };
370
371 };
372
373 #if defined (_MSC_VER)
374     #pragma warning( pop )
375 #endif
376
377 #endif /* __xmltooling_xmlobj_h__ */