Set fourth file version digit to signify rebuild.
[shibboleth/cpp-xmltooling.git] / xmltooling / exceptions.h
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * @file xmltooling/exceptions.h
23  * 
24  * Exception classes.
25  */
26  
27 #ifndef __xmltooling_exceptions_h__
28 #define __xmltooling_exceptions_h__
29
30 #include <xmltooling/base.h>
31
32 #include <map>
33 #include <string>
34 #include <vector>
35 #include <iostream>
36
37 /**
38  * Declares a derived exception class
39  * 
40  * @param name      the exception class
41  * @param linkage   linkage specification for class
42  * @param ns        the exception class C++ namespace
43  * @param base      the base class
44  * @param desc      documentation comment for class
45  */
46 #define DECL_XMLTOOLING_EXCEPTION(name,linkage,ns,base,desc) \
47     XMLTOOLING_DOXYGEN(desc) \
48     class linkage name : public base { \
49     public: \
50         XMLTOOLING_DOXYGEN(Constructor) \
51         name(const char* msg=nullptr, const xmltooling::params& p=xmltooling::params()) : base(msg,p) {} \
52         XMLTOOLING_DOXYGEN(Constructor) \
53         name(const char* msg, const xmltooling::namedparams& p) : base(msg,p) {} \
54         XMLTOOLING_DOXYGEN(Constructor) \
55         name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) : base(msg,p) {} \
56         XMLTOOLING_DOXYGEN(Constructor) \
57         name(const std::string& msg, const xmltooling::namedparams& p) : base(msg,p) {} \
58         virtual ~name() throw () {} \
59         virtual const char* getClassName() const { return #ns"::"#name; } \
60         void raise() const {throw *this;} \
61     }
62
63 /**
64  * Declares a factory function for an exception class.
65  * 
66  * @param name  the exception class name
67  * @param ns    the exception class C++ namespace
68  */
69 #define DECL_XMLTOOLING_EXCEPTION_FACTORY(name,ns) \
70     xmltooling::XMLToolingException* name##Factory() \
71     { \
72         return new ns::name(); \
73     }
74
75 /**
76  * Registers a factory for an exception class.
77  * 
78  * @param name      the exception class name
79  * @param ns        the exception class C++ namespace
80  */
81 #define REGISTER_XMLTOOLING_EXCEPTION_FACTORY(name,ns) XMLToolingException::registerFactory(#ns"::"#name,name##Factory)
82
83 #if defined (_MSC_VER)
84     #pragma warning( push )
85     #pragma warning( disable : 4250 4251 )
86 #endif
87
88 namespace xmltooling {
89     
90     /**
91      * Wrapper around a variable number of arguments.
92      */
93     class XMLTOOL_API params
94     {
95     public:
96         /**
97          * Initializes with zero parameters.
98          */
99         params() {}
100         
101         /**
102          * Initializes the parameter set.
103          * 
104          * @param count     the number of parameters that follow
105          */
106         params(int count,...);
107         
108         /**
109          * Returns an immutable reference to the set of parameters.
110          * 
111          * @return the parameter set
112          */
113         const std::vector<const char*>& get() const {return v;}
114         
115     protected:
116         /** Contains the parameters being passed. */
117         std::vector<const char*> v;
118     };
119     
120     /**
121      * Wrapper around a variable number of name/value pairs.
122      */
123     class XMLTOOL_API namedparams : public params
124     {
125     public:
126         /**
127          * Initializes with zero parameters.
128          */
129         namedparams() {}
130
131         /**
132          * Initializes the named parameter set.
133          * 
134          * @param count     the number of name/value pairs that follow (must be even)
135          */
136         namedparams(int count,...);
137     };
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 : public std::exception
145     {
146     public:
147         virtual ~XMLToolingException() throw () {}
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=nullptr, 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 throw () {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 nullptr
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 nullptr
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         /**
285          * Returns a set of query string name/value pairs, URL-encoded, representing the
286          * exception's type, message, and parameters.
287          *
288          * @return  the query string representation
289          */
290         std::string toQueryString() const;
291
292     private:
293         std::string m_msg;
294         mutable std::string m_processedmsg;
295         std::map<std::string,std::string> m_params;
296
297     public:
298         /**
299          * Builds an empty exception of the given type.
300          * 
301          * @param exceptionClass    the name of the exception type to build
302          * @return an empty exception object
303          */
304         static XMLToolingException* getInstance(const char* exceptionClass);
305
306         /**
307          * Builds an exception from a serialized input stream.
308          * 
309          * @param in    input stream
310          * @return the exception object found in the stream
311          */
312         static XMLToolingException* fromStream(std::istream& in);
313         
314         /**
315          * Builds an exception from a serialized input buffer.
316          * 
317          * @param s   input buffer
318          * @return the exception object found in the buffer
319          */
320         static XMLToolingException* fromString(const char* s);
321                 
322         /** A factory function that returns an empty exception object of a given type. */
323         typedef XMLToolingException* ExceptionFactory();
324         
325         /**
326          * Registers a factory to create exceptions of a given class name.
327          * 
328          * @param exceptionClass    name of exception type
329          * @param factory           factory function to build exceptions with
330          */
331         static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {
332             m_factoryMap[exceptionClass] = factory;
333         }
334         
335         /**
336          * Unregisters the factory for a given class name.
337          * 
338          * @param exceptionClass    name of exception type
339          */
340         static void deregisterFactory(const char* exceptionClass) {
341             m_factoryMap.erase(exceptionClass);
342         }
343
344         /**
345          * Unregisters all factories.
346          */
347         static void deregisterFactories() {
348             m_factoryMap.clear();
349         }
350
351     private:
352         typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;
353         static ExceptionFactoryMap m_factoryMap;
354     };
355
356     DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to XML parsing);
357     DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions in basic object usage);
358     DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object marshalling);
359     DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object unmarshalling);
360     DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown element content);
361     DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions due to processing of unknown attributes);
362     DECL_XMLTOOLING_EXCEPTION(UnknownExtensionException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions from use of an unrecognized extension/plugin);
363     DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during object validation);
364     DECL_XMLTOOLING_EXCEPTION(IOException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to physical input/output errors);
365
366 #ifndef XMLTOOLING_NO_XMLSEC
367     DECL_XMLTOOLING_EXCEPTION(XMLSecurityException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions related to the XML security layer);
368 #endif
369 };
370
371 #if defined (_MSC_VER)
372     #pragma warning( pop )
373 #endif
374
375 #endif /* __xmltooling_exceptions_h__ */