9d6319eb46aae70fe5d37ea72fff66c4f23081bc
[shibboleth/cpp-xmltooling.git] / xmltooling / AbstractXMLObject.h
1 /*
2 *  Copyright 2001-2009 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/AbstractXMLObject.h
19  *
20  * An abstract implementation of XMLObject.
21  */
22
23 #ifndef __xmltooling_abstractxmlobj_h__
24 #define __xmltooling_abstractxmlobj_h__
25
26 #include <xmltooling/logging.h>
27 #include <xmltooling/XMLObject.h>
28 #include <xmltooling/util/DateTime.h>
29
30 #if defined (_MSC_VER)
31     #pragma warning( push )
32     #pragma warning( disable : 4250 4251 )
33 #endif
34
35 namespace xmltooling {
36
37     /**
38      * An abstract implementation of XMLObject.
39      * This is the primary concrete base class, and supplies basic namespace,
40      * type, and parent handling. Most implementation classes should not
41      * directly inherit from this class, but rather from the various mixins
42      * that supply the rest of the XMLObject interface, as required.
43      */
44     class XMLTOOL_API AbstractXMLObject : public virtual XMLObject
45     {
46     public:
47         virtual ~AbstractXMLObject();
48
49         void detach();
50
51         const QName& getElementQName() const {
52             return m_elementQname;
53         }
54
55         const std::set<Namespace>& getNamespaces() const {
56             return m_namespaces;
57         }
58
59         void addNamespace(const Namespace& ns) const;
60
61         void removeNamespace(const Namespace& ns) {
62             m_namespaces.erase(ns);
63         }
64
65         const QName* getSchemaType() const {
66             return m_typeQname;
67         }
68
69         const XMLCh* getXMLID() const {
70             return NULL;
71         }
72
73         xmlconstants::xmltooling_bool_t getNil() const {
74                 return m_nil;
75         }
76
77         void nil(xmlconstants::xmltooling_bool_t value) {
78             if (m_nil != value) {
79                 releaseThisandParentDOM();
80                 m_nil = value;
81             }
82         }
83
84         bool hasParent() const {
85             return m_parent != NULL;
86         }
87
88         XMLObject* getParent() const {
89             return m_parent;
90         }
91
92         void setParent(XMLObject* parent) {
93             m_parent = parent;
94         }
95
96      protected:
97         /**
98          * Constructor
99          *
100          * @param nsURI         the namespace of the element
101          * @param localName     the local name of the XML element this Object represents
102          * @param prefix        the namespace prefix to use
103          * @param schemaType    the xsi:type to use
104          */
105         AbstractXMLObject(
106             const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const QName* schemaType=NULL
107             );
108
109         /** Copy constructor. */
110         AbstractXMLObject(const AbstractXMLObject& src);
111
112         /**
113          * A helper function for derived classes, for assignment of strings.
114          *
115          * This 'normalizes' newString, and then if it is different from oldString,
116          * it invalidates the DOM, frees the old string, and returns the new.
117          * If not different, it frees the new string and just returns the old value.
118          *
119          * @param oldValue the current value
120          * @param newValue the new value
121          *
122          * @return the value that should be assigned
123          */
124         XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue);
125
126         /**
127          * A helper function for derived classes, for assignment of date/time data.
128          *
129          * It invalidates the DOM, frees the old object, and returns the new.
130          *
131          * @param oldValue the current value
132          * @param newValue the new value
133          *
134          * @return the value that should be assigned
135          */
136         DateTime* prepareForAssignment(DateTime* oldValue, const DateTime* newValue);
137
138         /**
139          * A helper function for derived classes, for assignment of date/time data.
140          *
141          * It invalidates the DOM, frees the old object, and returns the new.
142          *
143          * @param oldValue the current value
144          * @param newValue the epoch to assign as the new value
145          * @param duration true iff the value is a duration rather than an absolute timestamp
146          *
147          * @return the value that should be assigned
148          */
149         DateTime* prepareForAssignment(DateTime* oldValue, time_t newValue, bool duration=false);
150
151         /**
152          * A helper function for derived classes, for assignment of date/time data.
153          *
154          * It invalidates the DOM, frees the old object, and returns the new.
155          *
156          * @param oldValue the current value
157          * @param newValue the new value in string form
158          * @param duration true iff the value is a duration rather than an absolute timestamp
159          *
160          * @return the value that should be assigned
161          */
162         DateTime* prepareForAssignment(DateTime* oldValue, const XMLCh* newValue, bool duration=false);
163
164         /**
165          * A helper function for derived classes, for assignment of QName data.
166          *
167          * It invalidates the DOM, frees the old object, and returns the new.
168          *
169          * @param oldValue the current value
170          * @param newValue the new value
171          *
172          * @return the value that should be assigned
173          */
174         QName* prepareForAssignment(QName* oldValue, const QName* newValue);
175
176         /**
177          * A helper function for derived classes, for assignment of (singleton) XML objects.
178          *
179          * It is indifferent to whether either the old or the new version of the value is null.
180          * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate.
181          * Note that since the new value (even if NULL) is always returned, it may be more efficient
182          * to discard the return value and just assign independently if a dynamic cast would be involved.
183          *
184          * @param oldValue current value
185          * @param newValue proposed new value
186          * @return the new value
187          *
188          * @throws XMLObjectException if the new child already has a parent.
189          */
190         XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue);
191
192         /**
193          * Set of namespaces associated with the object.
194          */
195         mutable std::set<Namespace> m_namespaces;
196
197         /**
198          * Logging object.
199          */
200         logging::Category& m_log;
201
202         /**
203          * Stores off xsi:schemaLocation attribute.
204          */
205         XMLCh* m_schemaLocation;
206
207         /**
208          * Stores off xsi:noNamespaceSchemaLocation attribute.
209          */
210         XMLCh* m_noNamespaceSchemaLocation;
211
212         /**
213          * Stores off xsi:nil attribute.
214          */
215         xmlconstants::xmltooling_bool_t m_nil;
216
217     private:
218         XMLObject* m_parent;
219         QName m_elementQname;
220         QName* m_typeQname;
221     };
222
223 };
224
225 #if defined (_MSC_VER)
226     #pragma warning( pop )
227 #endif
228
229 #endif /* __xmltooling_abstractxmlobj_h__ */