00001
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
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
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
00140 parser.startElement(GLOBAL_DEVICE_TAG);
00141 parser.writeAttribute("name", pu.getGlobalDevice().getName());
00142 parser.writeNewline();
00143
00144
00145
00146 storeFields(parser, pu.getGlobalDevice().getPersistentFieldsCollection(), GLOBAL_DEVICE_TAG);
00147
00148 parser.endElement();
00149 parser.writeNewline();
00150
00151
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
00161 storeFields(parser, (*dev)->getPersistentFieldsCollection(), DEVICE_INSTANCE_TAG);
00162 parser.endElement();
00163 parser.writeNewline();
00164 }
00165
00166
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
00175 storeFields(parser, (*domain)->getPersistentFieldsCollection(), DOMAIN_STORE_TAG);
00176 parser.endElement();
00177 parser.writeNewline();
00178
00179 }
00180 parser.endElement();
00181 parser.endDocument();
00182 }
00183
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
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 (*itFields)->store(*fieldElement);
00222
00223 parser.startElement(fieldName);
00224 parser.writeNewline();
00225
00226
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
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
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
00261 parser.endElement();
00262 parser.writeNewline();
00263 }
00264
00265
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
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
00336 for (uint32_t i = 0; i < pElCol->size(); i++)
00337 {
00338 ElementXML* pDeviceEl = (*pElCol)[i];
00339
00340
00341
00342
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
00379 pElCol = parser.extractElements(DOMAIN_STORE_TAG);
00380
00381 if (!pElCol)
00382 {
00383 return NULL;
00384 }
00385
00386
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
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
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
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
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
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 }