00001 #include "AIDA_Tree.h"
00002 #include "PathParser.h"
00003 #include "AIDA_Dev/IStore.h"
00004 #include "AIDA_Dev/IDevManagedObject.h"
00005 #include "SubTree.h"
00006 #include "MountInfo.h"
00007
00008 static const std::string emptyString = "";
00009
00010 Anaphe::AIDA_Tree_native::AIDA_Tree::AIDA_Tree( AIDA::Dev::IStore* store ):
00011 m_store( store ),
00012 m_parentTree( 0 ),
00013 m_overWrite( true ),
00014 m_cwd( "/" ),
00015 m_mountPoints(),
00016 m_objectPaths(),
00017 m_rootDir( 0 )
00018 {
00019
00020 m_rootDir = new Anaphe::AIDA_Tree_native::SubTree( "/", this );
00021
00023 std::vector< std::string > objectPaths = m_store->listObjectPaths( "/", true );
00024 std::vector< std::string > objectTypes = m_store->listObjectTypes( "/", true );
00025
00027 for ( unsigned int iEntry = 0; iEntry < objectTypes.size(); ++iEntry ) {
00028 if ( objectTypes[ iEntry ] == "dir" ) {
00029 std::list< std::string > dirPath = anaphe_path_parser.formNames( objectPaths[iEntry] );
00030 m_rootDir->mkdirs( dirPath );
00031 }
00032 }
00033
00035 for ( unsigned int iEntry = 0; iEntry < objectTypes.size(); ++iEntry ) {
00036 if ( objectTypes[ iEntry ] != "dir" ) {
00037 std::list< std::string > path = anaphe_path_parser.formNames( objectPaths[iEntry] );
00038 m_rootDir->add( 0, path, true, m_objectPaths, false );
00039 }
00040 }
00041 }
00042
00043
00044 Anaphe::AIDA_Tree_native::AIDA_Tree::~AIDA_Tree()
00045 {
00047 if ( m_parentTree ) m_parentTree->unmountTree( this );
00048
00050 for ( std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >::const_iterator iMountPoint = m_mountPoints.begin();
00051 iMountPoint != m_mountPoints.end(); ++iMountPoint ) {
00052 iMountPoint->first->setParentTree( 0 );
00053 }
00054
00056 if ( m_rootDir ) delete m_rootDir;
00057
00059 if ( m_store ) {
00060 m_store->close();
00061 delete m_store;
00062 }
00063 }
00064
00065
00066 bool
00067 Anaphe::AIDA_Tree_native::AIDA_Tree::add( AIDA::IManagedObject * object,
00068 const std::string& directory )
00069 {
00070
00071 if ( ! object ) return false;
00072
00073 std::string objectName = object->name();
00074 std::list< std::string > objectNameList = anaphe_path_parser.formNames( objectName );
00075 if ( objectNameList.size() != 1 ) return false;
00076 objectName = anaphe_path_parser.formPath( objectNameList );
00077
00078 std::list<std::string> dirNames = anaphe_path_parser.formNames( absolutePath( directory ) + "/" + objectName );
00079 return m_rootDir->add( object, dirNames, m_overWrite, m_objectPaths, false );
00080 }
00081
00082
00083 bool
00084 Anaphe::AIDA_Tree_native::AIDA_Tree::copyAndAdd( AIDA::IManagedObject * object,
00085 const std::string& path )
00086 {
00087
00088 if ( ! object ) return false;
00089
00090
00091 AIDA::Dev::IDevManagedObject* devObject = dynamic_cast< AIDA::Dev::IDevManagedObject* >( object );
00092 if ( ! devObject ) return false;
00093 if ( devObject->userLevelClassType() == "ITuple" && ! ( m_store->canCopyTuples() ) ) return false;
00094
00095 std::string dir = absolutePath( path ) + "/";
00096
00097 if ( existsDirectory( dir ) ) dir += "/" + object->name();
00098 std::list< std::string > dirNames = anaphe_path_parser.formNames( dir );
00099 return m_rootDir->add( object, dirNames, m_overWrite, m_objectPaths, true );
00100 }
00101
00102
00103 AIDA::Dev::IStore*
00104 Anaphe::AIDA_Tree_native::AIDA_Tree::nativeStore()
00105 {
00106 return m_store;
00107 }
00108
00109
00110 AIDA::Dev::IStore*
00111 Anaphe::AIDA_Tree_native::AIDA_Tree::store( const std::string& path )
00112 {
00113 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00114 if ( names.size() == 0 ) return m_store;
00115 return m_rootDir->store( names );
00116 }
00117
00118
00119 bool
00120 Anaphe::AIDA_Tree_native::AIDA_Tree::isMounted() const
00121 {
00122 return ( ( m_parentTree == 0 ) ? false : true );
00123 }
00124
00125
00126 bool
00127 Anaphe::AIDA_Tree_native::AIDA_Tree::setParentTree( AIDA::Dev::IDevTree * parentTree )
00128 {
00129 m_parentTree = parentTree;
00130 return true;
00131 }
00132
00133
00134 bool
00135 Anaphe::AIDA_Tree_native::AIDA_Tree::unmountTree( AIDA::Dev::IDevTree * daughterTree )
00136 {
00137 std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >::const_iterator iMountPoint = m_mountPoints.find( daughterTree );
00138 if ( iMountPoint == m_mountPoints.end() ) return false;
00139 std::list< std::string > names = anaphe_path_parser.formNames( iMountPoint->second->mountPoint() );
00140 return m_rootDir->unmount( names, m_mountPoints );
00141 }
00142
00143
00144 const std::string&
00145 Anaphe::AIDA_Tree_native::AIDA_Tree::storeName() const
00146 {
00147 return m_store->name();
00148 }
00149
00150
00151 AIDA::IManagedObject*
00152 Anaphe::AIDA_Tree_native::AIDA_Tree::find( const std::string & path )
00153 {
00154 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00155 return m_rootDir->find( names, m_objectPaths );
00156 }
00157
00158
00159 bool
00160 Anaphe::AIDA_Tree_native::AIDA_Tree::cd( const std::string & path )
00161 {
00162 if ( path.size() == 0 ) {
00163 m_cwd = "/";
00164 return true;
00165 }
00166
00167 m_cwd = absolutePath( path ) + "/";
00168 return true;
00169 }
00170
00171
00172 const std::string&
00173 Anaphe::AIDA_Tree_native::AIDA_Tree::pwd() const
00174 {
00175 return m_cwd;
00176 }
00177
00178
00179 bool
00180 Anaphe::AIDA_Tree_native::AIDA_Tree::existsDirectory( const std::string& path ) const
00181 {
00182 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00183 if ( names.size() == 0 ) return true;
00184 return m_rootDir->existsDirectory( names );
00185 }
00186
00187
00188 bool
00189 Anaphe::AIDA_Tree_native::AIDA_Tree::mkdir( const std::string & path )
00190 {
00191 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00192 return m_rootDir->mkdir( names );
00193 }
00194
00195
00196 bool
00197 Anaphe::AIDA_Tree_native::AIDA_Tree::mkdirs( const std::string & path )
00198 {
00199 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00200 return m_rootDir->mkdirs( names );
00201 }
00202
00203
00204 bool
00205 Anaphe::AIDA_Tree_native::AIDA_Tree::rmdir( const std::string & path )
00206 {
00207 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00208 return m_rootDir->rmdir( names );
00209 }
00210
00211
00212 std::string
00213 Anaphe::AIDA_Tree_native::AIDA_Tree::findPath( const AIDA::IManagedObject & object ) const
00214 {
00215
00216 std::map< const AIDA::IManagedObject*, std::string >::const_iterator iObj = m_objectPaths.find( &object );
00217 if ( iObj != m_objectPaths.end() ) return iObj->second;
00218
00219
00220 for ( std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >::const_iterator iTree = m_mountPoints.begin();
00221 iTree != m_mountPoints.end(); ++iTree ) {
00222 std::string path = iTree->first->findPath( object );
00223 if ( path.size() > 0 ) {
00224
00225 std::list< std::string > names = anaphe_path_parser.formNames( path );
00226 const int dirSize = anaphe_path_parser.formNames( iTree->second->targetPath() ).size();
00227 for ( int i = 0; i < dirSize; ++i ) names.pop_front();
00228 const std::list< std::string > namesOfMountPoint = anaphe_path_parser.formNames( iTree->second->mountPoint() );
00229 for ( std::list< std::string >::const_reverse_iterator iName = namesOfMountPoint.rbegin();
00230 iName != namesOfMountPoint.rend(); ++iName ) {
00231 names.push_front( *iName );
00232 }
00233 std::string objectPath = "/" + anaphe_path_parser.formPath( names );
00234 return objectPath;
00235 }
00236 }
00237
00238 return emptyString;
00239 }
00240
00241
00242 std::string
00243 Anaphe::AIDA_Tree_native::AIDA_Tree::pathInStore( const AIDA::IManagedObject& object ) const
00244 {
00245
00246 std::map< const AIDA::IManagedObject*, std::string >::const_iterator iObj = m_objectPaths.find( &object );
00247 if ( iObj != m_objectPaths.end() ) return iObj->second;
00248
00249
00250 for ( std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >::const_iterator iTree = m_mountPoints.begin();
00251 iTree != m_mountPoints.end(); ++iTree ) {
00252 std::string path = iTree->first->pathInStore( object );
00253 if ( path.size() > 0 ) return path;
00254 }
00255
00256 return emptyString;
00257 }
00258
00259
00260 bool
00261 Anaphe::AIDA_Tree_native::AIDA_Tree::mv( const std::string & oldPath,
00262 const std::string & newPath )
00263 {
00264
00265 AIDA::Dev::IStore* oldStore = store( oldPath );
00266 if ( ! oldStore ) return false;
00267
00268
00269 AIDA::Dev::IStore* newStore = store( newPath );
00270 if ( ! newStore ) {
00271 newStore = store( anaphe_path_parser.parent( absolutePath( newPath ) ) );
00272 if ( ! newStore ) return false;
00273 }
00274
00275 if ( oldStore != newStore ) {
00276 if ( cp( oldPath, newPath ) ) {
00277 rm( oldPath );
00278 return true;
00279 }
00280 else {
00281 return false;
00282 }
00283 }
00284
00285
00286 if ( oldStore == m_store ) {
00287 std::string oldAbsolutePath = absolutePath( oldPath );
00288 std::list< std::string > oldNames = anaphe_path_parser.formNames( oldAbsolutePath );
00289 AIDA::IManagedObject* object = m_rootDir->findAndErase( oldNames );
00290 if ( ! object ) return false;
00291 m_objectPaths.erase( object );
00292 std::string dir = absolutePath( newPath );
00293
00294 if ( existsDirectory( dir + "/" ) ) dir += "/" + object->name();
00295 std::list< std::string > dirNames = anaphe_path_parser.formNames( dir );
00296 bool bSuccess = m_rootDir->add( object, dirNames, m_overWrite, m_objectPaths, false, false );
00297 if ( ! bSuccess ) {
00298 std::string odir = absolutePath( oldPath ) + "/";
00299 if ( existsDirectory( odir ) ) odir += "/" + object->name();
00300 std::list< std::string > odirNames = anaphe_path_parser.formNames( odir );
00301 m_rootDir->add( object, odirNames, m_overWrite, m_objectPaths, false, false );
00302 return false;
00303 }
00304
00305 return m_store->moveObject( oldAbsolutePath, absolutePath( dir ) );
00306 }
00307 else {
00308 std::string oldAbsolutePath = absolutePath( oldPath );
00309 std::string newAbsolutePath = absolutePath( newPath );
00310 for ( std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >::iterator iMountedTree = m_mountPoints.begin();
00311 iMountedTree != m_mountPoints.end(); ++iMountedTree ) {
00312 AIDA::Dev::IDevTree* tree = iMountedTree->first;
00313 if ( tree->nativeStore() == oldStore ) {
00314 std::list<std::string> oldPathNames = anaphe_path_parser.formNames( oldAbsolutePath );
00315 std::list<std::string> newPathNames = anaphe_path_parser.formNames( newAbsolutePath );
00316 const unsigned int prefixSize = anaphe_path_parser.formNames( iMountedTree->second->mountPoint() ).size();
00317 for ( unsigned int i = 0; i < prefixSize; ++i ) {
00318 oldPathNames.pop_front();
00319 newPathNames.pop_front();
00320 }
00321 const std::list<std::string> baseNames = anaphe_path_parser.formNames( iMountedTree->second->targetPath() );
00322 for ( std::list<std::string>::const_reverse_iterator iBase = baseNames.rbegin();
00323 iBase != baseNames.rend(); ++iBase ) {
00324 oldPathNames.push_front( *iBase );
00325 newPathNames.push_front( *iBase );
00326 }
00327
00328 tree->mv( "/" + anaphe_path_parser.formPath( oldPathNames ),
00329 "/" + anaphe_path_parser.formPath( newPathNames ) );
00330 }
00331 }
00332 }
00333
00334 return false;
00335 }
00336
00337
00338 bool
00339 Anaphe::AIDA_Tree_native::AIDA_Tree::commit()
00340 {
00341 bool success = m_store->commit();
00342
00343 for ( std::map< AIDA::Dev::IDevTree*, Anaphe::AIDA_Tree_native::MountInfo* >::const_iterator iTree = m_mountPoints.begin();
00344 iTree != m_mountPoints.end(); ++iTree ) {
00345 success = success && iTree->first->commit();
00346 }
00347 return success;
00348 }
00349
00350
00351 void
00352 Anaphe::AIDA_Tree_native::AIDA_Tree::setOverwrite( bool overwrite )
00353 {
00354 m_overWrite = overwrite;
00355 }
00356
00357
00358 bool
00359 Anaphe::AIDA_Tree_native::AIDA_Tree::rm( const std::string & path )
00360 {
00361 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00362 return m_rootDir->rm( names, m_objectPaths );
00363 }
00364
00365
00366 bool
00367 Anaphe::AIDA_Tree_native::AIDA_Tree::cp( const std::string & oldPath,
00368 const std::string & newPath,
00369 bool recursive )
00370 {
00371 if ( recursive ) {
00372
00373 std::vector< std::string > objectNames = listObjectNames( oldPath, true );
00374 std::vector< std::string > objectTypes = listObjectTypes( oldPath, true );
00375
00376
00377 if ( newPath.size() == 0 ) return false;
00378 std::string dir = absolutePath( newPath ) + "/";
00379
00380
00381 if ( oldPath.size() == 0 ) return false;
00382 std::string oldDir = absolutePath( oldPath ) + "/";
00383
00384
00385 mkdirs( dir );
00386 for ( unsigned int i = 0; i < objectNames.size(); ++i ) {
00387 if ( objectTypes[i] == "dir" ) {
00388 mkdirs( dir + objectNames[i] );
00389 }
00390 }
00391
00392
00393 for ( unsigned int i = 0; i < objectNames.size(); ++i ) {
00394 if ( objectTypes[i] != "dir" ) {
00395 AIDA::IManagedObject* object = find( oldDir + objectNames[i] );
00396 if ( object ) copyAndAdd( object, dir + objectNames[i] );
00397 }
00398 }
00399 return true;
00400 }
00401 else {
00402 AIDA::IManagedObject* object = find( oldPath );
00403 if ( ! object ) return false;
00404 return copyAndAdd( object, newPath );
00405 }
00406 }
00407
00408
00409 bool
00410 Anaphe::AIDA_Tree_native::AIDA_Tree::symlink( const std::string & path,
00411 const std::string & alias )
00412 {
00413 if ( alias.size() == 0 ) return false;
00414 std::list< std::string > aliasNames = anaphe_path_parser.formNames( alias );
00415 if( aliasNames.size() == 0 || ( aliasNames.size() == 1 && aliasNames.front() == "." ) ) return false;
00416 std::list< std::string > dirNames = anaphe_path_parser.formNames( absolutePath( alias ) );
00417 return m_rootDir->symlink( absolutePath( path ), dirNames );
00418 }
00419
00420
00421 bool
00422 Anaphe::AIDA_Tree_native::AIDA_Tree::mount( const std::string & path,
00423 AIDA::ITree & tree,
00424 const std::string & treePath )
00425 {
00426 AIDA::Dev::IDevTree * daughterTree = dynamic_cast< AIDA::Dev::IDevTree * >( &tree );
00427 if ( daughterTree->isMounted() ) return false;
00428
00429 if ( path.size() == 0 ) return false;
00430 std::list< std::string > pathNames = anaphe_path_parser.formNames( path );
00431 if( pathNames.size() == 0 || ( pathNames.size() == 1 && pathNames.front() == "." ) ) return false;
00432 std::list< std::string > dirNames = anaphe_path_parser.formNames( absolutePath( path ) );
00433
00434
00435 std::list< std::string > targetNames = anaphe_path_parser.formNames( treePath );
00436 std::string targetTreePath = "/";
00437 if (targetNames.size() > 0 ) targetTreePath = anaphe_path_parser.formPath( targetNames ) + "/";
00438 return m_rootDir->mount( targetTreePath, daughterTree, dirNames, m_mountPoints );
00439 }
00440
00441
00442 bool
00443 Anaphe::AIDA_Tree_native::AIDA_Tree::unmount( const std::string & path )
00444 {
00445 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00446 return m_rootDir->unmount( names, m_mountPoints );
00447 }
00448
00449
00450 bool
00451 Anaphe::AIDA_Tree_native::AIDA_Tree::close()
00452 {
00453 return m_store->close();
00454 }
00455
00456
00457 std::vector< std::string >
00458 Anaphe::AIDA_Tree_native::AIDA_Tree::listObjectNames( const std::string & path,
00459 bool recursive ) const
00460 {
00461 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00462 return m_rootDir->listObjectNames( names, recursive );
00463 }
00464
00465
00466 std::vector< std::string >
00467 Anaphe::AIDA_Tree_native::AIDA_Tree::listObjectTypes( const std::string & path,
00468 bool recursive ) const
00469 {
00470 std::list< std::string > names = anaphe_path_parser.formNames( absolutePath( path ) );
00471 return m_rootDir->listObjectTypes( names, recursive );
00472 }
00473
00474
00475 bool
00476 Anaphe::AIDA_Tree_native::AIDA_Tree::ls( const std::string & path,
00477 bool recursive,
00478 std::ostream & os ) const
00479 {
00480 if ( ! existsDirectory( path ) ) return false;
00481 std::vector< std::string > objectNames = listObjectNames( path, recursive );
00482 std::vector< std::string > objectTypes = listObjectTypes( path, recursive );
00483
00484 for ( unsigned int i = 0; i < objectNames.size(); ++i ) {
00485 os << objectNames[i] << "\t : \t" << objectTypes[i] << std::endl;
00486 }
00487 return true;
00488 }
00489
00490
00491 std::string
00492 Anaphe::AIDA_Tree_native::AIDA_Tree::absolutePath( const std::string& path ) const
00493 {
00494 if ( path.size() == 0 ) return emptyString;
00495 std::list< std::string > names = anaphe_path_parser.formNames( m_cwd );
00496 if ( path.size() > 0 && path[0] == '/' ) names.clear();
00497 std::list< std::string > relativeNames = anaphe_path_parser.formNames( path );
00498 if ( relativeNames.size() > 0 ) {
00499 if ( relativeNames.front() == "." ) relativeNames.pop_front();
00500 else if ( relativeNames.front() == ".." ) {
00501 if ( names.size() == 0 ) return emptyString;
00502 else {
00503 relativeNames.pop_front();
00504 names.pop_back();
00505 }
00506 }
00507 }
00508 std::string dir = "/";
00509 if ( names.size() > 0 ) dir += anaphe_path_parser.formPath( names ) + "/";
00510 if ( relativeNames.size() > 0 ) dir += anaphe_path_parser.formPath( relativeNames );
00511 return dir;
00512 }