00001 #include "SubTree.h"
00002 #include "PathParser.h"
00003 #include "MountInfo.h"
00004
00005 #include "AIDA_Dev/IDevTree.h"
00006 #include "AIDA_Dev/IStore.h"
00007
00008 Anaphe::AIDA_Tree_native::SubTree::SubTree( const std::string& name,
00009 AIDA::Dev::IDevTree* masterTree ):
00010 m_name( name ),
00011 m_masterTree( masterTree ),
00012 m_mountInfo( 0 ),
00013 m_subTrees(),
00014 m_objects(),
00015 m_links()
00016 {}
00017
00018
00019 Anaphe::AIDA_Tree_native::SubTree::~SubTree()
00020 {
00021 if ( m_mountInfo ) delete m_mountInfo;
00022 for ( std::map< std::string, AIDA::IManagedObject* >::iterator iObj = m_objects.begin();
00023 iObj != m_objects.end(); ++iObj ) {
00024 delete iObj->second;
00025 }
00026 for ( std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.begin();
00027 iDir != m_subTrees.end(); ++iDir ) {
00028 delete iDir->second;
00029 }
00030 }
00031
00032
00033 bool
00034 Anaphe::AIDA_Tree_native::SubTree::add( AIDA::IManagedObject * object,
00035 std::list< std::string >& path,
00036 bool overWrite,
00037 std::map< const AIDA::IManagedObject*, std::string >& objectMap,
00038 bool copy,
00039 bool addInStore )
00040 {
00041 if ( m_mountInfo ) {
00042 if ( ! object ) return false;
00043 std::list< std::string > targetNames = anaphe_path_parser.formNames( m_mountInfo->targetPath() );
00044 for ( std::list< std::string >::const_iterator iName = path.begin(); iName != path.end(); ++iName ) {
00045 targetNames.push_back( *iName );
00046 }
00047 if ( copy ) {
00048 return m_mountInfo->targetTree()->copyAndAdd( object, "/" + anaphe_path_parser.formPath( targetNames ) );
00049 }
00050 else {
00051 targetNames.pop_back();
00052 return m_mountInfo->targetTree()->add( object, "/" + anaphe_path_parser.formPath( targetNames ) );
00053 }
00054 }
00055
00056 const std::string& name = path.front();
00057
00058 if ( path.size() > 1 ) {
00059 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iSubDir = m_subTrees.find( name );
00060 if ( iSubDir == m_subTrees.end() ) {
00061 return false;
00062 }
00063 else {
00064 path.pop_front();
00065 return iSubDir->second->add( object, path, overWrite, objectMap, copy, addInStore );
00066 }
00067 }
00068
00069
00070
00071 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iSubDir = m_subTrees.find( name );
00072 if ( iSubDir != m_subTrees.end() ) {
00073 if ( copy &&
00074 iSubDir->second->m_mountInfo == 0 &&
00075 iSubDir->second->m_subTrees.find( name ) != iSubDir->second->m_subTrees.end() ) {
00076 return iSubDir->second->add( object, path, overWrite, objectMap, copy, addInStore );
00077 }
00078 else return false;
00079 }
00080
00081
00082 if ( m_objects.find( name ) != m_objects.end() ) {
00083 if ( overWrite ) {
00084
00085 m_masterTree->rm( m_name + name );
00086 m_objects.insert( std::make_pair( name, object ) );
00087 if ( object ) {
00088 if ( copy ) {
00089 AIDA::IManagedObject* newObject = m_masterTree->nativeStore()->copyAndWrite( *object, m_name + name );
00090 m_objects[ name ] = newObject;
00091 objectMap[ newObject ] = m_name + name;
00092 }
00093 else {
00094 if (addInStore) m_masterTree->nativeStore()->writeObject( *object, m_name + name );
00095 objectMap[ object ] = m_name + name;
00096 }
00097 }
00098 return true;
00099 }
00100 else return false;
00101 }
00102 else {
00103
00104
00105
00106 if ( m_links.find( name ) != m_links.end() ){
00107 if ( overWrite ) {
00108 m_links.erase( name );
00109 }
00110 else {
00111 return false;
00112 }
00113 }
00114 m_objects.insert( std::make_pair( name, object ) );
00115 if ( object ) {
00116 if ( copy ) {
00117 AIDA::IManagedObject* newObject = m_masterTree->nativeStore()->copyAndWrite( *object, m_name + name );
00118 m_objects[ name ] = newObject;
00119 objectMap[ newObject ] = m_name + name;
00120 }
00121 else {
00122 if (addInStore) m_masterTree->nativeStore()->writeObject( *object, m_name + name );
00123 objectMap[ object ] = m_name + name;
00124 }
00125 }
00126 return true;
00127 }
00128 }
00129
00130
00131 AIDA::Dev::IStore*
00132 Anaphe::AIDA_Tree_native::SubTree::store( std::list< std::string >& path )
00133 {
00134 if ( m_mountInfo ) {
00135 return m_mountInfo->targetTree()->store( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ) );
00136 }
00137 const std::string& dirName = path.front();
00138 if ( path.size() > 1 ) {
00139 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00140 if ( iDir == m_subTrees.end() ) {
00141 return 0;
00142 }
00143 path.pop_front();
00144 return iDir->second->store( path );
00145 }
00146
00147
00148 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00149 if ( iDir != m_subTrees.end() ) {
00150 if ( iDir->second->m_mountInfo ) {
00151 return iDir->second->m_mountInfo->targetTree()->store( iDir->second->m_mountInfo->targetPath() );
00152 }
00153 else return m_masterTree->nativeStore();
00154 }
00155 if ( m_objects.find( dirName ) != m_objects.end() ) return m_masterTree->nativeStore();
00156 std::map< std::string, std::string >::const_iterator iLink = m_links.find( dirName );
00157 if ( iLink == m_links.end() ) return 0;
00158 else return m_masterTree->store( iLink->second );
00159 }
00160
00161
00162 bool
00163 Anaphe::AIDA_Tree_native::SubTree::existsDirectory( std::list< std::string >& path )
00164 {
00165 if ( m_mountInfo ) {
00166 return m_mountInfo->targetTree()->existsDirectory( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ) );
00167 }
00168 const std::string& dirName = path.front();
00169 if ( path.size() > 1 ) {
00170 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00171 if ( iDir == m_subTrees.end() ) {
00172 return false;
00173 }
00174 path.pop_front();
00175 return iDir->second->existsDirectory( path );
00176 }
00177
00178
00179 if ( m_subTrees.find( dirName ) != m_subTrees.end() ) return true;
00180 else return false;
00181 }
00182
00183
00184 bool
00185 Anaphe::AIDA_Tree_native::SubTree::mkdir( std::list< std::string >& path )
00186 {
00187 if ( m_mountInfo ) {
00188 return m_mountInfo->targetTree()->mkdir( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ) );
00189 }
00190 const std::string& dirName = path.front();
00191 if ( path.size() > 1 ) {
00192 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00193 if ( iDir == m_subTrees.end() ) {
00194 return false;
00195 }
00196 path.pop_front();
00197 return iDir->second->mkdir( path );
00198 }
00199
00200
00201 if ( m_objects.find( dirName ) != m_objects.end() ) return false;
00202 if ( m_links.find( dirName ) != m_links.end() ) return false;
00203 if ( m_subTrees.find( dirName ) != m_subTrees.end() ) return false;
00204 if ( dirName == "" || dirName == "." || dirName == ".." ) return false;
00205
00206 m_subTrees.insert( std::make_pair( dirName, new Anaphe::AIDA_Tree_native::SubTree( m_name + dirName + "/", m_masterTree ) ) );
00207 return true;
00208 }
00209
00210
00211 bool
00212 Anaphe::AIDA_Tree_native::SubTree::mkdirs( std::list< std::string >& path )
00213 {
00214 if ( m_mountInfo ) {
00215 return m_mountInfo->targetTree()->mkdirs( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ) );
00216 }
00217 if ( path.size() == 1 ) return mkdir( path );
00218
00219
00220 std::string dirName = path.front();
00221 path.pop_front();
00222
00223 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::const_iterator iDir = m_subTrees.find( dirName );
00224 if ( iDir == m_subTrees.end() ) {
00225 if ( m_objects.find( dirName ) != m_objects.end() ) return false;
00226 else if ( m_links.find( dirName ) != m_links.end() ) return false;
00227 else {
00228 m_subTrees[ dirName ] = new Anaphe::AIDA_Tree_native::SubTree( m_name + dirName + "/", m_masterTree );
00229 return m_subTrees[ dirName ]->mkdirs( path );
00230 }
00231 }
00232 else {
00233 return iDir->second->mkdirs( path );
00234 }
00235 }
00236
00237
00238 bool
00239 Anaphe::AIDA_Tree_native::SubTree::rmdir( std::list< std::string >& path )
00240 {
00241 if ( m_mountInfo ) {
00242 return m_mountInfo->targetTree()->rmdir( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ) );
00243 }
00244
00245 const std::string& dirName = path.front();
00246 if ( path.size() > 1 ) {
00247 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00248 if ( iDir == m_subTrees.end() ) {
00249 return false;
00250 }
00251 path.pop_front();
00252 return iDir->second->rmdir( path );
00253 }
00254
00255
00256 if ( m_objects.find( dirName ) != m_objects.end() ) return false;
00257
00258
00259 Anaphe::AIDA_Tree_native::SubTree& subTree = * ( m_subTrees[ dirName ] );
00260 if ( subTree.m_objects.size() > 0 ) return false;
00261 if ( subTree.m_subTrees.size() > 0 ) return false;
00262
00263 delete m_subTrees[ dirName ];
00264 m_subTrees.erase( dirName );
00265 return true;
00266 }
00267
00268
00269 bool
00270 Anaphe::AIDA_Tree_native::SubTree::symlink( const std::string& path,
00271 std::list< std::string >& alias )
00272 {
00273 if ( m_mountInfo ) {
00274 return m_mountInfo->targetTree()->symlink( m_mountInfo->targetPath() + anaphe_path_parser.formPath( alias ), path );
00275 }
00276
00277 const std::string& dirName = alias.front();
00278 if ( alias.size() > 1 ) {
00279 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00280 if ( iDir == m_subTrees.end() ) {
00281 return false;
00282 }
00283 alias.pop_front();
00284 return iDir->second->symlink( path, alias );
00285 }
00286
00287
00288 if ( m_subTrees.find( dirName ) != m_subTrees.end() ) return false;
00289 if ( m_objects.find( dirName ) != m_objects.end() ) return false;
00290
00291
00292 return m_links.insert( std::make_pair( dirName, path ) ).second;
00293 }
00294
00295
00296
00297 bool
00298 Anaphe::AIDA_Tree_native::SubTree::mount( const std::string & path,
00299 AIDA::Dev::IDevTree* tree,
00300 std::list< std::string >& treePath,
00301 std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >& mountPoints )
00302 {
00303 if ( m_mountInfo ) {
00304 return false;
00305 }
00306
00307 if ( treePath.size() > 0 ) {
00308 const std::string& dirName = treePath.front();
00309 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00310 if ( iDir == m_subTrees.end() ) {
00311 return false;
00312 }
00313 treePath.pop_front();
00314 return iDir->second->mount( path, tree, treePath, mountPoints );
00315 }
00316
00317
00318 if ( tree == m_masterTree ) return false;
00319
00320 m_mountInfo = new MountInfo( tree, path, m_name );
00321 tree->setParentTree( m_masterTree );
00322 return mountPoints.insert( std::make_pair( tree, m_mountInfo ) ).second;
00323 }
00324
00325
00326 bool
00327 Anaphe::AIDA_Tree_native::SubTree::unmount( std::list< std::string >& path,
00328 std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >& mountPoints )
00329 {
00330 AIDA::Dev::IDevTree* p = 0;
00331 if ( m_mountInfo ) {
00332 if ( path.size() == 0 ) {
00333 p = m_mountInfo->targetTree();
00334 delete m_mountInfo;
00335 m_mountInfo = 0;
00336 }
00337 }
00338 else if ( path.size() > 0 ) {
00339 const std::string& dirName = path.front();
00340 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00341 if ( iDir == m_subTrees.end() ) {
00342 return false;
00343 }
00344 path.pop_front();
00345 return iDir->second->unmount( path, mountPoints );
00346 }
00347
00348 if ( p ) {
00349 p->setParentTree( 0 );
00350 mountPoints.erase( p );
00351 return true;
00352 }
00353 else return false;
00354 }
00355
00356
00357 bool
00358 Anaphe::AIDA_Tree_native::SubTree::rm( std::list< std::string >& path,
00359 std::map< const AIDA::IManagedObject*, std::string >& objectMap )
00360 {
00361 if ( m_mountInfo ) {
00362 return m_mountInfo->targetTree()->rm( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ) );
00363 }
00364
00365 const std::string& dirName = path.front();
00366 if ( path.size() > 1 ) {
00367 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00368 if ( iDir == m_subTrees.end() ) {
00369 return false;
00370 }
00371 path.pop_front();
00372 return iDir->second->rm( path, objectMap );
00373 }
00374
00375
00376
00377 if ( m_links.find( dirName ) != m_links.end() ) {
00378 m_links.erase( dirName );
00379 return true;
00380 }
00381 else {
00382 std::map< std::string, AIDA::IManagedObject* >::iterator iObj = m_objects.find( dirName );
00383 if ( iObj == m_objects.end() ) return false;
00384 AIDA::IManagedObject* objectPointer = iObj->second;
00385 if ( objectPointer ) delete objectPointer;
00386 m_objects.erase( iObj );
00387 m_masterTree->nativeStore()->removeObject( m_name + dirName );
00388 objectMap.erase( objectPointer );
00389 return true;
00390 }
00391 }
00392
00393
00394 AIDA::IManagedObject*
00395 Anaphe::AIDA_Tree_native::SubTree::find( std::list< std::string >& path,
00396 std::map< const AIDA::IManagedObject*, std::string >& objectMap )
00397 {
00398 if ( m_mountInfo ) {
00399 return m_mountInfo->targetTree()->find( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ) );
00400 }
00401
00402 const std::string& dirName = path.front();
00403 if ( path.size() > 1 ) {
00404 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00405 if ( iDir == m_subTrees.end() ) {
00406 return 0;
00407 }
00408 path.pop_front();
00409 return iDir->second->find( path, objectMap );
00410 }
00411
00412
00413
00414 std::map< std::string, std::string >::const_iterator iLink = m_links.find( dirName );
00415 if ( iLink != m_links.end() ) {
00416 return m_masterTree->find( iLink->second );
00417 }
00418 else {
00419 std::map< std::string, AIDA::IManagedObject* >::iterator iObj = m_objects.find( dirName );
00420 if ( iObj == m_objects.end() ) return 0;
00421 else {
00422
00423 AIDA::IManagedObject* objectPointer = iObj->second;
00424 if ( objectPointer == 0 ) {
00425 objectPointer = m_masterTree->nativeStore()->retrieveObject( m_name + dirName );
00426 if ( objectPointer ) objectMap[ objectPointer ] = m_name + dirName;
00427 }
00428 return objectPointer;
00429 }
00430 }
00431 }
00432
00433
00434 AIDA::IManagedObject*
00435 Anaphe::AIDA_Tree_native::SubTree::findAndErase( std::list< std::string >& path )
00436 {
00437 if ( m_mountInfo ) return 0;
00438
00439 const std::string& dirName = path.front();
00440 if ( path.size() > 1 ) {
00441 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::iterator iDir = m_subTrees.find( dirName );
00442 if ( iDir == m_subTrees.end() ) {
00443 return 0;
00444 }
00445 path.pop_front();
00446 return iDir->second->findAndErase( path );
00447 }
00448
00449
00450
00451 if ( m_links.find( dirName ) != m_links.end() ) return 0;
00452 else {
00453 std::map< std::string, AIDA::IManagedObject* >::const_iterator iObj = m_objects.find( dirName );
00454 if ( iObj == m_objects.end() ) return 0;
00455 else {
00456 AIDA::IManagedObject* p = iObj->second;
00457 m_objects.erase( iObj->first );
00458 return p;
00459 }
00460 }
00461 }
00462
00463
00464 std::vector< std::string >
00465 Anaphe::AIDA_Tree_native::SubTree::listObjectNames( std::list< std::string >& path,
00466 bool recursive ) const
00467 {
00468 if ( m_mountInfo ) {
00469 return m_mountInfo->targetTree()->listObjectNames( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ), recursive );
00470 }
00471
00472 const std::string& dirName = path.front();
00473 if ( path.size() > 0 ) {
00474 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::const_iterator iDir = m_subTrees.find( dirName );
00475 if ( iDir == m_subTrees.end() ) {
00476 return std::vector< std::string >();
00477 }
00478 path.pop_front();
00479 return iDir->second->listObjectNames( path, recursive );
00480 }
00481
00482
00483 std::vector< std::string > output;
00484
00485 for ( std::map< std::string, std::string >::const_iterator iLink = m_links.begin();
00486 iLink != m_links.end(); ++iLink ) {
00487 output.push_back( iLink->first );
00488 }
00489
00490
00491 std::vector< std::string > objectNamesFromStore = m_masterTree->nativeStore()->listObjectPaths( m_name, false );
00492 std::vector< std::string > objectTypesFromStore = m_masterTree->nativeStore()->listObjectTypes( m_name, false );
00493 for ( unsigned int i = 0; i < objectNamesFromStore.size(); ++i ) {
00494 if ( objectTypesFromStore[i] != "dir" ) {
00495 output.push_back( objectNamesFromStore[i].substr( m_name.size() ) );
00496 }
00497 }
00498
00499
00500 for ( std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::const_iterator iDir = m_subTrees.begin();
00501 iDir != m_subTrees.end(); ++iDir ) {
00502 output.push_back( iDir->first );
00503 if ( recursive ) {
00504 std::list< std::string > emptyList;
00505 std::vector< std::string > dirOutput = iDir->second->listObjectNames( emptyList, recursive );
00506 for ( unsigned int i = 0; i < dirOutput.size(); ++i ) output.push_back( iDir->first + "/" + dirOutput[i] );
00507 }
00508 }
00509 return output;
00510 }
00511
00512
00513 std::vector< std::string >
00514 Anaphe::AIDA_Tree_native::SubTree::listObjectTypes( std::list< std::string >& path,
00515 bool recursive ) const
00516 {
00517 if ( m_mountInfo ) {
00518 return m_mountInfo->targetTree()->listObjectTypes( m_mountInfo->targetPath() + anaphe_path_parser.formPath( path ), recursive );
00519 }
00520
00521 const std::string& dirName = path.front();
00522 if ( path.size() > 0 ) {
00523 std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::const_iterator iDir = m_subTrees.find( dirName );
00524 if ( iDir == m_subTrees.end() ) {
00525 return std::vector< std::string >();
00526 }
00527 path.pop_front();
00528 return iDir->second->listObjectTypes( path, recursive );
00529 }
00530
00531
00532 std::vector< std::string > output;
00533
00534 for ( std::map< std::string, std::string >::const_iterator iLink = m_links.begin();
00535 iLink != m_links.end(); ++iLink ) {
00536 output.push_back( "-> " + iLink->second );
00537 }
00538
00539
00540 std::vector< std::string > objectTypesFromStore = m_masterTree->nativeStore()->listObjectTypes( m_name, false );
00541 for ( unsigned int i = 0; i < objectTypesFromStore.size(); ++i ) {
00542 if ( objectTypesFromStore[i] != "dir" ) output.push_back( objectTypesFromStore[i] );
00543 }
00544
00545
00546 for ( std::map< std::string, Anaphe::AIDA_Tree_native::SubTree* >::const_iterator iDir = m_subTrees.begin();
00547 iDir != m_subTrees.end(); ++iDir ) {
00548 output.push_back( "dir" );
00549 if ( recursive ) {
00550 std::list< std::string > emptyList;
00551 std::vector< std::string > dirOutput = iDir->second->listObjectTypes( emptyList, recursive );
00552 for ( unsigned int i = 0; i < dirOutput.size(); ++i ) output.push_back( dirOutput[i] );
00553 }
00554 }
00555 return output;
00556 }