bes  Updated for version 3.19.1
BESInfo.cc
1 // BESInfo.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 <iostream>
36 #include <fstream>
37 #include <cstring>
38 
39 using std::ostringstream;
40 using std::ifstream;
41 
42 #include "BESInfo.h"
43 #include "TheBESKeys.h"
44 #include "BESInternalError.h"
45 
46 #define BES_INFO_FILE_BUFFER_SIZE 4096
47 
54  _strm(0), _strm_owned(false), _buffered(true), _response_started(false)
55 {
56  _strm = new ostringstream;
57  _strm_owned = true;
58 }
59 
73 BESInfo::BESInfo(const string &key, ostream *strm, bool strm_owned) :
74  _strm(0), _strm_owned(false), _buffered(true), _response_started(false), _response_name("")
75 {
76  bool found = false;
77  vector < string > vals;
78  string b;
79  TheBESKeys::TheKeys()->get_value(key, b, found);
80  if (b == "true" || b == "True" || b == "TRUE" || b == "yes" || b == "Yes" || b == "YES") {
81  _strm = new ostringstream;
82  _strm_owned = true;
83  _buffered = true;
84  if (strm && strm_owned) delete strm;
85  }
86  else {
87  if (!strm) {
88  string s = "Informational response not buffered but no stream passed";
89  throw BESInternalError(s, __FILE__, __LINE__);
90  }
91  _strm = strm;
92  _strm_owned = strm_owned;
93  _buffered = false;
94  }
95 }
96 
97 BESInfo::~BESInfo()
98 {
99  if (_strm && _strm_owned) {
100  delete _strm;
101  _strm = 0;
102  }
103 }
104 
112 void BESInfo::begin_response(const string &response_name, BESDataHandlerInterface &/*dhi*/)
113 {
114  _response_started = true;
115  _response_name = response_name;
116 }
117 
118 void BESInfo::end_response()
119 {
120  _response_started = false;
121  if (_tags.size()) {
122  string s = "Not all tags were ended in info response";
123  throw BESInternalError(s, __FILE__, __LINE__);
124  }
125 }
126 
127 void BESInfo::begin_tag(const string &tag_name, map<string, string> */*attrs*/)
128 {
129  _tags.push(tag_name);
130 }
131 
132 void BESInfo::end_tag(const string &tag_name)
133 {
134  if (_tags.size() == 0 || _tags.top() != tag_name) {
135  string s = (string) "tag " + tag_name + " already ended or not started";
136  throw BESInternalError(s, __FILE__, __LINE__);
137  }
138  else {
139  _tags.pop();
140  }
141 }
142 
148 void BESInfo::add_data(const string &s)
149 {
150  // If not buffered then we've been passed a stream to use.
151  // If it is buffered then we created the stream.
152  (*_strm) << s;
153 }
154 
170 void BESInfo::add_data_from_file(const string &key, const string &name)
171 {
172  bool found = false;
173  string file;
174  try {
175  TheBESKeys::TheKeys()->get_value(key, file, found);
176  }
177  catch (...) {
178  found = false;
179  }
180  if (found == false) {
181  add_data(name + " file key " + key + " not found, information not available\n");
182  }
183  else {
184  ifstream ifs(file.c_str());
185  int myerrno = errno;
186  if (!ifs) {
187  string serr = name + " file " + file + " not found, information not available: ";
188  char *err = strerror(myerrno);
189  if (err)
190  serr += err;
191  else
192  serr += "Unknown error";
193 
194  serr += "\n";
195 
196  add_data(serr);
197  }
198  else {
199  char line[BES_INFO_FILE_BUFFER_SIZE];
200  while (!ifs.eof()) {
201  ifs.getline(line, BES_INFO_FILE_BUFFER_SIZE);
202  if (!ifs.eof()) {
203  add_data(line);
204  add_data("\n");
205  }
206  }
207  ifs.close();
208  }
209  }
210 }
211 
222 void BESInfo::add_exception(BESError &e, const string &admin)
223 {
224  begin_tag("BESError");
225  ostringstream stype;
226  stype << e.get_error_type();
227  add_tag("Type", stype.str());
228  add_tag("Message", e.get_message());
229  add_tag("Administrator", admin);
230 
231  begin_tag( "Location" );
232  add_tag( "File", e.get_file() );
233  ostringstream sline;
234  sline << e.get_line();
235  add_tag( "Line", sline.str() );
236  end_tag( "Location" );
237 
238  end_tag("BESError");
239 }
240 
249 void BESInfo::print(ostream &strm)
250 {
251  if (_buffered) {
252  strm << ((ostringstream *) _strm)->str();
253  }
254 }
255 
263 void BESInfo::dump(ostream &strm) const
264 {
265  strm << BESIndent::LMarg << "BESInfo::dump - (" << (void *) this << ")" << endl;
266  BESIndent::Indent();
267  strm << BESIndent::LMarg << "response name: " << _response_name << endl;
268  strm << BESIndent::LMarg << "is it buffered? " << _buffered << endl;
269  strm << BESIndent::LMarg << "has response been started? " << _response_started << endl;
270  if (_tags.size()) {
271  strm << BESIndent::LMarg << "tags:" << endl;
272  BESIndent::Indent();
273  stack < string > temp_tags = _tags;
274  while (!temp_tags.empty()) {
275  string tag = temp_tags.top();
276  strm << BESIndent::LMarg << tag << endl;
277  temp_tags.pop();
278  }
279  BESIndent::UnIndent();
280  }
281  else {
282  strm << BESIndent::LMarg << "tags: empty" << endl;
283  }
284  BESIndent::UnIndent();
285 }
286 
virtual void dump(ostream &strm) const
Displays debug information about this object.
Definition: BESInfo.cc:263
exception thrown if inernal error encountered
virtual void add_data_from_file(const string &key, const string &name)
add data from a file to the informational object.
Definition: BESInfo.cc:170
BESInfo()
constructs a BESInfo object
Definition: BESInfo.cc:53
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:97
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:422
virtual int get_error_type()
Return the return code for this error class.
Definition: BESError.h:138
Abstract exception class for the BES with basic string message.
Definition: BESError.h:56
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
virtual void add_exception(BESError &e, const string &admin)
add exception information to this informational object
Definition: BESInfo.cc:222
Structure storing information used by the BES to handle the request.
virtual std::string get_file()
get the file name where the exception was thrown
Definition: BESError.h:105
virtual void begin_response(const string &response_name, BESDataHandlerInterface &dhi)
begin the informational response
Definition: BESInfo.cc:112
virtual void add_data(const string &s)
add data to this informational object. If buffering is not set then the information is output directl...
Definition: BESInfo.cc:148
virtual void print(ostream &strm)
print the information from this informational object to the specified stream
Definition: BESInfo.cc:249
virtual int get_line()
get the line number where the exception was thrown
Definition: BESError.h:113