NotificationIDManager.cpp

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 
00003 #include <fesa-core/Core/NotificationIDManager.h>
00004 
00005 #include <fesa-core/Core/AbstractEquipment.h>
00006 #include <fesa-core/Core/NotificationID.h>
00007 #include <fesa-core/DataStore/EquipmentData.h>
00008 #include <fesa-core/Utilities/XMLParser.h>
00009 #include <fesa-core/Utilities/StringUtilities.h>
00010 #include <fesa-core/Exception/FesaException.h>
00011 #include <fesa-core/Diagnostic/Diagnostics.h>
00012 
00013 #include <cmw-log/Logger.h>
00014 
00015 
00016 namespace
00017 {
00018 
00019 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.Core.NotificationIDManager");
00020 const std::string diagTopic = fesa::DiagnosticUtils::notificationProfilingStr;
00021 
00022 } // namespace
00023 
00024 
00025 namespace fesa
00026 {
00027 
00028 NotificationIDManager* NotificationIDManager::theInstance_ = NULL;
00029 
00030 NotificationIDManager::NotificationIDManager()
00031 {
00032 }
00033 
00034 NotificationIDManager::~NotificationIDManager()
00035 {
00036 }
00037 
00038 NotificationIDManager* NotificationIDManager::getInstance()
00039 {
00040     if (theInstance_ == NULL)
00041     {
00042         theInstance_ = new NotificationIDManager();
00043     }
00044     return theInstance_;
00045 }
00046 
00047 void NotificationIDManager::releaseInstance()
00048 {
00049     if (theInstance_ != NULL)
00050     {
00051         delete theInstance_;
00052         theInstance_ = NULL;
00053     }
00054 }
00055 
00056 void NotificationIDManager::save()
00057 {
00058     if (AbstractEquipment::getInstance()->getProcessType() == unsplit)
00059     {
00060         return;
00061     }
00062     const boost::shared_ptr<Diagnostics>& diagnostics = AbstractEquipment::getInstance()->getDiagnostics();
00063     DiagnosticUtils::DiagnosticMessage diagMsg;
00064     diagMsg.side = DiagnosticUtils::framework;
00065     diagMsg.source = DiagnosticUtils::notification;
00066     diagMsg.name = "NotificationIDManager";
00067     diagMsg.msg = "Will save notification ID collection to file (RT side)";
00068     diagnostics->log(diagTopic, diagMsg);
00069     // store the notifications into a file
00070     storeNotificationIDCollection();
00071     /* Set notificationIDreadoutFlag to permit read out from server side */
00072     EquipmentData* equipmentData = EquipmentData::getInstance();
00073     *(equipmentData->notificationIDreadoutFlag_) = true;
00074     diagMsg.msg = "Saved notification ID collection to file";
00075     diagnostics->log(diagTopic, diagMsg);
00076 }
00077 
00078 void NotificationIDManager::storeNotificationIDCollection()
00079 {
00080     XMLParser parser(AbstractEquipment::getInstance()->getNotificationFileName(), false);
00081 
00082     parser.createFile();
00083     parser.startDocument();
00084 
00085     parser.startElement(NOTIFICATION_ID_COLLECTION_TAG);
00086     parser.writeNewline();
00087 
00088     for (std::map<uint32_t, NotificationID*>::iterator notification = notificationIDCol_.begin(); notification
00089              != notificationIDCol_.end(); notification++)
00090     {
00091         parser.startElement("NotificationID");
00092         parser.writeNewline();
00093         parser.writeElement("idkey", StringUtilities::toString((*notification).second->getIDKey()));
00094         parser.writeNewline();
00095         parser.writeElement("classname", (*notification).second->getClassName());
00096         parser.writeNewline();
00097 
00098         const std::set<std::string>& PropCol = (*notification).second->getPropertyCol();
00099         for (std::set<std::string>::iterator stringIter = PropCol.begin(); stringIter != PropCol.end(); stringIter++)
00100         {
00101             parser.writeElement("property", *stringIter);
00102             parser.writeNewline();
00103         }
00104         const std::set<std::string>& DevCol = (*notification).second->getDeviceCol();
00105         for (std::set<std::string>::iterator stringIter = DevCol.begin(); stringIter != DevCol.end(); stringIter++)
00106         {
00107             parser.writeElement("device", *stringIter);
00108             parser.writeNewline();
00109         }
00110         parser.endElement();
00111         parser.writeNewline();
00112     }
00113     parser.endElement();
00114     parser.writeNewline();
00115     parser.endDocument();
00116 }
00117 
00118 void NotificationIDManager::load()
00119 {
00120     const boost::shared_ptr<Diagnostics>& diagnostics = AbstractEquipment::getInstance()->getDiagnostics();
00121     DiagnosticUtils::DiagnosticMessage diagMsg;
00122     diagMsg.side = DiagnosticUtils::framework;
00123     diagMsg.source = DiagnosticUtils::notification;
00124     diagMsg.name = "NotificationIDManager";
00125     diagMsg.msg = "Will load notification ID collection from file (server side)";
00126     diagnostics->log(diagTopic, diagMsg);
00127     AbstractEquipment* eqp = AbstractEquipment::getInstance();
00128     // Reading fails if one of the classes does not have the flag
00129     EquipmentData* equipmentData = EquipmentData::getInstance();
00130     if (*(equipmentData->notificationIDreadoutFlag_) == false)
00131     {
00132         diagMsg.msg = "Failed loading notification ID collection from file";
00133         diagnostics->log(diagTopic, diagMsg);
00134         // TODO: if the Exception is not consistent with the definition in terms of variable arguments there is a seg fault
00135         // temporary fix by adding "unknown"
00136         throw FesaException(__FILE__, __LINE__, FesaErrorLoadNotificationIDCollection.c_str(), "Unknown");
00137 
00138 
00139     }
00140 
00141     // If all flags are set, start the read out
00142     try
00143     {
00144         loadNotificationIDCollection();
00145     }
00146     catch (FesaException& ex)
00147     {
00148         std::ostringstream traceStrStream;
00149         traceStrStream << "Failed loading notification ID collection from file, file not found."
00150                        << "Either file '" << eqp->getNotificationFileName()
00151                        << "' has been removed accidently or RT-side is not ready yet";
00152         diagMsg.msg = traceStrStream.str();
00153         diagnostics->log(diagTopic, diagMsg);
00154         throw;
00155     }
00156     diagMsg.msg = "Loaded notification ID collection from file";
00157     diagnostics->log(diagTopic, diagMsg);
00158 }
00159 
00160 const std::map<uint32_t, NotificationID*>& NotificationIDManager::getNotificationIDCol()
00161 {
00162     FesaProcessType processType = AbstractEquipment::getInstance()->getProcessType();
00163     if (processType == unsplit || processType == splitServerOnly || processType == splitRealTimeOnly)
00164     {
00165         return notificationIDCol_;
00166     }
00167     else
00168     {
00169         load();
00170         return notificationIDCol_;
00171     }
00172 }
00173 
00174 void NotificationIDManager::loadNotificationIDCollection()
00175 {
00176     std::string fileName = AbstractEquipment::getInstance()->getNotificationFileName();
00177 
00178     XMLParser parser(fileName, true);
00179 
00180     uint32_t tempKey;
00181     bool error = false;
00182 
00183     std::vector<ElementXML*>* pElCol = parser.extractElements("NotificationID");
00184 
00185     if (pElCol == NULL)
00186     {
00187         throw FesaException(__FILE__, __LINE__, FesaErrorLoadNotificationIDCollection.c_str(), fileName.c_str());
00188     }
00189 
00190     //for each NotificationID
00191     for (std::vector<ElementXML*>::iterator iter = pElCol->begin(); iter != pElCol->end(); iter++)
00192     {
00193         std::string className;
00194         std::set<std::string> properties;
00195         std::set<std::string> devices;
00196 
00197         //for each child
00198         for (std::vector<ElementXML*>::iterator iter2 = (*iter)->childList_.begin(); iter2
00199                  != (*iter)->childList_.end(); iter2++)
00200         {
00201             if ((*iter2)->name_ == "idkey")
00202             {
00203                 StringUtilities::fromString(tempKey, (*iter2)->value_);
00204             }
00205             else if ((*iter2)->name_ == "classname")
00206             {
00207                 className = (*iter2)->value_;
00208             }
00209             else if ((*iter2)->name_ == "property")
00210             {
00211                 properties.insert((*iter2)->value_);
00212             }
00213             else if ((*iter2)->name_ == "device")
00214             {
00215                 devices.insert((*iter2)->value_);
00216             }
00217             else
00218             {
00219                 error = true;
00220                 break;
00221             }
00222         }//end for each attribute
00223 
00224         NotificationID* tempID = new NotificationID(tempKey, className, devices, properties);
00225         notificationIDCol_.insert(std::pair<uint32_t, NotificationID*>(tempKey, tempID));
00226     }//end for Each NotificationID
00227 
00228     if (pElCol != NULL)
00229     {
00230         for (std::vector<ElementXML*>::iterator iter = pElCol->begin(); iter != pElCol->end(); iter++)
00231         {
00232             delete (*iter);
00233         }
00234         delete pElCol;
00235     }
00236 
00237     if (error)
00238     {
00239         throw FesaException(__FILE__, __LINE__, FesaErrorLoadNotificationIDCollection.c_str(), fileName.c_str());
00240     }
00241 }
00242 
00243 uint32_t NotificationIDManager::createNotificationID(const std::set<std::string>& notifiedProperties,
00244                                                          const std::set<std::string>& deviceNames, const std::string& classname)
00245 {
00246     //check, if the ID already exists
00247     std::map<uint32_t, NotificationID*>::iterator iter;
00248     for (iter = notificationIDCol_.begin(); iter != notificationIDCol_.end(); iter++)
00249     {
00250         if ((*iter).second->getClassName() == classname)
00251         {
00252             if ((*iter).second->getDeviceCol() == deviceNames && (*iter).second->getPropertyCol()
00253                 == notifiedProperties)
00254             {
00255                 return (*iter).first;
00256             }
00257         }
00258     }
00259 
00260     // 0 means noID, therefore 1 is added to the size of the notification collections size
00261     NotificationID *pID = new NotificationID(static_cast<uint32_t>(notificationIDCol_.size()) + 1, classname, deviceNames,
00262                                              notifiedProperties);
00263 
00264     notificationIDCol_.insert(std::pair<uint32_t, NotificationID*>(pID->getIDKey(), pID));
00265     return pID->getIDKey();
00266 }
00267 
00268 } // fesa

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1