diff --git a/Doxyfile b/Doxyfile
index 4f8d9c93b..eaadb283d 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -1469,7 +1469,7 @@ ENABLE_PREPROCESSING = YES
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
-MACRO_EXPANSION = NO
+MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
diff --git a/base/Makefile.am b/base/Makefile.am
index f5520d9e6..601d09d50 100644
--- a/base/Makefile.am
+++ b/base/Makefile.am
@@ -21,7 +21,7 @@ libbase_la_SOURCES = \
delegate.h \
dictionary.cpp \
dictionary.h \
- event.h \
+ observable.h \
exception.cpp \
exception.h \
fifo.cpp \
diff --git a/base/application.cpp b/base/application.cpp
index 11fc30fe5..de3054477 100644
--- a/base/application.cpp
+++ b/base/application.cpp
@@ -460,12 +460,12 @@ int Application::Run(int argc, char **argv)
} else {
try {
result = Main(m_Arguments);
- } catch (const Exception& ex) {
+ } catch (const exception& ex) {
Application::Instance.reset();
Application::Log("---");
Application::Log("Exception: " + Utility::GetTypeName(ex));
- Application::Log("Message: " + ex.GetMessage());
+ Application::Log("Message: " + string(ex.what()));
return EXIT_FAILURE;
}
diff --git a/base/base.vcxproj b/base/base.vcxproj
index 3710e309d..bdcca97ad 100644
--- a/base/base.vcxproj
+++ b/base/base.vcxproj
@@ -45,7 +45,7 @@
-
+
diff --git a/base/configcollection.h b/base/configcollection.h
index 1846453c3..a37332ab1 100644
--- a/base/configcollection.h
+++ b/base/configcollection.h
@@ -50,8 +50,8 @@ public:
void ForEachObject(function callback);
- Event OnObjectCommitted;
- Event OnObjectRemoved;
+ Observable OnObjectCommitted;
+ Observable OnObjectRemoved;
};
}
diff --git a/base/confighive.h b/base/confighive.h
index c137cf6ca..0bb3b708a 100644
--- a/base/confighive.h
+++ b/base/confighive.h
@@ -45,8 +45,8 @@ public:
void ForEachObject(const string& type,
function callback);
- Event OnObjectCommitted;
- Event OnObjectRemoved;
+ Observable OnObjectCommitted;
+ Observable OnObjectRemoved;
};
}
diff --git a/base/dictionary.cpp b/base/dictionary.cpp
index e8e626580..90d6c7c06 100644
--- a/base/dictionary.cpp
+++ b/base/dictionary.cpp
@@ -21,65 +21,6 @@
using namespace icinga;
-/**
- * Retrieves a value from the dictionary.
- *
- * @param key The key.
- * @param value Pointer to the value.
- * @returns true if the value was retrieved, false otherwise.
- */
-bool Dictionary::GetProperty(string key, Variant *value) const
-{
- ConstDictionaryIterator i = m_Data.find(key);
-
- if (i == m_Data.end())
- return false;
-
- *value = i->second;
- return true;
-}
-
-/**
- * Sets a value in the dictionary.
- *
- * @param key The key.
- * @param value The value.
- */
-void Dictionary::SetProperty(string key, const Variant& value)
-{
- DictionaryIterator i = m_Data.find(key);
-
- Variant oldValue;
- if (i != m_Data.end()) {
- oldValue = i->second;
- m_Data.erase(i);
- }
-
- m_Data[key] = value;
-}
-
-/**
- * Retrieves a value from the dictionary.
- *
- * @param key The key.
- * @param value Pointer to the value.
- * @returns true if the value was retrieved, false otherwise.
- */
-bool Dictionary::GetProperty(string key, Dictionary::Ptr *value) const
-{
- Object::Ptr object;
-
- if (!GetProperty(key, &object))
- return false;
-
- Dictionary::Ptr dictionary = dynamic_pointer_cast(object);
- if (!dictionary)
- throw InvalidArgumentException();
-
- *value = dictionary;
- return true;
-}
-
/**
* Returns an iterator to the beginning of the dictionary.
*
@@ -109,25 +50,3 @@ long Dictionary::GetLength(void) const
{
return m_Data.size();
}
-
-/**
- * Adds an unnamed value to the dictionary.
- *
- * @param value The value.
- */
-void Dictionary::AddUnnamedProperty(const Variant& value)
-{
- map::const_iterator it;
- string key;
- long index = GetLength();
- do {
- stringstream s;
- s << "_" << index;
- index++;
-
- key = s.str();
- it = m_Data.find(key);
- } while (it != m_Data.end());
-
- m_Data[key] = value;
-}
diff --git a/base/dictionary.h b/base/dictionary.h
index edfeda281..ec8df2451 100644
--- a/base/dictionary.h
+++ b/base/dictionary.h
@@ -38,29 +38,64 @@ public:
typedef shared_ptr Ptr;
typedef weak_ptr WeakPtr;
- bool GetProperty(string key, Variant *value) const;
- void SetProperty(string key, const Variant& value);
-
+ /**
+ * Retrieves a value from the dictionary.
+ *
+ * @param key The key.
+ * @param value Pointer to the value.
+ * @returns true if the value was retrieved, false otherwise.
+ */
template
bool GetProperty(string key, T *value) const
{
- Variant data;
+ ConstDictionaryIterator i = m_Data.find(key);
- if (!GetProperty(key, &data))
+ if (i == m_Data.end())
return false;
- *value = data;
+ *value = i->second;
return true;
}
- bool GetProperty(string key, Dictionary::Ptr *value) const;
+ /**
+ * Sets a value in the dictionary.
+ *
+ * @param key The key.
+ * @param value The value.
+ */
+ template
+ void SetProperty(string key, const T& value)
+ {
+ m_Data[key] = value;
+ }
+
+ /**
+ * Adds an unnamed value to the dictionary.
+ *
+ * @param value The value.
+ */
+ template
+ void AddUnnamedProperty(const T& value)
+ {
+ DictionaryIterator it;
+ string key;
+ long index = GetLength();
+ do {
+ stringstream s;
+ s << "_" << index;
+ index++;
+
+ key = s.str();
+ it = m_Data.find(key);
+ } while (it != m_Data.end());
+
+ SetProperty(key, value);
+ }
DictionaryIterator Begin(void);
DictionaryIterator End(void);
- void AddUnnamedProperty(const Variant& value);
-
long GetLength(void) const;
};
diff --git a/base/event.h b/base/event.h
deleted file mode 100644
index 430f7b06b..000000000
--- a/base/event.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef EVENT_H
-#define EVENT_H
-
-namespace icinga
-{
-
-/**
- * Base class for event arguments.
- */
-struct I2_BASE_API EventArgs
-{
- Object::Ptr Source; /**< The source of the event. */
-};
-
-/**
- * An observable event.
- */
-template
-class Event
-{
-public:
- typedef function ObserverType;
-
-private:
- vector m_Observers;
-
-public:
- /**
- * Adds an observer to this event.
- *
- * @param rhs The delegate.
- */
- Event& operator +=(const ObserverType& rhs)
- {
- m_Observers.push_back(rhs);
- return *this;
- }
-
- /**
- * Removes an observer from this event.
- *
- * @param rhs The delegate.
- */
- Event& operator -=(const ObserverType& rhs)
- {
- m_Observers.erase(rhs);
- return *this;
- }
-
- /**
- * Invokes each observer function that is registered for this event. Any
- * observer function which returns -1 is removed.
- *
- * @param args Event arguments.
- */
- void operator()(const TArgs& args)
- {
- typename vector::iterator i;
-
- for (i = m_Observers.begin(); i != m_Observers.end(); ) {
- int result = (*i)(args);
-
- if (result == -1)
- i = m_Observers.erase(i);
- else
- i++;
- }
- }
-};
-
-}
-
-#endif /* EVENT_H */
diff --git a/base/exception.cpp b/base/exception.cpp
index 8a339f29e..8f8af1ed3 100644
--- a/base/exception.cpp
+++ b/base/exception.cpp
@@ -33,7 +33,7 @@ Exception::Exception(void)
*
* @param message A message describing the exception.
*/
-Exception::Exception(const string& message)
+Exception::Exception(const char *message)
{
SetMessage(message);
}
@@ -43,19 +43,32 @@ Exception::Exception(const string& message)
*
* @returns The description.
*/
-string Exception::GetMessage(void) const
+const char *Exception::GetMessage(void) const
{
return m_Message;
}
+/**
+ * Retrieves the description for the exception.
+ *
+ * @returns The description.
+ */
+const char *Exception::what(void) const throw()
+{
+ return GetMessage();
+}
+
/**
* Sets the description for the exception.
*
* @param message The description.
*/
-void Exception::SetMessage(string message)
+void Exception::SetMessage(const char *message)
{
- m_Message = message;
+ if (m_Message)
+ delete m_Message;
+
+ m_Message = Memory::StrDup(message);
}
#ifdef _WIN32
diff --git a/base/exception.h b/base/exception.h
index 21c8dd2e7..9687b7341 100644
--- a/base/exception.h
+++ b/base/exception.h
@@ -26,26 +26,29 @@ namespace icinga
/**
* Base class for all exceptions.
*/
-class I2_BASE_API Exception
+class I2_BASE_API Exception : exception
{
private:
- string m_Message;
+ const char *m_Message;
protected:
- void SetMessage(string message);
+ void SetMessage(const char *message);
public:
Exception(void);
- Exception(const string& message);
+ Exception(const char *message);
/**
* Destructor for the Exception class. Must be virtual for RTTI to work.
*/
virtual ~Exception(void)
{
+ delete m_Message;
}
- string GetMessage(void) const;
+ const char *GetMessage(void) const;
+
+ virtual const char *what(void) const throw();
};
#define DEFINE_EXCEPTION_CLASS(klass) \
@@ -56,7 +59,7 @@ public:
{ \
} \
\
- inline klass(const string& message) \
+ inline klass(const char *message) \
: Exception(message) \
{ \
} \
@@ -64,6 +67,7 @@ public:
DEFINE_EXCEPTION_CLASS(NotImplementedException);
DEFINE_EXCEPTION_CLASS(InvalidArgumentException);
+DEFINE_EXCEPTION_CLASS(InvalidCastException);
#ifdef _WIN32
/**
@@ -80,7 +84,8 @@ public:
*/
inline Win32Exception(const string& message, int errorCode)
{
- SetMessage(message + ": " + FormatErrorCode(errorCode));
+ string msg = message + ": " + FormatErrorCode(errorCode);
+ SetMessage(msg.c_str());
}
/**
@@ -107,7 +112,8 @@ public:
*/
inline PosixException(const string& message, int errorCode)
{
- SetMessage(message + ": " + FormatErrorCode(errorCode));
+ string msg = message + ": " + FormatErrorCode(errorCode);
+ SetMessage(msg.c_str());
}
/**
@@ -133,7 +139,8 @@ public:
*/
inline OpenSSLException(const string& message, int errorCode)
{
- SetMessage(message + ": " + FormatErrorCode(errorCode));
+ string msg = message + ": " + FormatErrorCode(errorCode);
+ SetMessage(msg.c_str());
}
/**
diff --git a/base/i2-base.h b/base/i2-base.h
index 771708887..985565e89 100644
--- a/base/i2-base.h
+++ b/base/i2-base.h
@@ -103,7 +103,7 @@ using namespace std::tr1::placeholders;
#include "exception.h"
#include "memory.h"
#include "delegate.h"
-#include "event.h"
+#include "observable.h"
#include "variant.h"
#include "dictionary.h"
#include "timer.h"
diff --git a/base/socket.h b/base/socket.h
index ce6b77855..a222913df 100644
--- a/base/socket.h
+++ b/base/socket.h
@@ -62,12 +62,12 @@ public:
void SetFD(SOCKET fd);
SOCKET GetFD(void) const;
- Event OnReadable;
- Event OnWritable;
- Event OnException;
+ Observable OnReadable;
+ Observable OnWritable;
+ Observable OnException;
- Event OnError;
- Event OnClosed;
+ Observable OnError;
+ Observable OnClosed;
virtual bool WantsToRead(void) const;
virtual bool WantsToWrite(void) const;
diff --git a/base/tcpclient.h b/base/tcpclient.h
index 5c36dfa33..de7ed3757 100644
--- a/base/tcpclient.h
+++ b/base/tcpclient.h
@@ -64,7 +64,7 @@ public:
virtual bool WantsToRead(void) const;
virtual bool WantsToWrite(void) const;
- Event OnDataAvailable;
+ Observable OnDataAvailable;
};
/**
diff --git a/base/tcpserver.h b/base/tcpserver.h
index d9b30190d..370cac0d6 100644
--- a/base/tcpserver.h
+++ b/base/tcpserver.h
@@ -54,7 +54,7 @@ public:
void Listen(void);
- Event OnNewClient;
+ Observable OnNewClient;
virtual bool WantsToRead(void) const;
};
diff --git a/base/thread.cpp b/base/thread.cpp
index 70c2fe2e9..611dbbfaf 100644
--- a/base/thread.cpp
+++ b/base/thread.cpp
@@ -21,12 +21,6 @@
using namespace icinga;
-typedef struct threadparam_s
-{
- ThreadProc callback;
- void *param;
-} threadparam_t;
-
/**
* Helper function that deals with OS-specific differences in the thread
* proc's function signature.
@@ -34,16 +28,16 @@ typedef struct threadparam_s
#ifdef _WIN32
static DWORD WINAPI ThreadStartProc(LPVOID param)
{
- threadparam_t *tparam = (threadparam_t *)param;
- tparam->callback(tparam->param);
+ ThreadParameters *tparam = (ThreadParameters *)param;
+ tparam->Callback(tparam->UserParams);
delete tparam;
return 0;
}
#else /* _WIN32 */
static void *ThreadStartProc(void *param)
{
- threadparam_t *tparam = (threadparam_t *)param;
- tparam->callback(tparam->param);
+ ThreadParameters *tparam = (ThreadParameters *)param;
+ tparam->Callback(tparam->UserParams);
delete tparam;
return NULL;
}
@@ -55,13 +49,13 @@ static void *ThreadStartProc(void *param)
*/
Thread::Thread(ThreadProc callback, void *param)
{
- threadparam_t *tparam = new threadparam_t();
+ ThreadParameters *tparam = new ThreadParameters();
if (tparam == NULL)
throw OutOfMemoryException("Out of memory");
- tparam->callback = callback;
- tparam->param = param;
+ tparam->Callback = callback;
+ tparam->UserParams = param;
#ifdef _WIN32
m_Thread = CreateThread(NULL, 0, ThreadStartProc, tparam, CREATE_SUSPENDED, NULL);
@@ -69,7 +63,8 @@ Thread::Thread(ThreadProc callback, void *param)
if (m_Thread == NULL)
throw Win32Exception("CreateThread failed.", GetLastError());
#else /* _WIN32 */
- pthread_create(&m_Thread, NULL, ThreadStartProc, &tparam);
+ if (pthread_create(&m_Thread, NULL, ThreadStartProc, &tparam) < 0)
+ throw PosixException("pthread_create failed.", errno);
#endif /* _WIN32 */
}
diff --git a/base/thread.h b/base/thread.h
index cf6744a25..7f3237025 100644
--- a/base/thread.h
+++ b/base/thread.h
@@ -25,6 +25,12 @@ namespace icinga
typedef void (*ThreadProc)(void *);
+struct ThreadParameters
+{
+ ThreadProc Callback;
+ void *UserParams;
+};
+
/**
* A wrapper around OS-specific thread functionality.
*/
diff --git a/base/timer.h b/base/timer.h
index 79f013d53..17017a9f3 100644
--- a/base/timer.h
+++ b/base/timer.h
@@ -72,7 +72,7 @@ public:
void Reschedule(time_t next);
- Event OnTimerExpired;
+ Observable OnTimerExpired;
};
}
diff --git a/base/tlsclient.h b/base/tlsclient.h
index bf76dbe16..cec54277c 100644
--- a/base/tlsclient.h
+++ b/base/tlsclient.h
@@ -73,7 +73,7 @@ public:
virtual bool WantsToRead(void) const;
virtual bool WantsToWrite(void) const;
- Event OnVerifyCertificate;
+ Observable OnVerifyCertificate;
};
TCPClient::Ptr TLSClientFactory(TCPClientRole role, shared_ptr sslContext);
diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp
index b1fa37277..0dade5e88 100644
--- a/components/discovery/discoverycomponent.cpp
+++ b/components/discovery/discoverycomponent.cpp
@@ -357,10 +357,14 @@ bool DiscoveryComponent::HasMessagePermission(Dictionary::Ptr roles, string mess
if (!role)
continue;
- Dictionary::Ptr permissions;
- if (!role->GetProperty(messageType, &permissions))
+ Object::Ptr object;
+ if (!role->GetProperty(messageType, &object))
continue;
+ Dictionary::Ptr permissions = dynamic_pointer_cast(object);
+ if (!permissions)
+ throw InvalidCastException();
+
for (DictionaryIterator is = permissions->Begin(); is != permissions->End(); is++) {
if (Utility::Match(is->second.GetString(), message))
return true;
@@ -396,8 +400,15 @@ void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessa
ConfigObject::Ptr endpointConfig = endpointCollection->GetObject(identity);
Dictionary::Ptr roles;
- if (endpointConfig)
- endpointConfig->GetProperty("roles", &roles);
+ if (endpointConfig) {
+ Object::Ptr object;
+ if (endpointConfig->GetProperty("roles", &object)) {
+ roles = dynamic_pointer_cast(object);
+
+ if (!roles)
+ throw InvalidCastException();
+ }
+ }
Endpoint::Ptr endpoint = GetEndpointManager()->GetEndpointByIdentity(identity);
diff --git a/icinga/endpoint.h b/icinga/endpoint.h
index 71939675a..59f046c85 100644
--- a/icinga/endpoint.h
+++ b/icinga/endpoint.h
@@ -92,8 +92,8 @@ public:
ConstTopicIterator BeginPublications(void) const;
ConstTopicIterator EndPublications(void) const;
- Event OnIdentityChanged;
- Event OnSessionEstablished;
+ Observable OnIdentityChanged;
+ Observable OnSessionEstablished;
};
}
diff --git a/icinga/endpointmanager.h b/icinga/endpointmanager.h
index d7cd71c22..f6e322638 100644
--- a/icinga/endpointmanager.h
+++ b/icinga/endpointmanager.h
@@ -71,7 +71,7 @@ public:
Endpoint::Ptr GetEndpointByIdentity(string identity) const;
- Event OnNewEndpoint;
+ Observable OnNewEndpoint;
};
}
diff --git a/icinga/virtualendpoint.cpp b/icinga/virtualendpoint.cpp
index d36426b09..48e48ab2a 100644
--- a/icinga/virtualendpoint.cpp
+++ b/icinga/virtualendpoint.cpp
@@ -60,7 +60,7 @@ void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RpcRequest& req
if (!request.GetMethod(&method))
return;
- map >::iterator i = m_TopicHandlers.find(method);
+ map >::iterator i = m_TopicHandlers.find(method);
if (i == m_TopicHandlers.end())
return;
diff --git a/icinga/virtualendpoint.h b/icinga/virtualendpoint.h
index c7774d556..5222502d5 100644
--- a/icinga/virtualendpoint.h
+++ b/icinga/virtualendpoint.h
@@ -38,7 +38,7 @@ struct I2_ICINGA_API NewRequestEventArgs : public EventArgs
class I2_ICINGA_API VirtualEndpoint : public Endpoint
{
private:
- map< string, Event > m_TopicHandlers;
+ map< string, Observable > m_TopicHandlers;
public:
typedef shared_ptr Ptr;
diff --git a/jsonrpc/jsonrpcclient.cpp b/jsonrpc/jsonrpcclient.cpp
index 42dafe9d8..c240946ad 100644
--- a/jsonrpc/jsonrpcclient.cpp
+++ b/jsonrpc/jsonrpcclient.cpp
@@ -53,7 +53,7 @@ int JsonRpcClient::DataAvailableHandler(const EventArgs&)
nea.Message = message;
OnNewMessage(nea);
} catch (const Exception& ex) {
- Application::Log("Exception while processing message from JSON-RPC client: " + ex.GetMessage());
+ Application::Log("Exception while processing message from JSON-RPC client: " + string(ex.GetMessage()));
Close();
return 1;
diff --git a/jsonrpc/jsonrpcclient.h b/jsonrpc/jsonrpcclient.h
index 9f7d242ba..07aac91de 100644
--- a/jsonrpc/jsonrpcclient.h
+++ b/jsonrpc/jsonrpcclient.h
@@ -46,7 +46,7 @@ public:
virtual void Start(void);
- Event OnNewMessage;
+ Observable OnNewMessage;
};
TCPClient::Ptr JsonRpcClientFactory(TCPClientRole role, shared_ptr sslContext);
diff --git a/jsonrpc/messagepart.cpp b/jsonrpc/messagepart.cpp
index bd1446326..de701dc3f 100644
--- a/jsonrpc/messagepart.cpp
+++ b/jsonrpc/messagepart.cpp
@@ -130,10 +130,14 @@ Dictionary::Ptr MessagePart::GetDictionary(void) const
bool MessagePart::GetProperty(string key, MessagePart *value) const
{
- Dictionary::Ptr dictionary;
- if (!GetDictionary()->GetProperty(key, &dictionary))
+ Object::Ptr object;
+ if (GetDictionary()->GetProperty(key, &object))
return false;
+ Dictionary::Ptr dictionary = dynamic_pointer_cast(object);
+ if (!dictionary)
+ throw InvalidCastException();
+
*value = MessagePart(dictionary);
return true;
}