void CConfigProvider::createXmlPropertyCollection( const std::string& keyPath, const SmartPtrCXmlElement& thisXml, std::deque<std::pair<std::string, std::string> >& propertyCollection) const { CAF_CM_FUNCNAME_VALIDATE("createXmlPropertyCollection"); CAF_CM_ENTER { CAF_CM_VALIDATE_STRING(keyPath); CAF_CM_VALIDATE_SMARTPTR(thisXml); // propertyCollection is optional const CXmlElement::SmartPtrCAttributeCollection attributeCollection = thisXml->getAllAttributes(); if (! attributeCollection.IsNull() && ! attributeCollection->empty()) { for (TConstIterator<CXmlElement::CAttributeCollection> attributeXmlIter(*attributeCollection); attributeXmlIter; attributeXmlIter++) { const std::string attributeName = attributeXmlIter->first; const std::string attributeValue = attributeXmlIter->second; const std::string newKeyPath = keyPath + _keyPathDelimStr + attributeName; propertyCollection.push_back(std::make_pair(newKeyPath, attributeValue)); } } const CXmlElement::SmartPtrCElementCollection childrenXml = thisXml->getAllChildren(); if (! childrenXml.IsNull() && ! childrenXml->empty()) { for (TConstIterator<CXmlElement::CElementCollection > childrenXmlIter(*childrenXml); childrenXmlIter; childrenXmlIter++) { const SmartPtrCXmlElement childXml = childrenXmlIter->second; const std::string newKeyPath = keyPath + _keyPathDelimStr + childXml->getName(); const std::string value = childXml->getValue(); if (! value.empty()) { propertyCollection.push_back(std::make_pair(newKeyPath, value)); } createXmlPropertyCollection(newKeyPath, childXml, propertyCollection); } } } CAF_CM_EXIT; }
void CApplicationContext::parseBeanConfig( const std::string& beanConfigFile, CBeanCollection& beanCollection) const { CAF_CM_FUNCNAME("parseBeanConfig"); CAF_CM_VALIDATE_STRING(beanConfigFile); CAF_CM_LOG_DEBUG_VA1("Parsing bean config file %s", beanConfigFile.c_str()); // We will look up class references early in the process to fail as early // as possible and to make logging better. // Parse the bean config file CXmlElement::SmartPtrCElementCollection rootElements = CXmlUtils::parseFile(beanConfigFile, "caf:beans")->getAllChildren(); for (TSmartConstMultimapIterator<CXmlElement::CElementCollection> rootChild(*rootElements); rootChild; rootChild++) { // if the child is a bean... if (rootChild->getName() == "bean") { // Syntactic sugar const SmartPtrCXmlElement beanElement = *rootChild; // Bean attributes const std::string beanId = beanElement->findRequiredAttribute("id"); CAF_CM_LOG_DEBUG_VA1("Parsing bean [id=%s]", beanId.c_str()); const std::string beanClass = beanElement->findRequiredAttribute("class"); CAF_CM_LOG_DEBUG_VA2( "Checking bean class [id=%s][class=%s]", beanId.c_str(), beanClass.c_str()); if (!CEcmSubSystemRegistry::IsRegistered(beanClass)) { CAF_CM_EXCEPTIONEX_VA3( NoSuchElementException, 0, "Bean class %s is not registered. Fix the AppConfig file. " "[bean id=%s][bean_config_file=%s]", beanClass.c_str(), beanId.c_str(), beanConfigFile.c_str()); } // get optional constructor args and properties CBeanCtorArgCollection beanCtorArgs; Cmapstrstr beanProperties; CAF_CM_LOG_DEBUG_VA1("Parsing bean ctor args and properties [id=%s]", beanId.c_str()); CXmlElement::SmartPtrCElementCollection beanElements = beanElement->getAllChildren(); for (TSmartConstMultimapIterator<CXmlElement::CElementCollection> beanChild(*beanElements); beanChild; beanChild++) { if (beanChild->getName() == "property") { // Syntactic sugar const SmartPtrCXmlElement propArgElement = *beanChild; // property attributes const std::string name = propArgElement->findRequiredAttribute("name"); const std::string value = propArgElement->findRequiredAttribute("value"); if (!beanProperties.insert(std::make_pair(name, value)).second) { CAF_CM_EXCEPTIONEX_VA3( DuplicateElementException, 0, "Bean property name is duplicated. " "[bean id=%s][property name=%s][bean_config_file=%s]", beanId.c_str(), name.c_str(), beanConfigFile.c_str()); } } else if (beanChild->getName() == "constructor-arg") { // Syntactic sugar const SmartPtrCXmlElement ctorArgElement = *beanChild; // ctor attributes const uint32 ctorArgIndex = CStringConv::fromString<uint32>(ctorArgElement->findRequiredAttribute("index")); CBeanCtorArg::ARG_TYPE ctorArgType = CBeanCtorArg::NOT_SET; std::string ctorArgValue = ctorArgElement->findOptionalAttribute("value"); if (ctorArgValue.length() > 0) { ctorArgType = CBeanCtorArg::VALUE; } else { ctorArgValue = ctorArgElement->findOptionalAttribute("ref"); if (ctorArgValue.length() > 0) { ctorArgType = CBeanCtorArg::REFERENCE; } else { CAF_CM_EXCEPTIONEX_VA2( InvalidArgumentException, 0, "Bean constructor argument must be of type value or ref and cannot be empty. " "[bean id=%s][bean_config_file=%s]", beanId.c_str(), beanConfigFile.c_str()); } } if (!beanCtorArgs.insert( CBeanCtorArgCollection::value_type( ctorArgIndex, CBeanCtorArg(ctorArgType, ctorArgValue))).second) { CAF_CM_EXCEPTIONEX_VA3( DuplicateElementException, 0, "Bean has a duplicate constructor-arg index. " "[bean id=%s][bean_config_file=%s][arg-index=%d]", beanId.c_str(), beanConfigFile.c_str(), ctorArgIndex); } CAF_CM_LOG_DEBUG_VA4( "Bean ctor arg parsed [id=%s][arg-index=%d][arg-type=%s][arg-value=%s]", beanId.c_str(), ctorArgIndex, (CBeanCtorArg::VALUE == ctorArgType ? "VALUE" : "REFERENCE"), ctorArgValue.c_str()); } } // Add the bean definition to the collection SmartPtrCBeanNode beanNode; beanNode.CreateInstance(); beanNode->_id = beanId; beanNode->_class = beanClass; beanNode->_ctorArgs = beanCtorArgs; beanNode->_properties = beanProperties; if (!beanCollection.insert( CBeanCollection::value_type( beanId, beanNode)).second) { CAF_CM_EXCEPTIONEX_VA3( DuplicateElementException, 0, "Duplicate bean definition detected. " "[bean id=%s][bean class=%s][bean_config_file=%s]", beanId.c_str(), beanNode->_class.c_str(), beanConfigFile.c_str()); } } } CAF_CM_LOG_DEBUG_VA2( "Bean configuration file defined %d beans. " "[file=%s]", beanCollection.size(), beanConfigFile.c_str()); }