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

classad_utils.h

Go to the documentation of this file.
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.34 2004/08/04 14:08:26 dhsmith 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   if( find(exprTrace->begin(), exprTrace->end(), e) != exprTrace->end() ) return v;
00222   
00223   exprTrace -> push_front(e);
00224   switch( e -> GetKind() ) {
00225           case classad::ExprTree::LITERAL_NODE: break;
00226       
00227   case classad::ExprTree::OP_NODE: {
00228     classad::ExprTree* e1 = 0, *e2 = 0, *e3 = 0;
00229     classad::Operation::OpKind ok;
00230     dynamic_cast<classad::Operation*>(e) -> GetComponents(ok, e1, e2, e3);
00231     if( e1 ) insertAttributeInVector(v, e1, exprTrace, predicate);
00232     if( e2 ) insertAttributeInVector(v, e2, exprTrace, predicate);
00233     if( e3 ) insertAttributeInVector(v, e3, exprTrace, predicate);
00234   }
00235   break;
00236   case classad::ExprTree::FN_CALL_NODE: {
00237     std::vector<classad::ExprTree*> args;
00238     std::string fn;
00239     dynamic_cast<classad::FunctionCall*>(e) ->  GetComponents(fn, args);
00240     for(std::vector<classad::ExprTree*>::const_iterator it = args.begin();
00241         it != args.end(); it++) insertAttributeInVector(v,*it, exprTrace, predicate);
00242   }
00243   break;
00244   case classad::ExprTree::EXPR_LIST_NODE: {
00245     std::vector<classad::ExprTree*> args;
00246     dynamic_cast<classad::ExprList*>(e) ->  GetComponents(args);
00247     for(std::vector<classad::ExprTree*>::const_iterator it = args.begin();
00248         it != args.end(); it++) insertAttributeInVector(v,*it, exprTrace, predicate);
00249   }     
00250   break; 
00251   case classad::ExprTree::ATTRREF_NODE: {
00252     
00253     classad::AttributeReference* a = dynamic_cast<classad::AttributeReference*>(e);
00254     classad::ExprTree* reference_expr = 0;
00255     std::string name;
00256     bool absolute;
00257     a -> GetComponents(reference_expr, name, absolute);
00258     if(!reference_expr)  {
00259       reference_expr = a -> GetParentScope() -> Lookup(name);
00260       if(reference_expr && reference_expr != e) insertAttributeInVector(v, reference_expr, exprTrace, predicate);
00261     }   
00262     else {
00263         if( predicate(std::make_pair(exprTrace,a)) &&
00264             find(v -> begin(), v->end(), name) == v->end() ) v -> push_back(name);
00265    }
00266   }
00267   break;
00268   default:
00269     assert( false );
00270   }
00271   exprTrace -> pop_front();
00272   return v;
00273 }
00274 
00275 template<class Function>
00276 std::vector<std::string>* insertAttributeInVector(std::vector<std::string>* v, classad::ExprTree* e, Function predicate)
00277 {
00278   expression_trace_type exprTrace;
00279   return insertAttributeInVector(v,e,&exprTrace, predicate);
00280 }
00281 
00282 inline std::vector<std::string>* insertAttributeInVector(std::vector<std::string>* v, classad::ExprTree* e)
00283 {
00284   expression_trace_type exprTrace;
00285   return insertAttributeInVector(v,e,&exprTrace, always());
00286 }
00287 
00288 class ClassAdError: public std::exception
00289 {
00290 public:
00291   ~ClassAdError() throw() {};
00292   char const* what() const throw()
00293   {
00294     return "ClassAd utils - generic error";
00295   }
00296 };
00297 
00298 class CannotParseClassAd: public ClassAdError
00299 {
00300   std::string m_what;
00301   std::string m_str;
00302 public:
00303   CannotParseClassAd()
00304     : m_what("ClassAd utils - cannot parse classad")
00305   {
00306   }
00307   CannotParseClassAd(std::string const& ad_str)
00308     : m_what("ClassAd utils - cannot parse classad: " + ad_str),
00309       m_str(ad_str)
00310   {
00311   }
00312   ~CannotParseClassAd() throw() {}
00313   std::string str() const
00314   {
00315     return m_str;
00316   }
00317   char const* what() const throw()
00318   {
00319     return m_what.c_str();
00320   }
00321 };
00322 
00323 class nothrow_t {};
00324 extern nothrow_t const nothrow;
00325   
00326 // throws CannotParseClassAd
00327 classad::ClassAd* parse_classad(std::string const& s);
00328 
00329 classad::ClassAd* parse_classad(std::string const& s, nothrow_t const&);
00330 
00331 // throws CannotParseClassAd
00332 classad::ClassAd* parse_classad(std::istream& is);
00333 
00334 std::string unparse_classad(classad::ClassAd const& ad);
00335 
00336 class InvalidValue: public ClassAdError
00337 {
00338   std::string m_what;
00339 public:
00340   InvalidValue(std::string const& expression, std::string const& type)
00341     : m_what("ClassAd error: attribute \"" + expression
00342                 + "\" does not exist or has the wrong type (expecting \"" + type + "\")")
00343   {
00344   }
00345   ~InvalidValue() throw()
00346   {
00347   }
00348   char const* what() const throw()
00349   {
00350     return m_what.c_str();
00351   }
00352 };
00353   
00354 class ValueProxy
00355 {
00356   std::string m_expression;
00357   classad::Value m_value;
00358 public:
00359   ValueProxy(std::string const& e, classad::Value const& v);
00360   // all the following can throw InvalidValue
00361   operator bool() const;
00362   operator int() const;
00363   operator double() const;
00364   operator std::string() const;
00365   operator classad::ClassAd const*() const;
00366   operator classad::ExprList const*() const;
00367 };
00368 
00369 ValueProxy evaluate_attribute(classad::ClassAd const& ad,
00370                               std::string const& attribute);
00371   
00372 ValueProxy evaluate_expression(classad::ClassAd const& ad,
00373                                std::string const& expression);
00374   
00375 bool match(classad::ClassAd const& lhs,
00376            classad::ClassAd const& rhs,
00377            std::string const& match_type);
00378 
00379 bool left_matches_right (classad::ClassAd const& lhs, classad::ClassAd const& rhs);
00380 bool right_matches_left (classad::ClassAd const& lhs, classad::ClassAd const& rhs);
00381 bool symmetric_match    (classad::ClassAd const& lhs, classad::ClassAd const& rhs);
00382 
00383 class UndefinedRank: public ClassAdError
00384 {
00385 public:
00386   ~UndefinedRank() throw() {}
00387   char const* what() const throw()
00388   {
00389     return "ClassAd utils - undefined rank";
00390   }
00391 };
00392 
00393 double rank(classad::ClassAd const& lhs,
00394             classad::ClassAd const& rhs,
00395             std::string const& rank_type);
00396 
00397 double left_rank(classad::ClassAd const& lhs,
00398                  classad::ClassAd const& rhs);
00399 
00400 double right_rank(classad::ClassAd const& lhs,
00401                   classad::ClassAd const& rhs);
00402 
00403 // more traditional interface (to be completed)
00404   
00405 bool evaluate_attribute(classad::ClassAd const& ad,
00406                         std::string const& attribute,
00407                         std::string& value);
00408   
00409 bool evaluate_expression(classad::ClassAd const& ad,
00410                          std::string const& expression,
00411                          std::string& value);
00412   
00413 bool evaluate_expression(classad::ClassAd const& ad,
00414                          std::string const& expression,
00415                          classad::ClassAd const*& value);
00416   
00417 }}}} 
00418 
00419 #endif
00420 
00421 // Local Variables:
00422 // mode: c++
00423 // End:

Generated on Wed Mar 1 00:37:54 2006 for COMMON API - configuration, jobid, ldif2classadi, logger, process, requestad, socket++i, task, utilities by doxygen 1.3.5