bes  Updated for version 3.20.5
BESContainerStorageVolatile.cc
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 
33 #include "BESContainerStorageVolatile.h"
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 
58  BESContainerStorage(n), _root_dir(""), _follow_sym_links(false)
59 {
60  string key = "BES.Data.RootDirectory";
61  bool found = false;
62  TheBESKeys::TheKeys()->get_value(key, _root_dir, found);
63  if (_root_dir == "") {
64  string s = key + " not defined in BES configuration file";
65  throw BESSyntaxUserError(s, __FILE__, __LINE__);
66  }
67 
68  found = false;
69  key = (string) "BES.FollowSymLinks";
70  string s_str;
71  TheBESKeys::TheKeys()->get_value(key, s_str, found);
72  s_str = BESUtil::lowercase(s_str);
73  if (found && (s_str == "yes" || s_str == "on" || s_str == "true")) {
74  _follow_sym_links = true;
75  }
76 }
77 
78 BESContainerStorageVolatile::~BESContainerStorageVolatile()
79 {
81 }
82 
94 {
95  BESContainer *ret_container = 0;
96 
97  BESContainerStorageVolatile::Container_citer i;
98  i = _container_list.find(sym_name);
99  if (i != _container_list.end()) {
100  BESContainer *c = (*i).second;
101  ret_container = c->ptr_duplicate();
102  }
103 
104  return ret_container;
105 }
106 
123 void BESContainerStorageVolatile::add_container(const string &sym_name, const string &real_name, const string &type)
124 {
125  // The type must be specified so that we can find the request handler
126  // that knows how to handle the container.
127  if (type.empty())
128  throw BESInternalError(string("Unable to add container '").append(sym_name).append("', type of data must be specified"), __FILE__, __LINE__);
129 
130  // if the container already exists then throw an error
131  BESContainerStorageVolatile::Container_citer i = _container_list.find(sym_name);
132  if (i != _container_list.end()) {
133  throw BESInternalError(string("A container with the name '").append(sym_name).append("' already exists"), __FILE__, __LINE__);
134  }
135 
136  // make sure that the path to the container exists. If follow_sym_links
137  // is false and there is a symbolic link in the path then an error will
138  // be thrown. If the path does not exist, an error will be thrown.
139  BESUtil::check_path(real_name, _root_dir, _follow_sym_links);
140 
141  // add the root directory to the real_name passed
142  string fully_qualified_real_name = BESUtil::assemblePath(_root_dir, real_name, false);
143 
144  BESDEBUG("container","BESContainerStorageVolatile::add_container() - "
145  << " _root_dir: " << _root_dir
146  << " real_name: " << real_name
147  << " symbolic name: " << sym_name
148  << " fully_qualified_real_name: " << fully_qualified_real_name
149  << " type: " << type
150  << endl);
151 
152  // Create the file container with the new information
153  BESContainer *c = new BESFileContainer(sym_name, fully_qualified_real_name, type);
154  c->set_relative_name(real_name);
155 
156  // add it to the container list
157  _container_list[sym_name] = c;
158 }
159 
178 {
179  if (!c) {
180  throw BESInternalError("Unable to add container, container passed is null", __FILE__, __LINE__);
181  }
182  if (c->get_container_type().empty()) {
183  throw BESInternalError("Unable to add container, type of data must be specified", __FILE__, __LINE__);
184  }
185 
186  string sym_name = c->get_symbolic_name();
187 
188  BESContainerStorageVolatile::Container_citer i = _container_list.find(sym_name);
189  if (i != _container_list.end()) {
190  throw BESInternalError(string("A container with the name '").append(sym_name).append("' already exists"), __FILE__, __LINE__);
191  }
192 
193  _container_list[sym_name] = c;
194 }
195 
203 {
204  bool ret = false;
205  BESContainerStorageVolatile::Container_iter i = _container_list.find(s_name);
206  if (i != _container_list.end()) {
207  BESContainer *c = (*i).second;
208  _container_list.erase(i);
209  if (c) {
210  delete c;
211  }
212  ret = true;
213  }
214  return ret;
215 }
216 
225 {
226  while (_container_list.size() != 0) {
227  Container_iter ci = _container_list.begin();
228  BESContainer *c = (*ci).second;
229  _container_list.erase(ci);
230  if (c) {
231  delete c;
232  }
233  }
234  return true;
235 }
236 
244 bool BESContainerStorageVolatile::isData(const string &inQuestion, list<string> &provides)
245 {
246  bool isit = false;
247  BESContainer *c = look_for(inQuestion);
248  if (c) {
249  isit = true;
250  string node_type = c->get_container_type();
251  BESServiceRegistry::TheRegistry()->services_handled(node_type, provides);
252  }
253  return isit;
254 }
255 
271 {
272  info.add_tag("name", get_name());
273  string::size_type root_len = _root_dir.length();
274  BESContainerStorageVolatile::Container_iter i = _container_list.begin();
275  BESContainerStorageVolatile::Container_iter e = _container_list.end();
276  for (; i != e; i++) {
277  BESContainer *c = (*i).second;
278  string sym = c->get_symbolic_name();
279  string real = c->get_real_name();
280  if (real.length() > root_len) {
281  if (real.compare(0, root_len, _root_dir) == 0) {
282  real = real.substr(root_len, real.length() - root_len);
283  }
284  }
285  string type = c->get_container_type();
286  show_container(sym, real, type, info);
287  }
288 }
289 
297 void BESContainerStorageVolatile::dump(ostream &strm) const
298 {
299  strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - (" << (void *) this << ")" << endl;
300  BESIndent::Indent();
301  strm << BESIndent::LMarg << "name: " << get_name() << endl;
302  if (_container_list.size()) {
303  strm << BESIndent::LMarg << "containers:" << endl;
304  BESIndent::Indent();
305  BESContainerStorageVolatile::Container_citer i = _container_list.begin();
306  BESContainerStorageVolatile::Container_citer ie = _container_list.end();
307  for (; i != ie; i++) {
308  BESContainer *c = (*i).second;
309  c->dump(strm);
310  }
311  BESIndent::UnIndent();
312  }
313  else {
314  strm << BESIndent::LMarg << "containers: none" << endl;
315  }
316  BESIndent::UnIndent();
317 }
318 
provides persistent storage for data storage information represented by a container.
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
Definition: BESContainer.h:155
exception thrown if inernal error encountered
static string lowercase(const string &s)
Definition: BESUtil.cc:197
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:70
virtual void dump(std::ostream &strm) const
dumps information about this object
Holds real data, container type and constraint for symbolic name read from persistence.
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:420
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
virtual void show_containers(BESInfo &info)
show information for each container in this persistent store
informational response object
Definition: BESInfo.h:68
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:61
virtual BESContainer * look_for(const std::string &sym_name)
looks for the specified container using the symbolic name passed
BESContainerStorageVolatile(const std::string &n)
create an instance of this persistent store with the given name.
virtual void show_container(const std::string &sym_name, const std::string &real_name, const std::string &type, BESInfo &info)
add information for a container to the informational response object
virtual bool isData(const std::string &inQuestion, std::list< std::string > &provides)
determine if the given container is data and what servies are available for it
string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:183
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:235
virtual bool del_containers()
removes all container
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:68
virtual bool del_container(const std::string &s_name)
removes a container with the given symbolic name from the list and deletes it.
static void check_path(const string &path, const string &root, bool follow_sym_links)
Check if the specified path is valid.
Definition: BESUtil.cc:251
static string assemblePath(const string &firstPart, const string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
Definition: BESUtil.cc:818
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
virtual const std::string & get_name() const
retrieve the name of this persistent store
string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:224