FieldExpression.cpp

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 
00003 #include <fesa-core/Sorting/FieldExpression.h>
00004 #include <fesa-core/Sorting/HomogeneousDevCol.h>
00005 #include <fesa-core/DataStore/AbstractDevice.h>
00006 
00007 #include <cmw-log/Logger.h>
00008 
00009 #include <iostream>
00010 
00011 namespace
00012 {
00013 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.Sorting.FieldExpression");
00014 }
00015 
00016 namespace fesa
00017 {
00018 
00019 bool FieldExpression::match(SortingContext sc)
00020 {
00021     std::string fieldExprCandidate = sc.formula_;
00022     enum automaton
00023     {
00024         initState,
00025         parenthesisStartState,
00026         fieldNameState,
00027         equalityState,
00028         fieldValueState,
00029         endState
00030     };
00031     automaton state = initState;
00032     automaton newState = initState;
00033     std::string::size_type pos;
00034     while (state != endState)
00035     {
00036         switch (state)
00037         {
00038             case initState:
00039                 if (fieldExprCandidate.size() == 0)
00040                     newState = endState;
00041                 else
00042                     newState = parenthesisStartState;
00043                 break;
00044             case parenthesisStartState:
00045                 if (fieldExprCandidate[0] != '(')
00046                     return false;
00047                 fieldExprCandidate.erase(0, 1);
00048                 newState = fieldNameState;
00049                 break;
00050             case fieldNameState:
00051                 pos = fieldExprCandidate.find("==");
00052                 if ((pos == std::string::npos))
00053                     return false;
00054                 this->fieldNameStr_ = fieldExprCandidate.substr(0, pos);
00055                 fieldExprCandidate.erase(0, pos + 2);
00056                 newState = equalityState;
00057                 break;
00058             case equalityState:
00059                 // already confident there was "=="
00060                 newState = fieldValueState;
00061                 break;
00062             case fieldValueState:
00063                 pos = fieldExprCandidate.rfind(")");
00064                 if ((pos == std::string::npos))
00065                 {
00066                     return false;
00067                 }
00068                 fieldExprCandidate.erase(pos, 1);
00069                 pos = fieldExprCandidate.find("[");
00070                 if (pos != 0)
00071                     return false;
00072                 fieldExprCandidate.erase(pos, 1);
00073                 pos = fieldExprCandidate.find("]");
00074                 if (pos != (fieldExprCandidate.length() - 1))
00075                     return false;
00076                 fieldExprCandidate.erase(pos, 1);
00077                 fieldValueStr_ = fieldExprCandidate; // make it a NULL-terminated string!
00078                 if(logger.isLoggable(CMW::Log::Level::LL_TRACE))
00079                 {
00080                     std::ostringstream msg;
00081                     msg << "candidate field value is " << fieldValueStr_;
00082                     LOG_TRACE_IF(logger, msg.str());
00083                 }
00084                 // the comparison shall be performed
00085                 // with the stringified value of the
00086                 // field (there should be a getStringified)
00087                 // method on the Field class, useful
00088                 // for debug as well as for the sorting
00089                 // criterion matching to be performed below.
00090                 newState = endState;
00091                 break;
00092             case endState:
00093                 // Check that there are no extra-characters left in the candidate string
00094                 break;
00095         }
00096         state = newState;
00097     }
00098     // Now update the devColCol attribute
00099     if (fieldValueStr_ == "?")
00100     {
00101         // Implicit device-recruitment => need several sets
00102         std::map<std::string, HomogeneousDevCol *> m;
00103         for (uint32_t i = 0; i < pDevCol_->size(); i++)
00104         {
00105             AbstractDevice * pDev = (*pDevCol_)[i];
00106             AbstractField * pField = pDev->getField(fieldNameStr_);
00107             if (!pField) // the field doesn't exist: the expression is not valid
00108                 return false;
00109             std::string fieldValue = pField->getAsString();
00110             // Removing the prefix className if any; That way no additional layers are created due to the prefix
00111             const std::string classNamePrefix = sc.className_ + "::";
00112             if (fieldValue.compare(0, classNamePrefix.size(), classNamePrefix) == 0)
00113             {
00114                 fieldValue = fieldValue.substr(classNamePrefix.size(), fieldValue.size() - classNamePrefix.size());
00115             }
00116             std::map<std::string, HomogeneousDevCol*>::iterator p;
00117             p = m.find(fieldValue);
00118             if (p != m.end())
00119             {
00120                 p->second->getDevCol()->insert(pDev);
00121             }
00122             else
00123             {
00124                 // there's no homogeneous device collection sorted for
00125                 // this field.
00126                 HomogeneousDevCol * pHomogeneousDevCol = new HomogeneousDevCol();
00127                 m[fieldValue] = pHomogeneousDevCol;
00128                 pHomogeneousDevCol->getDevCol()->insert(pDev);
00129                 std::string criterion = std::string("(") + fieldNameStr_ + std::string("==") + fieldValue
00130                     + std::string(")");
00131                 pHomogeneousDevCol->setSharedCriteria(criterion);
00132             }
00133         }
00134         std::map<std::string, HomogeneousDevCol *>::iterator it;
00135         for (it = m.begin(); it != m.end(); it++)
00136         {
00137             if (it->second->getSize() > 0)
00138             {
00139                 devColCol_.insert(it->second);
00140             } // otherwise there is no point of adding an empty device-set...
00141         }
00142     }
00143     else
00144     {
00145         // Explicit device-recruitment => need only one set
00146         HomogeneousDevCol* pHomogeneousDevCol = new HomogeneousDevCol();
00147         if (fieldValueStr_ == "")
00148         {
00149             pHomogeneousDevCol->setSharedCriteria("");
00150             for (uint32_t i = 0; i < pDevCol_->size(); i++)
00151                 pHomogeneousDevCol->getDevCol()->insert((*pDevCol_)[i]);
00152         }
00153         else
00154         {
00155             std::string criterion = std::string("(") + fieldNameStr_ + std::string("==") + fieldValueStr_
00156                 + std::string(")");
00157             pHomogeneousDevCol->setSharedCriteria(criterion);
00158             for (uint32_t i = 0; i < pDevCol_->size(); i++)
00159             {
00160                 AbstractDevice * pDev = (*pDevCol_)[i];
00161                 AbstractField *pField = pDev->getField(fieldNameStr_);
00162                 if (!pField) // the field doesn't exist: the expression is not valid
00163                     return false;
00164                 std::string fieldValue = pField->getAsString();
00165 
00166                 if (fieldValue == fieldValueStr_)
00167                 {
00168                     pHomogeneousDevCol->getDevCol()->insert(pDev);
00169                 }
00170             }
00171         }
00172         if (pHomogeneousDevCol->getSize() > 0)
00173         {
00174             devColCol_.insert(pHomogeneousDevCol); // only one.
00175         } // otherwise there is no point in adding an empty set of devices ...
00176     }
00177     if (logger.isLoggable(CMW::Log::Level::LL_TRACE))
00178     {
00179         std::ostringstream msg;
00180         msg << "   FieldExpression has been decoded : '" << fieldNameStr_ << "' == '" << fieldValueStr_ << "'";
00181         LOG_TRACE_IF(logger, msg.str());
00182     }
00183     return true;
00184 }
00185 
00186 std::set<HomogeneousDevCol *> FieldExpression::evaluate()
00187 {
00188     return devColCol_;
00189 }
00190 
00191 } // fesa

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1