Fully qualify the header filenames for doxygen.
[shibboleth/cpp-xmltooling.git] / xmltooling / exceptions.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/exceptions.h
19  * 
20  * Exception classes
21  */
22  
23 #ifndef __xmltooling_exceptions_h__
24 #define __xmltooling_exceptions_h__
25
26 #include <map>
27 #include <string>
28 #include <vector>
29 #include <iostream>
30 #include <xmltooling/base.h>
31
32 /**
33  * Declares a derived exception class
34  * 
35  * @param name      the exception class
36  * @param linkage   linkage specification for class
37  * @param ns        the exception class C++ namespace
38  * @param base      the base class
39  * @param desc      documentation comment for class
40  */
41 #define DECL_XMLTOOLING_EXCEPTION(name,linkage,ns,base,desc) \
42     XMLTOOLING_DOXYGEN(desc) \
43     class linkage name : public base { \
44     public: \
45         XMLTOOLING_DOXYGEN(Constructor) \
46         name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) : base(msg,p) {} \
47         XMLTOOLING_DOXYGEN(Constructor) \
48         name(const char* msg, const xmltooling::namedparams& p) : base(msg,p) {} \
49         XMLTOOLING_DOXYGEN(Constructor) \
50         name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) : base(msg,p) {} \
51         XMLTOOLING_DOXYGEN(Constructor) \
52         name(const std::string& msg, const xmltooling::namedparams& p) : base(msg,p) {} \
53         virtual ~name() throw () {} \
54         virtual const char* getClassName() const { return #ns"::"#name; } \
55         void raise() const {throw *this;} \
56     }
57
58 /**
59  * Declares a factory function for an exception class.
60  * 
61  * @param name  the exception class name
62  * @param ns    the exception class C++ namespace
63  */
64 #define DECL_XMLTOOLING_EXCEPTION_FACTORY(name,ns) \
65     xmltooling::XMLToolingException* name##Factory() \
66     { \
67         return new ns::name(); \
68     }
69
70 /**
71  * Registers a factory for an exception class.
72  * 
73  * @param name      the exception class name
74  * @param ns        the exception class C++ namespace
75  */
76 #define REGISTER_XMLTOOLING_EXCEPTION_FACTORY(name,ns) XMLToolingException::registerFactory(#ns"::"#name,name##Factory)
77
78 #if defined (_MSC_VER)
79     #pragma warning( push )
80     #pragma warning( disable : 4250 4251 )
81 #endif
82
83 namespace xmltooling {
84     
85     /**
86      * Wrapper around a variable number of arguments.
87      */
88     class XMLTOOL_API params
89     {
90     public:
91         /**
92          * Initializes with zero parameters.
93          */
94         params() {}
95         
96         /**
97          * Initializes the parameter set.
98          * 
99          * @param count     the number of parameters that follow
100          */
101         params(int count,...);
102         
103         /**
104          * Returns an immutable reference to the set of parameters.
105          * 
106          * @return the parameter set
107          */
108         const std::vector<const char*>& get() const {return v;}
109         
110     protected:
111         /** Contains the parameters being passed. */
112         std::vector<const char*> v;
113     };
114     
115     /**
116      * Wrapper around a variable number of name/value pairs.
117      */
118     class XMLTOOL_API namedparams : public params
119     {
120     public:
121         /**
122          * Initializes with zero parameters.
123          */
124         namedparams() {}
125
126         /**
127          * Initializes the named parameter set.
128          * 
129          * @param count     the number of name/value pairs that follow (must be even)
130          */
131         namedparams(int count,...);
132     };
133
134     /**
135      * Base exception class, supports parametrized messages and XML serialization.
136      * Parameters are prefixed with a dollar sign ($) and can be positional ($1)
137      * or named ($info).
138      */
139     class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException : public std::exception
140     {
141     public:
142         virtual ~XMLToolingException() throw () {}
143
144         /**
145          * Constructs an exception using a message and positional parameters.
146          * 
147          * @param msg   error message
148          * @param p     an ordered set of positional parameter strings
149          */
150         XMLToolingException(const char* msg=NULL, const params& p=params());
151
152         /**
153          * Constructs an exception using a message and named parameters.
154          * 
155          * @param msg   error message
156          * @param p     a set of named parameter strings
157          */
158         XMLToolingException(const char* msg, const namedparams& p);
159
160         /**
161          * Constructs an exception using a message and positional parameters.
162          * 
163          * @param msg   error message
164          * @param p     an ordered set of positional parameter strings
165          */
166         XMLToolingException(const std::string& msg, const params& p=params());
167
168         /**
169          * Constructs an exception using a message and named parameters.
170          * 
171          * @param msg   error message
172          * @param p     a set of named parameter strings
173          */
174         XMLToolingException(const std::string& msg, const namedparams& p);
175
176         /**
177          * Returns the error message, after processing any parameter references.
178          * 
179          * @return  the processed message
180          */
181         const char* getMessage() const;
182
183         /**
184          * Returns the error message, after processing any parameter references.
185          * 
186          * @return  the processed message
187          */
188         const char* what() const throw () {return getMessage();}
189
190         /**
191          * Sets the error message.
192          * 
193          * @param msg   the error message
194          */
195         void setMessage(const char* msg);
196
197         /**
198          * Sets the error message.
199          * 
200          * @param msg   the error message
201          */
202         void setMessage(const std::string& msg) {
203             setMessage(msg.c_str());
204         }
205
206         /**
207          * Attach a set of positional parameters to the exception.
208          * 
209          * @param p     an ordered set of named parameter strings
210          */
211         void addProperties(const params& p);
212         
213         /**
214          * Attach a set of named parameters to the exception.
215          * 
216          * @param p     a set of named parameter strings
217          */
218         void addProperties(const namedparams& p);
219
220         /**
221          * Attach a single positional parameter at the next available position.
222          * 
223          * @param value the parameter value
224          */
225         void addProperty(const char* value) {
226             addProperties(params(1,value));
227         }
228
229         /**
230          * Attach a single named parameter.
231          * 
232          * @param name  the parameter name
233          * @param value the parameter value
234          */
235         void addProperty(const char* name, const char* value) {
236             addProperties(namedparams(1,name,value));
237         }
238
239         /**
240          * Returns the parameter property with the designated position (based from one).
241          * 
242          * @param index     position to access
243          * @return  the parameter property or NULL
244          */
245         const char* getProperty(unsigned int index) const;
246
247         /**
248          * Returns the parameter property with the designated name.
249          * 
250          * @param name     named parameter to access
251          * @return  the parameter property or NULL
252          */
253         const char* getProperty(const char* name) const;
254
255         /**
256          * Raises an exception using itself.
257          * Used to raise an exception of a derived type.
258          */
259         virtual void raise() const {
260             throw *this;
261         }
262
263         /**
264          * Returns a unique name for the exception class.
265          * 
266          * @return class name
267          */
268         virtual const char* getClassName() const {
269             return "xmltooling::XMLToolingException";
270         }
271         
272         /**
273          * Returns a string containing a serialized representation of the exception.
274          * 
275          * @return  the serialization
276          */
277         std::string toString() const;
278
279         /**
280          * Returns a set of query string name/value pairs, URL-encoded, representing the
281          * exception's type, message, and parameters.
282          *
283          * @return  the query string representation
284          */
285         std::string toQueryString() const;
286
287     private:
288         std::string m_msg;
289         mutable std::string m_processedmsg;
290         std::map<std::string,std::string> m_params;
291
292     public:
293         /**
294          * Builds an empty exception of the given type.
295          * 
296          * @param exceptionClass    the name of the exception type to build
297          * @return an empty exception object
298          */
299         static XMLToolingException* getInstance(const char* exceptionClass);
300
301         /**
302          * Builds an exception from a serialized input stream.
303          * 
304          * @param in    input stream
305          * @return the exception object found in the stream
306          */
307         static XMLToolingException* fromStream(std::istream& in);
308         
309         /**
310          * Builds an exception from a serialized input buffer.
311          * 
312          * @param s   input buffer
313          * @return the exception object found in the buffer
314          */
315         static XMLToolingException* fromString(const char* s);
316                 
317         /** A factory function that returns an empty exception object of a given type. */
318         typedef XMLToolingException* ExceptionFactory();
319         
320         /**
321          * Registers a factory to create exceptions of a given class name.
322          * 
323          * @param exceptionClass    name of exception type
324          * @param factory           factory function to build exceptions with
325          */
326         static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {
327             m_factoryMap[exceptionClass] = factory;
328         }
329         
330         /**
331          * Unregisters the factory for a given class name.
332          * 
333          * @param exceptionClass    name of exception type
334          */
335         static void deregisterFactory(const char* exceptionClass) {
336             m_factoryMap.erase(exceptionClass);
337         }
338
339         /**
340          * Unregisters all factories.
341          */
342         static void deregisterFactories() {
343             m_factoryMap.clear();
344         }
345
346     private:
347         typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;
348         static ExceptionFactoryMap m_factoryMap;
349     };
350
351     DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to XML parsing);
352     DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions in basic object usage);
353     DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object marshalling);
354     DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object unmarshalling);
355     DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown element content);
356     DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown attributes);
357     DECL_XMLTOOLING_EXCEPTION(UnknownExtensionException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions from use of an unrecognized extension/plugin);
358     DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object validation);
359     DECL_XMLTOOLING_EXCEPTION(IOException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to physical input/output errors);
360
361 #ifndef XMLTOOLING_NO_XMLSEC
362     DECL_XMLTOOLING_EXCEPTION(XMLSecurityException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to the XML security layer);
363 #endif
364 };
365
366 #if defined (_MSC_VER)
367     #pragma warning( pop )
368 #endif
369
370 #endif /* __xmltooling_exceptions_h__ */