InitializeDataStoreManager.cpp

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 
00003 #include <fesa-core/DataStore/InitializeDataStoreManager.h>
00004 
00005 #include <fesa-core/Core/AbstractEquipment.h>
00006 #include <fesa-core/Utilities/XMLParser.h>
00007 #include <fesa-core/Utilities/ParserElements.h>
00008 #include <fesa-core/Utilities/StringUtilities.h>
00009 #include <fesa-core/Exception/FesaException.h>
00010 #include <fesa-core/DataStore/GlobalDevice.h>
00011 #include <fesa-core/DataStore/AbstractDevice.h>
00012 #include <fesa-core/DataStore/DomainStore.h>
00013 #include <fesa-core/DataStore/AbstractField.h>
00014 #include <fesa-core/Utilities/ParserElements/ParserElementDefs.h>
00015 #include <cmw-log/Logger.h>
00016 
00017 namespace
00018 {
00019 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.DataStore");
00020 }
00021 
00022 
00023 namespace fesa
00024 {
00025 
00026 InitializeDataStoreManager::InitializeDataStoreManager(const std::string className) :
00027     globalDeviceElement_(NULL)
00028 
00029 {
00030     className_ = className;
00031     std::string instanceFile = AbstractEquipment::getInstance()->getDeviceDataFileName();
00032     parser_ = new XMLParser(instanceFile, true);
00033     if(logger.isLoggable(CMW::Log::Level::LL_DEBUG))
00034     {
00035         std::ostringstream msg;
00036         msg << "Initialising DataStore for class " << className;
00037         LOG_DEBUG_IF(logger, msg.str());
00038     }
00039 }
00040 
00041 InitializeDataStoreManager::~InitializeDataStoreManager()
00042 {
00043     if (globalDeviceElement_)
00044         delete globalDeviceElement_;
00045 
00046     for (uint32_t i = 0; i < pDeviceElementCol_.size(); i++)
00047         delete pDeviceElementCol_[i];
00048     pDeviceElementCol_.clear();
00049 
00050     for (uint32_t i = 0; i < pDomainStoreElementCol_.size(); i++)
00051         delete pDomainStoreElementCol_[i];
00052 
00053     pDomainStoreElementCol_.clear();
00054     delete parser_;
00055 }
00056 
00057 GlobalDeviceElement& InitializeDataStoreManager::retrieveGlobalDeviceElement()
00058 {
00059     if (globalDeviceElement_ != NULL)
00060     {
00061         return *globalDeviceElement_;
00062     }
00063     AttributeXML* pAttr = NULL;
00064     std::string fieldValue = "";
00065     std::string extraConditionName = "";
00066     std::string extraConditionValue = "";
00067 
00068     // restore global device
00069     pAttr = parser_->extractAttribute(GLOBAL_DEVICE_ELEMENT_TAG,GLOBAL_DEVICE_ELEMENT_ATTRIBUTE_TAG);
00070     if (pAttr == NULL)
00071     {
00072         throw FesaException(__FILE__, __LINE__, FesaErrorXMLAttributeNotFound.c_str(), GLOBAL_DEVICE_ELEMENT_TAG.c_str(),
00073                         GLOBAL_DEVICE_ELEMENT_ATTRIBUTE_TAG.c_str());
00074     }
00075     std::string name = pAttr->value_;
00076     delete pAttr;
00077 
00078     globalDeviceElement_ = new GlobalDeviceElement(name);
00079     std::string globalDeviceXPath = CLASSES_TAG + "/" + className_ + "/" + GLOBAL_DEVICE_ELEMENT_TAG;
00080     std::vector<ElementXML*>* pElCol = parser_->extractElementsFromXPath(globalDeviceXPath);
00081     if (pElCol == NULL)
00082     {
00083         throw FesaException(__FILE__, __LINE__, FesaErrorXMLElementNotFound.c_str(), globalDeviceXPath.c_str());
00084     }
00085     ElementXML* pGlobalEl = (*pElCol)[0];
00086     delete pElCol;
00087 
00088     // go through the fields
00089     for (uint32_t i = 0; i < pGlobalEl->childList_.size(); i++)
00090     {
00091 
00092         ElementXML* pFieldType = pGlobalEl->childList_[i];
00093         if (pFieldType->name_ != DEVICE_CONFIGURATION_ELEMEMT_TAG && pFieldType->name_ != DEVICE_SETTING_ELEMEMT_TAG && pFieldType->name_
00094             != "generic" && pFieldType->name_  != DEVICE_ACQUISITION_ELEMEMT_TAG)
00095         {
00096             throw FesaException(__FILE__, __LINE__, FesaErrorLoadGlobalDeviceElement.c_str());
00097         }
00098         if (pFieldType->childList_.size() == 0)
00099         {
00100             throw FesaException(__FILE__, __LINE__, FesaErrorLoadGlobalDeviceElement.c_str());
00101         }
00102         for (uint32_t j = 0; j < pFieldType->childList_.size(); j++)
00103         {
00104             ElementXML* pField = pFieldType->childList_[j];
00105             FieldElement* pFieldElement = new FieldElement(pField->name_);
00106             pFieldElement->fromPersistency_ = false;
00107             this->fillElement(pField, pFieldElement);
00108             globalDeviceElement_->addFieldElement(pFieldElement);
00109         }
00110     }
00111     return *globalDeviceElement_;
00112 }
00113 
00114 const std::vector<DeviceElement*>& InitializeDataStoreManager::retrieveDeviceElements()
00115 {
00116     // remove previous devices if any
00117     for (uint32_t i = 0; i < pDeviceElementCol_.size(); i++)
00118     {
00119         delete pDeviceElementCol_[i];
00120     }
00121     pDeviceElementCol_.clear();
00122 
00123     std::vector<ElementXML*>* pElCol = NULL;
00124     std::string extraConditionName = "";
00125     std::string extraConditionValue = "";
00126 
00127     std::map<int32_t, std::string> mapCycle;
00128     std::string DeviceInstancesXPath = CLASSES_TAG + "/" + className_ + "/" + DEVICE_ELEMENT_TAG;
00129 
00130     pElCol = parser_->extractElementsFromXPath(DeviceInstancesXPath);
00131     if (pElCol == NULL)
00132     {
00133         LOG_ERROR_IF(logger, "No device-instance found!");
00134         throw FesaException(__FILE__, __LINE__, FesaErrorXMLElementNotFound.c_str(), DeviceInstancesXPath.c_str());
00135     }
00136 
00137     //Loop over all device-instance elements
00138     for (uint32_t i = 0; i < pElCol->size(); i++)
00139     {
00140         ElementXML* pDeviceEl = (*pElCol)[i];
00141         /*
00142          * Device instance field has attribute name
00143          * <device-instance name="PSBTestDevice">
00144          */
00145         if (pDeviceEl->attributeList_.size() == 0 || pDeviceEl->attributeList_[0]->name_ != DEVICE_ELEMENT_ATTRIBUTE_TAG)
00146         {
00147             LOG_DEBUG_IF(logger, "Mandatory attribute 'name' not found on device-instance element!");
00148             throw FesaException(__FILE__, __LINE__, FesaErrorLoadDeviceElements.c_str());
00149         }
00150         AttributeXML* pAttr = pDeviceEl->attributeList_[0];
00151 
00152         DeviceElement* pDeviceElement = new DeviceElement(pAttr->value_);
00153         pDeviceElementCol_.push_back(pDeviceElement);
00154 
00155         /*
00156          *<device-instance name="MyTestDevice">
00157          *    <configuration>
00158          *        <description value="It's a None PSB device"/>
00159          *        <accelerator value="ISO"/>
00160          *        <timingDomain value="PSB"/>
00161          *        <isMux value="false"/>
00162          *    </configuration>
00163          *   <setting>
00164          *        <amplitude value="20"/>
00165          *   </setting>
00166          *</device-instance>
00167          */        
00168         for (uint32_t i = 0; i < pDeviceEl->childList_.size(); i++)
00169         {
00170             ElementXML* pFieldType = pDeviceEl->childList_[i];
00171             if (logger.isLoggable(CMW::Log::Level::LL_TRACE))
00172             {
00173                 std::ostringstream msg;
00174                 msg << "Processing element " << pFieldType->name_ << " in device-instance " << pAttr->value_;
00175                 LOG_TRACE_IF(logger, msg.str());
00176             }
00177             if(pFieldType->name_ == EVENTS_MAPPING_ELEMENT_TAG)
00178             {
00179                 continue;//skip events-mapping element
00180             }
00181             if ( pFieldType->name_ != DEVICE_CONFIGURATION_ELEMEMT_TAG && pFieldType->name_ != DEVICE_SETTING_ELEMEMT_TAG && pFieldType->name_ != DEVICE_ACQUISITION_ELEMEMT_TAG )
00182             {
00183                 std::ostringstream msg;
00184                 msg << "Invalid field sub-part " << pFieldType->name_ << " for device-instance " << pAttr->value_;
00185                 LOG_ERROR_IF(logger, msg.str());
00186                 throw FesaException(__FILE__, __LINE__, FesaErrorLoadDeviceElements.c_str());
00187             }
00188             processDeviceFields(pFieldType->childList_, pDeviceElement);
00189         }
00190     }
00191     for (uint32_t i = 0; i < pElCol->size(); i++)
00192     {
00193         delete (*pElCol)[i];
00194     }
00195     delete pElCol;
00196     return pDeviceElementCol_;
00197 }
00198 
00199 void InitializeDataStoreManager::processDeviceFields(const std::vector<ElementXML*>& fields, DeviceElement* pDeviceElement)
00200 {
00201     if (fields.size() == 0)
00202     {
00203         LOG_ERROR_IF(logger, "processDeviceFields: fields vector can't be empty");
00204         throw FesaException(__FILE__, __LINE__, FesaErrorLoadDeviceElements.c_str());
00205     }
00206     for (uint32_t j = 0; j < fields.size(); j++)
00207     {
00208         ElementXML* pField = fields[j];
00209         FieldElement* pFieldElement = new FieldElement(pField->name_);
00210         pFieldElement->fromPersistency_ = false;
00211 
00212         // Checking if the ElementXML is a device-related field, in that case it does not have attributes
00213         // For device-related fields the fieldValue is the concatenation of device names
00214         if( pField->name_ == DEVICE_RELATIONS_TAG )
00215         {
00216             processDeviceRelationField(pField, pFieldElement);
00217         }
00218         else if( pField->name_ == EXTRA_MUX_TAG )
00219         {
00220             processExtraMuxField(pField, pDeviceElement);
00221         }
00222         else
00223         {
00224             fillElement(pField, pFieldElement);
00225         }
00226         pDeviceElement->addFieldElement(pFieldElement);
00227     }
00228 }
00229 
00230 void InitializeDataStoreManager::processDeviceRelationField(const ElementXML* pField, FieldElement* pFieldElement)
00231 {
00232     std::string fieldValue = "{";
00233     std::vector<ElementXML*> parameters = pField->childList_;
00234     // the field is a vector
00235     pFieldElement->dimension1_ = static_cast<uint32_t>(parameters.size());
00236     for (uint32_t k = 0; k < parameters.size(); k++)
00237     {
00238         // go through the attributes
00239         for (uint32_t m = 0; m < parameters[k]->attributeList_.size(); m++)
00240         {
00241             AttributeXML* pAttr = parameters[k]->attributeList_[m];
00242             fieldValue = fieldValue + pAttr->name_ + "=" + pAttr->value_ + " ";
00243         }
00244         if (k != parameters.size() - 1)
00245         {
00246             fieldValue += ",";
00247         }
00248     }
00249     fieldValue += "}";
00250     pFieldElement->fieldValuesCol_.insert(make_pair(0, fieldValue));
00251 }
00252 
00253 void InitializeDataStoreManager::processExtraMuxField(const ElementXML* pField, DeviceElement* pDeviceElement)
00254 {
00255     std::vector<ElementXML*> criteria = pField->childList_;
00256     // go through the different elements storing the extra criterion
00257     for (uint32_t k = 0; k < criteria.size(); k++)
00258     {
00259         // go through the attributes
00260         for (uint32_t m = 0; m < criteria[k]->attributeList_.size(); m++)
00261         {
00262             AttributeXML* pAttr = criteria[k]->attributeList_[m];
00263             if (pAttr->name_.compare("value"))
00264             {
00265                 pDeviceElement->extraCriterionCol_.push_back(pAttr->value_);
00266             }
00267         }
00268     }
00269 }
00270 
00271 void InitializeDataStoreManager::fillElement(const ElementXML* pField, FieldElement* pFieldElement)
00272 {
00273     std::string fieldValue = getFieldValue(pField);
00274     if (!fieldValue.empty())
00275     {
00276         pFieldElement->fieldValuesCol_.insert(make_pair(0, fieldValue));
00277     }
00278     for (uint32_t ext = 0; ext < pField->childList_.size(); ext++)
00279     {
00280         ElementXML* child = pField->childList_[ext];
00281         if (child->name_ == DIM_TAG || child->name_ == DIM1_TAG)
00282         {
00283             pFieldElement->dimension1_ = getAttributeValueAsInt(child);
00284         }
00285         else if (child->name_ == DIM2_TAG)
00286         {
00287             pFieldElement->dimension2_ = getAttributeValueAsInt(child);
00288         }
00289     }
00290     if (logger.isLoggable(CMW::Log::Level::LL_TRACE))
00291     {
00292         std::ostringstream msg;
00293         msg << "Element " << pField->name_ << " has value " << fieldValue;
00294         msg << ", dim(" << pFieldElement->dimension1_ << ", " << pFieldElement->dimension2_ << ").";
00295         LOG_TRACE_IF(logger, msg.str());
00296     }
00297 }
00298 
00299 std::string InitializeDataStoreManager::getFieldValue(const ElementXML* pField)
00300 {
00301     std::string value = getAttributeValue(pField); // most of the fields directly have a value attribute
00302     if(value.empty())
00303     {   // Others have an element "value"
00304         std::vector<ElementXML*>::const_iterator iter = pField->childList_.begin();
00305         for(;iter!=pField->childList_.end();++iter)
00306         {
00307             if((*iter)->name_ == "value")
00308             {
00309                 value = (*iter)->value_;
00310             }
00311         }
00312     }
00313     return value;
00314 }
00315 
00316 std::string InitializeDataStoreManager::getAttributeValue(const ElementXML* element)
00317 {
00318     AttributeXML* pAttr;
00319     for (uint32_t extIdx = 0; extIdx < element->attributeList_.size(); extIdx++)
00320     {   // looking for the value attribute in the element
00321         pAttr = element->attributeList_[extIdx];
00322         if (pAttr->name_ == VALUE_TAG)
00323         {
00324             return pAttr->value_;
00325         }
00326     }
00327     return std::string("");
00328 }
00329 
00330 uint32_t InitializeDataStoreManager::getAttributeValueAsInt(const ElementXML* element)
00331 {
00332     std::string value = getAttributeValue(element);
00333     if (!value.empty())
00334     {
00335         uint32_t dim;
00336         StringUtilities::fromString(dim, value);
00337         return dim;
00338     }
00339     return 0;
00340 }
00341 
00342 const std::vector<DomainStoreElement*>& InitializeDataStoreManager::retrieveDomainStoreElements()
00343 {
00344     // remove previous devices if any
00345     for (uint32_t i = 0; i < pDomainStoreElementCol_.size(); i++)
00346         delete pDomainStoreElementCol_[i];
00347     pDomainStoreElementCol_.clear();
00348 
00349     std::vector<ElementXML*>* pElCol = NULL;
00350     AttributeXML* pAttr = NULL;
00351     std::string fieldValue = "";
00352     std::string extraConditionName = "";
00353     std::string extraConditionValue = "";
00354     std::map<int32_t, std::string> map;
00355 
00356     std::string DomainStoreXPath = CLASSES_TAG + "/" + className_ + "/" + DOMAIN_STORE_TAG;
00357     pElCol = parser_->extractElementsFromXPath(DomainStoreXPath);
00358 
00359     if(pElCol != NULL) // since DomainStore is optional
00360     {
00361         //Loop over all device fields in vector pElCol
00362         for (uint32_t i = 0; i < pElCol->size(); i++)
00363         {
00364             ElementXML* pDomainEl = (*pElCol)[i];
00365 
00366             if( pDomainEl->attributeList_.size() == 0 || pDomainEl->attributeList_[0]->name_ != DOMAIN_STORE_ATTRIBUTE_TAG )
00367             {
00368                 throw FesaException(__FILE__, __LINE__, FesaErrorLoadDomainStoreElements.c_str());
00369             }
00370             pAttr = pDomainEl->attributeList_[0];
00371 
00372             DomainStoreElement* pDomainStoreElement = new DomainStoreElement(pAttr->value_);
00373             pDomainStoreElementCol_.push_back(pDomainStoreElement);
00374             /*
00375              *<domain-data name="PSB">
00376              *    <const>
00377              *        <description value="It's a None PSB device"/>
00378              *        <accelerator value="ISO"/>
00379              *        <timingDomain value="PSB"/>
00380              *        <isMux value="false"/>
00381              *    </const>
00382              *   <persistent>
00383              *        <amplitude value="20">
00384              *            <extra-criterion name="PSB.PARTY.PROT" value="30"/>
00385              *            <extra-criterion name="PSB.DEST.DUMP" value="40"/>
00386              *            <extra-criterion name="PSB.DEST.PS" value="50"/>
00387              *        </amplitude>
00388              *    </persistent>
00389              *    <volatile>
00390              *        <offset value="-13"/>
00391              *    </volatile>
00392              *</domain-data>
00393              */
00394             //The children of the device instance tag are <configuration>, <setting> or <generic>
00395             for (uint32_t i = 0; i < pDomainEl->childList_.size(); i++)
00396             {
00397                 ElementXML* pFieldType = pDomainEl->childList_[i];
00398                 if (pFieldType->name_ != DEVICE_CONFIGURATION_ELEMEMT_TAG && pFieldType->name_ != DEVICE_SETTING_ELEMEMT_TAG && pFieldType->name_ != GENERIC_TAG )
00399                 {
00400                     throw FesaException(__FILE__, __LINE__, FesaErrorLoadDomainStoreElements.c_str());
00401                 }
00402                 if (pFieldType->childList_.size() > 0)
00403                 {
00404                     throw FesaException(__FILE__, __LINE__, FesaErrorLoadDomainStoreElements.c_str());
00405                 }
00406                 for (uint32_t j = 0; j < pFieldType->childList_.size(); j++)
00407                 {
00408                     ElementXML* pField = pFieldType->childList_[j];
00409 
00410                     FieldElement* pFieldElement = new FieldElement(pField->name_);
00411                     pFieldElement->fromPersistency_ = false;
00412                     this->fillElement(pField, pFieldElement);
00413 
00414                     pDomainStoreElement->addFieldElement(pFieldElement);
00415                 }
00416             }
00417 
00418             for (uint32_t i = 0; i < pElCol->size(); i++)
00419             {
00420                 delete (*pElCol)[i];
00421             }
00422             delete pElCol;
00423         }
00424     }
00425     return pDomainStoreElementCol_;
00426 }
00427 
00428 int32_t InitializeDataStoreManager::getRollingManagerDepth()
00429 {
00430     std::vector<ElementXML*>* pElCol;
00431     std::vector<ElementXML*>::iterator pElColIter;
00432     std::vector<AttributeXML*>::iterator AttrIter;
00433 
00434     std::string RollingMuxManagerXPath = CLASSES_TAG + "/" + className_ + "/" + MUX_ROLLING_TAG;
00435     pElCol = parser_->extractElementsFromXPath(RollingMuxManagerXPath);
00436 
00437     int32_t depth = -1;
00438 
00439     if (pElCol == NULL)
00440     {
00441         return ROLLING_DEFAULT_SIZE;
00442     }
00443 
00444     for (pElColIter = pElCol->begin(); pElColIter != pElCol->end(); pElColIter++)
00445     {
00446         for (AttrIter = (*pElColIter)->attributeList_.begin(); AttrIter != (*pElColIter)->attributeList_.end(); AttrIter++)
00447         {
00448             if ( (*AttrIter)->name_ == MUX_DEPTH_TAG )
00449             {
00450                 depth = atoi((*AttrIter)->value_.c_str());
00451             }
00452         }
00453     }
00454 
00455     for (uint32_t i = 0; i < pElCol->size(); i++)
00456     {
00457         delete (*pElCol)[i];
00458     }
00459     delete pElCol;
00460 
00461     if (depth == -1)
00462     {
00463         throw FesaException(__FILE__, __LINE__, FesaErrorXMLElementNotFound.c_str(), MUX_ROLLING_TAG.c_str());
00464     }
00465 
00466     return depth;
00467 }
00468 } // fesa

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1