StoreManager.cpp

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 
00003 #include <fesa-core/Persistency/StoreManager.h>
00004 
00005 #include <fesa-core/Persistency/PersistencyUnit.h>
00006 #include <fesa-core/DataStore/GlobalDevice.h>
00007 #include <fesa-core/DataStore/DomainStore.h>
00008 #include <fesa-core/DataStore/AbstractDevice.h>
00009 #include <fesa-core/DataStore/AbstractField.h>
00010 #include <fesa-core/Core/AbstractEquipment.h>
00011 #include <fesa-core/Utilities/XMLParser.h>
00012 #include <fesa-core/Exception/FesaException.h>
00013 
00014 
00015 namespace fesa
00016 {
00017 
00018 const std::string StoreManager::GLOBAL_DEVICE_TAG = "global-instance";
00019 const std::string StoreManager::DEVICE_INSTANCE_TAG = "device-instance";
00020 const std::string StoreManager::DOMAIN_STORE_TAG = "domain-data";
00021 
00022 StoreManager::StoreManager()
00023 {
00024 }
00025 
00026 StoreManager::~StoreManager()
00027 {
00028 }
00029 
00030 void StoreManager::restore(GlobalDevice& globalDevice, std::vector<AbstractDevice*>& deviceCol,
00031                            std::vector<DomainStore*>& domainStoreCol, const std::string& className)
00032 {
00033     std::string persistencyFile = AbstractEquipment::getInstance()->getPersistencyFileName(className);
00034     XMLParser parser(persistencyFile, true);
00035 
00036     try
00037     {
00038         // Get the list of fields of the GlobalDevice
00039         GlobalDeviceElement* globalDeviceElement = retrieveGlobalDeviceElement(parser);
00040 
00041         globalDevice.restoreFromElement(*globalDeviceElement);
00042         delete globalDeviceElement;
00043     }
00044     catch (FesaException& ex)
00045     {
00046         throw FesaException(ex.getFileName(), ex.getLineNumber(), FesaErrorRestoringGlobalDevice.c_str());
00047     }
00048 
00049     std::vector<DeviceElement*>* pDeviceElementCol = retrieveDeviceElements(parser);
00050 
00051     try
00052     {
00053         for (uint32_t iDevEl = 0; iDevEl < pDeviceElementCol->size(); iDevEl++)
00054         {
00055             for (uint32_t iDev = 0; iDev < deviceCol.size(); iDev++)
00056             {
00057                 if ((*pDeviceElementCol)[iDevEl]->getName() == deviceCol[iDev]->name.get())
00058                 {
00059 
00060                     deviceCol[iDev]->restoreFromElement(*((*pDeviceElementCol)[iDevEl]));
00061                     delete (*pDeviceElementCol)[iDevEl];
00062                     break;
00063                 }
00064             }
00065         }
00066         delete pDeviceElementCol;
00067     }
00068     catch (FesaException& ex)
00069     {
00070         throw FesaException(ex.getFileName(), ex.getLineNumber(), FesaErrorRestoringDevices.c_str());
00071     }
00072 
00073     std::vector<DomainStoreElement*>* pDomainStoreElementCol = retrieveDomainStoreElements(parser);
00074 
00075     try
00076     {
00077         if (pDomainStoreElementCol)
00078         {
00079             for (uint32_t iDomEl = 0; iDomEl < pDomainStoreElementCol->size(); iDomEl++)
00080             {
00081                 for (uint32_t iDom = 0; iDom < domainStoreCol.size(); iDom++)
00082                 {
00083                     if ((*pDomainStoreElementCol)[iDomEl]->getName() == domainStoreCol[iDom]->name.get())
00084                     {
00085                         const std::vector<AbstractField*>& pFieldCol = domainStoreCol[iDom]->getFieldCollection();
00086                         for (uint32_t fieldIdx = 0; fieldIdx < pFieldCol.size(); fieldIdx++)
00087                         {
00088                             if (pFieldCol[fieldIdx]->isPersistent())
00089                             {
00090                                 FieldElement* fieldElement = (*pDomainStoreElementCol)[iDomEl]->getFieldElement(
00091                                     pFieldCol[fieldIdx]->getName());
00092                                 if (fieldElement != NULL)
00093                                 {
00094                                     pFieldCol[fieldIdx]->restore(*fieldElement);
00095                                 }
00096                                 else
00097                                 {
00098                                     throw FesaException(__FILE__, __LINE__,
00099                                                         FesaErrorDataStoreElementRetrievingFieldElement.c_str(),
00100                                                         pFieldCol[fieldIdx]->getName().c_str());
00101                                 }
00102                             }
00103                         }
00104 
00105                         break;
00106                     }
00107                     delete (*pDomainStoreElementCol)[iDomEl];
00108                 }
00109                 delete pDomainStoreElementCol;
00110             }
00111         }
00112     }
00113     catch (FesaException& ex)
00114     {
00115         throw FesaException(ex.getFileName(), ex.getLineNumber(), FesaErrorRestoringDomainStores.c_str());
00116     }
00117 }
00118 
00119 void StoreManager::store(PersistencyUnit& pu)
00120 {
00121     // Store we use a tmp file and at the end we rename it
00122     std::string tmpFileName = pu.getPersistencyFileName() + ".tmp";
00123     {
00124         XMLParser parser(tmpFileName, false);
00125 
00126         parser.createFile();
00127         parser.startDocument();
00128         parser.startElement("persistency-unit");
00129         parser.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
00130         parser.writeAttribute("xsi:noNamespaceSchemaLocation", "");
00131         parser.writeAttribute("class", pu.getGlobalDevice().className.getAsString());
00132         parser.writeAttribute("version", pu.getGlobalDevice().version.getAsString());
00133         parser.writeNewline();
00134         parser.startElement("FEC-name");
00135         parser.writeAttribute("value", pu.getGlobalDevice().fecName.getAsString());
00136         parser.endElement();
00137         parser.writeNewline();
00138 
00139         // store the global device
00140         parser.startElement(GLOBAL_DEVICE_TAG);
00141         parser.writeAttribute("name", pu.getGlobalDevice().getName());
00142         parser.writeNewline();
00143 
00144         // retrieve all fields
00145 
00146         storeFields(parser, pu.getGlobalDevice().getPersistentFieldsCollection(), GLOBAL_DEVICE_TAG);
00147 
00148         parser.endElement();
00149         parser.writeNewline();
00150 
00151         // loop over all devices in vector
00152         for (std::vector<AbstractDevice*>::const_iterator dev = pu.getDeviceCollection().begin(); dev
00153                  != pu.getDeviceCollection().end(); dev++)
00154         {
00155             parser.writeNewline();
00156             parser.startElement(DEVICE_INSTANCE_TAG);
00157             parser.writeAttribute("name", (*dev)->getName());
00158             parser.writeNewline();
00159 
00160             // store settings
00161             storeFields(parser, (*dev)->getPersistentFieldsCollection(), DEVICE_INSTANCE_TAG);
00162             parser.endElement();
00163             parser.writeNewline();
00164         }
00165 
00166         // loop over all domains in vector
00167         for (std::vector<DomainStore*>::const_iterator domain = pu.getDomainStoreCollection().begin(); domain
00168                  != pu.getDomainStoreCollection().end(); domain++)
00169         {
00170             parser.writeNewline();
00171             parser.startElement(DOMAIN_STORE_TAG);
00172             parser.writeAttribute("name", (*domain)->getName());
00173             parser.writeNewline();
00174             // store fields
00175             storeFields(parser, (*domain)->getPersistentFieldsCollection(), DOMAIN_STORE_TAG);
00176             parser.endElement();
00177             parser.writeNewline();
00178 
00179         }
00180         parser.endElement();
00181         parser.endDocument();
00182     }
00183     //parser has been deleted, therefroe we can safely rename the temp file
00184     rename(tmpFileName.c_str(), pu.getPersistencyFileName().c_str());
00185 }
00186 
00187 void StoreManager::storeFields(XMLParser& parser, const std::vector<AbstractField*>& fields, std::string dataStore)
00188 {
00189     std::string fieldName;
00190     std::string criterion;
00191     std::string fieldValue;
00192     std::string cycleName;
00193     std::string cycleId;
00194 
00195     FieldElement* fieldElement = new FieldElement("");
00196 
00197     for (std::vector<AbstractField*>::const_iterator itFields = fields.begin(); itFields != fields.end(); ++itFields)
00198     {
00199 
00200         if (!(*itFields)->isPersistent())
00201             continue;
00202 
00203         fieldName = (*itFields)->getName();
00204 
00205         /*
00206          * <amplitude>
00207          <cycle id="1" name="AD" value="20">
00208          <extra-criterion name="PSB.PARTY.PROT" value="30"/>
00209          <extra-criterion name="PSB.DEST.DUMP" value="40"/>
00210          <extra-criterion name="PSB.DEST.PS" value="50"/>
00211          </cycle>
00212          <cycle id="2" name="NORMGPS" value="20">
00213          <extra-criterion name="PSB.PARTY.PROT" value="35"/>
00214          <extra-criterion name="PSB.DEST.DUMP" value="45"/>
00215          <extra-criterion name="PSB.DEST.PS" value="55"/>
00216          </cycle>
00217 
00218          </amplitude>
00219         */
00220 
00221         (*itFields)->store(*fieldElement);
00222 
00223         parser.startElement(fieldName);
00224         parser.writeNewline();
00225 
00226         // go through each cycle
00227         for (std::map<int32_t, std::string>::iterator cycle = fieldElement->cyclesNamesCol_.begin(); cycle
00228                  != fieldElement->cyclesNamesCol_.end(); cycle++)
00229         {
00230 
00231             cycleName = cycle->second;
00232             cycleId = StringUtilities::toString(cycle->first);
00233 
00234             parser.startElement("cycle");
00235             parser.writeAttribute("id", cycleId);
00236             parser.writeAttribute("name", cycleName);
00237             int32_t cycleIdTmp;
00238             Converter<int32_t>::stringToValue(cycleId, &cycleIdTmp);
00239             // retrieve the value
00240             std::map<int32_t, std::string>::iterator iterValue = fieldElement->fieldValuesCol_.find(cycleIdTmp);
00241             parser.writeAttribute("value", iterValue->second);
00242 
00243             parser.writeNewline();
00244 
00245             // go through each extra condition value
00246             std::map<std::string, std::string> extraConditions =
00247                 fieldElement->fieldExtraValuesCol_.find(cycleIdTmp)->second;
00248 
00249             for (std::map<std::string, std::string>::iterator extraCondition = extraConditions.begin(); extraCondition
00250                      != extraConditions.end(); extraCondition++)
00251             {
00252 
00253                 parser.startElement("extra-criterion");
00254                 parser.writeAttribute("name", extraCondition->first);
00255                 parser.writeAttribute("name", extraCondition->second);
00256                 parser.endElement();
00257                 parser.writeNewline();
00258             }
00259 
00260             // end cycle
00261             parser.endElement();
00262             parser.writeNewline();
00263         }
00264 
00265         // end fieldname
00266         parser.endElement();
00267         parser.writeNewline();
00268 
00269     }
00270 
00271     delete fieldElement;
00272 }
00273 
00274 GlobalDeviceElement* StoreManager::retrieveGlobalDeviceElement(XMLParser& parser)
00275 {
00276 
00277     GlobalDeviceElement* globalDevice = NULL;
00278 
00279     std::vector<ElementXML*>* pElCol = NULL;
00280     AttributeXML* pAttr = NULL;
00281     std::string fieldValue = "";
00282     std::string extraConditionName = "";
00283     std::string extraConditionValue = "";
00284 
00285     std::map<int32_t, std::string> mapCycle;
00286     std::map<int32_t, std::string> mapExtraCondition;
00287 
00288     // restore global device
00289 
00290     pAttr = parser.extractAttribute(GLOBAL_DEVICE_TAG, "name");
00291     if (!pAttr)
00292     {
00293         return NULL;
00294     }
00295 
00296     globalDevice = new GlobalDeviceElement(pAttr->value_);
00297 
00298     pElCol = parser.extractElements(GLOBAL_DEVICE_TAG);
00299 
00300     if (!pElCol)
00301         return NULL;
00302 
00303     ElementXML* pGlobalEl = (*pElCol)[0];
00304 
00305     this->fillElements(pGlobalEl, globalDevice);
00306 
00307     for (uint32_t i = 0; i < pElCol->size(); i++)
00308     {
00309         delete (*pElCol)[i];
00310     }
00311     delete pElCol;
00312     return globalDevice;
00313 }
00314 
00315 std::vector<DeviceElement*>* StoreManager::retrieveDeviceElements(XMLParser& parser)
00316 {
00317 
00318     std::vector<ElementXML*>* pElCol = NULL;
00319     AttributeXML* pAttr = NULL;
00320     std::string fieldValue = "";
00321     std::string extraConditionName = "";
00322     std::string extraConditionValue = "";
00323 
00324     std::map<int32_t, std::string> mapCycle;
00325     std::vector<std::map<int32_t, std::string> > vMapsExtraCondition;
00326     std::vector<std::string> vNamesExtraCondition;
00327 
00328     std::vector<DeviceElement*>* pDeviceElementCol = new std::vector<DeviceElement*>();
00329 
00330     pElCol = parser.extractElements(DEVICE_INSTANCE_TAG);
00331 
00332     if (!pElCol)
00333         return NULL;
00334 
00335     //Loop over all device fields in vector pElCol
00336     for (uint32_t i = 0; i < pElCol->size(); i++)
00337     {
00338         ElementXML* pDeviceEl = (*pElCol)[i];
00339 
00340         /*
00341          * Device instance field has attribute name
00342          * <device-instance name="PSBTestDevice">
00343          *
00344          */
00345         if (pDeviceEl->attributeList_.size() == 0 || pDeviceEl->attributeList_[0]->name_ != "name")
00346         {
00347             throw FesaException(__FILE__, __LINE__, FesaErrorLoadDeviceElements.c_str());
00348         }
00349         pAttr = pDeviceEl->attributeList_[0];
00350 
00351         DeviceElement* pDeviceElement = new DeviceElement(pAttr->value_);
00352         pDeviceElementCol->push_back(pDeviceElement);
00353 
00354         this->fillElements(pDeviceEl, pDeviceElement);
00355 
00356     }
00357 
00358     for (uint32_t i = 0; i < pElCol->size(); i++)
00359     {
00360         delete (*pElCol)[i];
00361     }
00362     delete pElCol;
00363 
00364     return pDeviceElementCol;
00365 }
00366 
00367 std::vector<DomainStoreElement*>* StoreManager::retrieveDomainStoreElements(XMLParser& parser)
00368 {
00369 
00370     std::vector<ElementXML*>* pElCol = NULL;
00371     AttributeXML* pAttr = NULL;
00372     std::string fieldValue = "";
00373     std::string extraConditionName = "";
00374     std::string extraConditionValue = "";
00375 
00376     std::vector<DomainStoreElement*>* pDomainStoreElementCol = new std::vector<DomainStoreElement*>();
00377 
00378     // since DomainStore is optional the extraction is done with mandatoryElement = false
00379     pElCol = parser.extractElements(DOMAIN_STORE_TAG);
00380 
00381     if (!pElCol)
00382     {
00383         return NULL;
00384     }
00385 
00386     //Loop over all device fields in vector pElCol
00387     for (uint32_t i = 0; i < pElCol->size(); i++)
00388     {
00389         ElementXML* pDomainEl = (*pElCol)[i];
00390 
00391         if (pDomainEl->attributeList_.size() == 0 || pDomainEl->attributeList_[0]->name_ != "name")
00392         {
00393             throw FesaException(__FILE__, __LINE__, FesaErrorLoadDomainStoreElements.c_str());
00394         }
00395 
00396         DomainStoreElement* pDomainStoreElement = new DomainStoreElement(pAttr->value_);
00397         pDomainStoreElementCol->push_back(pDomainStoreElement);
00398         this->fillElements(pDomainEl, pDomainStoreElement);
00399 
00400     }
00401 
00402     for (uint32_t i = 0; i < pElCol->size(); i++)
00403     {
00404         delete (*pElCol)[i];
00405     }
00406     delete pElCol;
00407 
00408     return pDomainStoreElementCol;
00409 }
00410 
00411 void StoreManager::fillElements(ElementXML* dataStoreXML, DataStoreElement* dataStoreElement)
00412 {
00413 
00414     AttributeXML* pAttr = NULL;
00415     int32_t cycleId = -1;
00416     std::string cycleName;
00417     std::string fieldValue;
00418     std::map<std::string, std::string> map;
00419 
00420     // format of each field
00421     /*
00422      * <amplitude>
00423      <cycle id="56" name="AD" value="20">
00424      <extra-criterion name="PSB.PARTY.PROT" value="30"/>
00425      <extra-criterion name="PSB.DEST.DUMP" value="40"/>
00426      <extra-criterion name="PSB.DEST.PS" value="50"/>
00427      </cycle>
00428      <cycle id="22" name="NORMGPS" value="20">
00429      <extra-criterion name="PSB.PARTY.PROT" value="35"/>
00430      <extra-criterion name="PSB.DEST.DUMP" value="45"/>
00431      <extra-criterion name="PSB.DEST.PS" value="55"/>
00432      </cycle>
00433 
00434      </amplitude>
00435     */
00436 
00437     // go through the fields
00438     for (uint32_t i = 0; i < dataStoreXML->childList_.size(); i++)
00439     {
00440 
00441         ElementXML* pField = dataStoreXML->childList_[i];
00442         FieldElement* pFieldElement = new FieldElement(pField->name_);
00443 
00444         pFieldElement->fromPersistency_ = true;
00445 
00446         // for each cycle
00447         for (uint32_t j = 0; j < pField->childList_.size(); j++)
00448         {
00449 
00450             ElementXML* pCycle = pField->childList_[j];
00451 
00452             fieldValue = "";
00453             for (uint32_t idx = 0; idx < pCycle->attributeList_.size(); idx++)
00454             {
00455                 pAttr = pCycle->attributeList_[idx];
00456                 if (pAttr->name_ == "id")
00457                 {
00458                     Converter<int32_t>::stringToValue(pAttr->value_, &cycleId);
00459                 }
00460                 else if (pAttr->name_ == "name")
00461                 {
00462                     cycleName = pAttr->value_;
00463                 }
00464                 else if (pAttr->name_ == "value")
00465                 {
00466                     fieldValue = pAttr->value_;
00467                 }
00468 
00469                 else if (pAttr->name_.at(0) == 'b')
00470                 {
00471                     fieldValue = fieldValue + " " + pAttr->name_ + "=\"" + pAttr->value_ + "\"";
00472                 }
00473             }
00474 
00475             pFieldElement->cyclesNamesCol_.insert(make_pair(cycleId, cycleName));
00476             pFieldElement->fieldValuesCol_.insert(make_pair(cycleId, fieldValue));
00477 
00478             // for each extra condition
00479             for (uint32_t ext = 0; ext < pCycle->childList_.size(); ext++)
00480             {
00481 
00482                 std::string extraConditionName = "";
00483                 std::string extraConditionValue = "";
00484 
00485                 ElementXML* pExtraCondition = pCycle->childList_[ext];
00486                 if (pExtraCondition->attributeList_.size() == 0)
00487                 {
00488                     throw FesaException(__FILE__, __LINE__, FesaErrorLoadGlobalDeviceElement.c_str());
00489                 }
00490 
00491                 for (uint32_t extIdx = 0; extIdx < pExtraCondition->attributeList_.size(); extIdx++)
00492                 {
00493                     pAttr = pExtraCondition->attributeList_[extIdx];
00494                     if (pAttr->name_ == "name")
00495                     {
00496                         extraConditionName = pAttr->value_;
00497                     }
00498                     else if (pAttr->name_ == "value")
00499                     {
00500                         extraConditionValue = pAttr->value_;
00501                     }
00502                     // TODO change this according to the new format. Take a look at the initialization store manager
00503                     else if (pAttr->name_.at(0) == 'b')
00504                     {
00505                         extraConditionValue = extraConditionValue + " " + pAttr->name_ + "=\"" + pAttr->value_
00506                             + "\"";
00507                     }
00508                 }
00509                 if (extraConditionName == "" || extraConditionValue == "")
00510                 {
00511                     throw FesaException(__FILE__, __LINE__, FesaErrorLoadGlobalDeviceElement.c_str());
00512                 }
00513 
00514                 map.insert(make_pair(extraConditionName, extraConditionValue));
00515 
00516             }
00517 
00518             pFieldElement->fieldExtraValuesCol_.insert(make_pair(cycleId, map));
00519 
00520         }
00521         dataStoreElement->addFieldElement(pFieldElement);
00522 
00523     }
00524 }
00525 
00526 } // fesa

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1