OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BESInfo.cc
Go to the documentation of this file.
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., 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 
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 ),
55  _strm_owned( false ),
56  _buffered( true )
57 {
58  _strm = new ostringstream ;
59  _strm_owned = true ;
60 }
61 
75 BESInfo::BESInfo( const string &key, ostream *strm, bool strm_owned )
76  : _strm( 0 ),
77  _strm_owned( false ),
78  _buffered( true )
79 {
80  bool found = false ;
81  vector<string> vals ;
82  string b ;
83  TheBESKeys::TheKeys()->get_value( key, b, found ) ;
84  if( b == "true" || b == "True" || b == "TRUE" ||
85  b == "yes" || b == "Yes" || b == "YES" )
86  {
87  _strm = new ostringstream ;
88  _strm_owned = true ;
89  _buffered = true ;
90  if( strm && strm_owned )
91  delete strm ;
92  }
93  else
94  {
95  if( !strm )
96  {
97  string s = "Informational response not buffered but no stream passed" ;
98  throw BESInternalError( s, __FILE__, __LINE__ ) ;
99  }
100  _strm = strm ;
101  _strm_owned = strm_owned ;
102  _buffered = false ;
103  }
104 }
105 
107 {
108  if( _strm && _strm_owned )
109  {
110  delete _strm ;
111  _strm = 0 ;
112  }
113 }
114 
122 void
123 BESInfo::begin_response( const string &response_name,
125 {
126  _response_started = true ;
127  _response_name = response_name ;
128 }
129 
130 void
132 {
133  _response_started = false ;
134  if( _tags.size() )
135  {
136  string s = "Not all tags were ended in info response" ;
137  throw BESInternalError( s, __FILE__, __LINE__ ) ;
138  }
139 }
140 
141 void
142 BESInfo::begin_tag( const string &tag_name,
143  map<string,string> *attrs )
144 {
145  _tags.push( tag_name ) ;
146 }
147 
148 void
149 BESInfo::end_tag( const string &tag_name )
150 {
151  if( _tags.size() == 0 || _tags.top() != tag_name )
152  {
153  string s = (string)"tag " + tag_name
154  + " already ended or not started" ;
155  throw BESInternalError( s, __FILE__, __LINE__ ) ;
156  }
157  else
158  {
159  _tags.pop() ;
160  }
161 }
162 
168 void
169 BESInfo::add_data( const string &s )
170 {
171  // If not buffered then we've been passed a stream to use.
172  // If it is buffered then we created the stream.
173  (*_strm) << s ;
174 }
175 
191 void
192 BESInfo::add_data_from_file( const string &key, const string &name )
193 {
194  bool found = false ;
195  string file ;
196  try
197  {
198  TheBESKeys::TheKeys()->get_value( key, file, found ) ;
199  }
200  catch( ... )
201  {
202  found = false ;
203  }
204  if( found == false )
205  {
206  add_data( name + " file key " + key
207  + " not found, information not available\n" ) ;
208  }
209  else
210  {
211  ifstream ifs( file.c_str() ) ;
212  int myerrno = errno ;
213  if( !ifs )
214  {
215  string serr = name + " file " + file
216  + " not found, information not available: " ;
217  char *err = strerror( myerrno ) ;
218  if( err )
219  serr += err ;
220  else
221  serr += "Unknown error" ;
222 
223  serr += "\n" ;
224 
225  add_data( serr ) ;
226  }
227  else
228  {
229  char line[BES_INFO_FILE_BUFFER_SIZE] ;
230  while( !ifs.eof() )
231  {
232  ifs.getline( line, BES_INFO_FILE_BUFFER_SIZE ) ;
233  if( !ifs.eof() )
234  {
235  add_data( line ) ;
236  add_data( "\n" ) ;
237  }
238  }
239  ifs.close() ;
240  }
241  }
242 }
243 
254 void
255 BESInfo::add_exception( BESError &e, const string &admin )
256 {
257  begin_tag( "BESError" ) ;
258  ostringstream stype ;
259  stype << e.get_error_type() ;
260  add_tag( "Type", stype.str() ) ;
261  add_tag( "Message", e.get_message() ) ;
262  add_tag( "Administrator", admin ) ;
263 #ifdef BES_DEVELOPER
264  begin_tag( "Location" ) ;
265  add_tag( "File", e.get_file() ) ;
266  ostringstream sline ;
267  sline << e.get_line() ;
268  add_tag( "Line", sline.str() ) ;
269  end_tag( "Location" ) ;
270 #endif
271  end_tag( "BESError" ) ;
272 }
273 
282 void
283 BESInfo::print( ostream &strm )
284 {
285  if( _buffered )
286  {
287  strm << ((ostringstream *)_strm)->str() ;
288  }
289 }
290 
298 void
299 BESInfo::dump( ostream &strm ) const
300 {
301  strm << BESIndent::LMarg << "BESInfo::dump - ("
302  << (void *)this << ")" << endl ;
304  strm << BESIndent::LMarg << "response name: " << _response_name << endl ;
305  strm << BESIndent::LMarg << "is it buffered? " << _buffered << endl ;
306  strm << BESIndent::LMarg << "has response been started? " << _response_started << endl ;
307  if( _tags.size() )
308  {
309  strm << BESIndent::LMarg << "tags:" << endl ;
311  stack<string> temp_tags = _tags ;
312  while( !temp_tags.empty() )
313  {
314  string tag = temp_tags.top() ;
315  strm << BESIndent::LMarg << tag << endl ;
316  temp_tags.pop() ;
317  }
319  }
320  else
321  {
322  strm << BESIndent::LMarg << "tags: empty" << endl ;
323  }
325 }
326 
virtual void end_response()
Definition: BESInfo.cc:131
virtual void dump(ostream &strm) const
Displays debug information about this object.
Definition: BESInfo.cc:299
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:192
BESInfo()
constructs a BESInfo object
Definition: BESInfo.cc:53
virtual ~BESInfo()
Definition: BESInfo.cc:106
stack< string > _tags
Definition: BESInfo.h:76
virtual void add_tag(const string &tag_name, const string &tag_data, map< string, string > *attrs=0)=0
string _response_name
Definition: BESInfo.h:77
static void Indent()
Definition: BESIndent.cc:38
virtual int get_error_type()
Return the return code for this error class.
Definition: BESError.h:120
virtual string get_file()
get the file name where the exception was thrown
Definition: BESError.h:96
virtual string get_message()
get the error message for this exception
Definition: BESError.h:91
Abstract exception class for the BES with basic string message.
Definition: BESError.h:51
virtual void add_exception(BESError &e, const string &admin)
add exception information to this informational object
Definition: BESInfo.cc:255
virtual void begin_tag(const string &tag_name, map< string, string > *attrs=0)
Definition: BESInfo.cc:142
static ostream & LMarg(ostream &strm)
Definition: BESIndent.cc:73
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: BESKeys.cc:466
bool _strm_owned
Definition: BESInfo.h:72
ostream * _strm
Definition: BESInfo.h:71
Structure storing information used by the BES to handle the request.
#define BES_INFO_FILE_BUFFER_SIZE
Definition: BESInfo.cc:46
virtual void begin_response(const string &response_name, BESDataHandlerInterface &dhi)
begin the informational response
Definition: BESInfo.cc:123
virtual void add_data(const string &s)
add data to this informational object.
Definition: BESInfo.cc:169
static void UnIndent()
Definition: BESIndent.cc:44
virtual void print(ostream &strm)
print the information from this informational object to the specified stream
Definition: BESInfo.cc:283
static BESKeys * TheKeys()
Definition: TheBESKeys.cc:46
bool _buffered
Definition: BESInfo.h:73
bool _response_started
Definition: BESInfo.h:74
virtual void end_tag(const string &tag_name)
Definition: BESInfo.cc:149
virtual int get_line()
get the line number where the exception was thrown
Definition: BESError.h:101