Example #1
0
void CApplicationContext::createBeanGraph(
		CBeanCollection& beanCollection,
		CBeanGraph& beanGraph,
		CBeanGraph::ClistVertexEdges& beanTopologySort) const {
	CAF_CM_FUNCNAME("createBeanGraph");

	// Iterate the bean collection and create the beans. They will not be initialized.
	// Two name sets will be built: bean names and contstructor-arg ref names.
	// These two sets will be compared to ensure that all referenced beans exist.
	Csetstr beanNames;
	Csetstr beanCtorRefNames;
	for (TSmartMapIterator<CBeanCollection> beanIter(beanCollection);
			beanIter;
			beanIter++) {

		// Create the bean and add it to the collection
		CAF_CM_LOG_DEBUG_VA2(
				"Creating bean [id=%s][class=%s]",
				beanIter.getKey().c_str(),
				beanIter->_class.c_str());
		beanIter->_bean.CreateInstance(beanIter->_class.c_str());

		// Add the bean id to the beanNames set
		if (!beanNames.insert(beanIter->_id).second) {
			CAF_CM_LOG_DEBUG_VA1(
				"Internal logic error: duplicate bean detected. "
				"[id=%s]",
				beanIter->_id.c_str());
		}

		// Add ref constructor args to the ctor ref name set
		for (TConstMapIterator<CBeanCtorArgCollection> beanCtorArg(beanIter->_ctorArgs);
				beanCtorArg;
				beanCtorArg++) {
			if (CBeanCtorArg::REFERENCE == beanCtorArg->_type) {
				beanCtorRefNames.insert(beanCtorArg->_value);
			}
		}
	}

	// Make sure that all beans referenced as ctor args exist
	Csetstr beanNameDiff;
	std::set_difference(
			beanCtorRefNames.begin(),
			beanCtorRefNames.end(),
			beanNames.begin(),
			beanNames.end(),
			std::inserter(beanNameDiff, beanNameDiff.end()));

	if (beanNameDiff.size()) {
		for (TConstIterator<Csetstr> missingName(beanNameDiff);
				missingName;
				missingName++) {
			CAF_CM_LOG_ERROR_VA1(
					"No bean definition exists for constructor-arg referenced bean '%s'",
					missingName->c_str());
		}
		CAF_CM_EXCEPTIONEX_VA0(
				NoSuchElementException,
				0,
				"One or more bean constructor-args references beans that are not defined.");
	}

	// Create a graph node for each bean
	for (TSmartConstMapIterator<CBeanCollection> beanIter(beanCollection);
			beanIter;
			beanIter++) {
		beanGraph.addVertex(*beanIter);
	}

	// Okay. Now connect the vertices according the constructor-arg references.
	// The resulting graph will give us the initialization/tear-down order.
	for (TSmartConstMapIterator<CBeanCollection> beanIter(beanCollection);
			beanIter;
			beanIter++) {
		for (TConstMapIterator<CBeanCtorArgCollection> ctorArg(beanIter->_ctorArgs);
				ctorArg;
				ctorArg++) {
			if (CBeanCtorArg::REFERENCE == ctorArg->_type) {
				CBeanCollection::const_iterator ctorBean = beanCollection.find(ctorArg->_value);
				if (beanCollection.end() == ctorBean) {
					CAF_CM_EXCEPTIONEX_VA1(
							NoSuchElementException,
							0,
							"Internal error: constructor-arg referenced bean '%s' is missing",
							ctorArg->_value.c_str());
				}
				beanGraph.addEdge(ctorBean->second, *beanIter);
			}
		}
	}

	// And finally - compute the bean topology sort order
	beanTopologySort = beanGraph.topologySort();

	// Debugging - you will thank me for this later
	CAF_CM_LOG_DEBUG_VA0("BEGIN: Bean initialization order")
	for (TSmartConstIterator<CBeanGraph::ClistVertexEdges> beanNode(beanTopologySort);
			beanNode;
			beanNode++) {
		CAF_CM_LOG_DEBUG_VA1("bean id=%s", beanNode->_id.c_str());
	}
	CAF_CM_LOG_DEBUG_VA0("END: Bean initialization order")
}
void CRecipientListRouterInstance::initialize(
	const IBean::Cargs& ctorArgs,
	const IBean::Cprops& properties,
	const SmartPtrIDocument& configSection) {
	CAF_CM_FUNCNAME("initialize");

	CAF_CM_ENTER {
		CAF_CM_PRECOND_ISNOTINITIALIZED(_isInitialized);
		CAF_CM_VALIDATE_INTERFACE(configSection);

		_id = configSection->findRequiredAttribute("id");

		std::string val = configSection->findOptionalAttribute("timeout");
		if (val.length()) {
			_timeout = CStringConv::fromString<int32>(val);
		}

		val = configSection->findOptionalAttribute("ignore-send-failures");
		_ignoreSendFailures = (val == "true");

		Csetstr channelIds;
		const IDocument::SmartPtrCChildCollection childCollection = configSection->getAllChildren();
		for(TSmartConstMultimapIterator<IDocument::CChildCollection> childIter(*childCollection);
				childIter;
				childIter++) {
			const std::string sectionName = childIter.getKey();
			if (sectionName == "recipient") {
				const SmartPtrIDocument document = *childIter;
				const std::string channelId = document->findRequiredAttribute("channel");
				const std::string selectorExpression
					= document->findOptionalAttribute("selector-expression");

				if (!channelIds.insert(channelId).second) {
					CAF_CM_EXCEPTIONEX_VA2(
							DuplicateElementException,
							0,
							"Duplicate channelId '%s' in "
							"recipient-list-router definition '%s'",
							channelId.c_str(),
							_id.c_str());
				}

				if (selectorExpression.length()) {
					_selectorDefinitions.insert(
							Cmapstrstr::value_type(channelId, selectorExpression));
				} else {
					_staticChannelIds.push_back(channelId);
				}
			}
		}

		if (!_staticChannelIds.size() && !_selectorDefinitions.size()) {
			CAF_CM_EXCEPTIONEX_VA1(
					NoSuchElementException,
					0,
					"No recipients were listed in the definition of "
					"recipient-list-router '%s'",
					_id.c_str());
		}
		_isInitialized = true;
	}
	CAF_CM_EXIT;
}