Main Page   Namespace List   Alphabetical List   Compound List   File List   Compound Members   File Members  

AIDA_Tree.cpp

Go to the documentation of this file.
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   // Create the local root directory
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   // Check the validity of the pointer
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   // Check the validity of the pointer
00088   if ( ! object ) return false;
00089 
00090   // Check if it is a tuple and if the store can copy tuples
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   // Check here if the target is an existing directory. If this is the case, append the object name.
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   // If the path points to an object inside the tree
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   // Check in the mounted trees
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       // The object is in a mounted tree. Extract the path relative to this tree.
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   // If the path points to an object inside the tree
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   // Check in the mounted trees
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   // Fetch the store from the oldPath
00265   AIDA::Dev::IStore* oldStore = store( oldPath );
00266   if ( ! oldStore ) return false;
00267 
00268   // Fetch the store from the new path
00269   AIDA::Dev::IStore* newStore = store( newPath );
00270   if ( ! newStore ) { // give a try with the directory
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   // If this is the local store, simply rename
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     // Check here if the target is an existing directory. If this is the case, append the object name.
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 ) { // recover the operation in case of failure
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     // OK, moved logically in the tree. We issue the command to the store
00305     return m_store->moveObject( oldAbsolutePath, absolutePath( dir ) );
00306   }
00307   else { // This is another tree. Let's propagate the call over there
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 ) { // OK, identified the tree. lets form the relative paths
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         // OK, return the move command inside the tree
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   // Propagate the commit to the dependent trees
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     // Retrieve the directory structure under the old path.
00373     std::vector< std::string > objectNames = listObjectNames( oldPath, true );
00374     std::vector< std::string > objectTypes = listObjectTypes( oldPath, true );
00375 
00376     // Form the new directory path correctly.
00377     if ( newPath.size() == 0 ) return false;
00378     std::string dir = absolutePath( newPath ) + "/";
00379 
00380     // Form the old directory path correctly.
00381     if ( oldPath.size() == 0 ) return false;
00382     std::string oldDir = absolutePath( oldPath ) + "/";
00383 
00384     // Copy the directory structure first
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     // Copy and add the new objects under the new structure.
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 { // Simple copy
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   // form correctly the target path
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(); // Action for absolute path
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 }

Generated on Tue May 20 14:49:45 2003 for AIDA_Tree_native by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002