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 _default_constraint( "" )
00045 {
00046 }
00047
00065 void
00066 BESXMLDefineCommand::parse_request( xmlNode *node )
00067 {
00068 string value ;
00069 string def_name ;
00070 string action ;
00071 map<string, string> props ;
00072
00073
00074 BESXMLUtils::GetNodeInfo( node, action, value, props ) ;
00075 if( action != DEFINE_RESPONSE_STR )
00076 {
00077 string err = "The specified command " + action
00078 + " is not a set context command" ;
00079 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00080 }
00081
00082 _dhi.action = DEFINE_RESPONSE ;
00083
00084 def_name = props["name"] ;
00085 if( def_name.empty() )
00086 {
00087 string err = action + " command: definition name missing" ;
00088 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00089 }
00090
00091 _dhi.data[DEF_NAME] = def_name ;
00092 _str_cmd = (string)"define " + def_name ;
00093
00094 int num_containers = 0 ;
00095 string child_name ;
00096 string child_value ;
00097 props.clear() ;
00098 xmlNode *child_node =
00099 BESXMLUtils::GetFirstChild( node, child_name, child_value, props ) ;
00100 while( child_node )
00101 {
00102 if( child_name == "constraint" )
00103 {
00104
00105 _default_constraint = child_value ;
00106 }
00107 else if( child_name == "container" )
00108 {
00109 handle_container_element( action, child_node, child_value, props ) ;
00110 num_containers++ ;
00111 }
00112 else if( child_name == "aggregate" )
00113 {
00114 handle_aggregate_element( action, child_node, child_value, props ) ;
00115 }
00116
00117
00118 props.clear() ;
00119 child_name.clear() ;
00120 child_value.clear() ;
00121 child_node = BESXMLUtils::GetNextChild( child_node, child_name,
00122 child_value, props ) ;
00123 }
00124
00125 if( num_containers < 1 )
00126 {
00127 string err = action + "The define element must contain at least "
00128 + "one container element" ;
00129 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00130 }
00131
00132 _str_cmd += " as " ;
00133 bool first = true ;
00134 vector<string>::iterator i = _containers.begin() ;
00135 vector<string>::iterator e = _containers.end() ;
00136 for( ; i != e; i++ )
00137 {
00138 if( !first ) _str_cmd += "," ;
00139 _str_cmd += (*i) ;
00140 first = false ;
00141 }
00142 if( _constraints.size() )
00143 {
00144 _str_cmd += " with " ;
00145 first = true ;
00146 map<string,string>::iterator ci = _constraints.begin() ;
00147 map<string,string>::iterator ce = _constraints.end() ;
00148 for( ; ci != ce; ci++ )
00149 {
00150 if( !first ) _str_cmd += "," ;
00151 _str_cmd += (*ci).first + ".constraint=\"" + (*ci).second + "\"" ;
00152 first = false ;
00153 string attrs = _attributes[(*ci).first] ;
00154 if( !attrs.empty() )
00155 {
00156 _str_cmd += "," + (*ci).first + ".attributes=\"" + attrs + "\"";
00157 }
00158 }
00159 }
00160 _str_cmd += ";" ;
00161
00162
00163
00164 BESXMLCommand::set_response() ;
00165 }
00166
00181 void
00182 BESXMLDefineCommand::handle_container_element( const string &action,
00183 xmlNode *node,
00184 const string &value,
00185 map<string,string> &props )
00186 {
00187 string name = props["name"] ;
00188 if( name.empty() )
00189 {
00190 string err = action + " command: container element missing name prop" ;
00191 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00192 }
00193
00194 _containers.push_back( name ) ;
00195
00196 bool have_constraint = false ;
00197 bool have_attributes = false ;
00198 string child_name ;
00199 string child_value ;
00200 string constraint ;
00201 string attributes ;
00202 map<string,string> child_props ;
00203 xmlNode *child_node =
00204 BESXMLUtils::GetFirstChild( node, child_name, child_value, child_props);
00205 while( child_node )
00206 {
00207 if( child_name == "constraint" )
00208 {
00209 if( child_props.size() )
00210 {
00211 string err = action + " command: constraint element "
00212 + "should not contain properties" ;
00213 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00214 }
00215 if( child_value.empty() )
00216 {
00217 string err = action + " command: attributes element "
00218 + "missing value" ;
00219 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00220 }
00221 if( have_constraint )
00222 {
00223 string err = action + " command: container element "
00224 + "contains multiple constraint elements" ;
00225 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00226 }
00227 have_constraint = true ;
00228 _constraints[name] = child_value ;
00229 }
00230 else if( child_name == "attributes" )
00231 {
00232 if( child_props.size() )
00233 {
00234 string err = action + " command: attributes element "
00235 + "should not contain properties" ;
00236 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00237 }
00238 if( child_value.empty() )
00239 {
00240 string err = action + " command: attributes element "
00241 + "missing value" ;
00242 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00243 }
00244 if( have_attributes )
00245 {
00246 string err = action + " command: container element "
00247 + "contains multiple attributes elements" ;
00248 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00249 }
00250 have_attributes = true ;
00251 _attributes[name] = child_value ;
00252 }
00253
00254
00255 props.clear() ;
00256 child_name.clear() ;
00257 child_value.clear() ;
00258 child_node = BESXMLUtils::GetNextChild( child_node, child_name,
00259 child_value, props ) ;
00260 }
00261 }
00262
00274 void
00275 BESXMLDefineCommand::handle_aggregate_element( const string &action,
00276 xmlNode *node,
00277 const string &value,
00278 map<string,string> &props )
00279 {
00280 string handler = props["handler"] ;
00281 string cmd = props["cmd"] ;
00282 if( handler.empty() )
00283 {
00284 string err = action + " command: must specify aggregation handler" ;
00285 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00286 }
00287 if( cmd.empty() )
00288 {
00289 string err = action + " command: must specify aggregation cmd" ;
00290 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00291 }
00292
00293 _dhi.data[AGG_HANDLER] = handler ;
00294 _dhi.data[AGG_CMD] = cmd ;
00295 _str_cmd += " aggregate using " + handler + " by " + cmd ;
00296 }
00297
00300 void
00301 BESXMLDefineCommand::prep_request()
00302 {
00303 vector<string>::iterator i = _containers.begin() ;
00304 vector<string>::iterator e = _containers.end() ;
00305 for( ; i != e; i++ )
00306 {
00307
00308 BESContainer *d =
00309 BESContainerStorageList::TheList()->look_for( (*i) ) ;
00310 string constraint = _constraints[(*i)] ;
00311 if( constraint.empty() ) constraint = _default_constraint ;
00312 d->set_constraint( constraint ) ;
00313 d->set_attributes( _attributes[(*i)] ) ;
00314 _dhi.containers.push_back( d ) ;
00315 BESDEBUG( "xml", "define using container: " << endl << *d << endl ) ;
00316 }
00317 }
00318
00325 void
00326 BESXMLDefineCommand::dump( ostream &strm ) const
00327 {
00328 strm << BESIndent::LMarg << "BESXMLDefineCommand::dump - ("
00329 << (void *)this << ")" << endl ;
00330 BESIndent::Indent() ;
00331 BESXMLCommand::dump( strm ) ;
00332 BESIndent::UnIndent() ;
00333 }
00334
00335 BESXMLCommand *
00336 BESXMLDefineCommand::CommandBuilder( const BESDataHandlerInterface &base_dhi )
00337 {
00338 return new BESXMLDefineCommand( base_dhi ) ;
00339 }
00340