Added some validation code.
[shibboleth/cpp-xmltooling.git] / xmltooling / base.h
1 /*
2  *  Copyright 2001-2006 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 base.h
19  * 
20  * Base header file definitions
21  * Must be included prior to including any other header
22  */
23
24 #ifndef __xmltooling_base_h__
25 #define __xmltooling_base_h__
26
27 #if defined (_MSC_VER) || defined(__BORLANDC__)
28   #include <xmltooling/config_pub_win32.h>
29 #else
30   #include <xmltooling/config_pub.h>
31 #endif
32
33 /**
34  * @namespace xmltooling
35  * Public namespace of XML Tooling library
36  */
37
38 // Windows and GCC4 Symbol Visibility Macros
39 #ifdef WIN32
40   #define XMLTOOL_IMPORT __declspec(dllimport)
41   #define XMLTOOL_EXPORT __declspec(dllexport)
42   #define XMLTOOL_DLLLOCAL
43   #define XMLTOOL_DLLPUBLIC
44 #else
45   #define XMLTOOL_IMPORT
46   #ifdef GCC_HASCLASSVISIBILITY
47     #define XMLTOOL_EXPORT __attribute__ ((visibility("default")))
48     #define XMLTOOL_DLLLOCAL __attribute__ ((visibility("hidden")))
49     #define XMLTOOL_DLLPUBLIC __attribute__ ((visibility("default")))
50   #else
51     #define XMLTOOL_EXPORT
52     #define XMLTOOL_DLLLOCAL
53     #define XMLTOOL_DLLPUBLIC
54   #endif
55 #endif
56
57 // Define XMLTOOL_API for DLL builds
58 #ifdef XMLTOOLING_EXPORTS
59   #define XMLTOOL_API XMLTOOL_EXPORT
60 #else
61   #define XMLTOOL_API XMLTOOL_IMPORT
62 #endif
63
64 // Throwable classes must always be visible on GCC in all binaries
65 #ifdef WIN32
66   #define XMLTOOL_EXCEPTIONAPI(api) api
67 #elif defined(GCC_HASCLASSVISIBILITY)
68   #define XMLTOOL_EXCEPTIONAPI(api) XMLTOOL_EXPORT
69 #else
70   #define XMLTOOL_EXCEPTIONAPI(api)
71 #endif
72
73 #ifndef NULL
74 #define NULL    0
75 #endif
76
77 #ifdef _MSC_VER
78     #define XMLTOOLING_DOXYGEN(desc) /##** desc */
79 #else
80     #define XMLTOOLING_DOXYGEN(desc)
81 #endif
82
83 /**
84  * Blocks copy c'tor and assignment operator for a class.
85  */
86 #define MAKE_NONCOPYABLE(type) \
87     private: \
88         type(const type&); \
89         type& operator=(const type&);
90
91 /**
92  * Begins the declaration of an XMLObject specialization.
93  * Basic boilerplate includes a protected constructor, empty virtual destructor,
94  * and Unicode constants for the default associated element's name and prefix.
95  * 
96  * @param cname the name of the class to declare
97  * @param base  the base class to derive from using public virtual inheritance
98  */
99 #define BEGIN_XMLOBJECT(cname,base) \
100     class XMLTOOL_API cname : public virtual base, public virtual ValidatingXMLObject { \
101     protected: \
102         cname() {} \
103     public: \
104         virtual ~cname() {} \
105         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
106         virtual cname* clone##cname() const=0; \
107         XMLTOOLING_DOXYGEN(Element local name) \
108         static const XMLCh LOCAL_NAME[]
109
110 /**
111  * Ends the declaration of an XMLObject specialization.
112  */
113 #define END_XMLOBJECT }
114
115 /**
116  * Declares abstract get/set methods for a named XML attribute.
117  * 
118  * @param proper    the proper name of the attribute
119  * @param upcased   the upcased name of the attribute
120  */
121 #define DECL_XMLOBJECT_ATTRIB(proper,upcased) \
122     XMLTOOLING_DOXYGEN(proper attribute name) \
123     static const XMLCh upcased##_ATTRIB_NAME[]; \
124     XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
125     virtual const XMLCh* get##proper() const=0; \
126     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
127     virtual void set##proper(const XMLCh* proper)=0
128
129 /**
130  * Implements get/set methods and a private member for a named XML attribute.
131  * 
132  * @param proper    the proper name of the attribute
133  */
134 #define IMPL_XMLOBJECT_ATTRIB(proper) \
135     private: \
136         XMLCh* m_##proper; \
137     public: \
138         const XMLCh* get##proper() const { \
139             return m_##proper; \
140         } \
141         void set##proper(const XMLCh* proper) { \
142             m_##proper = prepareForAssignment(m_##proper,proper); \
143         }
144
145 /**
146  * Declares abstract get/set methods for named XML element content.
147  * 
148  * @param proper    the proper name to label the element's content
149  */
150 #define DECL_XMLOBJECT_CONTENT(proper) \
151     XMLTOOLING_DOXYGEN(Returns proper.) \
152     virtual const XMLCh* get##proper() const=0; \
153     XMLTOOLING_DOXYGEN(Sets proper.) \
154     virtual void set##proper(const XMLCh* proper)=0
155
156 /**
157  * Implements get/set methods and a private member for named XML element content.
158  * 
159  * @param proper    the proper name to label the element's content
160  */
161 #define IMPL_XMLOBJECT_CONTENT(proper) \
162     private: \
163         XMLCh* m_##proper; \
164     public: \
165         const XMLCh* get##proper() const { \
166             return m_##proper; \
167         } \
168         void set##proper(const XMLCh* proper) { \
169             m_##proper = prepareForAssignment(m_##proper,proper); \
170         } \
171     protected: \
172         void marshallElementContent(DOMElement* domElement) const { \
173             if(get##proper()) { \
174                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(get##proper())); \
175             } \
176         } \
177         void processElementContent(const XMLCh* elementContent) { \
178             set##proper(elementContent); \
179         }
180
181
182 /**
183  * Implements cloning methods for an XMLObject specialization implementation class.
184  * 
185  * @param cname    the name of the XMLObject specialization
186  */
187 #define IMPL_XMLOBJECT_CLONE(cname) \
188     cname* clone##cname() const { \
189         return clone(); \
190     } \
191     cname* clone() const { \
192         auto_ptr<XMLObject> domClone(AbstractDOMCachingXMLObject::clone()); \
193         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
194         if (ret) { \
195             domClone.release(); \
196             return ret; \
197         } \
198         return new cname##Impl(*this); \
199     }
200
201 /**
202  * Begins the declaration of an XMLObjectBuilder specialization.
203  * Basic boilerplate includes an empty virtual destructor, and
204  * a default builder.
205  * 
206  * @param cname the name of the XMLObject specialization
207  */
208 #define BEGIN_XMLOBJECTBUILDER(cname) \
209     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
210     class XMLTOOL_API cname##Builder : public xmltooling::XMLObjectBuilder { \
211     public: \
212         virtual ~cname##Builder() {} \
213         XMLTOOLING_DOXYGEN(Default builder.) \
214         virtual cname* buildObject() const=0
215
216 /**
217  * Ends the declaration of an XMLObjectBuilder specialization.
218  */
219 #define END_XMLOBJECTBUILDER }
220
221 /**
222  * Begins the declaration of an XMLObjectBuilder specialization implementation class.
223  * 
224  * @param cname             the name of the XMLObject specialization
225  * @param namespaceURI      the XML namespace of the default associated element
226  * @param namespacePrefix   the XML namespace prefix of the default associated element
227  */
228 #define BEGIN_XMLOBJECTBUILDERIMPL(cname,namespaceURI,namespacePrefix) \
229     class XMLTOOL_DLLLOCAL cname##BuilderImpl : public cname##Builder { \
230     public: \
231         cname* buildObject( \
232             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const QName* schemaType=NULL \
233             ) const; \
234         cname* buildObject() const { \
235             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
236         }
237
238 /**
239  * Begins the declaration of an XMLObjectBuilder specialization implementation class.
240  * 
241  * @param cname the name of the XMLObject specialization
242  */
243 #define IMPL_XMLOBJECTBUILDER(cname) \
244     cname* cname##BuilderImpl::buildObject( \
245         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \
246         ) const \
247     { \
248         return new cname##Impl(nsURI,localName,prefix,schemaType); \
249     }
250
251 /**
252  * Ends the declaration of an XMLObjectBuilder specialization implementation class.
253  */
254 #define END_XMLOBJECTBUILDERIMPL }
255
256 /**
257  * Begins the declaration of a Validator specialization.
258  * 
259  * @param cname the base name of the Validator specialization
260  */
261  #define BEGIN_XMLOBJECTVALIDATOR(cname) \
262     class cname##Validator : public Validator \
263     { \
264     public: \
265         virtual ~cname##Validator() {} \
266         Validator* clone() const { \
267             return new cname##Validator(); \
268         } \
269         void validate(const XMLObject* xmlObject) const
270
271 /**
272  * Ends the declaration of a Validator specialization.
273  */
274 #define END_XMLOBJECTVALIDATOR }
275
276
277 #include <utility>
278
279 namespace xmltooling {
280
281     /**
282      * Template function for cloning a sequence of XMLObjects.
283      * Invokes the clone() member on each element of the input sequence and adds the copy to
284      * the output sequence. Order is preserved.
285      * 
286      * @param in    input sequence to clone
287      * @param out   output sequence to copy cloned pointers into
288      */
289     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
290         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
291             if (*i)
292                 out.push_back((*i)->clone());
293             else
294                 out.push_back(*i);
295         }
296     }
297
298     /**
299      * Functor for cleaning up heap objects in containers.
300      */
301     template<class T> struct cleanup
302     {
303         /**
304          * Function operator to delete an object.
305          * 
306          * @param ptr   object to delete
307          */
308         void operator()(T* ptr) {delete ptr;}
309         
310         /**
311          * Function operator to delete an object stored as const.
312          * 
313          * @param ptr   object to delete after casting away const
314          */
315         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
316     };
317
318     /**
319      * Functor for cleaning up heap objects in key/value containers.
320      */
321     template<class A,class B> struct cleanup_pair
322     {
323         /**
324          * Function operator to delete an object.
325          * 
326          * @param p   a pair in which the second component is the object to delete
327          */
328         void operator()(const std::pair<A,B*>& p) {delete p.second;}
329     };
330 };
331
332 #endif /* __xmltooling_base_h__ */