bes  Updated for version 3.20.6
BESDDSResponseHandler.cc
1 // BESDDSResponseHandler.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 "BESDDSResponseHandler.h"
40 #include "BESDDSResponse.h"
41 #include "BESRequestHandlerList.h"
42 #include "BESDapNames.h"
43 #include "BESDataNames.h"
44 #include "BESTransmitter.h"
45 
46 #include "GlobalMetadataStore.h"
47 #include "BESDebug.h"
48 
49 using namespace libdap;
50 using namespace bes;
51 
52 BESDDSResponseHandler::BESDDSResponseHandler(const string &name) :
53  BESResponseHandler(name)
54 {
55 }
56 
57 BESDDSResponseHandler::~BESDDSResponseHandler()
58 {
59 }
60 
69 static bool
70 function_in_ce(const string &ce)
71 {
72  // 0x28 is '('
73  return ce.find("(") != string::npos || ce.find("%28") != string::npos; // hack
74 }
75 
96 {
97  dhi.action_name = DDS_RESPONSE_STR;
98 
99  GlobalMetadataStore *mds = GlobalMetadataStore::get_instance();
100 
102 
103  dhi.first_container();
104  if (mds) lock = mds->is_dds_available(*(dhi.container));
105 
106  if (mds && lock() && dhi.container->get_constraint().empty()) {
107  // Unconstrained DDS requests; send the stored response
108  mds->write_dds_response(dhi.container->get_relative_name(), dhi.get_output_stream());
109  // suppress transmitting a ResponseObject in transmit()
110  d_response_object = 0;
111  }
112  else {
113  DDS *dds = 0;
114 
115  // Constrained DDS request (but not a CE with a function).
116  if (mds && lock() && !function_in_ce(dhi.container->get_constraint())) {
117  // If mds and lock(), the DDS is in the cache, get the _object_
118  dds = mds->get_dds_object(dhi.container->get_relative_name());
119  BESDDSResponse *bdds = new BESDDSResponse(dds);
120  bdds->set_constraint(dhi);
121  bdds->clear_container();
122  d_response_object = bdds;
123  }
124  else {
125  dds = new DDS(NULL, "virtual");
126 
127  d_response_object = new BESDDSResponse(dds);
128 
129  BESRequestHandlerList::TheList()->execute_each(dhi);
130 
131  dhi.first_container(); // must reset container; execute_each() iterates over all of them
132 
133 #if ANNOTATION_SYSTEM
134  // Support for the experimental Dataset Annotation system. jhrg 12/19/18
135  if (!d_annotation_service_url.empty()) {
136  // resp_dds is a convenience object
137  BESDDSResponse *resp_dds = static_cast<BESDDSResponse*>(d_response_object);
138 
139  // Add the Annotation Service URL attribute in the DODS_EXTRA container.
140  AttrTable *dods_extra = resp_dds->get_dds()->get_attr_table().find_container(DODS_EXTRA_ATTR_TABLE);
141  if (dods_extra)
142  dods_extra->append_attr(DODS_EXTRA_ANNOTATION_ATTR, "String", d_annotation_service_url);
143  else {
144  auto_ptr<AttrTable> new_dods_extra(new AttrTable);
145  new_dods_extra->append_attr(DODS_EXTRA_ANNOTATION_ATTR, "String", d_annotation_service_url);
146  resp_dds->get_dds()->get_attr_table().append_container(new_dods_extra.release(), DODS_EXTRA_ATTR_TABLE);
147  }
148  }
149 #endif
150 
151  // Cache the DDS if the MDS is not null but the DDS response was not in the cache
152  if (mds && !lock() && !function_in_ce(dhi.container->get_constraint())) {
153  // moved dhi.first_container(); // must reset container; execute_each() iterates over all of them
154  mds->add_responses(static_cast<BESDDSResponse*>(d_response_object)->get_dds(),
156  }
157  }
158  }
159 }
160 
174 {
175  if (d_response_object) {
176  transmitter->send_response(DDS_SERVICE, d_response_object, dhi);
177  }
178 }
179 
186 void BESDDSResponseHandler::dump(ostream &strm) const
187 {
188  strm << BESIndent::LMarg << "BESDDSResponseHandler::dump - (" << (void *) this << ")" << endl;
189  BESIndent::Indent();
191  BESIndent::UnIndent();
192 }
193 
195 BESDDSResponseHandler::DDSResponseBuilder(const string &name)
196 {
197  return new BESDDSResponseHandler(name);
198 }
199 
BESDataHandlerInterface::container
BESContainer * container
pointer to current container in this interface
Definition: BESDataHandlerInterface.h:75
bes::GlobalMetadataStore::MDSReadLock
Unlock and close the MDS item when the ReadLock goes out of scope.
Definition: GlobalMetadataStore.h:193
BESDDSResponseHandler::execute
virtual void execute(BESDataHandlerInterface &dhi)
executes the command <get type="dds" definition=...>
Definition: BESDDSResponseHandler.cc:95
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
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
BESDDSResponseHandler::transmit
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)
transmit the response object built by the execute command using the specified transmitter object
Definition: BESDDSResponseHandler.cc:173
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
bes::GlobalMetadataStore::write_dds_response
virtual void write_dds_response(const std::string &name, std::ostream &os)
Write the stored DDS response to a stream.
Definition: GlobalMetadataStore.cc:1082
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
BESDDSResponseHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESDDSResponseHandler.cc:186
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
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:56
BESDDSResponseHandler
response handler that builds an OPeNDAP DDS response object
Definition: BESDDSResponseHandler.h:54