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