bes Updated for version 3.20.13
ShowNodeResponseHandler.cc
1// ShowNodeResponseHandler.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) 2018 OPeNDAP, Inc
7// Author: James Gallagher <jgallagher@opendap.org>
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 OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24
25#include "config.h"
26
27#include <memory>
28#include <string>
29
30#include "BESInfoList.h"
31#include "BESInfo.h"
32#include "BESCatalogList.h"
33#include "BESCatalog.h"
34
35#include "BESNames.h"
36#include "BESDataNames.h"
37
38#include "BESDebug.h"
39#include "BESUtil.h"
40#include "BESStopWatch.h"
41#include "BESSyntaxUserError.h"
42
43#include "CatalogNode.h"
44#include "CatalogItem.h"
45#include "ShowNodeResponseHandler.h"
46
47using namespace bes;
48using namespace std;
49
50#define MODULE "bes"
51#define prolog string("ShowNodeResponseHandler::").append(__func__).append("() - ")
52
63{
64 BESStopWatch sw;
65 if (BESDebug::IsSet(TIMING_LOG_KEY)) sw.start("ShowNodeResponseHandler::execute", dhi.data[REQUEST_ID]);
66
67 // Get the container. By convention, the path can start with a slash,
68 // but doesn't have too. However, get_node() requires the leading '/'.
69 string container = dhi.data[CONTAINER];
70
71 BESDEBUG(MODULE, prolog << "Requested container: " << container << endl);
72
73 // Look for the name of a catalog in the first part of the pathname in
74 // 'container' and, if found, set 'catalog' to that catalog. The value
75 // null is used as a sentinel that the path in 'container' does not
76 // name a catalog.
77 BESCatalog *catalog = 0;
78
79 vector<string> path_tokens;
80 BESUtil::tokenize(container, path_tokens);
81 if (!path_tokens.empty()) {
82
83 catalog = BESCatalogList::TheCatalogList()->find_catalog(path_tokens[0]);
84 if (catalog) {
85 string catalog_name = catalog->get_catalog_name();
86
87 // Remove the catalog name from the start of 'container.' Now 'container'
88 // is a relative path within the catalog.
89 container = container.substr(container.find(catalog_name) + catalog_name.length());
90
91 BESDEBUG(MODULE, prolog << "Modified container/path value to: " << container << endl);
92 }
93 }
94
95 // if we found no catalog name in the first part of the container name/path,
96 // use the default catalog.
97 if (!catalog) {
99 if (!catalog) throw BESInternalError(string("Could not find the default catalog."), __FILE__, __LINE__);
100 }
101
102 BESDEBUG(MODULE, prolog << "Using the '" << catalog->get_catalog_name() << "' catalog."<< endl);
103 BESDEBUG(MODULE, prolog << "use_container: " << container << endl);
104
105 // Get the node info from the catalog.
106 unique_ptr<CatalogNode> node(catalog->get_node(container));
107
108 // If the path name passed into this command is '/' we are using the default
109 // catalog and must add any other catalogs to the set of nodes shown at the
110 // top level. Since the variable 'container' may have been modified above,
111 // use the value of dhi.data[CONTAINER] for the path passed to the command.
112 if (dhi.data[CONTAINER] == "/") {
113
114 BESDEBUG(MODULE, prolog << "Adding additional catalog nodes to top level node." << endl);
115
118 for (; i != e; i++) {
119 string catalog_name = i->first;
120 BESCatalog *cat = i->second;
121
122 BESDEBUG(MODULE, prolog << "Checking catalog '" << catalog_name << "' ptr: " << (void *) cat << endl);
123
124 if (cat != BESCatalogList::TheCatalogList()->default_catalog()) {
125 auto *collection = new CatalogItem(catalog_name, 0, BESUtil::get_time(), false, CatalogItem::node);
126 node->add_node(collection);
127
128 BESDEBUG(MODULE, prolog << "Added catalog node " << catalog_name << " to top level node." << endl);
129 }
130 }
131 }
132
133 BESInfo *info = BESInfoList::TheList()->build_info();
134
135 // Transfer the catalog's node info to the BESInfo object
136 info->begin_response(NODE_RESPONSE_STR, dhi);
137
138 // calls encode_item()
139 node->encode_node(info);
140
141 info->end_response();
142
143 // set the state and return
144 dhi.action_name = NODE_RESPONSE_STR;
145 d_response_object = info;
146}
147
160{
161 if (d_response_object) {
162 BESInfo *info = dynamic_cast<BESInfo *>(d_response_object);
163 if (!info) throw BESInternalError("Expected the Response Object to be a BESInfo instance.", __FILE__, __LINE__);
164 info->transmit(transmitter, dhi);
165 }
166}
167
174void ShowNodeResponseHandler::dump(ostream &strm) const
175{
176 strm << BESIndent::LMarg << "ShowNodeResponseHandler::dump - (" << (void *) this << ")" << endl;
177 BESIndent::Indent();
179 BESIndent::UnIndent();
180}
181
183ShowNodeResponseHandler::ShowNodeResponseBuilder(const string &name)
184{
185 return new ShowNodeResponseHandler(name);
186}
187
virtual BESCatalog * default_catalog() const
The 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
virtual std::string get_catalog_name() const
Get the name for this catalog.
Definition: BESCatalog.h:102
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:168
informational response object
Definition: BESInfo.h:63
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)=0
transmit the informational object
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
static void tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters="/")
Definition: BESUtil.cc:992
static std::string get_time(bool use_local_time=false)
Definition: BESUtil.cc:1014
Evaluate a showNode command.
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)
transmit the response object built by the execute command using the specified transmitter object
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void execute(BESDataHandlerInterface &dhi)
Execute the showNode command.