static inline Value NewObject(ScriptFrame& frame, bool abstract, const String& type, const String& name, const boost::shared_ptr<Expression>& filter, const String& zone, std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo()) { ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo); String checkName = name; if (!abstract) { Type::Ptr ptype = Type::GetByName(type); NameComposer *nc = dynamic_cast<NameComposer *>(ptype.get()); if (nc) checkName = nc->MakeName(name, Dictionary::Ptr()); } if (!checkName.IsEmpty()) { ConfigItem::Ptr oldItem = ConfigItem::GetObject(type, checkName); if (oldItem) { std::ostringstream msgbuf; msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo(); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo)); } } item->SetType(type); if (name.FindFirstOf("!") != String::NPos) { std::ostringstream msgbuf; msgbuf << "Name for object '" << name << "' of type '" << type << "' is invalid: Object names may not contain '!'"; BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo)); } item->SetName(name); item->AddExpression(new OwnedExpression(expression)); item->SetAbstract(abstract); item->SetScope(EvaluateClosedVars(frame, closedVars)); item->SetZone(zone); item->SetFilter(filter); item->Compile()->Register(); return Empty; }
/** * Commits the configuration item by creating a ConfigObject * object. * * @returns The ConfigObject that was created/updated. */ ConfigObject::Ptr ConfigItem::Commit(bool discard) { #ifdef I2_DEBUG Log(LogDebug, "ConfigItem") << "Commit called for ConfigItem Type=" << GetType() << ", Name=" << GetName(); #endif /* I2_DEBUG */ /* Make sure the type is valid. */ Type::Ptr type = Type::GetByName(GetType()); ASSERT(type && ConfigObject::TypeInstance->IsAssignableFrom(type)); if (IsAbstract()) return ConfigObject::Ptr(); ConfigObject::Ptr dobj = static_pointer_cast<ConfigObject>(type->Instantiate()); dobj->SetDebugInfo(m_DebugInfo); dobj->SetZoneName(m_Zone); dobj->SetPackage(m_Package); dobj->SetName(m_Name); DebugHint debugHints; ScriptFrame frame(dobj); if (m_Scope) m_Scope->CopyTo(frame.Locals); try { m_Expression->Evaluate(frame, &debugHints); } catch (const std::exception& ex) { if (m_IgnoreOnError) { Log(LogWarning, "ConfigObject") << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex); return ConfigObject::Ptr(); } throw; } if (discard) m_Expression.reset(); String item_name; String short_name = dobj->GetShortName(); if (!short_name.IsEmpty()) { item_name = short_name; dobj->SetName(short_name); } else item_name = m_Name; String name = item_name; NameComposer *nc = dynamic_cast<NameComposer *>(type.get()); if (nc) { name = nc->MakeName(name, dobj); if (name.IsEmpty()) BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object")); } if (name != item_name) dobj->SetShortName(item_name); dobj->SetName(name); try { dobj->OnConfigLoaded(); } catch (const std::exception& ex) { if (m_IgnoreOnError) { Log(LogWarning, "ConfigObject") << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex); return ConfigObject::Ptr(); } throw; } Dictionary::Ptr persistentItem = new Dictionary(); persistentItem->Set("type", GetType()); persistentItem->Set("name", GetName()); persistentItem->Set("properties", Serialize(dobj, FAConfig)); Dictionary::Ptr dhint = debugHints.ToDictionary(); persistentItem->Set("debug_hints", dhint); Array::Ptr di = new Array(); di->Add(m_DebugInfo.Path); di->Add(m_DebugInfo.FirstLine); di->Add(m_DebugInfo.FirstColumn); di->Add(m_DebugInfo.LastLine); di->Add(m_DebugInfo.LastColumn); persistentItem->Set("debug_info", di); try { DefaultValidationUtils utils; dobj->Validate(FAConfig, utils); } catch (ValidationError& ex) { if (m_IgnoreOnError) { Log(LogWarning, "ConfigObject") << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex); return ConfigObject::Ptr(); } ex.SetDebugHint(dhint); throw; } ConfigCompilerContext::GetInstance()->WriteObject(persistentItem); persistentItem.reset(); dhint.reset(); dobj->Register(); m_Object = dobj; return dobj; }
/** * Commits the configuration item by creating a DynamicObject * object. * * @returns The DynamicObject that was created/updated. */ DynamicObject::Ptr ConfigItem::Commit(bool discard) { ASSERT(!OwnsLock()); #ifdef _DEBUG Log(LogDebug, "ConfigItem") << "Commit called for ConfigItem Type=" << GetType() << ", Name=" << GetName(); #endif /* _DEBUG */ /* Make sure the type is valid. */ Type::Ptr type = Type::GetByName(GetType()); ASSERT(type && Type::GetByName("DynamicObject")->IsAssignableFrom(type)); if (IsAbstract()) return DynamicObject::Ptr(); DynamicObject::Ptr dobj = static_pointer_cast<DynamicObject>(type->Instantiate()); dobj->SetDebugInfo(m_DebugInfo); dobj->SetTypeName(m_Type); dobj->SetZone(m_Zone); Dictionary::Ptr locals = new Dictionary(); locals->Set("__parent", m_Scope); m_Scope.reset(); dobj->SetParentScope(locals); locals.reset(); dobj->SetName(m_Name); DebugHint debugHints; try { m_Expression->Evaluate(dobj, &debugHints); } catch (const ConfigError& ex) { const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo()); } catch (const std::exception& ex) { ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex)); } if (discard) m_Expression.reset(); dobj->SetParentScope(Object::Ptr()); String name = m_Name; NameComposer *nc = dynamic_cast<NameComposer *>(type.get()); if (nc) { name = nc->MakeName(m_Name, dobj); if (name.IsEmpty()) BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object")); } if (name != m_Name) dobj->SetShortName(m_Name); dobj->SetName(name); Dictionary::Ptr attrs = Serialize(dobj, FAConfig); Dictionary::Ptr persistentItem = new Dictionary(); persistentItem->Set("type", GetType()); persistentItem->Set("name", GetName()); persistentItem->Set("properties", attrs); persistentItem->Set("debug_hints", debugHints.ToDictionary()); ConfigCompilerContext::GetInstance()->WriteObject(persistentItem); persistentItem.reset(); ConfigType::Ptr ctype = ConfigType::GetByName(GetType()); if (!ctype) ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'"); else { TypeRuleUtilities utils; try { attrs->Remove("name"); ctype->ValidateItem(GetName(), attrs, GetDebugInfo(), &utils); } catch (const ConfigError& ex) { const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo()); } catch (const std::exception& ex) { ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex)); } } dobj->Register(); m_Object = dobj; return dobj; }