bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
FitsRequestHandler.cc
1// FitsRequestHandler.cc
2
3// This file is part of fits_handler, a data handler for the OPeNDAP data
4// server.
5
6// Copyright (c) 2004,2005 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 Atmostpheric 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 <libdap/DAS.h>
36#include <libdap/DDS.h>
37#include <libdap/DataDDS.h>
38#include <libdap/DMR.h>
39#include <libdap/D4BaseTypeFactory.h>
40#include <libdap/Ancillary.h>
41#include <libdap/InternalErr.h>
42#include <libdap/mime_util.h>
43
44#include <BESResponseHandler.h>
45#include <BESDapError.h>
46
47#include <BESDapNames.h>
48#include <BESResponseNames.h>
49#include <BESDASResponse.h>
50#include <BESDDSResponse.h>
51#include <BESDataDDSResponse.h>
52#include <BESDMRResponse.h>
53
54#include <BESVersionInfo.h>
55#include <BESConstraintFuncs.h>
56#include <BESServiceRegistry.h>
57#include <BESUtil.h>
58#include <BESDebug.h>
59
60#include <fitsio.h>
61
62#include "FitsRequestHandler.h"
63#include "fits_read_attributes.h"
64#include "fits_read_descriptors.h"
65
66using namespace libdap;
67
68#define FITS_NAME "fits"
69
70FitsRequestHandler::FitsRequestHandler(const string &name) :
72{
73 add_method(DAS_RESPONSE, FitsRequestHandler::fits_build_das);
74 add_method(DDS_RESPONSE, FitsRequestHandler::fits_build_dds);
75 add_method(DATA_RESPONSE, FitsRequestHandler::fits_build_data);
76
77 add_method(DMR_RESPONSE, FitsRequestHandler::fits_build_dmr);
78 add_method(DAP4DATA_RESPONSE, FitsRequestHandler::fits_build_dmr);
79
80 add_method(VERS_RESPONSE, FitsRequestHandler::fits_build_vers);
81 add_method(HELP_RESPONSE, FitsRequestHandler::fits_build_help);
82}
83
84FitsRequestHandler::~FitsRequestHandler()
85{
86}
87
88bool FitsRequestHandler::fits_build_das(BESDataHandlerInterface &dhi)
89{
90 BESResponseObject *response = dhi.response_handler->get_response_object();
91 BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
92 if (!bdas) throw BESInternalError("cast error", __FILE__, __LINE__);
93
94 try {
96 DAS *das = bdas->get_das();
97 string accessed = dhi.container->access();
98 string fits_error;
99 if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
100 throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
101 }
102 Ancillary::read_ancillary_das(*das, accessed);
103 bdas->clear_container();
104 }
105 catch( InternalErr &e ) {
106 throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
107 }
108 catch( Error &e ) {
109 throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
110 }
111 catch (BESError &e) {
112 throw;
113 }
114 catch( ... ) {
115 throw BESDapError("Unknown exception caught building FITS das response", true, unknown_error, __FILE__, __LINE__);
116 }
117 return true;
118}
119
120bool FitsRequestHandler::fits_build_dds(BESDataHandlerInterface &dhi)
121{
122 BESResponseObject *response = dhi.response_handler->get_response_object();
123 BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
124 if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);
125
126 try {
128 DDS *dds = bdds->get_dds();
129 string accessed = dhi.container->access();
130 string fits_error;
131
132 if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
133 throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
134 }
135
136 Ancillary::read_ancillary_dds(*dds, accessed);
137 DAS *das = new DAS;
138 BESDASResponse bdas(das);
140 if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
141 throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
142 }
143 Ancillary::read_ancillary_das(*das, accessed);
144
145 dds->transfer_attributes(das);
146
147 bdds->set_constraint(dhi);
148
149 bdds->clear_container();
150 }
151 catch( InternalErr &e ) {
152 throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
153 }
154 catch( Error &e ) {
155 throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
156 }
157 catch (BESError &e) {
158 throw;
159 }
160 catch( ... ) {
161 string err = "Unknown exception caught building FITS dds response";
162 throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
163 }
164
165 return true;
166}
167
168bool FitsRequestHandler::fits_build_data(BESDataHandlerInterface &dhi)
169{
170 BESResponseObject *response = dhi.response_handler->get_response_object();
171 BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
172 if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);
173
174 try {
176 DDS *dds = bdds->get_dds();
177 string accessed = dhi.container->access();
178 string fits_error;
179 if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
180 throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
181 }
182 Ancillary::read_ancillary_dds(*dds, accessed);
183 bdds->set_constraint(dhi);
184
185 // We don't need to build the DAS here. Set the including attribute flag to false. KY 10/30/19
186 BESDEBUG(FITS_NAME, "Data ACCESS build_data(): set the including attribute flag to false: "<<accessed << endl);
187 bdds->set_ia_flag(false);
188 bdds->clear_container();
189 }
190 catch( InternalErr &e ) {
191 throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
192 }
193 catch( Error &e ) {
194 throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
195 }
196 catch (BESError &e) {
197 throw;
198 }
199 catch( ... ) {
200 string err = "Unknown exception caught building FITS data response";
201 throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
202 }
203
204 return true;
205}
206
220{
221 string data_path = dhi.container->access();
222
223 BaseTypeFactory factory;
224 DDS dds(&factory, name_path(data_path), "3.2");
225 dds.filename(data_path);
226
227 try {
228 string fits_error;
229
230 if (!fits_handler::fits_read_descriptors(dds, data_path, fits_error))
231 throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
232
233 DAS das;
234 if (!fits_handler::fits_read_attributes(das, data_path, fits_error))
235 throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
236 Ancillary::read_ancillary_das(das, data_path);
237
238 dds.transfer_attributes(&das);
239 }
240 catch( InternalErr &e ) {
241 throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
242 }
243 catch( Error &e ) {
244 throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
245 }
246 catch (BESError &e) {
247 throw;
248 }
249 catch( ... ) {
250 throw BESDapError("Unknown exception caught building FITS DMR response", true, unknown_error, __FILE__, __LINE__);
251 }
252
253
254 // Extract the DMR Response object - this holds the DMR used by the
255 // other parts of the framework.
256 BESResponseObject *response = dhi.response_handler->get_response_object();
257 BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);
258
259 // Extract the DMR Response object - this holds the DMR used by the
260 // other parts of the framework.
261 DMR *dmr = bdmr.get_dmr();
262 dmr->set_factory(new D4BaseTypeFactory);
263 dmr->build_using_dds(dds);
264
265 bdmr.set_dap4_constraint(dhi);
266 bdmr.set_dap4_function(dhi);
267
268 return true;
269}
270
271bool FitsRequestHandler::fits_build_vers(BESDataHandlerInterface &dhi)
272{
273 BESResponseObject *response = dhi.response_handler->get_response_object();
274 BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
275 if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);
276
277 info->add_module(MODULE_NAME, MODULE_VERSION);
278
279 return true;
280}
281
282bool FitsRequestHandler::fits_build_help(BESDataHandlerInterface &dhi)
283{
284 BESResponseObject *response = dhi.response_handler->get_response_object();
285 BESInfo *info = dynamic_cast<BESInfo *>(response);
286 if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);
287
288 map<string, string, std::less<>> attrs;
289 attrs["name"] = MODULE_NAME ;
290 attrs["version"] = MODULE_VERSION ;
291 list<string> services;
292 BESServiceRegistry::TheRegistry()->services_handled(FITS_NAME, services);
293 if (!services.empty()) {
294 string handles = BESUtil::implode(services, ',');
295 attrs["handles"] = handles;
296 }
297 info->begin_tag("module", &attrs);
298 info->end_tag("module");
299
300 return true;
301}
302
311{
312 strm << BESIndent::LMarg << "FitsRequestHandler::dump - (" << (void *) this << ")" << endl;
313 BESIndent::Indent();
315 BESIndent::UnIndent();
316}
317
318void FitsRequestHandler::add_attributes(BESDataHandlerInterface &dhi) {
319
320 BESResponseObject *response = dhi.response_handler->get_response_object();
321 BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
322 if (!bdds)
323 throw BESInternalError("cast error", __FILE__, __LINE__);
324 DDS *dds = bdds->get_dds();
325 string accessed = dhi.container->access();
326 DAS *das = new DAS;
327 BESDASResponse bdas(das);
329 string fits_error;
330 if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
331 throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
332 }
333 Ancillary::read_ancillary_das(*das, accessed);
334
335 dds->transfer_attributes(das);
336 BESDEBUG(FITS_NAME, "Data ACCESS in add_attributes(): set the including attribute flag to true: "<<accessed << endl);
337 bdds->set_ia_flag(true);
338 return;
339}
340
std::string get_symbolic_name() const
retrieve the symbolic name for this container
virtual std::string access()=0
returns the true name of this container
Represents an OPeNDAP DAS DAP2 data object within the BES.
virtual void clear_container()
clear the container in the DAP response object
virtual void set_container(const std::string &cn)
set the container in the DAP response object
virtual void set_container(const std::string &cn)
set the container in the DAP response object
virtual void clear_container()
clear the container in the DAP response object
libdap::DDS * get_dds()
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:50
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
virtual void set_container(const std::string &cn)
set the container in the DAP response object
virtual void clear_container()
clear the container in the DAP response object
Structure storing information used by the BES to handle the request.
BESContainer * container
pointer to current container in this interface
Base exception class for the BES with basic string message.
Definition BESError.h:66
exception thrown if internal error encountered
Represents a specific data type request handler.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual BESResponseObject * get_response_object()
return the current response object
Abstract base class representing a specific set of information in response to a request to the BES.
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
static std::string implode(const std::list< std::string > &values, char delim)
Definition BESUtil.cc:620
virtual void dump(std::ostream &strm) const
dumps information about this object
static bool fits_build_dmr(BESDataHandlerInterface &dhi)
STL class.