OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BESContainerStorageVolatile.cc
Go to the documentation of this file.
1 // BESContainerStorageVolatile.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
34 #include "BESFileContainer.h"
35 #include "BESInternalError.h"
36 #include "BESSyntaxUserError.h"
37 #include "BESInfo.h"
38 #include "TheBESKeys.h"
39 #include "BESUtil.h"
40 #include "BESServiceRegistry.h"
41 #include "BESDebug.h"
42 
51  : BESContainerStorage( n )
52 {
53  string key = "BES.Data.RootDirectory" ;
54  bool found = false ;
55  TheBESKeys::TheKeys()->get_value( key, _root_dir, found ) ;
56  if( _root_dir == "" )
57  {
58  string s = key + " not defined in BES configuration file" ;
59  throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
60  }
61 
62  found = false ;
63  key = (string)"BES.FollowSymLinks" ;
64  string s_str ;
65  TheBESKeys::TheKeys()->get_value( key, s_str, found ) ;
66  s_str = BESUtil::lowercase( s_str ) ;
67  if( found && ( s_str == "yes" || s_str == "on" || s_str == "true" ) )
68  {
69  _follow_sym_links = true ;
70  }
71 }
72 
74 {
75  del_containers() ;
76 }
77 
88 BESContainerStorageVolatile::look_for( const string &sym_name )
89 {
90  BESContainer *ret_container = 0 ;
91 
93  i = _container_list.find( sym_name ) ;
94  if( i != _container_list.end() )
95  {
96  BESContainer *c = (*i).second ;
97  ret_container = c->ptr_duplicate() ;
98  }
99 
100  return ret_container ;
101 }
102 
118 void
120  const string &real_name,
121  const string &type )
122 {
123  BESDEBUG( "bes", "BESContainerStorageCatalog::add_container: "
124  << "adding container with name \"" << sym_name
125  << "\", real name \"" << real_name
126  << "\", type \"" << type << "\"" << endl ) ;
127 
128  // The type must be specified so that we can find the request handler
129  // that knows how to handle the container.
130  if( type == "" )
131  {
132  string s = "Unable to add container, type of data must be specified" ;
133  throw BESInternalError( s, __FILE__, __LINE__ ) ;
134  }
135 
136  // if the container already exists then throw an error
138  i = _container_list.find( sym_name ) ;
139  if( i != _container_list.end() )
140  {
141  string s = (string)"A container with the name "
142  + sym_name
143  + " already exists" ;
144  throw BESInternalError( s, __FILE__, __LINE__ ) ;
145  }
146 
147  // make sure that the path to the container exists. If follow_sym_links
148  // is false and there is a symbolic link in the path then an error will
149  // be thrown. If the path does not exist, an error will be thrown.
151 
152  // add the root directory to the real_name passed
153  string new_r_name = _root_dir + "/" + real_name ;
154 
155  // Create the file container with the new information
156  BESContainer *c = new BESFileContainer( sym_name, new_r_name, type ) ;
157 
158  // add it to the container list
159  _container_list[sym_name] = c ;
160 }
161 
179 void
181 {
182  if( !c )
183  {
184  string s = "Unable to add container, container passed is null" ;
185  throw BESInternalError( s, __FILE__, __LINE__ ) ;
186  }
187  if( c->get_container_type() == "" )
188  {
189  string s = "Unable to add container, type of data must be specified" ;
190  throw BESInternalError( s, __FILE__, __LINE__ ) ;
191  }
192  string sym_name = c->get_symbolic_name() ;
194  i = _container_list.find( sym_name ) ;
195  if( i != _container_list.end() )
196  {
197  string s = (string)"A container with the name "
198  + sym_name
199  + " already exists" ;
200  throw BESInternalError( s, __FILE__, __LINE__ ) ;
201  }
202  _container_list[sym_name] = c ;
203 }
204 
211 bool
213 {
214  bool ret = false ;
216  i = _container_list.find( s_name ) ;
217  if( i != _container_list.end() )
218  {
219  BESContainer *c = (*i).second;
220  _container_list.erase( i ) ;
221  if( c )
222  {
223  delete c ;
224  }
225  ret = true ;
226  }
227  return ret ;
228 }
229 
237 bool
239 {
240  while( _container_list.size() != 0 )
241  {
242  Container_iter ci = _container_list.begin() ;
243  BESContainer *c = (*ci).second ;
244  _container_list.erase( ci ) ;
245  if( c )
246  {
247  delete c ;
248  }
249  }
250  return true ;
251 }
252 
260 bool
261 BESContainerStorageVolatile::isData( const string &inQuestion,
262  list<string> &provides )
263 {
264  bool isit = false ;
265  BESContainer *c = look_for( inQuestion ) ;
266  if( c )
267  {
268  isit = true ;
269  string node_type = c->get_container_type() ;
271  provides ) ;
272  }
273  return isit ;
274 }
275 
290 void
292 {
293  info.add_tag( "name", get_name() ) ;
294  string::size_type root_len = _root_dir.length() ;
295  BESContainerStorageVolatile::Container_iter i = _container_list.begin() ;
296  BESContainerStorageVolatile::Container_iter e = _container_list.end() ;
297  for( ; i != e; i++ )
298  {
299  BESContainer *c = (*i).second;
300  string sym = c->get_symbolic_name() ;
301  string real = c->get_real_name() ;
302  if( real.length() > root_len )
303  {
304  if( real.compare( 0, root_len, _root_dir ) == 0 )
305  {
306  real = real.substr( root_len, real.length() - root_len ) ;
307  }
308  }
309  string type = c->get_container_type() ;
310  show_container( sym, real, type, info ) ;
311  }
312 }
313 
321 void
322 BESContainerStorageVolatile::dump( ostream &strm ) const
323 {
324  strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - ("
325  << (void *)this << ")" << endl ;
327  strm << BESIndent::LMarg << "name: " << get_name() << endl ;
328  if( _container_list.size() )
329  {
330  strm << BESIndent::LMarg << "containers:" << endl ;
333  = _container_list.begin() ;
335  = _container_list.end() ;
336  for( ; i != ie; i++ )
337  {
338  BESContainer *c = (*i).second;
339  c->dump( strm ) ;
340  }
342  }
343  else
344  {
345  strm << BESIndent::LMarg << "containers: none" << endl ;
346  }
348 }
349 
provides persistent storage for data storage information represented by a container.
virtual void show_container(const string &sym_name, const string &real_name, const string &type, BESInfo &info)
add information for a container to the informational response object
virtual BESContainer * look_for(const string &sym_name)
looks for the specified container using the symbolic name passed
exception thrown if inernal error encountered
string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:159
static string lowercase(const string &s)
Convert a string to all lower case.
Definition: BESUtil.cc:190
virtual void add_tag(const string &tag_name, const string &tag_data, map< string, string > *attrs=0)=0
Holds real data, container type and constraint for symbolic name read from persistence.
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:170
static void Indent()
Definition: BESIndent.cc:38
virtual void add_container(BESContainer *c)
add the passed container to the list of containers in volatile storage
error thrown if there is a user syntax error in the request or any other user error ...
map< string, BESContainer * >::const_iterator Container_citer
virtual void show_containers(BESInfo &info)
show information for each container in this persistent store
informational response object
Definition: BESInfo.h:68
virtual bool del_container(const string &s_name)
removes a container with the given symbolic name from the list and deletes it.
static BESServiceRegistry * TheRegistry()
static ostream & LMarg(ostream &strm)
Definition: BESIndent.cc:73
string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:141
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: BESKeys.cc:453
BESContainerStorageVolatile(const string &n)
create an instance of this persistent store with the given name.
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:65
map< string, BESContainer * >::iterator Container_iter
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
virtual bool del_containers()
removes all container
A container is something that holds data.
Definition: BESContainer.h:60
virtual void dump(ostream &strm) const
dumps information about this object
static void UnIndent()
Definition: BESIndent.cc:44
static void check_path(const string &path, const string &root, bool follow_sym_links)
Check if the specified path is valid.
Definition: BESUtil.cc:249
static BESKeys * TheKeys()
Definition: TheBESKeys.cc:48
virtual bool isData(const string &inQuestion, list< string > &provides)
determine if the given container is data and what servies are available for it
virtual const string & get_name() const
retrieve the name of this persistent store
virtual BESContainer * ptr_duplicate()=0
pure abstract method to duplicate this instances of BESContainer
virtual void services_handled(const string &handler, list< string > &services)
returns the list of servies provided by the handler in question