00001 00002 #include "DetectorDescription/Core/interface/DDQuery.h" 00003 #include "DetectorDescription/Core/interface/DDCompactView.h" 00004 //#include "DetectorDescription/Base/interface/DDdebug.h" 00005 00006 DDQuery::DDQuery(const DDCompactView & cpv) 00007 : epv_(cpv), scope_(0) 00008 { } 00009 00010 00011 DDQuery::~DDQuery() 00012 { } 00013 00014 00018 void DDQuery::addFilter(const DDFilter & f, log_op op) 00019 { 00020 // cheating a bit with const .... 00021 // Filters have a non-const ::accept(..) member function to allow 00022 // a possible internal state change in a particular filter implementation ... 00023 DDFilter * nonConstFilter = const_cast<DDFilter *>(&f); 00024 criteria_.push_back(std::make_pair(false,nonConstFilter)); 00025 logOps_.push_back(op); 00026 //DCOUT('F',"DDQuery::addFilter(): log-op=" << op ); 00027 } 00028 00029 00030 void DDQuery::setScope(const DDScope & s) 00031 { 00032 scope_ = &s; 00033 } 00034 00035 00036 const std::vector<DDExpandedNode> & DDQuery::exec() 00037 { 00038 result_.clear(); 00039 epv_.reset(); 00040 00041 //bool filtered = bool(filters_.size()); 00042 //bool unfiltered = !filtered; 00043 00044 // currently at least one filter must be set, because 00045 // the query simply consists in applying at least one filter! 00046 if(criteria_.size()) { // <- remove the 'if' when implementing 'the QUERY' 00047 int depth = 0; 00048 bool scoped = false; 00049 DDScope::scope_type dummy; 00050 DDScope::scope_type::const_iterator it = dummy.begin(); 00051 DDScope::scope_type::const_iterator it_end = dummy.end(); 00052 if (scope_) { 00053 const DDScope & sc = *scope_; 00054 it = sc.scope().begin(); 00055 depth = sc.depth(); 00056 scoped = bool(sc.scope().end()-it); 00057 } 00058 00059 bool runonce = scoped ? false : true; 00060 00061 while (runonce || (it != it_end) ) { 00062 if (scoped) epv_.setScope(*it,depth); // set the subtree-scope & depth within 00063 bool run = true; 00064 while(run) { 00065 //DCOUT('F', "DDQuery: examining " << epv_.geoHistory().back() ); 00066 00067 std::vector<const DDsvalues_type *> specs = epv_.specifics(); 00068 std::vector<const DDsvalues_type *>::const_iterator sit = specs.begin(); 00069 //FIXME: find a solution when more then one specifics_type is attached to 00070 //FIXME: particlular nodes ... (merging the specifics-map, etc ...) 00071 //FIXME: for (; sit != specs.end() ; ++sit) { 00072 DDsvalues_type dummy; 00073 const DDsvalues_type * specifics; 00074 if (sit==specs.end()) 00075 specifics = &dummy; 00076 else 00077 specifics = *sit; 00078 00079 criteria_type::iterator it = criteria_.begin(); 00080 logops_type::iterator logOpIt = logOps_.begin(); 00081 // loop over all user-supplied criteria (==filters) 00082 bool result=true; 00083 for (; it != criteria_.end(); ++it, ++logOpIt) { 00084 DDFilter * filter = it->second; 00085 if (filter->accept(epv_)) { 00086 //.geoHistory().back(), // expanded node 00087 //epv_.geoHistory(), 00088 //specifics)) { // geom.history 00089 00090 it->first=true; 00091 //DCOUT('F', " Filter(" << criteria_.end()-it << ") accepted: " << epv_.geoHistory().back()); 00092 } 00093 else { 00094 it->first=false; 00095 } 00096 00097 // now do the logical-operations on the results encountered so far: 00098 if (*logOpIt==AND) { // AND 00099 result &= it->first; 00100 } 00101 else { // OR 00102 result |= it->first; 00103 } 00104 } // <-- loop over filters 00105 //DCOUT('f', "-------------------"); 00106 if (result) { 00107 // HERE THE ACTUAL QUERY SHOULD BE INVOKED!!! 00108 result_.push_back(epv_.geoHistory().back()); 00109 } 00110 //} <-- loop over std::vector of specifics_type ... 00111 run = epv_.next(); 00112 } 00113 if (scoped) 00114 ++it; 00115 else 00116 runonce=false; 00117 } 00118 } 00119 return result_; 00120 }