bes  Updated for version 3.20.6
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 <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 
48 using namespace libdap;
49 using namespace bes;
50 
51 BESDDXResponseHandler::BESDDXResponseHandler(const string &name) :
52  BESResponseHandler(name)
53 {
54 }
55 
56 BESDDXResponseHandler::~BESDDXResponseHandler()
57 {
58 }
59 
72 static 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 
98  GlobalMetadataStore *mds = GlobalMetadataStore::get_instance();
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  auto_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 
205 void BESDDXResponseHandler::dump(ostream &strm) const
206 {
207  strm << BESIndent::LMarg << "BESDDXResponseHandler::dump - (" << (void *) this << ")" << endl;
208  BESIndent::Indent();
210  BESIndent::UnIndent();
211 }
212 
214 BESDDXResponseHandler::DDXResponseBuilder(const string &name)
215 {
216  return new BESDDXResponseHandler(name);
217 }
218 
BESDataHandlerInterface::container
BESContainer * container
pointer to current container in this interface
Definition: BESDataHandlerInterface.h:75
BESDDXResponseHandler::execute
virtual void execute(BESDataHandlerInterface &dhi)
executes the command 'get ddx for def_name;'
Definition: BESDDXResponseHandler.cc:92
bes::GlobalMetadataStore::MDSReadLock
Unlock and close the MDS item when the ReadLock goes out of scope.
Definition: GlobalMetadataStore.h:193
BESDDXResponseHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESDDXResponseHandler.cc:205
BESDataHandlerInterface::action
std::string action
the response object requested, e.g. das, dds
Definition: BESDataHandlerInterface.h:79
BESResponseHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESResponseHandler.cc:102
BESDDSResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDDSResponse.cc:73
BESDDSResponse::get_dds
libdap::DDS * get_dds()
Definition: BESDDSResponse.h:80
BESContainer::get_relative_name
std::string get_relative_name() const
Get the relative name of the object in this container.
Definition: BESContainer.h:186
BESDDXResponseHandler::transmit
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)
transmit the response object built by the execute command
Definition: BESDDXResponseHandler.cc:192
BESContainer::get_constraint
std::string get_constraint() const
retrieve the constraint expression for this container
Definition: BESContainer.h:194
BESRequestHandlerList::execute_each
virtual void execute_each(BESDataHandlerInterface &dhi)
for each container in the given data handler interface, execute the given request
Definition: BESRequestHandlerList.cc:167
libdap
Definition: BESDapFunctionResponseCache.h:35
bes::GlobalMetadataStore
Store the DAP metadata responses.
Definition: GlobalMetadataStore.h:89
bes::GlobalMetadataStore::add_responses
virtual bool add_responses(libdap::DDS *dds, const std::string &name)
Add the DAP2 metadata responses using a DDS.
Definition: GlobalMetadataStore.cc:645
BESResponseHandler
handler object that knows how to create a specific response object
Definition: BESResponseHandler.h:77
BESTransmitter
Definition: BESTransmitter.h:47
BESDDSResponse
Holds a DDS object within the BES.
Definition: BESDDSResponse.h:50
bes::GlobalMetadataStore::get_dds_object
virtual libdap::DDS * get_dds_object(const std::string &name)
Build a DDS object from the cached Response.
Definition: GlobalMetadataStore.cc:1248
BESDapResponse::set_constraint
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:115
bes::GlobalMetadataStore::is_dds_available
virtual MDSReadLock is_dds_available(const std::string &name)
Is the DDS response for.
Definition: GlobalMetadataStore.cc:832
BESDataHandlerInterface::first_container
void first_container()
set the container pointer to the first container in the containers list
Definition: BESDataHandlerInterface.h:135
BESDapResponse::get_request_xml_base
std::string get_request_xml_base() const
Return the xml:base URL for this request.
Definition: BESDapResponse.h:76
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:56
BESDDXResponseHandler
response handler that builds an OPeNDAP DDX object
Definition: BESDDXResponseHandler.h:53