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