bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
BESDDXResponseHandler.cc
1// BESDDXResponseHandler.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 "config.h"
34
35#include <memory>
36
37#include <libdap/DDS.h>
38
39#include "GlobalMetadataStore.h"
40#include "BESDDXResponseHandler.h"
41#include "BESDDSResponse.h"
42#include "BESDapNames.h"
43#include "BESTransmitter.h"
44#include "BESRequestHandlerList.h"
45
46#include "BESDebug.h"
47
48using namespace libdap;
49using namespace bes;
50
51BESDDXResponseHandler::BESDDXResponseHandler(const string &name) :
53{
54}
55
56BESDDXResponseHandler::~BESDDXResponseHandler()
57{
58}
59
72static bool function_in_ce(const string &ce)
73{
74 // 0x28 is '('
75 return ce.find("(") != string::npos || ce.find("%28") != string::npos; // hack
76}
77
93{
94 BESDEBUG("dap", "Entering BESDDXResponseHandler::execute" << endl);
95
96 dhi.action_name = DDX_RESPONSE_STR;
97
100
101 dhi.first_container();
102 if (mds) lock = mds->is_dds_available(*(dhi.container));
103
104 if (mds && lock() && !function_in_ce(dhi.container->get_constraint())) {
105 DDS *dds = mds->get_dds_object(dhi.container->get_relative_name());
106 BESDDSResponse *bdds = new BESDDSResponse(dds);
107
108 dds->set_request_xml_base(bdds->get_request_xml_base());
109
110 bdds->set_constraint(dhi);
111 bdds->clear_container();
112
113 d_response_object = bdds;
114 }
115 else {
116 // Make a blank DDS. It is the responsibility of the specific request
117 // handler to set the BaseTypeFactory. It is set to NULL here
118 DDS *dds = new DDS(NULL, "virtual");
119
120 BESDDSResponse *bdds = new BESDDSResponse(dds);
121 d_response_name = DDS_RESPONSE;
122 dhi.action = DDS_RESPONSE;
123
124 dds->set_request_xml_base(bdds->get_request_xml_base());
125
126 d_response_object = bdds;
127
128 BESRequestHandlerList::TheList()->execute_each(dhi);
129
130 dhi.first_container(); // must reset container; execute_each() iterates over all of them
131
132#if ANNOTATION_SYSTEM
133 // Support for the experimental Dataset Annotation system. jhrg 12/19/18
134 if (!d_annotation_service_url.empty()) {
135 // resp_dds is a convenience object
136 BESDDSResponse *resp_dds = static_cast<BESDDSResponse*>(d_response_object);
137
138 // Add the Annotation Service URL attribute in the DODS_EXTRA container.
139 AttrTable *dods_extra = resp_dds->get_dds()->get_attr_table().find_container(DODS_EXTRA_ATTR_TABLE);
140 if (dods_extra)
141 dods_extra->append_attr(DODS_EXTRA_ANNOTATION_ATTR, "String", d_annotation_service_url);
142 else {
143 unique_ptr<AttrTable> new_dods_extra(new AttrTable);
144 new_dods_extra->append_attr(DODS_EXTRA_ANNOTATION_ATTR, "String", d_annotation_service_url);
145 resp_dds->get_dds()->get_attr_table().append_container(new_dods_extra.release(), DODS_EXTRA_ATTR_TABLE);
146 }
147 }
148#endif
149
150 if (mds && !function_in_ce(dhi.container->get_constraint())) {
151 // dhi.first_container(); // must reset container; execute_each() iterates over all of them
152 mds->add_responses(static_cast<BESDDSResponse*>(d_response_object)->get_dds(), dhi.container->get_relative_name());
153 }
154 }
155
156#if 0
157 bdds = new BESDDSResponse(dds);
158 d_response_object = bdds;
159 d_response_name = DDS_RESPONSE;
160 dhi.action = DDS_RESPONSE;
161
162 BESDEBUG("bes", "about to set dap version to: " << bdds->get_dap_client_protocol() << endl);
163 BESDEBUG("bes", "about to set xml:base to: " << bdds->get_request_xml_base() << endl);
164
165 if (!bdds->get_dap_client_protocol().empty()) {
166 dds->set_dap_version(bdds->get_dap_client_protocol());
167 }
168
169 dds->set_request_xml_base(bdds->get_request_xml_base());
170
171 BESRequestHandlerList::TheList()->execute_each(dhi);
172
173 dhi.action = DDX_RESPONSE;
174 d_response_object = bdds;
175#endif
176
177 BESDEBUG("dap", "Leaving BESDDXResponseHandler::execute" << endl);
178}
179
193{
194 if (d_response_object) {
195 transmitter->send_response(DDX_SERVICE, d_response_object, dhi);
196 }
197}
198
206{
207 strm << BESIndent::LMarg << "BESDDXResponseHandler::dump - (" << (void *) this << ")" << endl;
208 BESIndent::Indent();
210 BESIndent::UnIndent();
211}
212
214BESDDXResponseHandler::DDXResponseBuilder(const string &name)
215{
216 return new BESDDXResponseHandler(name);
217}
218
std::string get_relative_name() const
Get the relative name of the object in this container.
std::string get_constraint() const
retrieve the constraint expression for this container
Holds a DDS object within the BES.
virtual void clear_container()
clear the container in the DAP response object
libdap::DDS * get_dds()
response handler that builds an OPeNDAP DDX object
virtual void execute(BESDataHandlerInterface &dhi)
executes the command 'get ddx for def_name;'
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)
transmit the response object built by the execute command
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
std::string get_request_xml_base() const
Return the xml:base URL for this request.
Structure storing information used by the BES to handle the request.
std::string action
the response object requested, e.g. das, dds
void first_container()
set the container pointer to the first container in the containers list
BESContainer * container
pointer to current container in this interface
handler object that knows how to create a specific response object
void dump(std::ostream &strm) const override
dumps information about this object
Store the DAP metadata responses.
virtual libdap::DDS * get_dds_object(const std::string &name)
Build a DDS object from the cached Response.
static GlobalMetadataStore * get_instance()
virtual MDSReadLock is_dds_available(const std::string &name)
Is the DDS response for.
virtual bool add_responses(libdap::DDS *dds, const std::string &name)
Add the DAP2 metadata responses using a DDS.
STL class.
STL class.
Unlock and close the MDS item when the ReadLock goes out of scope.