• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

glite/jdl/DAGAd.h

Go to the documentation of this file.
00001 /*
00002 Copyright (c) Members of the EGEE Collaboration. 2004.
00003 See http://www.eu-egee.org/partners/ for details on the
00004 copyright holders.
00005 
00006 Licensed under the Apache License, Version 2.0 (the "License");
00007 you may not use this file except in compliance with the License.
00008 You may obtain a copy of the License at
00009 
00010     http://www.apache.org/licenses/LICENSE-2.0
00011 
00012 Unless required by applicable law or agreed to in writing, software
00013 distributed under the License is distributed on an "AS IS" BASIS,
00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00015 either express or implied.
00016 See the License for the specific language governing permissions and
00017 limitations under the License.
00018 */
00019 
00020 // File: DAGAd.h
00021 // Author: Francesco Giacomini <Francesco.Giacomini@cnaf.infn.it>
00022 //         Marco Cecchi
00023 
00024 // $Id: DAGAd.h,v 1.5.2.2.6.1 2011/09/01 13:29:09 mcecchi Exp $
00025 
00026 #ifndef GLITE_WMS_COMMON_REQUESTAD_DAGAD_H
00027 #define GLITE_WMS_COMMON_REQUESTAD_DAGAD_H
00028 
00029 #include <string>
00030 #include <utility>
00031 #include <map>
00032 #include <set>
00033 #include <iosfwd>
00034 #include <classad_distribution.h>
00035 #include <exception>
00036 
00037 #include <boost/shared_ptr.hpp>
00038 #include <boost/utility.hpp>
00039 #include <boost/tuple/tuple.hpp>
00040 #include <boost/config.hpp>
00041 
00042 #include "glite/wmsutils/classads/classad_utils.h"
00043 
00044 //graph libraries
00045 #include <boost/graph/adjacency_list.hpp>
00046 #include <boost/graph/graph_traits.hpp>
00047 #include <boost/graph/depth_first_search.hpp>
00048 #include <boost/graph/visitors.hpp>
00049 
00050 namespace glite {
00051 namespace jdl {
00052 
00053 namespace utilities = glite::wmsutils::classads;
00054 
00055 class DAG_Error: public std::exception
00056 {
00057 protected:
00058   std::string m_msg;
00059 public:
00060   virtual char const* what() const throw() { return "Invalid DAG"; }
00061   virtual ~DAG_Error() throw() { };
00062 };
00063 
00064 class NotDAG: public DAG_Error
00065 {
00066 public:
00067   virtual char const* what() const throw() {
00068     return "'node_type' must be \"dag\"";
00069   }
00070 };
00071 
00072 class InvalidMaxRunningNodes: public DAG_Error
00073 {
00074 public:
00075   virtual char const* what() const throw() {
00076     return "'max_running_nodes' has to be an integer > 0";
00077   }
00078 };
00079 
00080 class InvalidNodes: public DAG_Error
00081 {
00082 public:
00083   virtual char const* what() const throw() {
00084     return "'nodes' not valid";
00085   }
00086 };
00087 
00088 class InvalidDependencies: public DAG_Error
00089 {
00090 public:
00091   virtual char const* what() const throw() {
00092     return "'dependencies' not valid";
00093   }
00094 };
00095 
00096 class InconsistentDependencies: public DAG_Error
00097 {
00098 public:
00099   virtual char const* what() const throw() {
00100     return "Invalid reference in 'dependencies'";
00101   }
00102 };
00103 
00104 class DAG_HasCycle: public DAG_Error
00105 {
00106 public:
00107   virtual char const* what() const throw() {
00108     return "DAG has a cycle";
00109   }
00110 };
00111 
00112 class Invalid_DAG_NodeType: public DAG_Error
00113 {
00114 private:
00115   std::string m_type;
00116 public:
00117   Invalid_DAG_NodeType(std::string const& type)
00118     : DAG_Error(), m_type(type)
00119   { }
00120   virtual char const* what() throw() {
00121     m_msg = "'node_type': " + m_type + " is not valid";
00122     return m_msg.c_str();
00123   }
00124   virtual ~Invalid_DAG_NodeType() throw() { }
00125 };
00126 
00127 class Invalid_DAG_RetryCount: public DAG_Error
00128 {
00129 public:
00130   virtual char const* what() const throw() {
00131     return "'node_retry_count' must be an integer >= 0";
00132   }
00133 };
00134 
00135 class DAG_NodeError: public std::exception
00136 {
00137 protected:
00138   std::string m_node_name;
00139   std::string m_msg;
00140 public:
00141   DAG_NodeError(std::string const& node_name)
00142     : m_node_name(node_name) { }
00143   virtual char const* what() throw()
00144   {
00145     m_msg = "Invalid node " + m_node_name;
00146     return m_msg.c_str();
00147   }
00148   std::string node() const { return m_node_name; }
00149   virtual ~DAG_NodeError() throw() { };
00150 };
00151 
00152 class NeitherAdNorFile: public DAG_NodeError
00153 {
00154 public:
00155   virtual char const* what() throw()
00156   {
00157     m_msg = "Neither 'ad' nor 'file' specified" +
00158       (m_node_name.empty() ? "" : " for node " + m_node_name);
00159     return m_msg.c_str();
00160   }
00161   NeitherAdNorFile(std::string const& node)
00162     : DAG_NodeError(node) { }
00163 };
00164 
00165 class BothAdAndFile: public DAG_NodeError
00166 {
00167 public:
00168   virtual char const* what() throw()
00169   {
00170     m_msg = "Both 'ad' and 'file' specified" +
00171       (m_node_name.empty() ? "" : " for node " + m_node_name);
00172     return m_msg.c_str();
00173   }
00174   BothAdAndFile(std::string const& node)
00175     : DAG_NodeError(node) { }
00176 };
00177 
00178 class InvalidDescriptionFilename: public DAG_NodeError
00179 {
00180   std::string m_description;
00181 public:
00182   virtual char const* what() throw()
00183   {
00184     m_msg = "'file' not valid" +
00185       (m_description.empty() ? "" : " (" + m_description + ")");
00186       (m_node_name.empty() ? "" : " for node " + m_node_name);
00187     return m_msg.c_str();
00188   }
00189   InvalidDescriptionFilename(
00190     std::string const& node,
00191     std::string const& description
00192   )
00193     : DAG_NodeError(node), m_description(description) { }
00194   virtual ~InvalidDescriptionFilename() throw() { };
00195 };
00196 
00197 class InvalidDescription: public DAG_NodeError
00198 {
00199 public:
00200   virtual char const* what() throw()
00201   {
00202     m_msg = "'description' not valid" +
00203       (m_node_name.empty() ? "" : " for node " + m_node_name);
00204     return m_msg.c_str();
00205   }
00206   InvalidDescription(std::string const& node)
00207     : DAG_NodeError(node) { }
00208 };
00209 
00210 class InvalidRetryCount: public DAG_NodeError
00211 {
00212 public:
00213   virtual char const* what() throw()
00214   {
00215     m_msg = "'node_retry_count' must be an integer >= 0" +
00216       (m_node_name.empty() ? "" : " for node " + m_node_name);
00217     return m_msg.c_str();
00218   }
00219   InvalidRetryCount(std::string const& node)
00220     : DAG_NodeError(node) { }
00221 };
00222 
00223 class InvalidNodeType: public DAG_NodeError
00224 {
00225   std::string m_type;
00226 public:
00227   virtual char const* what() throw()
00228   {
00229     m_msg = "node_type not valid" +
00230       (m_type.empty() ? "" : " (" + m_type + ")");
00231       (m_node_name.empty() ? "" : " for node " + m_node_name);
00232     return m_msg.c_str();
00233   }
00234   InvalidNodeType(std::string const& node, std::string const& type)
00235     : DAG_NodeError(node), m_type(type) { }
00236   virtual ~InvalidNodeType() throw() { };
00237 };
00238 
00239 class DAGNodeInfo
00240 {
00241   class Implementation;
00242   boost::shared_ptr<Implementation> m_impl;
00243 
00244 public:
00245   DAGNodeInfo();
00246   DAGNodeInfo(classad::ClassAd const& node_description,
00247               std::string const& node_type = std::string(),
00248               std::string const& node_name = std::string()
00249   );
00250   ~DAGNodeInfo() { };
00251 
00252 public:
00253   std::string             description_file() const;
00254   bool                    replace_description_file(std::string const& file);
00255   classad::ClassAd const* description_ad() const;
00256   bool                    replace_description_ad(classad::ClassAd* ad);
00257   bool                    description_file_for_ad(std::string const& file);
00258   bool                    description_ad_for_file(classad::ClassAd* ad);
00259 
00260   std::string             type() const;
00261 
00262   int                     retry_count() const;
00263   bool                    retry_count(int n);
00264 
00265   classad::ClassAd        as_classad() const;
00266 };
00267 
00268 class DAGAdNodeIterator
00269   : public std::iterator<
00270   std::input_iterator_tag
00271   ,std::pair<std::string, DAGNodeInfo>
00272   ,ptrdiff_t
00273   ,std::pair<std::string, DAGNodeInfo> const*
00274   ,std::pair<std::string, DAGNodeInfo> const&
00275 >
00276 {
00277   friend bool operator==(DAGAdNodeIterator const& lhs,
00278     DAGAdNodeIterator const& rhs
00279   );
00280 
00281   classad::ClassAd const* m_nodes;
00282   classad::ClassAd::const_iterator m_node;
00283   value_type m_value;
00284 
00285   bool is_good() const
00286   {
00287     return m_node != m_nodes->end();
00288   }
00289 
00290   void set_value();
00291 
00292 public:
00293 
00294   DAGAdNodeIterator();
00295   ~DAGAdNodeIterator() {};
00296   DAGAdNodeIterator(classad::ClassAd const* nodes,
00297     classad::ClassAd::const_iterator it
00298   );
00299   DAGAdNodeIterator(DAGAdNodeIterator const& other);
00300   DAGAdNodeIterator& operator=(DAGAdNodeIterator const& other);
00301   DAGAdNodeIterator& operator++();
00302   DAGAdNodeIterator operator++(int);
00303   reference operator*() const;
00304 
00305   pointer operator->() const
00306   {
00307     return &(operator*());
00308   }
00309 
00310 };
00311 
00312 inline bool operator==(DAGAdNodeIterator const& lhs,
00313   DAGAdNodeIterator const& rhs
00314 ) {
00315   return lhs.m_nodes == rhs.m_nodes && lhs.m_node == rhs.m_node;
00316 }
00317 
00318 inline bool operator!=(DAGAdNodeIterator const& lhs,
00319   DAGAdNodeIterator const& rhs
00320 ) {
00321   return !(lhs == rhs);
00322 }
00323 
00324 struct DAGAdDependencyIterator
00325   : public std::iterator<
00326   std::input_iterator_tag
00327   ,std::pair<DAGAdNodeIterator, DAGAdNodeIterator>
00328   ,ptrdiff_t
00329   ,std::pair<DAGAdNodeIterator, DAGAdNodeIterator> const*
00330   ,std::pair<DAGAdNodeIterator, DAGAdNodeIterator> const&
00331 >
00332 {
00333   friend bool operator==(DAGAdDependencyIterator const& lhs,
00334                          DAGAdDependencyIterator const& rhs);
00335 
00336   typedef DAGAdNodeIterator node_iterator;
00337   typedef classad::ExprList::iterator Iterator;
00338 
00339   classad::ClassAd const* m_dag;
00340   Iterator m_dep;
00341   Iterator m_dep_end;
00342   Iterator m_parent;
00343   Iterator m_child;
00344   value_type m_value;
00345 
00346   static classad::ExprList* parents(classad::ExprTree* dep)
00347   {
00348     assert(utilities::is_expression_list(dep));
00349     classad::ExprTree* et = *static_cast<classad::ExprList*>(dep)->begin();
00350     assert(utilities::is_expression_list(et));
00351     return static_cast<classad::ExprList*>(et);
00352   }
00353   static classad::ExprList* children(classad::ExprTree* dep)
00354   {
00355     assert(utilities::is_expression_list(dep));
00356     classad::ExprTree* et = *++static_cast<classad::ExprList*>(dep)->begin();
00357     assert(utilities::is_expression_list(et));
00358     return static_cast<classad::ExprList*>(et);
00359   }
00360   bool is_good() const { return m_dep != m_dep_end; }
00361   void set_value();
00362 
00363   DAGAdDependencyIterator(classad::ClassAd const* dag = 0, bool begin = false);
00364 
00365   // copy ctor, operator=() and dtor are ok
00366 
00367   DAGAdDependencyIterator& operator++();
00368   DAGAdDependencyIterator operator++(int);
00369 
00370   reference operator*() const
00371   {
00372     return m_value;
00373   }
00374 
00375   pointer operator->() const
00376   {
00377     return &(operator*());
00378   }
00379 };
00380 
00381 inline bool operator==(DAGAdDependencyIterator const& lhs,
00382                        DAGAdDependencyIterator const& rhs)
00383 {
00384   return (!lhs.is_good() && !rhs.is_good())
00385     || (lhs.is_good() && rhs.is_good()
00386         && lhs.m_dep == rhs.m_dep
00387         && lhs.m_parent == rhs.m_parent
00388         && lhs.m_child == rhs.m_child
00389         );
00390 }
00391 
00392 inline bool operator!=(DAGAdDependencyIterator const& lhs,
00393                 DAGAdDependencyIterator const& rhs)
00394 {
00395   return !(lhs == rhs);
00396 }
00397 
00398 class DAGAd: boost::noncopyable
00399 {
00400 public:
00401 
00402   typedef DAGAdNodeIterator node_iterator;
00403   typedef DAGAdNodeIterator::value_type node_value_type;
00404   typedef DAGAdDependencyIterator dependency_iterator;
00405   typedef DAGAdDependencyIterator::value_type dependency_value_type;
00406 
00407   typedef boost::property<
00408       boost::vertex_name_t, std::string, boost::property<
00409       boost::vertex_color_t, boost::default_color_type
00410   > > VertexProperties;
00411 
00412   typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, VertexProperties> Graph_t; // bidirectional to have in_edges
00413   typedef boost::graph_traits<Graph_t>::vertex_descriptor Vertex;
00414   typedef boost::graph_traits<Graph_t >::vertex_iterator VertexIterator;
00415   typedef boost::graph_traits<Graph_t>::in_edge_iterator InEdgeIterator;
00416 
00417 private:
00418   boost::shared_ptr<classad::ClassAd> m_ad;
00419   Graph_t m_graph;
00420 
00421 public:
00422   DAGAd();
00423   explicit DAGAd(classad::ClassAd const& ad);
00424 
00425   Graph_t& graph() { return m_graph; }
00426   classad::ClassAd const& ad() const;
00427 
00428   // set the default node type
00429   // if new_value is "" the attribute becomes unspecified
00430   // return the previous value ("" means unspecified)
00431   std::string default_node_type(std::string const& new_value);
00432 
00433   // get the default node type
00434   // "" means unspecified
00435   std::string default_node_type() const;
00436 
00437   // set the default retry count for a node
00438   // if new_value is -1 the attribute becomes unspecified
00439   // return the previous value (-1 means unspecified)
00440   int default_node_retry_count(int new_value);
00441 
00442   // get the default retry count for a node
00443   // -1 means unspecified
00444   int default_node_retry_count() const;
00445 
00446   bool add_node(std::string const& name, DAGNodeInfo const& info);
00447   bool replace_node(std::string const& name, DAGNodeInfo const& info);
00448   bool remove_node(std::string const& name);
00449   std::size_t num_nodes() const;
00450   node_iterator find(std::string const& name) const;
00451 
00452   bool add_dependency(std::string const& first, std::string const& second);
00453   bool remove_dependency(std::string const& first, std::string const& second);
00454   std::size_t num_dependencies() const;
00455 
00456   bool set_generic(std::string const& attribute, classad::ExprTree* value);
00457   classad::ExprTree const* get_generic(std::string const& attribute) const;
00458   bool remove_generic(std::string const& attribute);
00459 
00460   std::pair<dependency_iterator, dependency_iterator> classad_dependencies() const;
00461   std::pair<node_iterator, node_iterator> nodes() const;
00462 
00463   struct Attributes
00464   {
00465     static std::string const TYPE;
00466     static std::string const NODES;
00467     static std::string const DEPENDENCIES;
00468     static std::string const NODE_RETRY_COUNT;
00469     static std::string const NODE_TYPE;
00470     static std::string const DESCRIPTION_FILE;
00471     static std::string const DESCRIPTION_AD;
00472   };
00473 };
00474 
00475 } // jdl namespace
00476 } // glite namespace
00477 
00478 #endif

Generated on Tue Mar 5 2013 13:56:08 for jdl-api-cpp-3.4.1 by  doxygen 1.7.1