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         delete c ;
00215         ret = true ;
00216     }
00217     return ret ;
00218 }
00219 
00227 bool
00228 BESContainerStorageVolatile::del_containers( )
00229 {
00230     while( _container_list.size() != 0 )
00231     {
00232         Container_iter ci = _container_list.begin() ;
00233         BESContainer *c = (*ci).second ;
00234         _container_list.erase( ci ) ;
00235         if( c )
00236         {
00237             delete c ;
00238         }
00239     }
00240     return true ;
00241 }
00242 
00257 void
00258 BESContainerStorageVolatile::show_containers( BESInfo &info )
00259 {
00260     info.add_tag( "name", get_name() ) ;
00261     string::size_type root_len = _root_dir.length() ;
00262     BESContainerStorageVolatile::Container_iter i = _container_list.begin() ;
00263     BESContainerStorageVolatile::Container_iter e = _container_list.end() ;
00264     for( ; i != e; i++ )
00265     {
00266         BESContainer *c = (*i).second;
00267         string sym = c->get_symbolic_name() ;
00268         string real = c->get_real_name() ;
00269         if( real.length() > root_len )
00270         {
00271             if( real.compare( 0, root_len, _root_dir ) == 0 )
00272             {
00273                 real = real.substr( root_len, real.length() - root_len ) ;
00274             }
00275         }
00276         string type = c->get_container_type() ;
00277         show_container( sym, real, type, info ) ;
00278     }
00279 }
00280 
00288 void
00289 BESContainerStorageVolatile::dump( ostream &strm ) const
00290 {
00291     strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - ("
00292                              << (void *)this << ")" << endl ;
00293     BESIndent::Indent() ;
00294     strm << BESIndent::LMarg << "name: " << get_name() << endl ;
00295     if( _container_list.size() )
00296     {
00297         strm << BESIndent::LMarg << "containers:" << endl ;
00298         BESIndent::Indent() ;
00299         BESContainerStorageVolatile::Container_citer i
00300             = _container_list.begin() ;
00301         BESContainerStorageVolatile::Container_citer ie
00302             = _container_list.end() ;
00303         for( ; i != ie; i++ )
00304         {
00305             BESContainer *c = (*i).second;
00306             c->dump( strm ) ;
00307         }
00308         BESIndent::UnIndent() ;
00309     }
00310     else
00311     {
00312         strm << BESIndent::LMarg << "containers: none" << endl ;
00313     }
00314     BESIndent::UnIndent() ;
00315 }
00316