bes  Updated for version 3.20.8
SiteMapResponseHandler.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 //
3 // SiteMapResponseHandler.cc
4 //
5 // This file is part of the BES default command set
6 //
7 // Copyright (c) 2018 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 // Please read the full copyright statement in the file COPYRIGHT_URI.
26 //
27 
28 #include "config.h"
29 
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <time.h>
34 
35 #include <cerrno>
36 #include <cstring>
37 
38 #include <sstream>
39 #include <fstream>
40 
41 #include "ShowBesKeyCommand.h"
42 #include "SiteMapResponseHandler.h"
43 
44 
45 #include "BESTextInfo.h"
46 #include "BESDataNames.h"
47 #include "BESNames.h"
48 #include "TheBESKeys.h"
49 #include "BESCatalog.h"
50 #include "BESCatalogList.h"
51 
52 #include "BESError.h"
53 #include "BESDebug.h"
54 #include "BESStopWatch.h"
55 
56 using namespace std;
57 
58 SiteMapResponseHandler::SiteMapResponseHandler(const string &name) :
59  BESResponseHandler(name)
60 {
61 }
62 
63 SiteMapResponseHandler::~SiteMapResponseHandler()
64 {
65 }
66 
78 {
79  BESStopWatch sw;
80  if (BESDebug::IsSet(TIMING_LOG_KEY)) sw.start("SiteMapResponseHandler::execute", dhi.data[REQUEST_ID]);
81 
82  // Force this command to use a TextInfo object. The default Info object type
83  // is set using a key in bes.conf. jheg 11/27/18
84  BESInfo *info = new BESTextInfo(); // BESInfoList::TheList()->build_info();
85  d_response_object = info;
86 
87  if (dhi.data[SITE_MAP_RESPONSE] != SITE_MAP_RESPONSE)
88  throw BESInternalError("Not a Site Map command in SiteMapResponseHandler::execute().", __FILE__, __LINE__);
89 
90  // remove trailing '/' if present
91  if (*(dhi.data[PREFIX].end()-1) == '/')
92  dhi.data[PREFIX].erase(dhi.data[PREFIX].end()-1);
93 
94  ostringstream oss;
95  const BESCatalogList *catalog_list = BESCatalogList::TheCatalogList(); // convenience variable
96 
97  info->begin_response(SITE_MAP_RESPONSE_STR, dhi);
98 
99  // If no catalog is named, return the concatenation of the site maps for
100  // all of the catalogs. This mimics the way shwoNode returns information
101  // for the path '/'.
102  if (dhi.data[CATALOG].empty()) {
103  BESCatalogList::catalog_citer i = catalog_list->first_catalog();
104  BESCatalogList::catalog_citer e = catalog_list->end_catalog();
105  for (; i != e; ++i) {
106  BESCatalog *catalog = i->second;
107  if (!catalog)
108  throw BESInternalError(string("Build site map found a null catalog in the catalog list."), __FILE__, __LINE__);
109 
110  // Don't add 'default' to the prefix value here. For other catalogs, do add their
111  // names to the prefix (i->first is the name of the catalog). This matches the
112  // behavior of showNode, where the non-default catalogs 'appear' in the default
113  // catalog's top level as 'phantom' directories.
114  string prefix = (i->first == catalog_list->default_catalog_name()) ? dhi.data[PREFIX]: dhi.data[PREFIX] + "/" + i->first;
115  catalog->get_site_map(prefix, dhi.data[NODE_SUFFIX], dhi.data[LEAF_SUFFIX], oss, "/");
116 
117  info->add_data(oss.str());
118 
119  // clearing oss to keep the size of the object small.
120  // Maybe change get_site_map so it takes an Info object? jhrg 11/28/18
121  oss.str("");
122  oss.clear();
123  }
124  }
125  else {
126  BESCatalog *catalog = catalog_list->find_catalog(dhi.data[CATALOG]);
127  if (!catalog)
128  throw BESInternalError(string("Build site map could not find the catalog: ") + dhi.data[CATALOG], __FILE__, __LINE__);
129 
130  string prefix = (dhi.data[CATALOG] == catalog_list->default_catalog_name()) ? dhi.data[PREFIX]: dhi.data[PREFIX] + "/" + dhi.data[CATALOG];
131  catalog->get_site_map(prefix, dhi.data[NODE_SUFFIX], dhi.data[LEAF_SUFFIX], oss, "/");
132 
133  info->add_data(oss.str());
134 
135  // As above, no sense keeping this in memory any longer than needed
136  oss.str("");
137  oss.clear();
138  }
139 
140  info->end_response();
141 }
142 
155 {
156  if (d_response_object) {
157  BESInfo *info = dynamic_cast<BESInfo *>(d_response_object);
158  if (!info) throw BESInternalError("Could not get the Info object in SiteMapResponseHandler::transmit()", __FILE__, __LINE__);
159  info->transmit(transmitter, dhi);
160  }
161 }
162 
169 void SiteMapResponseHandler::dump(ostream &strm) const
170 {
171  strm << BESIndent::LMarg << "SiteMapResponseHandler::dump - (" << (void *) this << ")" << std::endl;
172  BESIndent::Indent();
174  BESIndent::UnIndent();
175 }
176 
178 SiteMapResponseHandler::SiteMapResponseBuilder(const string &name)
179 {
180  return new SiteMapResponseHandler(name);
181 }
List of all registered catalogs.
virtual std::string default_catalog_name() const
The name of the default catalog.
static BESCatalogList * TheCatalogList()
Get the singleton BESCatalogList instance.
virtual catalog_citer end_catalog() const
Iterator to the last catalog.
virtual catalog_citer first_catalog() const
Iterator to the first catalog.
Catalogs provide a hierarchical organization for data.
Definition: BESCatalog.h:51
Structure storing information used by the BES to handle the request.
std::map< std::string, std::string > data
the map of string data that will be required for the current request.
static bool IsSet(const std::string &flagName)
see if the debug context flagName is set to true
Definition: BESDebug.h:160
informational response object
Definition: BESInfo.h:63
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)=0
transmit the informational object
virtual void add_data(const std::string &s)
add data to this informational object. If buffering is not set then the information is output directl...
Definition: BESInfo.cc:160
virtual void begin_response(const std::string &response_name, BESDataHandlerInterface &dhi)
begin the informational response
Definition: BESInfo.cc:124
exception thrown if internal error encountered
handler object that knows how to create a specific response object
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual bool start(std::string name)
Definition: BESStopWatch.cc:67
represents simple text information in a response object, such as version and help information.
Definition: BESTextInfo.h:48
Response handler that returns a site map.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void execute(BESDataHandlerInterface &dhi)
executes the command 'show catalog|leaves [for <node>];' by returning nodes or leaves at the top leve...
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)
transmit the response object built by the execute command using the specified transmitter object