OPeNDAP Hyrax Back End Server (BES) Updated for version 3.8.3
BESContainerStorageVolatile.cc
Go to the documentation of this file.
00001 // BESContainerStorageVolatile.cc
00002 
00003 // This file is part of bes, A C++ back-end server implementation framework
00004 // for the OPeNDAP Data Access Protocol.
00005 
00006 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 // 
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact University Corporation for Atmospheric Research at
00024 // 3080 Center Green Drive, Boulder, CO 80301
00025  
00026 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
00028 //
00029 // Authors:
00030 //      pwest       Patrick West <pwest@ucar.edu>
00031 //      jgarcia     Jose Garcia <jgarcia@ucar.edu>
00032 
00033 #include "BESContainerStorageVolatile.h"
00034 #include "BESFileContainer.h"
00035 #include "BESInternalError.h"
00036 #include "BESSyntaxUserError.h"
00037 #include "BESInfo.h"
00038 #include "TheBESKeys.h"
00039 #include "BESUtil.h"
00040 
00048 BESContainerStorageVolatile::BESContainerStorageVolatile( const string &n )
00049     : BESContainerStorage( n )
00050 {
00051     string key = "BES.Data.RootDirectory" ;
00052     bool found = false ;
00053     TheBESKeys::TheKeys()->get_value( key, _root_dir, found ) ;
00054     if( _root_dir == "" )
00055     {
00056         string s = key + " not defined in BES configuration file" ;
00057         throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00058     }
00059 
00060     found = false ;
00061     key = (string)"BES.FollowSymLinks" ;
00062     string s_str ;
00063     TheBESKeys::TheKeys()->get_value( key, s_str, found ) ;
00064     s_str = BESUtil::lowercase( s_str ) ;
00065     if( found && ( s_str == "yes" || s_str == "on" || s_str == "true" ) )
00066     {
00067         _follow_sym_links = true ;
00068     }
00069 }
00070 
00071 BESContainerStorageVolatile::~BESContainerStorageVolatile()
00072 { 
00073     del_containers() ;
00074 }
00075 
00085 BESContainer *
00086 BESContainerStorageVolatile::look_for( const string &sym_name )
00087 {
00088     BESContainer *ret_container = 0 ;
00089 
00090     BESContainerStorageVolatile::Container_citer i ;
00091     i = _container_list.find( sym_name ) ;
00092     if( i != _container_list.end() )
00093     {
00094         BESContainer *c = (*i).second ;
00095         ret_container = c->ptr_duplicate() ;
00096     }
00097 
00098     return ret_container ;
00099 }
00100 
00116 void
00117 BESContainerStorageVolatile::add_container( const string &sym_name,
00118                                             const string &real_name,
00119                                             const string &type )
00120 {
00121     // The type must be specified so that we can find the request handler
00122     // that knows how to handle the container.
00123     if( type == "" )
00124     {
00125         string s = "Unable to add container, type of data must be specified"  ;
00126         throw BESInternalError( s, __FILE__, __LINE__ ) ;
00127     }
00128 
00129     // if the container already exists then throw an error
00130     BESContainerStorageVolatile::Container_citer i ;
00131     i = _container_list.find( sym_name ) ;
00132     if( i != _container_list.end() )
00133     {
00134         string s = (string)"A container with the name "
00135                    + sym_name
00136                    + " already exists" ;
00137         throw BESInternalError( s, __FILE__, __LINE__ ) ;
00138     }
00139 
00140     // make sure that the path to the container exists. If follow_sym_links
00141     // is false and there is a symbolic link in the path then an error will
00142     // be thrown. If the path does not exist, an error will be thrown.
00143     BESUtil::check_path( real_name, _root_dir, _follow_sym_links ) ;
00144 
00145     // add the root directory to the real_name passed
00146     string new_r_name = _root_dir + "/" + real_name ;
00147 
00148     // Create the file container with the new information
00149     BESContainer *c = new BESFileContainer( sym_name, new_r_name, type ) ;
00150 
00151     // add it to the container list
00152     _container_list[sym_name] = c ;
00153 }
00154 
00172 void
00173 BESContainerStorageVolatile::add_container( BESContainer *c )
00174 {
00175     if( !c )
00176     {
00177         string s = "Unable to add container, container passed is null"  ;
00178         throw BESInternalError( s, __FILE__, __LINE__ ) ;
00179     }
00180     if( c->get_container_type() == "" )
00181     {
00182         string s = "Unable to add container, type of data must be specified"  ;
00183         throw BESInternalError( s, __FILE__, __LINE__ ) ;
00184     }
00185     string sym_name = c->get_symbolic_name() ;
00186     BESContainerStorageVolatile::Container_citer i ;
00187     i = _container_list.find( sym_name ) ;
00188     if( i != _container_list.end() )
00189     {
00190         string s = (string)"A container with the name "
00191                    + sym_name
00192                    + " already exists" ;
00193         throw BESInternalError( s, __FILE__, __LINE__ ) ;
00194     }
00195     _container_list[sym_name] = c ;
00196 }
00197 
00204 bool
00205 BESContainerStorageVolatile::del_container( const string &s_name )
00206 {
00207     bool ret = false ;
00208     BESContainerStorageVolatile::Container_iter i ;
00209     i = _container_list.find( s_name ) ;
00210     if( i != _container_list.end() )
00211     {
00212         BESContainer *c = (*i).second;
00213         _container_list.erase( i ) ;
00214         if( c )
00215         {
00216             delete c ;
00217         }
00218         ret = true ;
00219     }
00220     return ret ;
00221 }
00222 
00230 bool
00231 BESContainerStorageVolatile::del_containers( )
00232 {
00233     while( _container_list.size() != 0 )
00234     {
00235         Container_iter ci = _container_list.begin() ;
00236         BESContainer *c = (*ci).second ;
00237         _container_list.erase( ci ) ;
00238         if( c )
00239         {
00240             delete c ;
00241         }
00242     }
00243     return true ;
00244 }
00245 
00260 void
00261 BESContainerStorageVolatile::show_containers( BESInfo &info )
00262 {
00263     info.add_tag( "name", get_name() ) ;
00264     string::size_type root_len = _root_dir.length() ;
00265     BESContainerStorageVolatile::Container_iter i = _container_list.begin() ;
00266     BESContainerStorageVolatile::Container_iter e = _container_list.end() ;
00267     for( ; i != e; i++ )
00268     {
00269         BESContainer *c = (*i).second;
00270         string sym = c->get_symbolic_name() ;
00271         string real = c->get_real_name() ;
00272         if( real.length() > root_len )
00273         {
00274             if( real.compare( 0, root_len, _root_dir ) == 0 )
00275             {
00276                 real = real.substr( root_len, real.length() - root_len ) ;
00277             }
00278         }
00279         string type = c->get_container_type() ;
00280         show_container( sym, real, type, info ) ;
00281     }
00282 }
00283 
00291 void
00292 BESContainerStorageVolatile::dump( ostream &strm ) const
00293 {
00294     strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - ("
00295                              << (void *)this << ")" << endl ;
00296     BESIndent::Indent() ;
00297     strm << BESIndent::LMarg << "name: " << get_name() << endl ;
00298     if( _container_list.size() )
00299     {
00300         strm << BESIndent::LMarg << "containers:" << endl ;
00301         BESIndent::Indent() ;
00302         BESContainerStorageVolatile::Container_citer i
00303             = _container_list.begin() ;
00304         BESContainerStorageVolatile::Container_citer ie
00305             = _container_list.end() ;
00306         for( ; i != ie; i++ )
00307         {
00308             BESContainer *c = (*i).second;
00309             c->dump( strm ) ;
00310         }
00311         BESIndent::UnIndent() ;
00312     }
00313     else
00314     {
00315         strm << BESIndent::LMarg << "containers: none" << endl ;
00316     }
00317     BESIndent::UnIndent() ;
00318 }
00319