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