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