Exception hierarchy altered, add EncryptedKey resolution.
[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() {} \
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_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_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     class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException;
135     
136     /** A factory function that returns an empty exception object of a given type. */
137     typedef XMLToolingException* ExceptionFactory();
138     
139     /**
140      * Base exception class, supports parametrized messages and XML serialization.
141      * Parameters are prefixed with a dollar sign ($) and can be positional ($1)
142      * or named ($info).
143      */
144     class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException
145     {
146     public:
147         virtual ~XMLToolingException() {}
148
149         /**
150          * Constructs an exception using a message and positional parameters.
151          * 
152          * @param msg   error message
153          * @param p     an ordered set of positional parameter strings
154          */
155         XMLToolingException(const char* msg=NULL, const params& p=params());
156
157         /**
158          * Constructs an exception using a message and named parameters.
159          * 
160          * @param msg   error message
161          * @param p     a set of named parameter strings
162          */
163         XMLToolingException(const char* msg, const namedparams& p);
164
165         /**
166          * Constructs an exception using a message and positional parameters.
167          * 
168          * @param msg   error message
169          * @param p     an ordered set of positional parameter strings
170          */
171         XMLToolingException(const std::string& msg, const params& p=params());
172
173         /**
174          * Constructs an exception using a message and named parameters.
175          * 
176          * @param msg   error message
177          * @param p     a set of named parameter strings
178          */
179         XMLToolingException(const std::string& msg, const namedparams& p);
180
181         /**
182          * Returns the error message, after processing any parameter references.
183          * 
184          * @return  the processed message
185          */
186         const char* getMessage() const;
187
188         /**
189          * Returns the error message, after processing any parameter references.
190          * 
191          * @return  the processed message
192          */
193         const char* what() const {return getMessage();}
194
195         /**
196          * Sets the error message.
197          * 
198          * @param msg   the error message
199          */
200         void setMessage(const char* msg);
201
202         /**
203          * Sets the error message.
204          * 
205          * @param msg   the error message
206          */
207         void setMessage(const std::string& msg) {
208             setMessage(msg.c_str());
209         }
210
211         /**
212          * Attach a set of positional parameters to the exception.
213          * 
214          * @param p     an ordered set of named parameter strings
215          */
216         void addProperties(const params& p);
217         
218         /**
219          * Attach a set of named parameters to the exception.
220          * 
221          * @param p     a set of named parameter strings
222          */
223         void addProperties(const namedparams& p);
224
225         /**
226          * Attach a single positional parameter at the next available position.
227          * 
228          * @param value the parameter value
229          */
230         void addProperty(const char* value) {
231             addProperties(params(1,value));
232         }
233
234         /**
235          * Attach a single named parameter.
236          * 
237          * @param name  the parameter name
238          * @param value the parameter value
239          */
240         void addProperty(const char* name, const char* value) {
241             addProperties(namedparams(1,name,value));
242         }
243
244         /**
245          * Returns the parameter property with the designated position (based from one).
246          * 
247          * @param index     position to access
248          * @return  the parameter property or NULL
249          */
250         const char* getProperty(unsigned int index) const;
251
252         /**
253          * Returns the parameter property with the designated name.
254          * 
255          * @param name     named parameter to access
256          * @return  the parameter property or NULL
257          */
258         const char* getProperty(const char* name) const;
259
260         /**
261          * Raises an exception using itself.
262          * Used to raise an exception of a derived type.
263          */
264         virtual void raise() const {
265             throw *this;
266         }
267
268         /**
269          * Returns a unique name for the exception class.
270          * 
271          * @return class name
272          */
273         virtual const char* getClassName() const {
274             return "xmltooling::XMLToolingException";
275         }
276         
277         /**
278          * Returns a string containing a serialized representation of the exception.
279          * 
280          * @return  the serialization
281          */
282         std::string toString() const;
283
284     private:
285         std::string m_msg;
286         mutable std::string m_processedmsg;
287         std::map<std::string,std::string> m_params;
288
289     public:
290         /**
291          * Builds an empty exception of the given type.
292          * 
293          * @param exceptionClass    the name of the exception type to build
294          * @return an empty exception object
295          */
296         static XMLToolingException* getInstance(const char* exceptionClass);
297
298         /**
299          * Builds an exception from a serialized input stream.
300          * 
301          * @param in    input stream
302          * @return the exception object found in the stream
303          */
304         static XMLToolingException* fromStream(std::istream& in);
305         
306         /**
307          * Builds an exception from a serialized input buffer.
308          * 
309          * @param s   input buffer
310          * @return the exception object found in the buffer
311          */
312         static XMLToolingException* fromString(const char* s);
313                 
314         /**
315          * Registers a factory to create exceptions of a given class name.
316          * 
317          * @param exceptionClass    name of exception type
318          * @param factory           factory function to build exceptions with
319          */
320         static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {
321             m_factoryMap[exceptionClass] = factory;
322         }
323         
324         /**
325          * Unregisters the factory for a given class name.
326          * 
327          * @param exceptionClass    name of exception type
328          */
329         static void deregisterFactory(const char* exceptionClass) {
330             m_factoryMap.erase(exceptionClass);
331         }
332
333         /**
334          * Unregisters all factories.
335          */
336         static void deregisterFactories() {
337             m_factoryMap.clear();
338         }
339
340     private:
341         typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;
342         static ExceptionFactoryMap m_factoryMap;
343     };
344
345     DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to XML parsing);
346     DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions in basic object usage);
347     DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object marshalling);
348     DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object unmarshalling);
349     DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown element content);
350     DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown attributes);
351     DECL_XMLTOOLING_EXCEPTION(UnknownExtensionException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions from use of an unrecognized extension/plugin);
352     DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object validation);
353     DECL_XMLTOOLING_EXCEPTION(XMLSecurityException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to the XML security layer);
354
355 };
356
357 #if defined (_MSC_VER)
358     #pragma warning( pop )
359 #endif
360
361 #endif /* __xmltooling_exceptions_h__ */