Multi-line svn commit, see body.
[shibboleth/cpp-xmltooling.git] / xmltooling / AbstractXMLObject.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/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             delete m_typeQname;
49             xercesc::XMLString::release(&m_schemaLocation);
50             xercesc::XMLString::release(&m_noNamespaceSchemaLocation);
51         }
52
53         void detach();
54
55         const QName& getElementQName() const {
56             return m_elementQname;
57         }
58
59         const std::set<Namespace>& getNamespaces() const {
60             return m_namespaces;
61         }
62     
63         void addNamespace(const Namespace& ns) const {
64             std::set<Namespace>::iterator i = m_namespaces.find(ns);
65             if (i == m_namespaces.end())
66                 m_namespaces.insert(ns);
67             else if (ns.alwaysDeclare())
68                 const_cast<Namespace&>(*i).setAlwaysDeclare(true);
69         }
70     
71         void removeNamespace(const Namespace& ns) {
72             m_namespaces.erase(ns);
73         }
74         
75         const QName* getSchemaType() const {
76             return m_typeQname;
77         }
78         
79         const XMLCh* getXMLID() const {
80             return NULL;
81         }
82         
83         xmlconstants::xmltooling_bool_t getNil() const {
84                 return m_nil;
85         }
86         
87         void nil(xmlconstants::xmltooling_bool_t value) {
88             if (m_nil != value) {
89                 releaseThisandParentDOM();
90                 m_nil = value;
91             }
92         }
93
94         bool hasParent() const {
95             return m_parent != NULL;
96         }
97      
98         XMLObject* getParent() const {
99             return m_parent;
100         }
101     
102         void setParent(XMLObject* parent) {
103             m_parent = parent;
104         }
105
106      protected:
107         /**
108          * Constructor
109          * 
110          * @param nsURI         the namespace of the element
111          * @param localName     the local name of the XML element this Object represents
112          * @param prefix        the namespace prefix to use
113          * @param schemaType    the xsi:type to use
114          */
115         AbstractXMLObject(
116             const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const QName* schemaType=NULL
117             );
118
119         /** Copy constructor. */
120         AbstractXMLObject(const AbstractXMLObject& src);
121         
122         /**
123          * A helper function for derived classes, for assignment of strings.
124          *
125          * This 'normalizes' newString, and then if it is different from oldString,
126          * it invalidates the DOM, frees the old string, and returns the new.
127          * If not different, it frees the new string and just returns the old value.
128          * 
129          * @param oldValue - the current value
130          * @param newValue - the new value
131          * 
132          * @return the value that should be assigned
133          */
134         XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue);
135
136         /**
137          * A helper function for derived classes, for assignment of date/time data.
138          *
139          * It invalidates the DOM, frees the old object, and returns the new.
140          * 
141          * @param oldValue - the current value
142          * @param newValue - the new value
143          * 
144          * @return the value that should be assigned
145          */
146         DateTime* prepareForAssignment(DateTime* oldValue, const DateTime* newValue);
147
148         /**
149          * A helper function for derived classes, for assignment of date/time data.
150          *
151          * It invalidates the DOM, frees the old object, and returns the new.
152          * 
153          * @param oldValue - the current value
154          * @param newValue - the epoch to assign as the new value
155          * 
156          * @return the value that should be assigned
157          */
158         DateTime* prepareForAssignment(DateTime* oldValue, time_t newValue);
159
160         /**
161          * A helper function for derived classes, for assignment of date/time data.
162          *
163          * It invalidates the DOM, frees the old object, and returns the new.
164          * 
165          * @param oldValue - the current value
166          * @param newValue - the new value in string form
167          * 
168          * @return the value that should be assigned
169          */
170         DateTime* prepareForAssignment(DateTime* oldValue, const XMLCh* newValue);
171
172         /**
173          * A helper function for derived classes, for assignment of QName data.
174          *
175          * It invalidates the DOM, frees the old object, and returns the new.
176          * 
177          * @param oldValue - the current value
178          * @param newValue - the new value
179          * 
180          * @return the value that should be assigned
181          */
182         QName* prepareForAssignment(QName* oldValue, const QName* newValue);
183
184         /**
185          * A helper function for derived classes, for assignment of (singleton) XML objects.
186          * 
187          * It is indifferent to whether either the old or the new version of the value is null. 
188          * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate.
189          * Note that since the new value (even if NULL) is always returned, it may be more efficient
190          * to discard the return value and just assign independently if a dynamic cast would be involved.
191          * 
192          * @param oldValue - current value
193          * @param newValue - proposed new value
194          * @return the new value 
195          * 
196          * @throws XMLObjectException if the new child already has a parent.
197          */
198         XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue);
199
200         /**
201          * Set of namespaces associated with the object.
202          */
203         mutable std::set<Namespace> m_namespaces;
204
205         /**
206          * Logging object.
207          */
208         logging::Category& m_log;
209
210         /**
211          * Stores off xsi:schemaLocation attribute.
212          */
213         XMLCh* m_schemaLocation;
214
215         /**
216          * Stores off xsi:noNamespaceSchemaLocation attribute.
217          */
218         XMLCh* m_noNamespaceSchemaLocation;
219         
220         /**
221          * Stores off xsi:nil attribute.
222          */
223         xmlconstants::xmltooling_bool_t m_nil;
224
225     private:
226         XMLObject* m_parent;
227         QName m_elementQname;
228         QName* m_typeQname;
229     };
230
231 };
232
233 #if defined (_MSC_VER)
234     #pragma warning( pop )
235 #endif
236
237 #endif /* __xmltooling_abstractxmlobj_h__ */