bes  Updated for version 3.17.4
BESCatalogResponseHandler.cc
1 // BESCatalogResponseHandler.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 "BESCatalogResponseHandler.h"
34 #include "BESInfoList.h"
35 #include "BESInfo.h"
36 #include "BESRequestHandlerList.h"
37 #include "BESRequestHandler.h"
38 #include "BESNames.h"
39 #include "BESDataNames.h"
40 #include "BESCatalogList.h"
41 #include "BESCatalog.h"
42 #include "BESCatalogEntry.h"
43 #include "BESCatalogUtils.h"
44 #include "BESSyntaxUserError.h"
45 #include "BESNotFoundError.h"
46 #include "BESDebug.h"
47 #include "BESStopWatch.h"
48 
49 BESCatalogResponseHandler::BESCatalogResponseHandler( const string &name )
50  : BESResponseHandler( name )
51 {
52 }
53 
54 BESCatalogResponseHandler::~BESCatalogResponseHandler( )
55 {
56 }
57 
69 
70  BESStopWatch sw;
71  if (BESISDEBUG( TIMING_LOG ))
72  sw.start("BESCatalogResponseHandler::execute", dhi.data[REQUEST_ID]);
73 
74  BESInfo *info = BESInfoList::TheList()->build_info();
75  _response = info;
76 
77  string container = dhi.data[CONTAINER];
78  string catname;
79  string defcatname = BESCatalogList::TheCatalogList()->default_catalog();
81  if (!defcat) {
82  string err = (string) "Not able to find the default catalog "
83  + defcatname;
84  throw BESInternalError(err, __FILE__, __LINE__);
85  }
86 
87  // remove all of the leading slashes from the container name
88  string::size_type notslash = container.find_first_not_of("/", 0);
89  if (notslash != string::npos) {
90  container = container.substr(notslash);
91  }
92 
93  // see if there is a catalog name here. It's only a possible catalog
94  // name
95  string::size_type slash = container.find_first_of("/", 0);
96  if (slash != string::npos) {
97  catname = container.substr(0, slash);
98  } else {
99  catname = container;
100  }
101 
102  // see if this catalog exists. If it does, then remove the catalog
103  // name from the container (node)
105  catname);
106  if (catobj) {
107  if (slash != string::npos) {
108  container = container.substr(slash + 1);
109 
110  // remove repeated slashes
111  notslash = container.find_first_not_of("/", 0);
112  if (notslash != string::npos) {
113  container = container.substr(notslash);
114  }
115  } else {
116  container = "";
117  }
118  }
119 
120  if (container.empty())
121  container = "/";
122 
123  string coi = dhi.data[CATALOG_OR_INFO];
124 
125  BESCatalogEntry *entry = 0;
126  if (catobj) {
127  entry = catobj->show_catalog(container, coi, entry);
128  } else {
129  // we always want to get the container information from the
130  // default catalog, whether the node is / or not
131  entry = defcat->show_catalog(container, coi, entry);
132 
133  // we only care to get the list of catalogs if the container is
134  // slash (/)
135  int num_cats = BESCatalogList::TheCatalogList()->num_catalogs();
136  if (container == "/" && num_cats > 1) {
137  entry = BESCatalogList::TheCatalogList()->show_catalogs(dhi, entry,
138  false);
139  }
140  }
141 
142  if (!entry) {
143  string err = (string) "Failed to find node " + container;
144  throw BESNotFoundError(err, __FILE__, __LINE__);
145  }
146 
147  // now that we have all the catalog entry information, display it
148  // start the response depending on if show catalog or show info
149  if (coi == CATALOG_RESPONSE) {
150  info->begin_response(CATALOG_RESPONSE_STR, dhi);
151  dhi.action_name = CATALOG_RESPONSE_STR;
152  } else {
153  info->begin_response(SHOW_INFO_RESPONSE_STR, dhi);
154  dhi.action_name = SHOW_INFO_RESPONSE_STR;
155  }
156 
157  // start with the first level entry
158  BESCatalogUtils::display_entry(entry, info);
159 
160  // if we are doing a catalog response, then go one deeper
161  if (coi == CATALOG_RESPONSE) {
162  BESCatalogEntry::catalog_citer ei = entry->get_beginning_entry();
163  BESCatalogEntry::catalog_citer ee = entry->get_ending_entry();
164  for (; ei != ee; ei++) {
165  BESCatalogUtils::display_entry((*ei).second, info);
166  info->end_tag("dataset");
167  }
168  }
169  info->end_tag("dataset");
170 
171  // end the response object
172  info->end_response();
173 
174  delete entry;
175 }
176 
188 void
191 {
192  if( _response )
193  {
194  BESInfo *info = dynamic_cast<BESInfo *>(_response) ;
195  if( !info )
196  throw BESInternalError( "cast error", __FILE__, __LINE__ ) ;
197  info->transmit( transmitter, dhi ) ;
198  }
199 }
200 
207 void
208 BESCatalogResponseHandler::dump( ostream &strm ) const
209 {
210  strm << BESIndent::LMarg << "BESCatalogResponseHandler::dump - ("
211  << (void *)this << ")" << endl ;
212  BESIndent::Indent() ;
213  BESResponseHandler::dump( strm ) ;
214  BESIndent::UnIndent() ;
215 }
216 
218 BESCatalogResponseHandler::CatalogResponseBuilder( const string &name )
219 {
220  return new BESCatalogResponseHandler( name ) ;
221 }
222 
error thrown if the resource requested cannot be found
response handler that returns nodes or leaves within the catalog either at the root or at a specified...
exception thrown if inernal error encountered
virtual BESCatalog * find_catalog(const string &catalog_name)
find the catalog in the list with the specified name
virtual void execute(BESDataHandlerInterface &dhi)
executes the command &#39;show catalog|leaves [for <node>];&#39; by returning nodes or leaves at the top leve...
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)=0
transmit the informational object
virtual void dump(ostream &strm) const
dumps information about this object
virtual BESCatalogEntry * show_catalogs(BESDataHandlerInterface &dhi, BESCatalogEntry *entry, bool show_default=true)
show the list of catalogs
virtual bool start(string name)
Definition: BESStopWatch.cc:57
handler object that knows how to create a specific response object
informational response object
Definition: BESInfo.h:68
abstract base class catalog object. Derived classes know how to show nodes and leaves in a catalog...
Definition: BESCatalog.h:47
Structure storing information used by the BES to handle the request.
map< string, string > data
the map of string data that will be required for the current request.
virtual void dump(ostream &strm) const
dumps information about this object
virtual void begin_response(const string &response_name, BESDataHandlerInterface &dhi)
begin the informational response
Definition: BESInfo.cc:112
static BESCatalogList * TheCatalogList()
returns the singleton BESCatalogList instance. The pthreads library insures that only one instance ca...
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)
transmit the response object built by the execute command using the specified transmitter object ...