bes  Updated for version 3.20.5
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 = new BaseTypeFactory;
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 = new BaseTypeFactory;
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 
180  DAS das;
181  csv_read_attributes(das, accessed);
182  Ancillary::read_ancillary_das(das, accessed);
183  dds->transfer_attributes(&das);
184 
185  bdds->set_constraint(dhi);
186  return ret;
187  }
188  catch (InternalErr &e) {
189  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
190  }
191  catch (Error &e) {
192  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
193  }
194  catch (...) {
195  throw BESDapError("Caught unknown error build CSV DataDDS response", true, unknown_error, __FILE__, __LINE__);
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  dmr->set_factory(new D4BaseTypeFactory);
249  dmr->build_using_dds(dds);
250 
251  // Instead of fiddling with the internal storage of the DHI object,
252  // (by setting dhi.data[DAP4_CONSTRAINT], etc., directly) use these
253  // methods to set the constraints. But, why? Maybe setting data[]
254  // directly is better? jhrg 8/14/14
255  bdmr.set_dap4_constraint(dhi);
256  bdmr.set_dap4_function(dhi);
257 
258  // What about async and store_result? See BESDapTransmit::send_dap4_data()
259 
260  return true;
261 }
262 
263 bool CSVRequestHandler::csv_build_vers(BESDataHandlerInterface &dhi)
264 {
265  bool ret = true;
266 
267  BESResponseObject *response = dhi.response_handler->get_response_object();
268  BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
269  if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);
270 
271  info->add_module(MODULE_NAME, MODULE_VERSION);
272  return ret;
273 }
274 
275 bool CSVRequestHandler::csv_build_help(BESDataHandlerInterface &dhi)
276 {
277  bool ret = true;
278  BESInfo *info = dynamic_cast<BESInfo *>(dhi.response_handler->get_response_object());
279  if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);
280 
281  map<string, string> attrs;
282  attrs["name"] = PACKAGE_NAME;
283  attrs["version"] = PACKAGE_VERSION;
284  string handles = (string) DAS_RESPONSE + "," + DDS_RESPONSE + "," + DATA_RESPONSE + "," + HELP_RESPONSE + ","
285  + VERS_RESPONSE;
286  attrs["handles"] = handles;
287  info->begin_tag("module", &attrs);
288  info->end_tag("module");
289 
290  return ret;
291 }
292 
293 void CSVRequestHandler::dump(ostream &strm) const
294 {
295  strm << BESIndent::LMarg << "CSVRequestHandler::dump - (" << (void *) this << ")" << endl;
296  BESIndent::Indent();
298  BESIndent::UnIndent();
299 }
300 
exception thrown if inernal error encountered
Holds a DDS object within the BES.
libdap::DDS * get_dds()
virtual void dump(ostream &strm) const
dumps information about this object
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual string access()=0
returns the true name of this container
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
informational response object
Definition: BESInfo.h:68
virtual BESResponseObject * get_response_object()
return the current response object
static bool csv_build_dmr(BESDataHandlerInterface &dhi)
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Represents an OPeNDAP DMR DAP4 data object within the BES.
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:59
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
Represents a specific data type request handler.
virtual void dump(ostream &strm) const
dumps information about this object
Structure storing information used by the BES to handle the request.
Represents an OPeNDAP DAS DAP2 data object within the BES.
Abstract base class representing a specific set of information in response to a request to the BES.
BESContainer * container
pointer to current container in this interface