00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "BESXMLDefineCommand.h"
00034 #include "BESContainerStorageList.h"
00035 #include "BESXMLUtils.h"
00036 #include "BESUtil.h"
00037 #include "BESResponseNames.h"
00038 #include "BESDataNames.h"
00039 #include "BESSyntaxUserError.h"
00040 #include "BESDebug.h"
00041
00042 BESXMLDefineCommand::BESXMLDefineCommand( const BESDataHandlerInterface &base_dhi )
00043 : BESXMLCommand( base_dhi )
00044 {
00045 }
00046
00064 void
00065 BESXMLDefineCommand::parse_request( xmlNode *node )
00066 {
00067 string value ;
00068 string def_name ;
00069 string action ;
00070 map<string, string> props ;
00071
00072
00073 BESXMLUtils::GetNodeInfo( node, action, value, props ) ;
00074 if( action != DEFINE_RESPONSE_STR )
00075 {
00076 string err = "The specified command " + action
00077 + " is not a set context command" ;
00078 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00079 }
00080
00081 _dhi.action = DEFINE_RESPONSE ;
00082
00083 def_name = props["name"] ;
00084 if( def_name.empty() )
00085 {
00086 string err = action + " command: definition name missing" ;
00087 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00088 }
00089
00090 _dhi.data[DEF_NAME] = def_name ;
00091 _str_cmd = (string)"define " + def_name ;
00092
00093 int num_containers = 0 ;
00094 string child_name ;
00095 string child_value ;
00096 props.clear() ;
00097 xmlNode *child_node =
00098 BESXMLUtils::GetFirstChild( node, child_name, child_value, props ) ;
00099 while( child_node )
00100 {
00101 if( child_name == "container" )
00102 {
00103 handle_container_element( action, child_node, child_value, props ) ;
00104 num_containers++ ;
00105 }
00106 else if( child_name == "aggregate" )
00107 {
00108 handle_aggregate_element( action, child_node, child_value, props ) ;
00109 }
00110
00111
00112 props.clear() ;
00113 child_name.clear() ;
00114 child_value.clear() ;
00115 child_node = BESXMLUtils::GetNextChild( child_node, child_name,
00116 child_value, props ) ;
00117 }
00118
00119 if( num_containers < 1 )
00120 {
00121 string err = action + "The define element must contain at least "
00122 + "one container element" ;
00123 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00124 }
00125
00126 _str_cmd += " as " ;
00127 bool first = true ;
00128 vector<string>::iterator i = _containers.begin() ;
00129 vector<string>::iterator e = _containers.end() ;
00130 for( ; i != e; i++ )
00131 {
00132 if( !first ) _str_cmd += "," ;
00133 _str_cmd += (*i) ;
00134 first = false ;
00135 }
00136 if( _constraints.size() )
00137 {
00138 _str_cmd += " with " ;
00139 first = true ;
00140 map<string,string>::iterator ci = _constraints.begin() ;
00141 map<string,string>::iterator ce = _constraints.end() ;
00142 for( ; ci != ce; ci++ )
00143 {
00144 if( !first ) _str_cmd += "," ;
00145 _str_cmd += (*ci).first + ".constraint=\"" + (*ci).second + "\"" ;
00146 first = false ;
00147 string attrs = _attributes[(*ci).first] ;
00148 if( !attrs.empty() )
00149 {
00150 _str_cmd += "," + (*ci).first + ".attributes=\"" + attrs + "\"";
00151 }
00152 }
00153 }
00154
00155
00156
00157 BESXMLCommand::set_response() ;
00158 }
00159
00174 void
00175 BESXMLDefineCommand::handle_container_element( const string &action,
00176 xmlNode *node,
00177 const string &value,
00178 map<string,string> &props )
00179 {
00180 string name = props["name"] ;
00181 if( name.empty() )
00182 {
00183 string err = action + " command: container element missing name prop" ;
00184 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00185 }
00186
00187 _containers.push_back( name ) ;
00188
00189 bool have_constraint = false ;
00190 bool have_attributes = false ;
00191 string child_name ;
00192 string child_value ;
00193 string constraint ;
00194 string attributes ;
00195 map<string,string> child_props ;
00196 xmlNode *child_node =
00197 BESXMLUtils::GetFirstChild( node, child_name, child_value, child_props);
00198 while( child_node )
00199 {
00200 if( child_name == "constraint" )
00201 {
00202 if( child_props.size() )
00203 {
00204 string err = action + " command: constraint element "
00205 + "should not contain properties" ;
00206 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00207 }
00208 if( child_value.empty() )
00209 {
00210 string err = action + " command: attributes element "
00211 + "missing value" ;
00212 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00213 }
00214 if( have_constraint )
00215 {
00216 string err = action + " command: container element "
00217 + "contains multiple constraint elements" ;
00218 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00219 }
00220 have_constraint = true ;
00221 _constraints[name] = child_value ;
00222 }
00223 else if( child_name == "attributes" )
00224 {
00225 if( child_props.size() )
00226 {
00227 string err = action + " command: attributes element "
00228 + "should not contain properties" ;
00229 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00230 }
00231 if( child_value.empty() )
00232 {
00233 string err = action + " command: attributes element "
00234 + "missing value" ;
00235 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00236 }
00237 if( have_attributes )
00238 {
00239 string err = action + " command: container element "
00240 + "contains multiple attributes elements" ;
00241 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00242 }
00243 have_attributes = true ;
00244 _attributes[name] = child_value ;
00245 }
00246
00247
00248 props.clear() ;
00249 child_name.clear() ;
00250 child_value.clear() ;
00251 child_node = BESXMLUtils::GetNextChild( child_node, child_name,
00252 child_value, props ) ;
00253 }
00254 }
00255
00267 void
00268 BESXMLDefineCommand::handle_aggregate_element( const string &action,
00269 xmlNode *node,
00270 const string &value,
00271 map<string,string> &props )
00272 {
00273 string handler = props["handler"] ;
00274 string cmd = props["cmd"] ;
00275 if( handler.empty() )
00276 {
00277 string err = action + " command: must specify aggregation handler" ;
00278 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00279 }
00280 if( cmd.empty() )
00281 {
00282 string err = action + " command: must specify aggregation cmd" ;
00283 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00284 }
00285
00286 _dhi.data[AGG_HANDLER] = handler ;
00287 _dhi.data[AGG_CMD] = cmd ;
00288 _str_cmd += " aggregate using " + handler + " by " + cmd ;
00289 }
00290
00293 void
00294 BESXMLDefineCommand::prep_request()
00295 {
00296 vector<string>::iterator i = _containers.begin() ;
00297 vector<string>::iterator e = _containers.end() ;
00298 for( ; i != e; i++ )
00299 {
00300
00301 BESContainer *d =
00302 BESContainerStorageList::TheList()->look_for( (*i) ) ;
00303 d->set_constraint( _constraints[(*i)] ) ;
00304 d->set_attributes( _attributes[(*i)] ) ;
00305 _dhi.containers.push_back( d ) ;
00306 }
00307 }
00308
00315 void
00316 BESXMLDefineCommand::dump( ostream &strm ) const
00317 {
00318 strm << BESIndent::LMarg << "BESXMLDefineCommand::dump - ("
00319 << (void *)this << ")" << endl ;
00320 BESIndent::Indent() ;
00321 BESXMLCommand::dump( strm ) ;
00322 BESIndent::UnIndent() ;
00323 }
00324
00325 BESXMLCommand *
00326 BESXMLDefineCommand::CommandBuilder( const BESDataHandlerInterface &base_dhi )
00327 {
00328 return new BESXMLDefineCommand( base_dhi ) ;
00329 }
00330