bes  Updated for version 3.20.6
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 <DAS.h>
36 #include <DDS.h>
37 #include <DataDDS.h>
38 #include <DMR.h>
39 #include <D4BaseTypeFactory.h>
40 #include <Ancillary.h>
41 #include <InternalErr.h>
42 #include <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 
66 using namespace libdap;
67 
68 #define FITS_NAME "fits"
69 
70 FitsRequestHandler::FitsRequestHandler(const string &name) :
71  BESRequestHandler(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 
84 FitsRequestHandler::~FitsRequestHandler()
85 {
86 }
87 
88 bool 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 
120 bool 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 
168 bool 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 
271 bool 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 #if 0
278  info->add_module(PACKAGE_NAME, PACKAGE_VERSION);
279 #endif
280  info->add_module(MODULE_NAME, MODULE_VERSION);
281 
282  return true;
283 }
284 
285 bool FitsRequestHandler::fits_build_help(BESDataHandlerInterface &dhi)
286 {
287  BESResponseObject *response = dhi.response_handler->get_response_object();
288  BESInfo *info = dynamic_cast<BESInfo *>(response);
289  if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);
290 
291  map<string, string> attrs;
292  attrs["name"] = MODULE_NAME ;
293  attrs["version"] = MODULE_VERSION ;
294 #if 0
295  attrs["name"] = PACKAGE_NAME;
296  attrs["version"] = PACKAGE_VERSION;
297 #endif
298  list<string> services;
299  BESServiceRegistry::TheRegistry()->services_handled(FITS_NAME, services);
300  if (services.size() > 0) {
301  string handles = BESUtil::implode(services, ',');
302  attrs["handles"] = handles;
303  }
304  info->begin_tag("module", &attrs);
305  info->end_tag("module");
306 
307  return true;
308 }
309 
317 void FitsRequestHandler::dump(ostream &strm) const
318 {
319  strm << BESIndent::LMarg << "FitsRequestHandler::dump - (" << (void *) this << ")" << endl;
320  BESIndent::Indent();
322  BESIndent::UnIndent();
323 }
324 
325 void FitsRequestHandler::add_attributes(BESDataHandlerInterface &dhi) {
326 
327  BESResponseObject *response = dhi.response_handler->get_response_object();
328  BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
329  if (!bdds)
330  throw BESInternalError("cast error", __FILE__, __LINE__);
331  DDS *dds = bdds->get_dds();
332  string accessed = dhi.container->access();
333  DAS *das = new DAS;
334  BESDASResponse bdas(das);
336  string fits_error;
337  if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
338  throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
339  }
340  Ancillary::read_ancillary_das(*das, accessed);
341 
342  dds->transfer_attributes(das);
343  BESDEBUG(FITS_NAME, "Data ACCESS in add_attributes(): set the including attribute flag to true: "<<accessed << endl);
344  bdds->set_ia_flag(true);
345  return;
346 }
347 
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
BESServiceRegistry::services_handled
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
Definition: BESServiceRegistry.cc:334
BESDapResponse::set_dap4_constraint
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:137
BESDDSResponse::set_container
virtual void set_container(const std::string &cn)
set the container in the DAP response object
Definition: BESDDSResponse.cc:64
FitsRequestHandler::fits_build_dmr
static bool fits_build_dmr(BESDataHandlerInterface &dhi)
Definition: FitsRequestHandler.cc:219
BESDataDDSResponse::set_container
virtual void set_container(const std::string &cn)
set the container in the DAP response object
Definition: BESDataDDSResponse.cc:50
BESDapResponse::set_dap4_function
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:154
BESContainer::get_symbolic_name
std::string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:221
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
BESDASResponse
Represents an OPeNDAP DAS DAP2 data object within the BES.
Definition: BESDASResponse.h:44
BESInfo
informational response object
Definition: BESInfo.h:63
BESDASResponse::set_container
virtual void set_container(const std::string &cn)
set the container in the DAP response object
Definition: BESDASResponse.cc:49
libdap
Definition: BESDapFunctionResponseCache.h:35
FitsRequestHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: FitsRequestHandler.cc:317
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
BESDataDDSResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDataDDSResponse.cc:59
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
BESDDSResponse
Holds a DDS object within the BES.
Definition: BESDDSResponse.h:50
BESDASResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDASResponse.cc:58
BESDapResponse::set_constraint
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:115
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
BESUtil::implode
static std::string implode(const std::list< std::string > &values, char delim)
Definition: BESUtil.cc:638
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
BESError
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
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