00001 #include <typeinfo>
00002 #include <map>
00003 #include <stdexcept>
00004
00005 #include "AIDA_TupleFactory.h"
00006 #include "AIDA_Dev/IDevTree.h"
00007 #include "AIDA_Dev/IDevTupleFactory.h"
00008 #include "AIDA_Dev/IDevFilterFactory.h"
00009 #include "AIDA_Dev/IDevEvaluatorFactory.h"
00010 #include "AIDA_Dev/IDevTuple.h"
00011 #include "AIDA_Dev/IBackingStore.h"
00012 #include "AIDA_Dev/IStore.h"
00013 #include "AIDA_Dev/ITupleHeader.h"
00014 #include "AIDA/IFilter.h"
00015
00016 #include "TupleVariableCopy.h"
00017 #include "TupleVariableDescriptionBuilder.h"
00018
00019
00020 #ifdef ANAPHE_TUPLE_NO_EXCEPTIONS_TO_USER
00021 #include <iostream>
00022 #define TUPLE_REPORT_ERROR( XXX ) std::cerr << XXX << std::endl
00023 #endif
00024
00025 static const std::string emptyString = "";
00026
00027 static const std::string doubleType = "double";
00028 static const std::string floatType = "float";
00029 static const std::string intType = "int";
00030 static const std::string shortType = "short";
00031 static const std::string longType = "long";
00032 static const std::string charType = "char";
00033 static const std::string boolType = "bool";
00034 static const std::string stringType = "std::string";
00035 static const std::string tupleType = "AIDA::ITuple";
00036
00037
00038 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::AIDA_TupleFactory( AIDA::Dev::IDevTree& tree,
00039 AIDA::Dev::IDevTupleFactory& tupleFactory,
00040 AIDA::Dev::IDevFilterFactory& filterFactory,
00041 AIDA::Dev::IDevEvaluatorFactory& evaluatorFactory ):
00042 m_tree( tree ),
00043 m_tupleFactory( tupleFactory ),
00044 m_filterFactory( filterFactory ),
00045 m_evaluatorFactory( evaluatorFactory )
00046 {}
00047
00048
00049 AIDA::ITuple*
00050 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::create( const std::string& name,
00051 const std::string& title,
00052 const std::vector<std::string>& columnNames,
00053 const std::vector<std::string>& columnTypes,
00054 const std::string & options )
00055 {
00056 try{
00057 AIDA::Dev::IBackingStore* store = dynamic_cast<AIDA::Dev::IBackingStore*>( m_tree.store(".") );
00058 if ( ! store ) throw std::runtime_error( "Tuple factory could not access the backing store" );
00059 AIDA::Dev::IDevTuple* tuple = m_tupleFactory.create( store, title, options );
00060 if ( tuple ) {
00061 tuple->setName( name );
00062 if ( ! m_tree.add( tuple ) ) {
00063 delete tuple;
00064 tuple = 0;
00065 }
00066 else {
00067 tuple->header().setPathInStore( m_tree.pathInStore( *tuple ) );
00068 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder builder( m_tupleFactory );
00069 if ( ! builder.buildDescription( tuple->header(), columnNames, columnTypes ) ) {
00070 delete tuple;
00071 tuple = 0;
00072 }
00073 else if ( ! store->writeTupleHeader( tuple->header() ) ) {
00074 delete tuple;
00075 tuple = 0;
00076 }
00077 }
00078 }
00079 return tuple;
00080 }
00081 catch( std::bad_cast ) {
00082 return 0;
00083 }
00084 #ifdef ANAPHE_TUPLE_NO_EXCEPTIONS_TO_USER
00085 catch( std::exception& e ) {
00086 TUPLE_REPORT_ERROR( e.what() );
00087 return 0;
00088 }
00089 #endif
00090 }
00091
00092
00093 AIDA::ITuple*
00094 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::create( const std::string& name,
00095 const std::string& title,
00096 const std::string& columns,
00097 const std::string& options )
00098 {
00099 try{
00100 AIDA::Dev::IBackingStore* store = dynamic_cast<AIDA::Dev::IBackingStore*>( m_tree.store(".") );
00101 if ( ! store ) throw std::runtime_error( "Tuple factory could not access the backing store" );
00102 AIDA::Dev::IDevTuple* tuple = m_tupleFactory.create( store, title, options );
00103 if ( tuple ) {
00104 tuple->setName( name );
00105 if ( ! m_tree.add( tuple ) ) {
00106 delete tuple;
00107 tuple = 0;
00108 }
00109 else {
00110 tuple->header().setPathInStore( m_tree.pathInStore( *tuple ) );
00111 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder builder( m_tupleFactory );
00112 if (! builder.buildDescription( tuple->header(), columns ) ) {
00113 delete tuple;
00114 tuple = 0;
00115 }
00116 else if ( ! store->writeTupleHeader( tuple->header() ) ) {
00117 delete tuple;
00118 tuple = 0;
00119 }
00120 }
00121 }
00122 return tuple;
00123 }
00124 catch( std::bad_cast ) {
00125 return 0;
00126 }
00127 #ifdef ANAPHE_TUPLE_NO_EXCEPTIONS_TO_USER
00128 catch( std::exception& e ) {
00129 TUPLE_REPORT_ERROR( e.what() );
00130 return 0;
00131 }
00132 #endif
00133 }
00134
00135
00136 AIDA::ITuple*
00137 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::createChained( const std::string& name,
00138 const std::string& title,
00139 const std::vector<AIDA::ITuple*>& tupleSet )
00140 {
00141 #ifdef ANAPHE_TUPLE_NO_EXCEPTIONS_TO_USER
00142 try {
00143 #endif
00144 std::vector<AIDA::Dev::IDevTuple*> tuples;
00145 for ( unsigned int i = 0; i < tupleSet.size(); ++i ) {
00146 AIDA::ITuple* p = tupleSet[i];
00147 if ( !p ) return 0;
00148 tuples.push_back( dynamic_cast< AIDA::Dev::IDevTuple* >( p ) );
00149 if ( ! tuples.back() ) return 0;
00150 }
00151 AIDA::Dev::IDevTuple* tuple = m_tupleFactory.createChained( title, tuples );
00152 if ( tuple ) {
00153 tuple->setName( name );
00154 if ( ! m_tree.add( tuple ) ) {
00155 delete tuple;
00156 tuple = 0;
00157 }
00158 }
00159 return tuple;
00160 #ifdef ANAPHE_TUPLE_NO_EXCEPTIONS_TO_USER
00161 }
00162 catch( std::exception& e ) {
00163 TUPLE_REPORT_ERROR( e.what() );
00164 return 0;
00165 }
00166 #endif
00167 }
00168
00169
00170 AIDA::ITuple*
00171 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::createChained( const std::string& name,
00172 const std::string& title,
00173 const std::vector<std::string>& tupleSet )
00174 {
00175 #ifdef ANAPHE_TUPLE_NO_EXCEPTIONS_TO_USER
00176 try {
00177 #endif
00178 std::vector<AIDA::Dev::IDevTuple*> tuples;
00179 for ( unsigned int i = 0; i < tupleSet.size(); ++i ) {
00180 AIDA::IManagedObject* p = m_tree.find( tupleSet[i] );
00181 if ( !p ) return 0;
00182 tuples.push_back( dynamic_cast< AIDA::Dev::IDevTuple* >( p ) );
00183 if ( ! tuples.back() ) return 0;
00184 }
00185 AIDA::Dev::IDevTuple* tuple = m_tupleFactory.createChained( title, tuples );
00186 if ( tuple ) {
00187 tuple->setName( name );
00188 if ( ! m_tree.add( tuple ) ) {
00189 delete tuple;
00190 tuple = 0;
00191 }
00192 }
00193 return tuple;
00194 #ifdef ANAPHE_TUPLE_NO_EXCEPTIONS_TO_USER
00195 }
00196 catch( std::exception& e ) {
00197 TUPLE_REPORT_ERROR( e.what() );
00198 return 0;
00199 }
00200 #endif
00201 }
00202
00203
00204 AIDA::ITuple*
00205 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::createFiltered( const std::string& name,
00206 AIDA::ITuple& tuple,
00207 AIDA::IFilter& filter )
00208 {
00209 const int ncolumns = tuple.columns();
00210 std::vector<std::string> names( ncolumns );
00211 std::vector<std::string> types( ncolumns );
00212 std::vector< Anaphe::AIDA_Tuple_native::TupleVariableCopyBase* > copyMethods;
00213 bool typesOK = true;
00214 for ( int i = 0; i < ncolumns; ++i ) {
00215 names[i] = tuple.columnName( i );
00216 std::string type = tuple.columnType( i );
00217 types[i] = type;
00218 if ( type == doubleType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyDouble );
00219 else if ( type == floatType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyFloat );
00220 else if ( type == longType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyLong );
00221 else if ( type == intType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyInt );
00222 else if ( type == shortType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyShort );
00223 else if ( type == charType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyChar );
00224 else if ( type == boolType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyBoolean );
00225 else if ( type == stringType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyString );
00226 else if ( type == tupleType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyTuple );
00227 else {
00228 typesOK = false;
00229 break;
00230 }
00231 }
00232 if ( ! typesOK ) {
00233 for ( unsigned int i = 0; i < copyMethods.size(); ++i ) delete copyMethods[i];
00234 return 0;
00235 }
00236
00237 AIDA::ITuple* newTuple = this->create( name, tuple.title(), names, types, emptyString );
00238 if ( ! newTuple ) {
00239 for ( unsigned int i = 0; i < copyMethods.size(); ++i ) delete copyMethods[i];
00240 return 0;
00241 }
00242
00243 filter.initialize( tuple );
00244 tuple.start();
00245 while( tuple.next() ) {
00246 if ( filter.accept() ) {
00247 newTuple->addRow();
00248
00249 for ( int i = 0; i < ncolumns; ++i ) {
00250 copyMethods[i]->copyTupleVariable( tuple, i, *newTuple, i );
00251 }
00252 }
00253 }
00254
00255 for ( unsigned int i = 0; i < copyMethods.size(); ++i ) delete copyMethods[i];
00256 newTuple->start();
00257 return newTuple;
00258 }
00259
00260
00261 AIDA::ITuple*
00262 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::createFiltered( const std::string& name,
00263 AIDA::ITuple& tuple,
00264 AIDA::IFilter& filter,
00265 const std::vector<std::string>& columns )
00266 {
00267 int ncolumns = columns.size();
00268 std::vector<std::string> names;
00269 std::vector<std::string> types;
00270 std::map<int, int> columnFilteredToParent;
00271 std::vector< Anaphe::AIDA_Tuple_native::TupleVariableCopyBase* > copyMethods;
00272 bool typesOK = true;
00273 for ( int i = 0; i < ncolumns; ++i ) {
00274 const int j = tuple.findColumn( columns[i] );
00275 if ( j < 0 ) continue;
00276 names.push_back( tuple.columnName( j ) );
00277 std::string type = tuple.columnType( j );
00278 types.push_back( type );
00279 columnFilteredToParent.insert( std::make_pair( static_cast<int>( names.size() - 1 ), j ) );
00280 if ( type == doubleType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyDouble );
00281 else if ( type == floatType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyFloat );
00282 else if ( type == longType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyLong );
00283 else if ( type == intType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyInt );
00284 else if ( type == shortType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyShort );
00285 else if ( type == charType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyChar );
00286 else if ( type == boolType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyBoolean );
00287 else if ( type == stringType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyString );
00288 else if ( type == tupleType ) copyMethods.push_back( new Anaphe::AIDA_Tuple_native::TupleVarialbeCopyTuple );
00289 else {
00290 typesOK = false;
00291 break;
00292 }
00293 }
00294 if ( ! typesOK ) {
00295 for ( unsigned int i = 0; i < copyMethods.size(); ++i ) delete copyMethods[i];
00296 return 0;
00297 }
00298 ncolumns = names.size();
00299
00300 AIDA::ITuple* newTuple = this->create( name, tuple.title(), names, types, emptyString );
00301 if ( ! newTuple ) {
00302 for ( unsigned int i = 0; i < copyMethods.size(); ++i ) delete copyMethods[i];
00303 return 0;
00304 }
00305 filter.initialize( tuple );
00306 tuple.start();
00307 while( tuple.next() ) {
00308 if ( filter.accept() ) {
00309 newTuple->addRow();
00310
00311 for ( int i = 0; i < ncolumns; ++i ) {
00312 copyMethods[i]->copyTupleVariable( tuple, columnFilteredToParent[i], *newTuple, i );
00313 }
00314 }
00315 }
00316 for ( unsigned int i = 0; i < copyMethods.size(); ++i ) delete copyMethods[i];
00317 newTuple->start();
00318 return newTuple;
00319 }
00320
00321
00322 AIDA::IFilter*
00323 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::createFilter( const std::string& expression )
00324 {
00325 return m_filterFactory.createScripted( expression );
00326 }
00327
00328
00329 AIDA::IFilter*
00330 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::createFilter( const std::string& expression,
00331 int rowsToProcess,
00332 int startingRow )
00333 {
00334 return m_filterFactory.createScripted( expression, rowsToProcess, startingRow );
00335 }
00336
00337
00338 AIDA::IEvaluator*
00339 Anaphe::AIDA_Tuple_native::AIDA_TupleFactory::createEvaluator( const std::string& expression )
00340 {
00341 return m_evaluatorFactory.createScripted( expression );
00342 }