bes  Updated for version 3.20.6
CSVRequestHandler.cc
1 // CSVRequestHandler.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: Stephan Zednik <zednik@ucar.edu> and Patrick West <pwest@ucar.edu>
8 // and Jose Garcia <jgarcia@ucar.edu>
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 University Corporation for Atmospheric Research at
25 // 3080 Center Green Drive, Boulder, CO 80301
26 
27 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
28 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
29 //
30 // Authors:
31 // zednik Stephan Zednik <zednik@ucar.edu>
32 // pwest Patrick West <pwest@ucar.edu>
33 // jgarcia Jose Garcia <jgarcia@ucar.edu>
34 
35 #include "config.h"
36 
37 #include <DDS.h>
38 #include <DAS.h>
39 #include <DataDDS.h>
40 #include <BaseTypeFactory.h>
41 #include <Ancillary.h>
42 
43 #include <DMR.h>
44 #include <D4BaseTypeFactory.h>
45 #include <mime_util.h>
46 #include <InternalErr.h>
47 
48 #include <BESDASResponse.h>
49 #include <BESDDSResponse.h>
50 #include <BESDataDDSResponse.h>
51 #include <BESDMRResponse.h>
52 
53 #include <BESInfo.h>
54 #include <BESContainer.h>
55 #include <BESVersionInfo.h>
56 #include <BESDataNames.h>
57 #include <BESDapNames.h>
58 #include <BESResponseHandler.h>
59 #include <BESResponseNames.h>
60 #include <BESVersionInfo.h>
61 #include <BESTextInfo.h>
62 #include <BESConstraintFuncs.h>
63 #include <BESDapError.h>
64 #include <BESDebug.h>
65 
66 #include "CSVDDS.h"
67 #include "CSVDAS.h"
68 #include "CSVRequestHandler.h"
69 
70 using namespace libdap;
71 
72 CSVRequestHandler::CSVRequestHandler(string name) :
73  BESRequestHandler(name)
74 {
75  add_method(DAS_RESPONSE, CSVRequestHandler::csv_build_das);
76  add_method(DDS_RESPONSE, CSVRequestHandler::csv_build_dds);
77  add_method(DATA_RESPONSE, CSVRequestHandler::csv_build_data);
78 
79  // We can use the same DMR object for both the metadata and data
80  // responses. jhrg 8/13/14
81  add_method(DMR_RESPONSE, CSVRequestHandler::csv_build_dmr);
82  add_method(DAP4DATA_RESPONSE, CSVRequestHandler::csv_build_dmr);
83 
84  add_method(VERS_RESPONSE, CSVRequestHandler::csv_build_vers);
85  add_method(HELP_RESPONSE, CSVRequestHandler::csv_build_help);
86 }
87 
88 CSVRequestHandler::~CSVRequestHandler()
89 {
90 }
91 
92 bool CSVRequestHandler::csv_build_das(BESDataHandlerInterface &dhi)
93 {
94  string error;
95  bool ret = true;
96  BESResponseObject *response = dhi.response_handler->get_response_object();
97  BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
98  DAS *das = 0;
99  if (bdas)
100  das = bdas->get_das();
101  else
102  throw BESInternalError("cast error", __FILE__, __LINE__);
103 
104  try {
105  string accessed = dhi.container->access();
106  csv_read_attributes(*das, accessed);
107  Ancillary::read_ancillary_das(*das, accessed);
108  return ret;
109  }
110  catch (InternalErr &e) {
111  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
112  }
113  catch (Error &e) {
114  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
115  }
116  catch (...) {
117  throw BESDapError("Caught unknown error build CSV DAS response", true, unknown_error, __FILE__, __LINE__);
118  }
119 }
120 
121 bool CSVRequestHandler::csv_build_dds(BESDataHandlerInterface &dhi)
122 {
123  bool ret = true;
124  BESResponseObject *response = dhi.response_handler->get_response_object();
125  BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
126  DDS *dds = 0;
127  if (bdds)
128  dds = bdds->get_dds();
129  else
130  throw BESInternalError("cast error", __FILE__, __LINE__);
131 
132  BaseTypeFactory factory;
133  dds->set_factory(&factory);
134 
135  try {
136  string accessed = dhi.container->access();
137  dds->filename(accessed);
138  csv_read_descriptors(*dds, accessed);
139  Ancillary::read_ancillary_dds(*dds, accessed);
140 
141  DAS das;
142  csv_read_attributes(das, accessed);
143  Ancillary::read_ancillary_das(das, accessed);
144  dds->transfer_attributes(&das);
145 
146  bdds->set_constraint(dhi);
147  return ret;
148  }
149  catch (InternalErr &e) {
150  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
151  }
152  catch (Error &e) {
153  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
154  }
155  catch (...) {
156  throw BESDapError("Caught unknown error build CSV DDS response", true, unknown_error, __FILE__, __LINE__);
157  }
158 }
159 
160 bool CSVRequestHandler::csv_build_data(BESDataHandlerInterface &dhi)
161 {
162  bool ret = true;
163  BESResponseObject *response = dhi.response_handler->get_response_object();
164  BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
165  DDS *dds = 0;
166  if (bdds)
167  dds = bdds->get_dds();
168  else
169  throw BESInternalError("cast error", __FILE__, __LINE__);
170 
171  BaseTypeFactory factory;
172  dds->set_factory(&factory);
173 
174  try {
175  string accessed = dhi.container->access();
176  dds->filename(accessed);
177  csv_read_descriptors(*dds, accessed);
178  Ancillary::read_ancillary_dds(*dds, accessed);
179  bdds->set_constraint(dhi);
180 
181  // We don't need to build the DAS here. Set the including attribute flag to false. KY 10/30/19
182  BESDEBUG("csv", "Data ACCESS build_data(): set the including attribute flag to false: "<<accessed << endl);
183  bdds->set_ia_flag(false);
184  return ret;
185  }
186  catch (InternalErr &e) {
187  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
188  }
189  catch (Error &e) {
190  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
191  }
192  catch (...) {
193  throw BESDapError("Caught unknown error build CSV DataDDS response", true, unknown_error, __FILE__, __LINE__);
194  }
195 
196 
197 }
198 
208 {
209  // Because this code does not yet know how to build a DMR directly, use
210  // the DMR ctor that builds a DMR using a 'full DDS' (a DDS with attributes).
211  // First step, build the 'full DDS'
212  string data_path = dhi.container->access();
213 
214  BaseTypeFactory factory;
215  DDS dds(&factory, name_path(data_path), "3.2");
216  dds.filename(data_path);
217 
218  try {
219  csv_read_descriptors(dds, data_path);
220  // ancillary DDS objects never took off - this does nothing. jhrg 8/12/14
221  // Ancillary::read_ancillary_dds(*dds, data_path);
222 
223  DAS das;
224  csv_read_attributes(das, data_path);
225  Ancillary::read_ancillary_das(das, data_path);
226  dds.transfer_attributes(&das);
227  }
228  catch (InternalErr &e) {
229  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
230  }
231  catch (Error &e) {
232  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
233  }
234  catch (...) {
235  throw BESDapError("Caught unknown error build CSV DMR response", true, unknown_error, __FILE__, __LINE__);
236  }
237 
238  // Second step, make a DMR using the DDS
239 
240  // Extract the DMR Response object - this holds the DMR used by the
241  // other parts of the framework.
242  BESResponseObject *response = dhi.response_handler->get_response_object();
243  BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);
244 
245  // Extract the DMR Response object - this holds the DMR used by the
246  // other parts of the framework.
247  DMR *dmr = bdmr.get_dmr();
248  D4BaseTypeFactory MyD4TypeFactory;
249  dmr->set_factory(&MyD4TypeFactory);
250 
251  dmr->build_using_dds(dds);
252 
253  // Instead of fiddling with the internal storage of the DHI object,
254  // (by setting dhi.data[DAP4_CONSTRAINT], etc., directly) use these
255  // methods to set the constraints. But, why? Maybe setting data[]
256  // directly is better? jhrg 8/14/14
257  bdmr.set_dap4_constraint(dhi);
258  bdmr.set_dap4_function(dhi);
259 
260  // What about async and store_result? See BESDapTransmit::send_dap4_data()
261 
262  return true;
263 }
264 
265 bool CSVRequestHandler::csv_build_vers(BESDataHandlerInterface &dhi)
266 {
267  bool ret = true;
268 
269  BESResponseObject *response = dhi.response_handler->get_response_object();
270  BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
271  if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);
272 
273  info->add_module(MODULE_NAME, MODULE_VERSION);
274  return ret;
275 }
276 
277 bool CSVRequestHandler::csv_build_help(BESDataHandlerInterface &dhi)
278 {
279  bool ret = true;
280  BESInfo *info = dynamic_cast<BESInfo *>(dhi.response_handler->get_response_object());
281  if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);
282 
283  map<string, string> attrs;
284  attrs["name"] = PACKAGE_NAME;
285  attrs["version"] = PACKAGE_VERSION;
286  string handles = (string) DAS_RESPONSE + "," + DDS_RESPONSE + "," + DATA_RESPONSE + "," + HELP_RESPONSE + ","
287  + VERS_RESPONSE;
288  attrs["handles"] = handles;
289  info->begin_tag("module", &attrs);
290  info->end_tag("module");
291 
292  return ret;
293 }
294 
295 void CSVRequestHandler::dump(ostream &strm) const
296 {
297  strm << BESIndent::LMarg << "CSVRequestHandler::dump - (" << (void *) this << ")" << endl;
298  BESIndent::Indent();
300  BESIndent::UnIndent();
301 }
302 
303 
304 void CSVRequestHandler::add_attributes(BESDataHandlerInterface &dhi) {
305 
306  BESResponseObject *response = dhi.response_handler->get_response_object();
307  BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
308  if (!bdds)
309  throw BESInternalError("cast error", __FILE__, __LINE__);
310  DDS *dds = bdds->get_dds();
311  string dataset_name = dhi.container->access();
312  DAS das;
313  csv_read_attributes(das, dataset_name);
314  Ancillary::read_ancillary_das(das, dataset_name);
315  dds->transfer_attributes(&das);
316  BESDEBUG("csv", "Data ACCESS in add_attributes(): set the including attribute flag to true: "<<dataset_name << endl);
317  bdds->set_ia_flag(true);
318  return;
319 }
320 
BESRequestHandler
Represents a specific data type request handler.
Definition: BESRequestHandler.h:74
BESDataHandlerInterface::container
BESContainer * container
pointer to current container in this interface
Definition: BESDataHandlerInterface.h:75
BESDapResponse::set_dap4_constraint
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:137
BESDapResponse::set_dap4_function
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:154
BESDDSResponse::get_dds
libdap::DDS * get_dds()
Definition: BESDDSResponse.h:80
BESDASResponse
Represents an OPeNDAP DAS DAP2 data object within the BES.
Definition: BESDASResponse.h:44
BESInfo
informational response object
Definition: BESInfo.h:63
libdap
Definition: BESDapFunctionResponseCache.h:35
BESResponseHandler::get_response_object
virtual BESResponseObject * get_response_object()
return the current response object
Definition: BESResponseHandler.cc:82
BESVersionInfo
Definition: BESVersionInfo.h:47
BESContainer::access
virtual std::string access()=0
returns the true name of this container
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
BESDDSResponse
Holds a DDS object within the BES.
Definition: BESDDSResponse.h:50
BESDapResponse::set_constraint
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:115
CSVRequestHandler::csv_build_dmr
static bool csv_build_dmr(BESDataHandlerInterface &dhi)
Definition: CSVRequestHandler.cc:207
BESDataDDSResponse
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
Definition: BESDataDDSResponse.h:46
BESRequestHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESRequestHandler.cc:163
Error
BESDapError
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:59
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:56
CSVRequestHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: CSVRequestHandler.cc:295
BESResponseObject
Abstract base class representing a specific set of information in response to a request to the BES.
Definition: BESResponseObject.h:45
BESDMRResponse
Represents an OPeNDAP DMR DAP4 data object within the BES.
Definition: BESDMRResponse.h:39