#if !defined(__xmltooling_exceptions_h__)\r
#define __xmltooling_exceptions_h__\r
\r
+#include <map>\r
#include <string>\r
+#include <vector>\r
+#include <iostream>\r
#include <xmltooling/base.h>\r
\r
-#define DECL_XMLTOOLING_EXCEPTION(type) \\r
- class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) type : public XMLToolingException { \\r
+/**\r
+ * Declares a derived exception class\r
+ * \r
+ * @param name the exception class\r
+ * @param base the base class\r
+ */\r
+#define DECL_XMLTOOLING_EXCEPTION(name,base) \\r
+ class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public xmltooling::base { \\r
public: \\r
- type(const char* const msg) : XMLToolingException(msg) {} \\r
- type(const std::string& msg) : XMLToolingException(msg) {} \\r
- virtual ~type() {} \\r
+ name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) \\r
+ : xmltooling::base(msg,p) {} \\r
+ name(const char* msg, const xmltooling::namedparams& p) \\r
+ : xmltooling::base(msg,p) {} \\r
+ name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) \\r
+ : xmltooling::base(msg,p) {} \\r
+ name(const std::string& msg, const xmltooling::namedparams& p) \\r
+ : xmltooling::base(msg,p) {} \\r
+ virtual ~name() {} \\r
+ virtual const char* getClassName() const { return "xmltooling::"#name; } \\r
+ void raise() const {throw *this;} \\r
+ }\r
+\r
+/**\r
+ * Declares a factory function for an exception class.\r
+ * \r
+ * @param name the exception class name\r
+ */\r
+#define DECL_EXCEPTION_FACTORY(name) \\r
+ xmltooling::XMLToolingException* name##Factory() \\r
+ { \\r
+ return new xmltooling::name(); \\r
}\r
\r
+/**\r
+ * Registers a factory for an exception class.\r
+ * \r
+ * @param name the exception class name\r
+ */\r
+#define REGISTER_EXCEPTION_FACTORY(name) XMLToolingException::registerFactory("xmltooling::"#name,name##Factory)\r
+\r
namespace xmltooling {\r
\r
/**\r
- * Base exception class.\r
- * std::exception seems to be inconsistently defined, so this is just\r
- * a substitute base class.\r
+ * Wrapper around a variable number of arguments.\r
*/\r
+ class XMLTOOL_API params\r
+ {\r
+ public:\r
+ /**\r
+ * Initializes with zero parameters.\r
+ */\r
+ params() {}\r
+ \r
+ /**\r
+ * Initializes the parameter set.\r
+ * \r
+ * @param count the number of parameters that follow\r
+ */\r
+ params(int count,...);\r
+ \r
+ /**\r
+ * Returns an immutable reference to the set of parameters.\r
+ * \r
+ * @return the parameter set\r
+ */\r
+ const std::vector<const char*>& get() const {return v;}\r
+ \r
+ protected:\r
+ std::vector<const char*> v;\r
+ };\r
+ \r
+ /**\r
+ * Wrapper around a variable number of name/value pairs.\r
+ */\r
+ class XMLTOOL_API namedparams : public params\r
+ {\r
+ public:\r
+ /**\r
+ * Initializes with zero parameters.\r
+ */\r
+ namedparams() {}\r
+\r
+ /**\r
+ * Initializes the named parameter set.\r
+ * \r
+ * @param count the number of name/value pairs that follow (must be even)\r
+ */\r
+ namedparams(int count,...);\r
+ };\r
+\r
+ /**\r
+ * Base exception class, supports parametrized messages and XML serialization.\r
+ * Parameters are prefixed with a dollar sign ($) and can be positional ($1)\r
+ * or named ($info).\r
+ */\r
+ class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException;\r
+ typedef XMLToolingException* ExceptionFactory();\r
+ \r
class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException\r
{\r
public:\r
- XMLToolingException() {}\r
virtual ~XMLToolingException() {}\r
- XMLToolingException(const char* const msg) : m_msg(msg) {}\r
- XMLToolingException(const std::string& msg) : m_msg(msg) {}\r
- virtual const char* what() const { return m_msg.c_str(); }\r
+\r
+ /**\r
+ * Constructs an exception using a message and positional parameters.\r
+ * \r
+ * @param msg error message\r
+ * @param p an ordered set of positional parameter strings\r
+ */\r
+ XMLToolingException(const char* msg=NULL, const params& p=params());\r
+\r
+ /**\r
+ * Constructs an exception using a message and named parameters.\r
+ * \r
+ * @param msg error message\r
+ * @param p a set of named parameter strings\r
+ */\r
+ XMLToolingException(const char* msg, const namedparams& p);\r
+\r
+ /**\r
+ * Constructs an exception using a message and positional parameters.\r
+ * \r
+ * @param msg error message\r
+ * @param p an ordered set of positional parameter strings\r
+ */\r
+ XMLToolingException(const std::string& msg, const params& p=params());\r
+\r
+ /**\r
+ * Constructs an exception using a message and named parameters.\r
+ * \r
+ * @param msg error message\r
+ * @param p a set of named parameter strings\r
+ */\r
+ XMLToolingException(const std::string& msg, const namedparams& p);\r
+\r
+ /**\r
+ * Returns the error message, after processing any parameter references.\r
+ * \r
+ * @return the processed message\r
+ */\r
+ const char* getMessage() const;\r
+\r
+ /**\r
+ * Returns the error message, after processing any parameter references.\r
+ * \r
+ * @return the processed message\r
+ */\r
+ const char* what() const {return getMessage();}\r
+\r
+ /**\r
+ * Sets the error message.\r
+ * \r
+ * @param msg the error message\r
+ */\r
+ void setMessage(const char* msg);\r
+\r
+ /**\r
+ * Sets the error message.\r
+ * \r
+ * @param msg the error message\r
+ */\r
+ void setMessage(const std::string& msg) {\r
+ setMessage(msg.c_str());\r
+ }\r
+\r
+ /**\r
+ * Attach a set of positional parameters to the exception.\r
+ * \r
+ * @param p an ordered set of named parameter strings\r
+ */\r
+ void addProperties(const params& p);\r
+ \r
+ /**\r
+ * Attach a set of named parameters to the exception.\r
+ * \r
+ * @param p a set of named parameter strings\r
+ */\r
+ void addProperties(const namedparams& p);\r
+\r
+ /**\r
+ * Attach a single positional parameter at the next available position.\r
+ * \r
+ * @param value the parameter value\r
+ */\r
+ void addProperty(const char* value) {\r
+ addProperties(params(1,value));\r
+ }\r
+\r
+ /**\r
+ * Attach a single named parameter.\r
+ * \r
+ * @param name the parameter name\r
+ * @param value the parameter value\r
+ */\r
+ void addProperty(const char* name, const char* value) {\r
+ addProperties(namedparams(1,name,value));\r
+ }\r
+\r
+ /**\r
+ * Returns the parameter property with the designated position (based from one).\r
+ * \r
+ * @param index position to access\r
+ * @return the parameter property or NULL\r
+ */\r
+ const char* getProperty(unsigned int index) const;\r
+\r
+ /**\r
+ * Returns the parameter property with the designated name.\r
+ * \r
+ * @param name named parameter to access\r
+ * @return the parameter property or NULL\r
+ */\r
+ const char* getProperty(const char* name) const;\r
+\r
+ /**\r
+ * Raises an exception using itself.\r
+ * Used to raise an exception of a derived type.\r
+ */\r
+ virtual void raise() const {\r
+ throw *this;\r
+ }\r
+\r
+ /**\r
+ * Returns a unique name for the exception class.\r
+ * \r
+ * @return class name\r
+ */\r
+ virtual const char* getClassName() const {\r
+ return "xmltooling::XMLToolingException";\r
+ }\r
+ \r
+ /**\r
+ * Returns a string containing a serialized representation of the exception.\r
+ * \r
+ * @return the serialization\r
+ */\r
+ std::string toString() const;\r
+\r
private:\r
std::string m_msg;\r
+ mutable std::string m_processedmsg;\r
+ std::map<std::string,std::string> m_params;\r
+\r
+ public:\r
+ /**\r
+ * Builds an empty exception of the given type.\r
+ * \r
+ * @param exceptionClass the name of the exception type to build\r
+ * @return an empty exception object\r
+ */\r
+ static XMLToolingException* getInstance(const char* exceptionClass);\r
+\r
+ /**\r
+ * Builds an exception from a serialized input stream.\r
+ * \r
+ * @param in input stream\r
+ * @return the exception object found in the stream\r
+ */\r
+ static XMLToolingException* fromStream(std::istream& in);\r
+ \r
+ /**\r
+ * Builds an exception from a serialized input buffer.\r
+ * \r
+ * @param s input buffer\r
+ * @return the exception object found in the buffer\r
+ */\r
+ static XMLToolingException* fromString(const char* s);\r
+ \r
+ /**\r
+ * Registers a factory to create exceptions of a given class name.\r
+ * \r
+ * @param exceptionClass name of exception type\r
+ * @param factory factory function to build exceptions with\r
+ */\r
+ static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {\r
+ m_factoryMap[exceptionClass] = factory;\r
+ }\r
+ \r
+ /**\r
+ * Unregisters the factory for a given class name.\r
+ * \r
+ * @param exceptionClass name of exception type\r
+ */\r
+ static void deregisterFactory(const char* exceptionClass) {\r
+ m_factoryMap.erase(exceptionClass);\r
+ }\r
+\r
+ private:\r
+ typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;\r
+ static ExceptionFactoryMap m_factoryMap;\r
};\r
\r
- DECL_XMLTOOLING_EXCEPTION(XMLParserException);\r
- DECL_XMLTOOLING_EXCEPTION(XMLObjectException);\r
- DECL_XMLTOOLING_EXCEPTION(MarshallingException);\r
- DECL_XMLTOOLING_EXCEPTION(UnmarshallingException);\r
- DECL_XMLTOOLING_EXCEPTION(UnknownElementException);\r
- DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException);\r
- DECL_XMLTOOLING_EXCEPTION(ValidationException);\r
- DECL_XMLTOOLING_EXCEPTION(SignatureException);\r
+ DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException);\r
+ DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException);\r
+ DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException);\r
+ DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException);\r
+ DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException);\r
+ DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException);\r
+ DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException);\r
+ DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException);\r
\r
};\r
\r