Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

classad_utils.h

00001 // File: classad_utils.h
00002 // Author: Salvatore Monforte <salvatore.monforte@ct.infn.it>
00003 // Author: Rosario Peluso <Rosario.Peluso@pd.infn.it>
00004 // Author: Francesco Giacomini <Francesco.Giacomini@cnaf.infn.it>
00005 // Author: Marco Pappalardo <Marco.Pappalardo@ct.infn.it> 
00006 // Copyright (c) 2002 EU DataGrid.
00007 // For license conditions see http://www.eu-datagrid.org/license.html
00008 
00009 // $Id: classad_utils.h,v 1.32 2003/10/17 10:16:52 giaco Exp $
00010 
00011 #ifndef EDG_WORKLOAD_COMMON_UTILITIES_CLASSAD_UTILS_H
00012 #define EDG_WORKLOAD_COMMON_UTILITIES_CLASSAD_UTILS_H
00013 
00014 #include <string>
00015 #include <vector>
00016 #include <stack>
00017 #include <numeric>
00018 #include <functional>
00019 #include <algorithm>
00020 #include <classad_distribution.h>
00021 #include <iostream>
00022 
00023 namespace edg {
00024 namespace workload {
00025 namespace common {
00026 namespace utilities {
00027 
00028 inline void setValue(classad::Value& value, const std::string& s) { value.SetStringValue(s); }
00029 inline void setValue(classad::Value& value, double d) { value.SetRealValue(d); }
00030 inline void setValue(classad::Value& value, bool b)   { value.SetBooleanValue(b); }
00031 inline void setValue(classad::Value& value, int i)    { value.SetIntegerValue(i); }
00032   
00033 inline bool getValue(const classad::Value& value, std::string& s) { return value.IsStringValue(s); }
00034 inline bool getValue(const classad::Value& value, double& d)       { return value.IsRealValue(d); }
00035 inline bool getValue(const classad::Value& value, bool& b)         { return value.IsBooleanValue(b); }
00036 inline bool getValue(const classad::Value& value, int& i)          { return value.IsIntegerValue(i); }
00037   
00038 template<class T> 
00039 struct InsertExprInVector : public std::binary_function<std::vector<T>*, classad::ExprTree*, std::vector<T>* > 
00040 {
00041     std::vector<T>* operator()(std::vector<T>* v, classad::ExprTree* e) {
00042     classad::Value value;
00043 
00044 #ifndef WITH_UI_JCLIENT
00045     dynamic_cast<classad::Literal*>(e) -> GetValue(value);
00046 #else     
00047     ((classad::Literal*)(e)) -> GetValue(value);
00048 #endif
00049     
00050     T s;
00051     if( getValue(value,s) ) v -> push_back( s );  
00052     return v;
00053   }
00054 };
00055 
00056 template<class T> 
00057 bool EvaluateAttrList(const classad::ClassAd& ad, const std::string& what, std::vector<T>&l)
00058 {
00059   bool                     res = false;
00060   std::string              where;
00061   classad::Value           list_value;
00062   const classad::ExprList *expr_list;
00063     
00064   if( ad.EvaluateAttr(what, list_value) == true &&
00065       list_value.IsListValue( expr_list ) == true ) {
00066     accumulate(expr_list -> begin(), expr_list -> end(), &l, InsertExprInVector<T>());
00067     res = true;
00068   }
00069     
00070   return res;
00071 }
00072 
00073 template<class T>
00074 bool EvaluateAttrListOrSingle(const classad::ClassAd& ad, const std::string& what, std::vector<T>&l)
00075 {
00076   bool res = false;
00077   if ( !(res = EvaluateAttrList(ad, what, l)) ) {
00078     
00079     classad::Value v;
00080     T tmpvalue;
00081     if ( res = (ad.EvaluateAttr(what, v) && getValue(v, tmpvalue) ) ) {
00082             l.push_back(tmpvalue);
00083     }
00084   }
00085   return res;
00086 }
00087 
00088 template<class T>
00089 T EvaluateExpr(classad::ClassAd& ad, const std::string& what)
00090 {
00091   classad::Value v;
00092   T t;
00093   assert(ad.EvaluateExpr(what, v) && getValue(v,t));
00094   return t;
00095 }
00096   
00097 template<class T> 
00098 bool InsertAttrList(classad::ClassAd& ad, const std::string& what, const std::vector<T>&l)
00099 {
00100   classad::ExprList* expr_list = asExprList(l);
00101     
00102   if( !expr_list ) return false;
00103     
00104   expr_list -> SetParentScope( &ad );
00105   return ad.Insert(what,expr_list);
00106 } 
00107   
00108 inline std::string asString(classad::ClassAd& ad) 
00109 {
00110   std::string s;
00111   classad::ClassAdUnParser unparser;
00112   classad::Value value;
00113           
00114   value.SetClassAdValue(&ad);
00115   unparser.Unparse(s, value);
00116           
00117   return s;
00118 } 
00119   
00120 template<class T>
00121 classad::ExprList* asExprList(const std::vector<T>& v)
00122 {
00123   std::vector< classad::ExprTree* >          list;
00124   typename std::vector<T>::const_iterator    it;
00125     
00126   for(it = v.begin(); it != v.end(); it++) {
00127     classad::Value value;
00128     setValue(value, (*it));
00129     list.push_back( static_cast<classad::ExprTree*>(classad::Literal::MakeLiteral(value)));
00130   }
00131     
00132   classad::ExprList* result = NULL;
00133     
00134   result = classad::ExprList::MakeExprList(list);
00135     
00136   return result;
00137 }
00138   
00139 typedef std::list<classad::ExprTree*> expression_trace_type;
00140 typedef std::pair<expression_trace_type*, classad::AttributeReference*> predicate_context_type;
00141 typedef std::unary_function<predicate_context_type, bool> unary_predicate;
00142 
00143 struct is_reference_to : public unary_predicate
00144 { 
00145   is_reference_to(const std::string& r) : ref(r) {}
00146   bool operator()(const predicate_context_type& ctx) const {
00147         
00148     classad::ExprTree* reference_expr = 0;
00149     std::string name;
00150     bool absolute;
00151     ctx.second -> GetComponents(reference_expr, name, absolute);
00152     if( reference_expr && 
00153         reference_expr -> GetKind() == classad::ExprTree::ATTRREF_NODE ) {
00154       classad::ExprTree* e; 
00155       dynamic_cast<classad::AttributeReference*>(reference_expr) -> GetComponents(e, name, absolute);
00156       return name == ref;
00157     } 
00158     return false;
00159   }
00160   std::string ref;
00161 };
00162 
00163 struct is_absolute_reference : public unary_predicate
00164 { 
00165   bool operator()(const predicate_context_type& ctx) const {
00166     classad::ExprTree* reference_expr = 0;
00167     std::string name;
00168     bool absolute;
00169     ctx.second -> GetComponents(reference_expr, name, absolute);
00170     return absolute;
00171   }
00172 
00173 };
00174     
00175 struct always : unary_predicate
00176 {
00177   bool operator()(const predicate_context_type& ctx) const { return true; }
00178 };
00179 
00180 struct is_function_call_to : public std::unary_function<classad::ExprTree*, bool>
00181 {
00182    is_function_call_to(const std::string& fn) : fn_name( fn ) {}
00183    bool operator()(classad::ExprTree* e) const {
00184            if( e->GetKind() != classad::ExprTree::FN_CALL_NODE ) return false;
00185            std::vector<classad::ExprTree*> args;
00186            std::string fn;
00187            dynamic_cast<classad::FunctionCall*>(e) ->  GetComponents(fn, args);
00188            return fn == fn_name;
00189    }
00190    std::string fn_name;    
00191 };
00192 
00193 struct is_operand_of : public unary_predicate
00194 {
00195   is_operand_of(const std::string& fn) : fn_name( fn ) {}       
00196   bool operator()(const predicate_context_type& ctx) const {
00197   return find_if(ctx.first->begin(), ctx.first->end(), is_function_call_to(fn_name)) != ctx.first->end(); 
00198   }       
00199   std::string fn_name; 
00200 };
00201 
00202 struct is_rightmost_operand_of : public unary_predicate
00203 {
00204   is_rightmost_operand_of(const std::string& fn) : fn_name( fn ) {}
00205   bool operator()(const predicate_context_type& ctx) const {
00206         expression_trace_type::const_iterator it = find_if(ctx.first->begin(), ctx.first->end(), is_function_call_to(fn_name));
00207         if( it == ctx.first->end() ) return false;
00208         
00209         std::vector<classad::ExprTree*> args;
00210         std::string fn;
00211         dynamic_cast<classad::FunctionCall*>(*it) ->  GetComponents(fn, args);
00212         return ctx.second == args.back();
00213   }
00214   std::string fn_name;
00215 };
00216 
00217 template<class Function>
00218 std::vector<std::string>* insertAttributeInVector(std::vector<std::string>* v, classad::ExprTree* e, expression_trace_type* exprTrace, Function predicate)
00219 {
00220   if( !e ) return v;
00221   
00222   exprTrace -> push_front(e);
00223   switch( e -> GetKind() ) {
00224           case classad::ExprTree::LITERAL_NODE: break;
00225       
00226   case classad::ExprTree::OP_NODE: {
00227     classad::ExprTree* e1 = 0, *e2 = 0, *e3 = 0;
00228     classad::Operation::OpKind ok;
00229     dynamic_cast<classad::Operation*>(e) -> GetComponents(ok, e1, e2, e3);
00230     if( e1 ) insertAttributeInVector(v, e1, exprTrace, predicate);
00231     if( e2 ) insertAttributeInVector(v, e2, exprTrace, predicate);
00232     if( e3 ) insertAttributeInVector(v, e3, exprTrace, predicate);
00233   }
00234   break;
00235   case classad::ExprTree::FN_CALL_NODE: {
00236     std::vector<classad::ExprTree*> args;
00237     std::string fn;
00238     dynamic_cast<classad::FunctionCall*>(e) ->  GetComponents(fn, args);
00239     for(std::vector<classad::ExprTree*>::const_iterator it = args.begin();
00240         it != args.end(); it++) insertAttributeInVector(v,*it, exprTrace, predicate);
00241   }
00242   break;
00243   case classad::ExprTree::EXPR_LIST_NODE: {
00244     std::vector<classad::ExprTree*> args;
00245     dynamic_cast<classad::ExprList*>(e) ->  GetComponents(args);
00246     for(std::vector<classad::ExprTree*>::const_iterator it = args.begin();
00247         it != args.end(); it++) insertAttributeInVector(v,*it, exprTrace, predicate);
00248   }     
00249   break; 
00250   case classad::ExprTree::ATTRREF_NODE: {
00251     
00252     classad::AttributeReference* a = dynamic_cast<classad::AttributeReference*>(e);
00253     classad::ExprTree* reference_expr = 0;
00254     std::string name;
00255     bool absolute;
00256     a -> GetComponents(reference_expr, name, absolute);
00257     if(!reference_expr)  {
00258       reference_expr = a -> GetParentScope() -> Lookup(name);
00259       if(reference_expr) insertAttributeInVector(v, reference_expr, exprTrace, predicate);
00260     }   
00261     else {
00262         if( predicate(std::make_pair(exprTrace,a)) &&
00263             find(v -> begin(), v->end(), name) == v->end() ) v -> push_back(name);
00264    }
00265   }
00266   break;
00267   default:
00268     assert( false );
00269   }
00270   exprTrace -> pop_front();
00271   return v;
00272 }
00273 
00274 template<class Function>
00275 std::vector<std::string>* insertAttributeInVector(std::vector<std::string>* v, classad::ExprTree* e, Function predicate)
00276 {
00277   expression_trace_type exprTrace;
00278   return insertAttributeInVector(v,e,&exprTrace, predicate);
00279 }
00280 
00281 inline std::vector<std::string>* insertAttributeInVector(std::vector<std::string>* v, classad::ExprTree* e)
00282 {
00283   expression_trace_type exprTrace;
00284   return insertAttributeInVector(v,e,&exprTrace, always());
00285 }
00286 
00287 class ClassAdError: public std::exception
00288 {
00289 public:
00290   ~ClassAdError() throw() {};
00291   char const* what() const throw()
00292   {
00293     return "ClassAd utils - generic error";
00294   }
00295 };
00296 
00297 class CannotParseClassAd: public ClassAdError
00298 {
00299   std::string m_what;
00300   std::string m_str;
00301 public:
00302   CannotParseClassAd()
00303     : m_what("ClassAd utils - cannot parse classad")
00304   {
00305   }
00306   CannotParseClassAd(std::string const& ad_str)
00307     : m_what("ClassAd utils - cannot parse classad: " + ad_str),
00308       m_str(ad_str)
00309   {
00310   }
00311   ~CannotParseClassAd() throw() {}
00312   std::string str() const
00313   {
00314     return m_str;
00315   }
00316   char const* what() const throw()
00317   {
00318     return m_what.c_str();
00319   }
00320 };
00321 
00322 class nothrow_t {};
00323 extern nothrow_t const nothrow;
00324   
00325 // throws CannotParseClassAd
00326 classad::ClassAd* parse_classad(std::string const& s);
00327 
00328 classad::ClassAd* parse_classad(std::string const& s, nothrow_t const&);
00329 
00330 // throws CannotParseClassAd
00331 classad::ClassAd* parse_classad(std::istream& is);
00332 
00333 std::string unparse_classad(classad::ClassAd const& ad);
00334 
00335 class InvalidValue: public ClassAdError
00336 {
00337   std::string m_what;
00338 public:
00339   InvalidValue(std::string const& expression, std::string const& type)
00340     : m_what("ClassAd error: attribute \"" + expression
00341                 + "\" does not exist or has the wrong type (expecting \"" + type + "\")")
00342   {
00343   }
00344   ~InvalidValue() throw()
00345   {
00346   }
00347   char const* what() const throw()
00348   {
00349     return m_what.c_str();
00350   }
00351 };
00352   
00353 class ValueProxy
00354 {
00355   std::string m_expression;
00356   classad::Value m_value;
00357 public:
00358   ValueProxy(std::string const& e, classad::Value const& v);
00359   // all the following can throw InvalidValue
00360   operator bool() const;
00361   operator int() const;
00362   operator double() const;
00363   operator std::string() const;
00364   operator classad::ClassAd const*() const;
00365   operator classad::ExprList const*() const;
00366 };
00367 
00368 ValueProxy evaluate_attribute(classad::ClassAd const& ad,
00369                               std::string const& attribute);
00370   
00371 ValueProxy evaluate_expression(classad::ClassAd const& ad,
00372                                std::string const& expression);
00373   
00374 bool match(classad::ClassAd const& lhs,
00375            classad::ClassAd const& rhs,
00376            std::string const& match_type);
00377 
00378 bool left_matches_right (classad::ClassAd const& lhs, classad::ClassAd const& rhs);
00379 bool right_matches_left (classad::ClassAd const& lhs, classad::ClassAd const& rhs);
00380 bool symmetric_match    (classad::ClassAd const& lhs, classad::ClassAd const& rhs);
00381 
00382 class UndefinedRank: public ClassAdError
00383 {
00384 public:
00385   ~UndefinedRank() throw() {}
00386   char const* what() const throw()
00387   {
00388     return "ClassAd utils - undefined rank";
00389   }
00390 };
00391 
00392 double rank(classad::ClassAd const& lhs,
00393             classad::ClassAd const& rhs,
00394             std::string const& rank_type);
00395 
00396 double left_rank(classad::ClassAd const& lhs,
00397                  classad::ClassAd const& rhs);
00398 
00399 double right_rank(classad::ClassAd const& lhs,
00400                   classad::ClassAd const& rhs);
00401 
00402 // more traditional interface (to be completed)
00403   
00404 bool evaluate_attribute(classad::ClassAd const& ad,
00405                         std::string const& attribute,
00406                         std::string& value);
00407   
00408 bool evaluate_expression(classad::ClassAd const& ad,
00409                          std::string const& expression,
00410                          std::string& value);
00411   
00412 bool evaluate_expression(classad::ClassAd const& ad,
00413                          std::string const& expression,
00414                          classad::ClassAd const*& value);
00415   
00416 }}}} 
00417 
00418 #endif
00419 
00420 // Local Variables:
00421 // mode: c++
00422 // End:

Generated on Fri May 14 14:18:25 2004 for COMMON API - configuration, jobid, ldif2classadi, logger, process, requestad, socket++i, task, utilities by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002