Back to index

nordugrid-arc-nox  1.1.0~rc6
InformationInterface.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <arc/wsrf/WSResourceProperties.h>
00006 #include "InformationInterface.h"
00007 
00008 namespace Arc {
00009 
00010 #define XPATH_1_0_URI "http://www.w3.org/TR/1999/REC-xpath-19991116"
00011 
00012 class MutexSLock {
00013  private:
00014   Glib::Mutex& mutex_;
00015   bool locked_;
00016  public:
00017   MutexSLock(Glib::Mutex& mutex,bool lock = true):mutex_(mutex),locked_(false) {
00018     if(lock) { mutex_.lock(); locked_=true; };
00019   };
00020   ~MutexSLock(void) {
00021     if(locked_) mutex_.unlock();
00022   };
00023 };
00024 
00025 void InformationInterface::Get(const std::list<std::string>&,XMLNodeContainer&) {
00026   return;
00027 }
00028 
00029 void InformationInterface::Get(XMLNode,XMLNodeContainer&) {
00030   return;
00031 }
00032 
00033 InformationInterface::InformationInterface(bool safe):to_lock_(safe) {
00034 }
00035 
00036 InformationInterface::~InformationInterface(void) {
00037 }
00038 
00039 SOAPEnvelope* InformationInterface::Process(SOAPEnvelope& in) {
00040   // Try to extract WSRP object from message
00041   WSRF& wsrp = CreateWSRP(in);
00042   if(!wsrp) { delete &wsrp; return NULL; };
00043   // Check if operation is supported
00044   MutexSLock(lock_,to_lock_);
00045   try {
00046     WSRPGetResourcePropertyDocumentRequest* req = 
00047          dynamic_cast<WSRPGetResourcePropertyDocumentRequest*>(&wsrp);
00048     if(!req) throw std::exception();
00049     if(!(*req)) throw std::exception();
00050     // Requesting whole document
00051     XMLNodeContainer presp; Get(std::list<std::string>(),presp);
00052     XMLNode xresp; if(presp.Size() > 0) xresp=presp[0];
00053     WSRPGetResourcePropertyDocumentResponse resp(xresp);
00054     SOAPEnvelope* out = NULL;
00055     if(resp) {
00056       NS ns;
00057       (out = new SOAPEnvelope(ns))->Swap(resp.SOAP());
00058     };
00059     delete &wsrp;
00060     return out;
00061   } catch(std::exception& e) { };
00062   try {
00063     WSRPGetResourcePropertyRequest* req = 
00064          dynamic_cast<WSRPGetResourcePropertyRequest*>(&wsrp);
00065     if(!req) throw std::exception();
00066     if(!(*req)) throw std::exception();
00067     std::list<std::string> name; name.push_back(req->Name());
00068     XMLNodeContainer presp; Get(name,presp); // Requesting sub-element
00069     WSRPGetResourcePropertyResponse resp;
00070     for(int n = 0;n<presp.Size();++n) {
00071       XMLNode xresp = presp[n];
00072       // TODO: avoid copy
00073       resp.Property(xresp);
00074     };
00075     SOAPEnvelope* out = NULL;
00076     if(resp) {
00077       NS ns;
00078       (out = new SOAPEnvelope(ns))->Swap(resp.SOAP());
00079     };
00080     delete &wsrp;
00081     return out;
00082   } catch(std::exception& e) { };
00083   try {
00084     WSRPGetMultipleResourcePropertiesRequest* req = 
00085          dynamic_cast<WSRPGetMultipleResourcePropertiesRequest*>(&wsrp);
00086     if(!req) throw std::exception();
00087     if(!(*req)) throw std::exception();
00088     WSRPGetMultipleResourcePropertiesResponse resp;
00089     std::vector<std::string> names = req->Names();
00090     for(std::vector<std::string>::iterator iname = names.begin();
00091                               iname != names.end(); ++iname) {
00092       std::list<std::string> name; name.push_back(*iname);
00093       XMLNodeContainer presp; Get(name,presp); // Requesting sub-element
00094       for(int n = 0;n<presp.Size();++n) {
00095         XMLNode xresp = presp[n];
00096         resp.Property(xresp);
00097       };
00098     };
00099     SOAPEnvelope* out = NULL;
00100     if(resp) {
00101       NS ns;
00102       (out = new SOAPEnvelope(ns))->Swap(resp.SOAP());
00103     };
00104     delete &wsrp;
00105     return out;
00106   } catch(std::exception& e) { };
00107   try {
00108     WSRPQueryResourcePropertiesRequest* req = 
00109          dynamic_cast<WSRPQueryResourcePropertiesRequest*>(&wsrp);
00110     if(!req) throw std::exception();
00111     if(!(*req)) throw std::exception();
00112     if(req->Dialect() != XPATH_1_0_URI) {
00113       // TODO: generate proper fault
00114       delete &wsrp;
00115       return SOAPFault::MakeSOAPFault(SOAPFault::Sender,"Query dialect not supported");
00116     }
00117     XMLNodeContainer presp; Get(req->Query(),presp);
00118     WSRPQueryResourcePropertiesResponse resp;
00119     for(int n = 0;n<presp.Size();++n) {
00120       XMLNode xresp = presp[n];
00121       resp.Properties().NewChild(xresp);
00122     };
00123     SOAPEnvelope* out = NULL;
00124     if(resp) {
00125       NS ns;
00126       (out = new SOAPEnvelope(ns))->Swap(resp.SOAP());
00127     };
00128     delete &wsrp;
00129     return out;
00130   } catch(std::exception& e) { };
00131   if(to_lock_) lock_.unlock();
00132   delete &wsrp;
00133   return SOAPFault::MakeSOAPFault(SOAPFault::Sender,"Operation not supported");
00134 }
00135 
00136 SOAPEnvelope* InformationInterface::Process(SOAPEnvelope& in,const InfoFilter& filter,const InfoFilterPolicies& policies,const NS& ns) {
00137   SOAPEnvelope* out = Process(in);
00138   // If error or fault - leave
00139   if(!out) return out;
00140   if(!(*out)) return out;
00141   if(out->IsFault()) return out;
00142   // Otherwise filter body of result
00143   if(filter.Filter(out->Body(),policies,ns)) return out;
00144   // If filtering failed it is safer to return SOAP fault
00145   delete out;
00146   return SOAPFault::MakeSOAPFault(SOAPFault::Sender,"Operation not supported");
00147 }
00148 
00149 
00150 InformationContainer::InformationContainer(void):InformationInterface(true) {
00151 }
00152 
00153 InformationContainer::InformationContainer(XMLNode doc,bool copy):InformationInterface(true) {
00154   if(copy) {
00155     doc.New(doc_);
00156   } else {
00157     doc_=doc;
00158   };
00159 }
00160 
00161 InformationContainer::~InformationContainer(void) {
00162 }
00163 
00164 XMLNode InformationContainer::Acquire(void) {
00165   lock_.lock();
00166   return doc_;
00167 }
00168 
00169 void InformationContainer::Release(void) {
00170   lock_.unlock();
00171 }
00172 
00173 void InformationContainer::Assign(XMLNode doc,bool copy) {
00174   lock_.lock();
00175   if(copy) {
00176     doc.New(doc_);
00177   } else {
00178     doc_=doc;
00179   };
00180   lock_.unlock();
00181 }
00182 
00183 
00184 void InformationContainer::Get(const std::list<std::string>& path,XMLNodeContainer& result) {
00185   std::list<XMLNode> cur_list;
00186   std::list<std::string>::const_iterator cur_name = path.begin();
00187   cur_list.push_back(doc_);
00188   for(;cur_name != path.end(); ++cur_name) {
00189     std::list<XMLNode> new_list;
00190     for(std::list<XMLNode>::iterator cur_node = cur_list.begin();
00191                        cur_node != cur_list.end(); ++cur_node) {
00192       // TODO: namespaces
00193       std::string name = *cur_name;
00194       std::string::size_type p = name.find(':');
00195       if(p != std::string::npos) name=name.substr(p+1);
00196       XMLNode new_node = (*cur_node)[name];
00197       for(;;new_node=new_node[1]) {
00198         if(!new_node) break;
00199         new_list.push_back(new_node);
00200       };
00201     };
00202     cur_list=new_list;
00203   };
00204   result.Add(cur_list);
00205   return;
00206 }
00207 
00208 void InformationContainer::Get(XMLNode query,XMLNodeContainer& result) {
00209   std::string q = query;
00210   NS ns = query.Namespaces();
00211   result.Add(doc_.XPathLookup(q,ns));
00212   return;
00213 }
00214 
00215 InformationRequest::InformationRequest(void):wsrp_(NULL) {
00216   wsrp_=new WSRPGetResourcePropertyDocumentRequest();
00217 }
00218 
00219 InformationRequest::InformationRequest(const std::list<std::string>& path):wsrp_(NULL) {
00220   if(path.size() > 0) {
00221     wsrp_=new WSRPGetResourcePropertyRequest(*(path.begin()));
00222   } else {
00223     wsrp_=new WSRPGetResourcePropertyDocumentRequest();
00224   };
00225 }
00226 
00227 InformationRequest::InformationRequest(const std::list<std::list<std::string> >& paths):wsrp_(NULL) {
00228   std::vector<std::string> names;
00229   std::list<std::list<std::string> >::const_iterator path = paths.begin();
00230   for(;path != paths.end();++path) {
00231     if(path->size() > 0) names.push_back(*(path->begin()));
00232   };
00233   if(names.size() > 1) {
00234     wsrp_=new WSRPGetMultipleResourcePropertiesRequest(names);
00235   } else if(names.size() == 1) {
00236     wsrp_=new WSRPGetResourcePropertyRequest(*(names.begin()));
00237   } else {
00238     wsrp_=new WSRPGetResourcePropertyDocumentRequest();
00239   };
00240 }
00241 
00242 InformationRequest::InformationRequest(XMLNode query):wsrp_(NULL) {
00243   WSRPQueryResourcePropertiesRequest* req = new WSRPQueryResourcePropertiesRequest(XPATH_1_0_URI);
00244   wsrp_=req;
00245   XMLNode q = req->Query();
00246   std::string s = query;
00247   if(!s.empty()) { q=s; return; };
00248   for(int n = 0;;++n) {
00249     XMLNode node = query.Child(n);
00250     if(!node) break;
00251     q.NewChild(node);
00252   };
00253 }
00254 
00255 InformationRequest::~InformationRequest(void) {
00256   if(wsrp_) delete wsrp_;
00257 }
00258 
00259 SOAPEnvelope* InformationRequest::SOAP(void) {
00260   if(!wsrp_) return NULL;
00261   return &(wsrp_->SOAP());
00262 }
00263 
00264 InformationResponse::InformationResponse(SOAPEnvelope& soap) {
00265   // Try to extract WSRP object from message
00266   wsrp_ = &(CreateWSRP(soap));
00267   if(!(*wsrp_)) { delete wsrp_; wsrp_=NULL; };
00268 }
00269 
00270 InformationResponse::~InformationResponse(void) {
00271   if(wsrp_) delete wsrp_;
00272 }
00273 
00274 std::list<XMLNode> InformationResponse::Result(void) {
00275   if(!wsrp_) return std::list<XMLNode>();
00276   std::list<XMLNode> props;
00277   // Check if operation is supported
00278   try {
00279     WSRPGetResourcePropertyDocumentResponse* resp =
00280          dynamic_cast<WSRPGetResourcePropertyDocumentResponse*>(wsrp_);
00281     if(!resp) throw std::exception();
00282     if(!(*resp)) throw std::exception();
00283     props.push_back(resp->Document());
00284     return props;
00285   } catch(std::exception& e) { };
00286   try {
00287     WSRPGetResourcePropertyResponse* resp =
00288          dynamic_cast<WSRPGetResourcePropertyResponse*>(wsrp_);
00289     if(!resp) throw std::exception();
00290     if(!(*resp)) throw std::exception();
00291     for(int n = 0;;++n) {
00292       XMLNode prop = resp->Property(n);
00293       if(!prop) break;
00294       props.push_back(prop);
00295     };
00296     return props;
00297   } catch(std::exception& e) { };
00298   try {
00299     WSRPGetMultipleResourcePropertiesResponse* resp =
00300          dynamic_cast<WSRPGetMultipleResourcePropertiesResponse*>(wsrp_);
00301     if(!resp) throw std::exception();
00302     if(!(*resp)) throw std::exception();
00303     for(int n = 0;;++n) {
00304       XMLNode prop = resp->Property(n);
00305       if(!prop) break;
00306       props.push_back(prop);
00307     };
00308     return props;
00309   } catch(std::exception& e) { };
00310   try {
00311     WSRPQueryResourcePropertiesResponse* resp =
00312          dynamic_cast<WSRPQueryResourcePropertiesResponse*>(wsrp_);
00313     if(!resp) throw std::exception();
00314     if(!(*resp)) throw std::exception();
00315     XMLNode props_ = resp->Properties();
00316     for(int n = 0;;++n) {
00317       XMLNode prop = props_.Child(n);
00318       if(!prop) break;
00319       props.push_back(prop);
00320     };
00321     return props;
00322   } catch(std::exception& e) { };
00323   return props;
00324 }
00325 
00326 } // namespace Arc
00327