bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
BESContainerStorageFile.cc
1// BESContainerStorageFile.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 <cerrno>
34#include <sstream>
35#include <fstream>
36#include <iostream>
37#include <cstring>
38#include <list>
39
40using std::stringstream;
41using std::ifstream;
42using std::endl;
43using std::ostream;
44using std::string;
45using std::list;
46
47#include "BESContainerStorageFile.h"
48#include "BESFileContainer.h"
49#include "TheBESKeys.h"
50#include "BESInternalError.h"
51#include "BESSyntaxUserError.h"
52#include "BESInfo.h"
53#include "BESServiceRegistry.h"
54
86{
87 // TODO: Need to store the kind of container each line represents. Does
88 // it represent a file? A database entry? What? For now, they all
89 // represent a BESFileContainer.
90
91 string key = "BES.Container.Persistence.File." + n;
92 bool found = false;
93 TheBESKeys::TheKeys()->get_value(key, _file, found);
94 if (_file == "") {
95 string s = key + " not defined in BES configuration file";
96 throw BESSyntaxUserError(s, __FILE__, __LINE__);
97 }
98
99 ifstream persistence_file(_file.c_str());
100 int myerrno = errno;
101 if (!persistence_file) {
102 char *err = strerror(myerrno);
103 string s = "Unable to open persistence file " + _file + ": ";
104 if (err)
105 s += err;
106 else
107 s += "Unknown error";
108
109 throw BESInternalError(s, __FILE__, __LINE__);
110 }
111
112 try {
113 char cline[80];
114
115 while (!persistence_file.eof()) {
116 stringstream strm;
117 persistence_file.getline(cline, 80);
118 if (!persistence_file.eof()) {
119 strm << cline;
120 BESContainerStorageFile::container *c = new BESContainerStorageFile::container;
121 strm >> c->_symbolic_name;
122 strm >> c->_real_name;
123 strm >> c->_container_type;
124 string dummy;
125 strm >> dummy;
126 if (c->_symbolic_name == "" || c->_real_name == "" || c->_container_type == "") {
127 delete c;
128 persistence_file.close();
129 string s = "Incomplete container persistence line in file " + _file;
130 throw BESInternalError(s, __FILE__, __LINE__);
131 }
132 if (dummy != "") {
133 persistence_file.close();
134 delete c;
135 string s = "Too many fields in persistence file " + _file;
136 throw BESInternalError(s, __FILE__, __LINE__);
137 }
138 _container_list[c->_symbolic_name] = c;
139 }
140 }
141 persistence_file.close();
142 }
143 catch (...) {
144 persistence_file.close();
145 throw;
146 }
147}
148
149BESContainerStorageFile::~BESContainerStorageFile()
150{
151 BESContainerStorageFile::Container_citer i = _container_list.begin();
152 BESContainerStorageFile::Container_citer ie = _container_list.end();
153 for (; i != ie; i++) {
154 BESContainerStorageFile::container *c = (*i).second;
155 delete c;
156 }
157}
158
172{
173 BESFileContainer *ret_container = 0;
174 BESContainerStorageFile::Container_citer i;
175 i = _container_list.find(sym_name);
176 if (i != _container_list.end()) {
177 BESContainerStorageFile::container *c = (*i).second;
178 ret_container = new BESFileContainer(c->_symbolic_name, c->_real_name, c->_container_type);
179 }
180
181 return ret_container;
182}
183
194void BESContainerStorageFile::add_container(const string &, const string &, const string &)
195{
196 string err = "Unable to add a container to a file, not yet implemented";
197 throw BESInternalError(err, __FILE__, __LINE__);
198}
199
201{
202 string err = "Unable to add a container to a file, not yet implemented";
203 throw BESInternalError(err, __FILE__, __LINE__);
204}
205
216{
217 bool ret = false;
218 BESContainerStorageFile::Container_iter i;
219 i = _container_list.find(s_name);
220 if (i != _container_list.end()) {
221 BESContainerStorageFile::container *c = (*i).second;
222 _container_list.erase(i);
223 if (c) {
224 delete c;
225 }
226 ret = true;
227 }
228 return ret;
229}
230
239{
240 while (_container_list.size() != 0) {
241 Container_iter ci = _container_list.begin();
242 BESContainerStorageFile::container *c = (*ci).second;
243 _container_list.erase(ci);
244 if (c) {
245 delete c;
246 }
247 }
248 return true;
249}
250
258bool BESContainerStorageFile::isData(const string &inQuestion, list<string> &provides)
259{
260 bool isit = false;
261 BESContainer *c = look_for(inQuestion);
262 if (c) {
263 isit = true;
264 string node_type = c->get_container_type();
265 BESServiceRegistry::TheRegistry()->services_handled(node_type, provides);
266 delete c;
267 c = 0; // added jhrg 1.4.12
268 }
269 return isit;
270}
271
289{
290 BESContainerStorageFile::Container_citer i;
291 i = _container_list.begin();
292 for (i = _container_list.begin(); i != _container_list.end(); i++) {
293 BESContainerStorageFile::container *c = (*i).second;
294 string sym = c->_symbolic_name;
295 string real = c->_real_name;
296 string type = c->_container_type;
297 show_container(sym, real, type, info);
298 }
299}
300
308void BESContainerStorageFile::dump(ostream &strm) const
309{
310 strm << BESIndent::LMarg << "BESContainerStorageFile::dump - (" << (void *) this << ")" << endl;
311 BESIndent::Indent();
312 strm << BESIndent::LMarg << "name: " << get_name() << endl;
313 strm << BESIndent::LMarg << "file: " << _file << endl;
314 if (_container_list.size()) {
315 strm << BESIndent::LMarg << "containers:" << endl;
316 BESIndent::Indent();
317 BESContainerStorageFile::Container_citer i = _container_list.begin();
318 BESContainerStorageFile::Container_citer ie = _container_list.end();
319 for (i = _container_list.begin(); i != ie; i++) {
320 BESContainerStorageFile::container *c = (*i).second;
321 strm << BESIndent::LMarg << c->_symbolic_name;
322 strm << ", " << c->_real_name;
323 strm << ", " << c->_container_type;
324 strm << endl;
325 }
326 BESIndent::UnIndent();
327 }
328 else {
329 strm << BESIndent::LMarg << " containers: none" << endl;
330 }
331 BESIndent::UnIndent();
332}
333
virtual void show_containers(BESInfo &info)
show information for each container in this persistent store
virtual void add_container(const std::string &sym_name, const std::string &real_name, const std::string &type)
adds a container with the provided information
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
virtual BESContainer * look_for(const std::string &sym_name)
looks for the specified container in the list of containers loaded from the file.
virtual bool del_container(const std::string &s_name)
removes a container with the given symbolic name
BESContainerStorageFile(const std::string &n)
pull container information from the specified file
virtual bool del_containers()
removes all containers
virtual void dump(std::ostream &strm) const
dumps information about this object
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 const std::string & get_name() const
retrieve the name of this persistent store
BESContainerStorage(const std::string &name)
create an instance of BESContainerStorage with the given name.
A container is something that holds data. E.G., a netcdf file or a database entry.
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Holds real data, container type and constraint for symbolic name read from persistence.
informational response object
Definition BESInfo.h:63
exception thrown if internal error encountered
error thrown if there is a user syntax error in the request or any other user error
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
Access to the singleton.
Definition TheBESKeys.cc:85