mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-11-04 05:34:12 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			225 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
 | 
						|
 | 
						|
#include "base/namespace.hpp"
 | 
						|
#include "base/objectlock.hpp"
 | 
						|
#include "base/debug.hpp"
 | 
						|
#include "base/primitivetype.hpp"
 | 
						|
#include "base/debuginfo.hpp"
 | 
						|
#include "base/exception.hpp"
 | 
						|
#include <sstream>
 | 
						|
 | 
						|
using namespace icinga;
 | 
						|
 | 
						|
template class std::map<icinga::String, std::shared_ptr<icinga::NamespaceValue> >;
 | 
						|
 | 
						|
REGISTER_PRIMITIVE_TYPE(Namespace, Object, Namespace::GetPrototype());
 | 
						|
 | 
						|
Namespace::Namespace(NamespaceBehavior *behavior)
 | 
						|
	: m_Behavior(std::unique_ptr<NamespaceBehavior>(behavior))
 | 
						|
{ }
 | 
						|
 | 
						|
Value Namespace::Get(const String& field) const
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	Value value;
 | 
						|
	if (!GetOwnField(field, &value))
 | 
						|
		BOOST_THROW_EXCEPTION(ScriptError("Namespace does not contain field '" + field + "'"));
 | 
						|
	return value;
 | 
						|
}
 | 
						|
 | 
						|
bool Namespace::Get(const String& field, Value *value) const
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	auto nsVal = GetAttribute(field);
 | 
						|
 | 
						|
	if (!nsVal)
 | 
						|
		return false;
 | 
						|
 | 
						|
	*value =  nsVal->Get(DebugInfo());
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
void Namespace::Set(const String& field, const Value& value, bool overrideFrozen)
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	return SetFieldByName(field, value, overrideFrozen, DebugInfo());
 | 
						|
}
 | 
						|
 | 
						|
bool Namespace::Contains(const String& field) const
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	return HasOwnField(field);
 | 
						|
}
 | 
						|
 | 
						|
void Namespace::Remove(const String& field, bool overrideFrozen)
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	m_Behavior->Remove(this, field, overrideFrozen);
 | 
						|
}
 | 
						|
 | 
						|
void Namespace::RemoveAttribute(const String& field)
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	Namespace::Iterator it;
 | 
						|
	it = m_Data.find(field);
 | 
						|
 | 
						|
	if (it == m_Data.end())
 | 
						|
		return;
 | 
						|
 | 
						|
	m_Data.erase(it);
 | 
						|
}
 | 
						|
 | 
						|
NamespaceValue::Ptr Namespace::GetAttribute(const String& key) const
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	auto it = m_Data.find(key);
 | 
						|
 | 
						|
	if (it == m_Data.end())
 | 
						|
		return nullptr;
 | 
						|
 | 
						|
	return it->second;
 | 
						|
}
 | 
						|
 | 
						|
void Namespace::SetAttribute(const String& key, const NamespaceValue::Ptr& nsVal)
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	m_Data[key] = nsVal;
 | 
						|
}
 | 
						|
 | 
						|
Value Namespace::GetFieldByName(const String& field, bool, const DebugInfo& debugInfo) const
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	auto nsVal = GetAttribute(field);
 | 
						|
 | 
						|
	if (nsVal)
 | 
						|
		return nsVal->Get(debugInfo);
 | 
						|
	else
 | 
						|
		return GetPrototypeField(const_cast<Namespace *>(this), field, false, debugInfo); /* Ignore indexer not found errors similar to the Dictionary class. */
 | 
						|
}
 | 
						|
 | 
						|
void Namespace::SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	auto nsVal = GetAttribute(field);
 | 
						|
 | 
						|
	if (!nsVal)
 | 
						|
		m_Behavior->Register(this, field, value, overrideFrozen, debugInfo);
 | 
						|
	else
 | 
						|
		nsVal->Set(value, overrideFrozen, debugInfo);
 | 
						|
}
 | 
						|
 | 
						|
bool Namespace::HasOwnField(const String& field) const
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	return GetAttribute(field) != nullptr;
 | 
						|
}
 | 
						|
 | 
						|
bool Namespace::GetOwnField(const String& field, Value *result) const
 | 
						|
{
 | 
						|
	ObjectLock olock(this);
 | 
						|
 | 
						|
	auto nsVal = GetAttribute(field);
 | 
						|
 | 
						|
	if (!nsVal)
 | 
						|
		return false;
 | 
						|
 | 
						|
	*result = nsVal->Get(DebugInfo());
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
EmbeddedNamespaceValue::EmbeddedNamespaceValue(const Value& value)
 | 
						|
	: m_Value(value)
 | 
						|
{ }
 | 
						|
 | 
						|
Value EmbeddedNamespaceValue::Get(const DebugInfo& debugInfo) const
 | 
						|
{
 | 
						|
	return m_Value;
 | 
						|
}
 | 
						|
 | 
						|
void EmbeddedNamespaceValue::Set(const Value& value, bool, const DebugInfo&)
 | 
						|
{
 | 
						|
	m_Value = value;
 | 
						|
}
 | 
						|
 | 
						|
void ConstEmbeddedNamespaceValue::Set(const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
 | 
						|
{
 | 
						|
	if (!overrideFrozen)
 | 
						|
		BOOST_THROW_EXCEPTION(ScriptError("Constant must not be modified.", debugInfo));
 | 
						|
 | 
						|
	EmbeddedNamespaceValue::Set(value, overrideFrozen, debugInfo);
 | 
						|
}
 | 
						|
 | 
						|
void NamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const
 | 
						|
{
 | 
						|
	ns->SetAttribute(field, new EmbeddedNamespaceValue(value));
 | 
						|
}
 | 
						|
 | 
						|
void NamespaceBehavior::Remove(const Namespace::Ptr& ns, const String& field, bool overrideFrozen)
 | 
						|
{
 | 
						|
	if (!overrideFrozen) {
 | 
						|
		auto attr = ns->GetAttribute(field);
 | 
						|
 | 
						|
		if (dynamic_pointer_cast<ConstEmbeddedNamespaceValue>(attr))
 | 
						|
			BOOST_THROW_EXCEPTION(ScriptError("Constants must not be removed."));
 | 
						|
	}
 | 
						|
 | 
						|
	ns->RemoveAttribute(field);
 | 
						|
}
 | 
						|
 | 
						|
void ConstNamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const
 | 
						|
{
 | 
						|
	if (m_Frozen && !overrideFrozen)
 | 
						|
		BOOST_THROW_EXCEPTION(ScriptError("Namespace is read-only and must not be modified.", debugInfo));
 | 
						|
 | 
						|
	ns->SetAttribute(field, new ConstEmbeddedNamespaceValue(value));
 | 
						|
}
 | 
						|
 | 
						|
void ConstNamespaceBehavior::Remove(const Namespace::Ptr& ns, const String& field, bool overrideFrozen)
 | 
						|
{
 | 
						|
	if (m_Frozen && !overrideFrozen)
 | 
						|
		BOOST_THROW_EXCEPTION(ScriptError("Namespace is read-only and must not be modified."));
 | 
						|
 | 
						|
	NamespaceBehavior::Remove(ns, field, overrideFrozen);
 | 
						|
}
 | 
						|
 | 
						|
void ConstNamespaceBehavior::Freeze()
 | 
						|
{
 | 
						|
	m_Frozen = true;
 | 
						|
}
 | 
						|
 | 
						|
Namespace::Iterator Namespace::Begin()
 | 
						|
{
 | 
						|
	ASSERT(OwnsLock());
 | 
						|
 | 
						|
	return m_Data.begin();
 | 
						|
}
 | 
						|
 | 
						|
Namespace::Iterator Namespace::End()
 | 
						|
{
 | 
						|
	ASSERT(OwnsLock());
 | 
						|
 | 
						|
	return m_Data.end();
 | 
						|
}
 | 
						|
 | 
						|
Namespace::Iterator icinga::begin(const Namespace::Ptr& x)
 | 
						|
{
 | 
						|
	return x->Begin();
 | 
						|
}
 | 
						|
 | 
						|
Namespace::Iterator icinga::end(const Namespace::Ptr& x)
 | 
						|
{
 | 
						|
	return x->End();
 | 
						|
}
 | 
						|
 |