Esempio n. 1
0
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName,
    const String& config, const Array::Ptr& errors)
{
	if (!ConfigPackageUtility::PackageExists("_api")) {
		ConfigPackageUtility::CreatePackage("_api");

		String stage = ConfigPackageUtility::CreateStage("_api");
		ConfigPackageUtility::ActivateStage("_api", stage);
	}

	String path = GetObjectConfigPath(type, fullName);
	Utility::MkDirP(Utility::DirName(path), 0700);

	if (Utility::PathExists(path)) {
		errors->Add("Configuration file '" + path + "' already exists.");
		return false;
	}

	std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc);
	fp << config;
	fp.close();

	Expression *expr = ConfigCompiler::CompileFile(path, String(), "_api");

	try {
		ActivationScope ascope;

		ScriptFrame frame;
		expr->Evaluate(frame);
		delete expr;
		expr = NULL;

		WorkQueue upq;
		std::vector<ConfigItem::Ptr> newItems;

		if (!ConfigItem::CommitItems(ascope.GetContext(), upq, newItems) || !ConfigItem::ActivateItems(upq, newItems, true)) {
			if (errors) {
				if (unlink(path.CStr()) < 0 && errno != ENOENT) {
					BOOST_THROW_EXCEPTION(posix_error()
					    << boost::errinfo_api_function("unlink")
					    << boost::errinfo_errno(errno)
					    << boost::errinfo_file_name(path));
				}

				for (const boost::exception_ptr& ex : upq.GetExceptions()) {
					errors->Add(DiagnosticInformation(ex));
				}
			}

			return false;
		}

		ApiListener::UpdateObjectAuthority();
	} catch (const std::exception& ex) {
		delete expr;

		if (unlink(path.CStr()) < 0 && errno != ENOENT) {
			BOOST_THROW_EXCEPTION(posix_error()
			    << boost::errinfo_api_function("unlink")
			    << boost::errinfo_errno(errno)
			    << boost::errinfo_file_name(path));
		}

		if (errors)
			errors->Add(DiagnosticInformation(ex));

		return false;
	}

	return true;
}
Esempio n. 2
0
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName,
	const String& config, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation)
{
	{
		boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
		if (!ConfigPackageUtility::PackageExists("_api")) {
			ConfigPackageUtility::CreatePackage("_api");

			String stage = ConfigPackageUtility::CreateStage("_api");
			ConfigPackageUtility::ActivateStage("_api", stage);
		}
	}

	ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, fullName);

	if (item) {
		errors->Add("Object '" + fullName + "' already exists.");
		return false;
	}

	String path = GetObjectConfigPath(type, fullName);
	Utility::MkDirP(Utility::DirName(path), 0700);

	if (Utility::PathExists(path)) {
		errors->Add("Cannot create object '" + fullName + "'. Configuration file '" + path + "' already exists.");
		return false;
	}

	std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc);
	fp << config;
	fp.close();

	std::unique_ptr<Expression> expr = ConfigCompiler::CompileFile(path, String(), "_api");

	try {
		ActivationScope ascope;

		ScriptFrame frame(true);
		expr->Evaluate(frame);
		expr.reset();

		WorkQueue upq;
		upq.SetName("ConfigObjectUtility::CreateObject");

		std::vector<ConfigItem::Ptr> newItems;

		/* Disable logging for object creation, but do so ourselves later on. */
		if (!ConfigItem::CommitItems(ascope.GetContext(), upq, newItems, true) || !ConfigItem::ActivateItems(upq, newItems, true, true)) {
			if (errors) {
				if (unlink(path.CStr()) < 0 && errno != ENOENT) {
					BOOST_THROW_EXCEPTION(posix_error()
						<< boost::errinfo_api_function("unlink")
						<< boost::errinfo_errno(errno)
						<< boost::errinfo_file_name(path));
				}

				for (const boost::exception_ptr& ex : upq.GetExceptions()) {
					errors->Add(DiagnosticInformation(ex, false));

					if (diagnosticInformation)
						diagnosticInformation->Add(DiagnosticInformation(ex));
				}
			}

			return false;
		}

		ApiListener::UpdateObjectAuthority();

		Log(LogInformation, "ConfigObjectUtility")
			<< "Created and activated object '" << fullName << "' of type '" << type->GetName() << "'.";

	} catch (const std::exception& ex) {
		if (unlink(path.CStr()) < 0 && errno != ENOENT) {
			BOOST_THROW_EXCEPTION(posix_error()
				<< boost::errinfo_api_function("unlink")
				<< boost::errinfo_errno(errno)
				<< boost::errinfo_file_name(path));
		}

		if (errors)
			errors->Add(DiagnosticInformation(ex, false));

		if (diagnosticInformation)
			diagnosticInformation->Add(DiagnosticInformation(ex));

		return false;
	}

	return true;
}