Fix exception throw signatures
[shibboleth/cpp-xmltooling.git] / xmltooling / exceptions.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 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     private:
280         std::string m_msg;
281         mutable std::string m_processedmsg;
282         std::map<std::string,std::string> m_params;
283
284     public:
285         /**
286          * Builds an empty exception of the given type.
287          * 
288          * @param exceptionClass    the name of the exception type to build
289          * @return an empty exception object
290          */
291         static XMLToolingException* getInstance(const char* exceptionClass);
292
293         /**
294          * Builds an exception from a serialized input stream.
295          * 
296          * @param in    input stream
297          * @return the exception object found in the stream
298          */
299         static XMLToolingException* fromStream(std::istream& in);
300         
301         /**
302          * Builds an exception from a serialized input buffer.
303          * 
304          * @param s   input buffer
305          * @return the exception object found in the buffer
306          */
307         static XMLToolingException* fromString(const char* s);
308                 
309         /** A factory function that returns an empty exception object of a given type. */
310         typedef XMLToolingException* ExceptionFactory();
311         
312         /**
313          * Registers a factory to create exceptions of a given class name.
314          * 
315          * @param exceptionClass    name of exception type
316          * @param factory           factory function to build exceptions with
317          */
318         static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {
319             m_factoryMap[exceptionClass] = factory;
320         }
321         
322         /**
323          * Unregisters the factory for a given class name.
324          * 
325          * @param exceptionClass    name of exception type
326          */
327         static void deregisterFactory(const char* exceptionClass) {
328             m_factoryMap.erase(exceptionClass);
329         }
330
331         /**
332          * Unregisters all factories.
333          */
334         static void deregisterFactories() {
335             m_factoryMap.clear();
336         }
337
338     private:
339         typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;
340         static ExceptionFactoryMap m_factoryMap;
341     };
342
343     DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to XML parsing);
344     DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions in basic object usage);
345     DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object marshalling);
346     DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object unmarshalling);
347     DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown element content);
348     DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown attributes);
349     DECL_XMLTOOLING_EXCEPTION(UnknownExtensionException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions from use of an unrecognized extension/plugin);
350     DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object validation);
351     DECL_XMLTOOLING_EXCEPTION(IOException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to physical input/output errors);
352
353 #ifndef XMLTOOLING_NO_XMLSEC
354     DECL_XMLTOOLING_EXCEPTION(XMLSecurityException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to the XML security layer);
355 #endif
356 };
357
358 #if defined (_MSC_VER)
359     #pragma warning( pop )
360 #endif
361
362 #endif /* __xmltooling_exceptions_h__ */