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 _str_cmd += ";" ;
00155
00156
00157
00158 BESXMLCommand::set_response() ;
00159 }
00160
00175 void
00176 BESXMLDefineCommand::handle_container_element( const string &action,
00177 xmlNode *node,
00178 const string &value,
00179 map<string,string> &props )
00180 {
00181 string name = props["name"] ;
00182 if( name.empty() )
00183 {
00184 string err = action + " command: container element missing name prop" ;
00185 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00186 }
00187
00188 _containers.push_back( name ) ;
00189
00190 bool have_constraint = false ;
00191 bool have_attributes = false ;
00192 string child_name ;
00193 string child_value ;
00194 string constraint ;
00195 string attributes ;
00196 map<string,string> child_props ;
00197 xmlNode *child_node =
00198 BESXMLUtils::GetFirstChild( node, child_name, child_value, child_props);
00199 while( child_node )
00200 {
00201 if( child_name == "constraint" )
00202 {
00203 if( child_props.size() )
00204 {
00205 string err = action + " command: constraint element "
00206 + "should not contain properties" ;
00207 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00208 }
00209 if( child_value.empty() )
00210 {
00211 string err = action + " command: attributes element "
00212 + "missing value" ;
00213 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00214 }
00215 if( have_constraint )
00216 {
00217 string err = action + " command: container element "
00218 + "contains multiple constraint elements" ;
00219 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00220 }
00221 have_constraint = true ;
00222 _constraints[name] = child_value ;
00223 }
00224 else if( child_name == "attributes" )
00225 {
00226 if( child_props.size() )
00227 {
00228 string err = action + " command: attributes element "
00229 + "should not contain properties" ;
00230 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00231 }
00232 if( child_value.empty() )
00233 {
00234 string err = action + " command: attributes element "
00235 + "missing value" ;
00236 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00237 }
00238 if( have_attributes )
00239 {
00240 string err = action + " command: container element "
00241 + "contains multiple attributes elements" ;
00242 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00243 }
00244 have_attributes = true ;
00245 _attributes[name] = child_value ;
00246 }
00247
00248
00249 props.clear() ;
00250 child_name.clear() ;
00251 child_value.clear() ;
00252 child_node = BESXMLUtils::GetNextChild( child_node, child_name,
00253 child_value, props ) ;
00254 }
00255 }
00256
00268 void
00269 BESXMLDefineCommand::handle_aggregate_element( const string &action,
00270 xmlNode *node,
00271 const string &value,
00272 map<string,string> &props )
00273 {
00274 string handler = props["handler"] ;
00275 string cmd = props["cmd"] ;
00276 if( handler.empty() )
00277 {
00278 string err = action + " command: must specify aggregation handler" ;
00279 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00280 }
00281 if( cmd.empty() )
00282 {
00283 string err = action + " command: must specify aggregation cmd" ;
00284 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00285 }
00286
00287 _dhi.data[AGG_HANDLER] = handler ;
00288 _dhi.data[AGG_CMD] = cmd ;
00289 _str_cmd += " aggregate using " + handler + " by " + cmd ;
00290 }
00291
00294 void
00295 BESXMLDefineCommand::prep_request()
00296 {
00297 vector<string>::iterator i = _containers.begin() ;
00298 vector<string>::iterator e = _containers.end() ;
00299 for( ; i != e; i++ )
00300 {
00301
00302 BESContainer *d =
00303 BESContainerStorageList::TheList()->look_for( (*i) ) ;
00304 d->set_constraint( _constraints[(*i)] ) ;
00305 d->set_attributes( _attributes[(*i)] ) ;
00306 _dhi.containers.push_back( d ) ;
00307 }
00308 }
00309
00316 void
00317 BESXMLDefineCommand::dump( ostream &strm ) const
00318 {
00319 strm << BESIndent::LMarg << "BESXMLDefineCommand::dump - ("
00320 << (void *)this << ")" << endl ;
00321 BESIndent::Indent() ;
00322 BESXMLCommand::dump( strm ) ;
00323 BESIndent::UnIndent() ;
00324 }
00325
00326 BESXMLCommand *
00327 BESXMLDefineCommand::CommandBuilder( const BESDataHandlerInterface &base_dhi )
00328 {
00329 return new BESXMLDefineCommand( base_dhi ) ;
00330 }
00331