OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDF5RequestHandler.cc
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of hdf5_handler, a data handler for the OPeNDAP data
5 // server.
6 
7 // Copyright (c) 2002,2003 OPeNDAP, Inc.
8 // Copyright (c) 2007-2013 The HDF Group, Inc. and OPeNDAP, Inc.
9 // Author: James Gallagher <jgallagher@opendap.org>
10 //
11 // This is free software; you can redistribute it and/or modify it under the
12 // terms of the GNU Lesser General Public License as published by the Free
13 // Software Foundation; either version 2.1 of the License, or (at your
14 // option) any later version.
15 //
16 // This software is distributed in the hope that it will be useful, but
17 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19 // License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26 
27 // HDF5RequestHandler.cc
33 
34 
35 #include <string>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 
41 //#undef USE_DAP4
42 //#define USE_DAP4 1
43 #ifdef USE_DAP4
44 #include <DMR.h>
45 #include <D4BaseTypeFactory.h>
46 #include <BESDMRResponse.h>
47 #include "HDF5_DMR.h"
48 #endif
49 
50 #include<mime_util.h>
51 #include "hdf5_handler.h"
52 #include "HDF5RequestHandler.h"
53 #include "HDF5_DDS.h"
54 
55 #include <BESDASResponse.h>
56 #include <BESDDSResponse.h>
57 #include <BESDataDDSResponse.h>
58 #include <Ancillary.h>
59 #include <BESInfo.h>
60 #include <BESDapNames.h>
61 #include <BESResponseNames.h>
62 #include <BESContainer.h>
63 #include <BESResponseHandler.h>
64 #include <BESVersionInfo.h>
65 #include <BESServiceRegistry.h>
66 #include <BESUtil.h>
67 #include <BESDapError.h>
68 #include <BESNotFoundError.h>
69 #include <BESInternalFatalError.h>
70 #include <TheBESKeys.h>
71 #include <BESDebug.h>
72 #include "h5get.h"
73 #include "config_hdf5.h"
74 //#include "h5cfdap.h"
75 
76 #define HDF5_NAME "h5"
77 #include "h5cfdaputil.h"
78 using namespace std;
79 using namespace libdap;
80 
81 // For the CF option
82 extern void read_cfdas(DAS &das, const string & filename,hid_t fileid);
83 extern void read_cfdds(DDS &dds, const string & filename,hid_t fileid);
84 
85 
87  :BESRequestHandler(name)
88 {
92 #ifdef USE_DAP4
93  add_handler(DMR_RESPONSE, HDF5RequestHandler::hdf5_build_dmr);
94  add_handler(DAP4DATA_RESPONSE, HDF5RequestHandler::hdf5_build_dmr);
95 #endif
96 
99 
100 }
101 
103 {
104 }
105 
107 {
108 
109  bool found_key = false;
110  bool usecf = false;
111  string key = "H5.EnableCF";
112  string doset;
113 
114  // For the time being, separate CF file ID from the default file ID(mainly for debugging)
115  hid_t cf_fileid = -1;
116 
117  TheBESKeys::TheKeys()->get_value( key, doset, found_key ) ;
118 
119  if(true ==found_key ) {
120  // cerr<<"found it" <<endl;
121  doset = BESUtil::lowercase( doset ) ;
122  if( doset == "true" || doset == "yes" )
123  usecf = true;
124  }
125 
126  // Obtain the HDF5 file name.
127  string filename = dhi.container->access();
128 
129  // Obtain the BES object from the client
131 
132  // Convert to the BES DAS response
133  BESDASResponse *bdas = dynamic_cast < BESDASResponse * >(response) ;
134  if( !bdas )
135  throw BESInternalError( "cast error", __FILE__, __LINE__ ) ;
136 
137  try {
138  bdas->set_container( dhi.container->get_symbolic_name() ) ;
139  DAS *das = bdas->get_das();
140 
141  if (true == usecf) {
142 
143  cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
144  if (cf_fileid < 0){
145  throw BESNotFoundError((string) "Could not open this hdf5 file: "
146  + filename, __FILE__, __LINE__);
147  }
148 
149  read_cfdas( *das,filename,cf_fileid);
150  H5Fclose(cf_fileid);
151  }
152  else {
153  // go to the default option
154 //cerr<<"default option" <<endl;
155  hid_t fileid = get_fileid(filename.c_str());
156  if (fileid < 0) {
157  throw BESNotFoundError((string) "Could not open this hdf5 file: "
158  + filename, __FILE__, __LINE__);
159  }
160 
161  find_gloattr(fileid, *das);
162  depth_first(fileid, "/", *das);
163  close_fileid(fileid);
164  }
165 
166  Ancillary::read_ancillary_das( *das, filename ) ;
167  bdas->clear_container() ;
168  }
169  catch(InternalErr & e) {
170 
171  if(cf_fileid !=-1)
172  H5Fclose(cf_fileid);
173  throw BESDapError(e.get_error_message(), true, e.get_error_code(),
174  __FILE__, __LINE__);
175  }
176  catch(Error & e) {
177 
178  if(cf_fileid !=-1)
179  H5Fclose(cf_fileid);
180  throw BESDapError(e.get_error_message(), false, e.get_error_code(),
181  __FILE__, __LINE__);
182  }
183  catch(...) {
184 
185  if(cf_fileid !=-1)
186  H5Fclose(cf_fileid);
187  string s = "unknown exception caught building HDF5 DAS";
188  throw BESInternalFatalError(s, __FILE__, __LINE__);
189  }
190 
191  return true;
192 }
193 
195 {
196 
197  bool found = false;
198  bool usecf = false;
199 
200  string key="H5.EnableCF";
201  string doset;
202 
203  // Obtain the BESKeys. If finding the key, "found" will be true.
204  TheBESKeys::TheKeys()->get_value( key, doset, found ) ;
205  if(true == found ) {
206  doset = BESUtil::lowercase( doset ) ;
207  if( doset == "true" || doset == "yes" ) {
208  // This is the CF option, go to the CF function
209  usecf = true;
210  }
211  }
212 
213  // For the time being, separate CF file ID from the default file ID(mainly for debugging)
214  hid_t fileid = -1;
215  hid_t cf_fileid = -1;
216 
217  // Obtain the HDF5 file name.
218  string filename = dhi.container->access();
219 
220  // For the time being, not mess up CF's fileID with Default's fileID
221  if(true == usecf) {
222 
223  cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
224  if (cf_fileid < 0){
225  throw BESNotFoundError((string) "Could not open this hdf5 file: "
226  + filename, __FILE__, __LINE__);
227  }
228 
229  }
230  else {
231 
232  fileid = get_fileid(filename.c_str());
233  if (fileid < 0) {
234  throw BESNotFoundError(string("hdf5_build_dds: ")
235  + "Could not open hdf5 file: "
236  + filename, __FILE__, __LINE__);
237  }
238  }
239 
240 
242  BESDDSResponse *bdds = dynamic_cast < BESDDSResponse * >(response);
243  if( !bdds )
244  throw BESInternalError( "cast error", __FILE__, __LINE__ ) ;
245 
246  try {
247  bdds->set_container( dhi.container->get_symbolic_name() ) ;
248  DDS *dds = bdds->get_dds();
249 
250  if( true == usecf )
251  read_cfdds(*dds,filename,cf_fileid);
252 
253  else {
254 
255  depth_first(fileid, (char*)"/", *dds, filename.c_str());
256  }
257 
258  // Check semantics
259  if (!dds->check_semantics()) { // DDS didn't comply with the semantics
260  dds->print(cerr);
261  throw InternalErr(__FILE__, __LINE__,
262  "DDS check_semantics() failed. This can happen when duplicate variable names are defined. ");
263  }
264 
265  Ancillary::read_ancillary_dds( *dds, filename ) ;
266 
267  DAS *das = new DAS ;
268  BESDASResponse bdas( das ) ;
269  bdas.set_container( dhi.container->get_symbolic_name() ) ;
270 
271  if (true == usecf) {
272 
273  // go to the CF option
274  read_cfdas( *das,filename,cf_fileid);
275 
276  }
277  else {
278 
279  find_gloattr(fileid, *das);
280  depth_first(fileid, "/", *das);
281  close_fileid(fileid);
282 
283  // WARNING: I add this line because for the default option, the handler will hold
284  // the HDF5 object handles that are generated when handling DDS. If one only
285  // wants to run DDS, I assume that those resources will be lost and may cause the
286  // memory leaking..
287  // So adding H5close() will release all the resources HDF5 is using.
288  // Should ask James to see if this makes sense. KY-2011-11-17
289  //
290  H5close();
291  }
292 
293  if(cf_fileid != -1)
294  H5Fclose(cf_fileid);
295 
296  Ancillary::read_ancillary_das( *das, filename ) ;
297 
298  dds->transfer_attributes(das);
299 
300  bdds->set_constraint( dhi ) ;
301 
302  bdds->clear_container() ;
303  }
304  catch(InternalErr & e) {
305 
306  if(cf_fileid !=-1)
307  H5Fclose(cf_fileid);
308  throw BESDapError(e.get_error_message(), true, e.get_error_code(),
309  __FILE__, __LINE__);
310  }
311  catch(Error & e) {
312 
313  if(cf_fileid !=-1)
314  H5Fclose(cf_fileid);
315 
316  throw BESDapError(e.get_error_message(), false, e.get_error_code(),
317  __FILE__, __LINE__);
318  }
319  catch(...) {
320 
321  if(cf_fileid !=-1)
322  H5Fclose(cf_fileid);
323  string s = "unknown exception caught building HDF5 DDS";
324  throw BESInternalFatalError(s, __FILE__, __LINE__);
325  }
326 
327  return true;
328 }
329 
331 {
332 
333  bool found = false;
334  bool usecf = false;
335 
336  string key="H5.EnableCF";
337  string doset;
338 
339  TheBESKeys::TheKeys()->get_value( key, doset, found ) ;
340  if(true == found )
341  {
342  // cerr<<"found it" <<endl;
343  doset = BESUtil::lowercase( doset ) ;
344  if( doset == "true" || doset == "yes" ) {
345 
346  // This is the CF option, go to the CF function
347  // cerr<<"go to CF option "<<endl;
348  usecf = true;
349  }
350  }
351 
352  // For the time being, separate CF file ID from the default file ID(mainly for debugging)
353  hid_t fileid = -1;
354  hid_t cf_fileid = -1;
355 
356 
357  string filename = dhi.container->access();
358 
359  if(true ==usecf) {
360 
361  if(true == HDF5CFDAPUtil::check_beskeys("H5.EnablePassFileID"))
362  return hdf5_build_data_with_IDs(dhi);
363 
364  cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
365  if (cf_fileid < 0){
366  throw BESNotFoundError((string) "Could not open this hdf5 file: "
367  + filename, __FILE__, __LINE__);
368  }
369 
370  }
371  else {
372  // Obtain the HDF5 file ID.
373  fileid = get_fileid(filename.c_str());
374  if (fileid < 0) {
375  throw BESNotFoundError(string("hdf5_build_data: ")
376  + "Could not open hdf5 file: "
377  + filename, __FILE__, __LINE__);
378  }
379  }
380 
381  BESDEBUG("h5","Building DataDDS without passing file IDs. "<<endl);
383  BESDataDDSResponse *bdds = dynamic_cast < BESDataDDSResponse * >(response);
384  if( !bdds )
385  throw BESInternalError( "cast error", __FILE__, __LINE__ ) ;
386 
387  try {
388 
389  bdds->set_container( dhi.container->get_symbolic_name() ) ;
390 
391 #if 0
392  HDF5DDS *hdds = new HDF5DDS(bdds->get_dds());
393  delete bdds->get_dds();
394 
395  bdds->set_dds(hdds);
396 
397  hdds->setHDF5Dataset(cf_fileid);
398 #endif
399  DataDDS* dds = bdds->get_dds();
400  dds->filename(filename);
401 
402  // DataDDS *dds = bdds->get_dds();
403  if(true == usecf) {
404 
405  // This is the CF option
406  read_cfdds( *dds,filename,cf_fileid);
407  }
408  else {
409  depth_first(fileid, (char*)"/", *dds, filename.c_str());
410  }
411 
412  if (!dds->check_semantics()) { // DDS didn't comply with the DAP semantics
413  dds->print(cerr);
414  throw InternalErr(__FILE__, __LINE__,
415  "DDS check_semantics() failed. This can happen when duplicate variable names are defined.");
416  }
417 
418  Ancillary::read_ancillary_dds( *dds, filename ) ;
419 
420  DAS *das = new DAS ;
421  BESDASResponse bdas( das ) ;
422  bdas.set_container( dhi.container->get_symbolic_name() ) ;
423 
424  if(true == usecf) {
425  // CF option
426  read_cfdas( *das,filename,cf_fileid);
427  // cerr<<"end of DAS "<<endl;
428 
429  }
430  else {
431 
432  // Obtain the global attributes and map them to DAS
433  find_gloattr(fileid, *das);
434 
435  // Obtain the rest attributes and map them to DAS
436  depth_first(fileid, "/", *das);
437 
438  // The HDF5 file id will be closed now!
439  close_fileid(fileid);
440  }
441 
442  Ancillary::read_ancillary_das( *das, filename ) ;
443 
444  dds->transfer_attributes(das);
445  bdds->set_constraint( dhi ) ;
446  bdds->clear_container() ;
447 
449  if(cf_fileid !=-1)
450  H5Fclose(cf_fileid);
451 
452  }
453  catch(InternalErr & e) {
454 
455  throw BESDapError(e.get_error_message(), true, e.get_error_code(),
456  __FILE__, __LINE__);
457  }
458  catch(Error & e) {
459  throw BESDapError(e.get_error_message(), false, e.get_error_code(),
460  __FILE__, __LINE__);
461  }
462  catch(...) {
463  string s = "unknown exception caught building HDF5 DataDDS";
464  throw BESInternalFatalError(s, __FILE__, __LINE__);
465  }
466 
467  return true;
468 }
469 
471 {
472 
473  BESDEBUG("h5","Building DataDDS by passing file IDs. "<<endl);
474  hid_t cf_fileid = -1;
475 
476  string filename = dhi.container->access();
477 
478  cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
479  if (cf_fileid < 0){
480  throw BESNotFoundError((string) "Could not open this hdf5 file: "
481  + filename, __FILE__, __LINE__);
482  }
483 
485  BESDataDDSResponse *bdds = dynamic_cast < BESDataDDSResponse * >(response);
486  if( !bdds )
487  throw BESInternalError( "cast error", __FILE__, __LINE__ ) ;
488 
489  try {
490 
491  bdds->set_container( dhi.container->get_symbolic_name() ) ;
492 
493  HDF5DDS *hdds = new HDF5DDS(bdds->get_dds());
494  delete bdds->get_dds();
495 
496  bdds->set_dds(hdds);
497 
498  hdds->setHDF5Dataset(cf_fileid);
499 
500  read_cfdds( *hdds,filename,cf_fileid);
501 
502  if (!hdds->check_semantics()) { // DDS didn't comply with the DAP semantics
503  hdds->print(cerr);
504  throw InternalErr(__FILE__, __LINE__,
505  "DDS check_semantics() failed. This can happen when duplicate variable names are defined.");
506  }
507 
508  Ancillary::read_ancillary_dds( *hdds, filename ) ;
509 
510  DAS *das = new DAS ;
511  BESDASResponse bdas( das ) ;
512  bdas.set_container( dhi.container->get_symbolic_name() ) ;
513  read_cfdas( *das,filename,cf_fileid);
514  Ancillary::read_ancillary_das( *das, filename ) ;
515 
516  hdds->transfer_attributes(das);
517  bdds->set_constraint( dhi ) ;
518  bdds->clear_container() ;
519 
520  }
521 
522  catch(InternalErr & e) {
523 
524  throw BESDapError(e.get_error_message(), true, e.get_error_code(),
525  __FILE__, __LINE__);
526  }
527  catch(Error & e) {
528  throw BESDapError(e.get_error_message(), false, e.get_error_code(),
529  __FILE__, __LINE__);
530  }
531  catch(...) {
532  string s = "unknown exception caught building HDF5 DataDDS";
533  throw BESInternalFatalError(s, __FILE__, __LINE__);
534  }
535 
536  return true;
537 }
538 
539 #ifdef USE_DAP4
540 bool HDF5RequestHandler::hdf5_build_dmr(BESDataHandlerInterface & dhi)
541 {
542 
543  bool found = false;
544  bool usecf = false;
545 
546  string key="H5.EnableCF";
547  string doset;
548 
549  TheBESKeys::TheKeys()->get_value( key, doset, found ) ;
550  if(true == found )
551  {
552  // cerr<<"found it" <<endl;
553  doset = BESUtil::lowercase( doset ) ;
554  if( doset == "true" || doset == "yes" ) {
555 
556  // This is the CF option, go to the CF function
557  // cerr<<"go to CF option "<<endl;
558  usecf = true;
559  }
560  }
561 
562  // For the time being, separate CF file ID from the default file ID(mainly for debugging)
563  hid_t fileid = -1;
564  hid_t cf_fileid = -1;
565 
566 
567  string filename = dhi.container->access();
568 
569  if(true ==usecf) {
570 
571  if(true == HDF5CFDAPUtil::check_beskeys("H5.EnablePassFileID"))
572  return hdf5_build_dmr_with_IDs(dhi);
573 
574  cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
575  if (cf_fileid < 0){
576  throw BESNotFoundError((string) "Could not open this hdf5 file: "
577  + filename, __FILE__, __LINE__);
578  }
579 
580  }
581  else {
582  // Obtain the HDF5 file ID.
583  fileid = get_fileid(filename.c_str());
584  if (fileid < 0) {
585  throw BESNotFoundError(string("hdf5_build_dmr: ")
586  + "Could not open hdf5 file: "
587  + filename, __FILE__, __LINE__);
588  }
589  }
590 
591  BESDEBUG("h5","Building DMR without passing file IDs. "<<endl);
592 
593  BaseTypeFactory factory;
594  DDS dds(&factory, name_path(filename), "3.2");
595  dds.filename(filename);
596 
597  DAS das;
598 
599  try {
600 
601  if(true == usecf) {
602 
603  // This is the CF option
604  read_cfdds( dds,filename,cf_fileid);
605  }
606  else {
607  depth_first(fileid, (char*)"/", dds, filename.c_str());
608  }
609 
610  if (!dds.check_semantics()) { // DDS didn't comply with the DAP semantics
611  dds.print(cerr);
612  throw InternalErr(__FILE__, __LINE__,
613  "DDS check_semantics() failed. This can happen when duplicate variable names are defined.");
614  }
615 
616  Ancillary::read_ancillary_dds( dds, filename ) ;
617 
618 
619  if(true == usecf) {
620  // CF option
621  read_cfdas(das,filename,cf_fileid);
622 
623  }
624  else {
625 
626  // Obtain the global attributes and map them to DAS
627  find_gloattr(fileid, das);
628 
629  // Obtain the rest attributes and map them to DAS
630  depth_first(fileid, "/", das);
631 
632  // The HDF5 file id will be closed now!
633  close_fileid(fileid);
634  }
635 
636  Ancillary::read_ancillary_das( das, filename ) ;
637 
638  dds.transfer_attributes(&das);
639 
641  if(cf_fileid !=-1)
642  H5Fclose(cf_fileid);
643 
644  }
645  catch(InternalErr & e) {
646 
647  throw BESDapError(e.get_error_message(), true, e.get_error_code(),
648  __FILE__, __LINE__);
649  }
650  catch(Error & e) {
651  throw BESDapError(e.get_error_message(), false, e.get_error_code(),
652  __FILE__, __LINE__);
653  }
654  catch(...) {
655  string s = "unknown exception caught building HDF5 DataDDS";
656  throw BESInternalFatalError(s, __FILE__, __LINE__);
657  }
658  //dds.print(cout);
659  //dds.print_das(cout);
660  // Extract the DMR Response object - this holds the DMR used by the
661  // other parts of the framework.
663  BESDMRResponse &bes_dmr = dynamic_cast<BESDMRResponse &>(*response);
664 
665  // In this handler we use a different pattern since the handler specializes the DDS/DMR.
666  // First, build the DMR adding the open handle to the HDF4 dataset, then free the DMR
667  // the BES built and add this one. The HDF4DMR object will close the open dataset when
668  // the BES runs the DMR's destructor.
669 
670  DMR *dmr = bes_dmr.get_dmr();
671  D4BaseTypeFactory MyD4TypeFactory;
672  dmr->set_factory(&MyD4TypeFactory);
673  dmr->build_using_dds(dds);
674 
675  //dmr->print(cout);
676 
677  // Instead of fiddling with the internal storage of the DHI object,
678  // (by setting dhi.data[DAP4_CONSTRAINT], etc., directly) use these
679  // methods to set the constraints. But, why? Ans: from Patrick is that
680  // in the 'container' mode of BES each container can have a different
681  // CE.
682  bes_dmr.set_dap4_constraint(dhi);
683  bes_dmr.set_dap4_function(dhi);
684  dmr->set_factory(0);
685 
686  return true;
687 }
688 
689 bool HDF5RequestHandler::hdf5_build_dmr_with_IDs(BESDataHandlerInterface & dhi)
690 {
691 
692  BESDEBUG("h5","Building DMR with passing file IDs. "<<endl);
693  string filename = dhi.container->access();
694  hid_t cf_fileid = -1;
695 
696 
697  cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
698  if (cf_fileid < 0){
699  throw BESNotFoundError((string) "Could not open this hdf5 file: "
700  + filename, __FILE__, __LINE__);
701  }
702 
703  BaseTypeFactory factory;
704  DDS dds(&factory, name_path(filename), "3.2");
705  dds.filename(filename);
706 
707  DAS das;
708 
709  try {
710 
711 
712  // This is the CF option
713  read_cfdds( dds,filename,cf_fileid);
714 
715  if (!dds.check_semantics()) { // DDS didn't comply with the DAP semantics
716  dds.print(cerr);
717  throw InternalErr(__FILE__, __LINE__,
718  "DDS check_semantics() failed. This can happen when duplicate variable names are defined.");
719  }
720 
721  Ancillary::read_ancillary_dds( dds, filename ) ;
722 
723 
724  read_cfdas(das,filename,cf_fileid);
725 
726  Ancillary::read_ancillary_das( das, filename ) ;
727 
728  dds.transfer_attributes(&das);
729 
731  //if(cf_fileid !=-1)
732  // H5Fclose(cf_fileid);
733 
734  }
735  catch(InternalErr & e) {
736 
737  throw BESDapError(e.get_error_message(), true, e.get_error_code(),
738  __FILE__, __LINE__);
739  }
740  catch(Error & e) {
741  throw BESDapError(e.get_error_message(), false, e.get_error_code(),
742  __FILE__, __LINE__);
743  }
744  catch(...) {
745  string s = "unknown exception caught building HDF5 DataDDS";
746  throw BESInternalFatalError(s, __FILE__, __LINE__);
747  }
748 
749  //dds.print(cout);
750  //dds.print_das(cout);
751  // Extract the DMR Response object - this holds the DMR used by the
752  // other parts of the framework.
754  BESDMRResponse &bes_dmr = dynamic_cast<BESDMRResponse &>(*response);
755 
756  // In this handler we use a different pattern since the handler specializes the DDS/DMR.
757  // First, build the DMR adding the open handle to the HDF4 dataset, then free the DMR
758  // the BES built and add this one. The HDF4DMR object will close the open dataset when
759  // the BES runs the DMR's destructor.
760 
761  DMR *dmr = bes_dmr.get_dmr();
762  D4BaseTypeFactory MyD4TypeFactory;
763  dmr->set_factory(&MyD4TypeFactory);
764  //dmr->set_factory(new D4BaseTypeFactory);
765  dmr->build_using_dds(dds);
766  //dmr->print(cout);
767 
768  HDF5DMR *hdf5_dmr = new HDF5DMR(dmr);
769  hdf5_dmr->setHDF5Dataset(cf_fileid);
770  delete dmr; // The call below will make 'dmr' unreachable; delete it now to avoid a leak.
771  bes_dmr.set_dmr(hdf5_dmr); // BESDMRResponse will delete hdf5_dmr
772 
773  // Instead of fiddling with the internal storage of the DHI object,
774  // (by setting dhi.data[DAP4_CONSTRAINT], etc., directly) use these
775  // methods to set the constraints. But, why? Ans: from Patrick is that
776  // in the 'container' mode of BES each container can have a different
777  // CE.
778  bes_dmr.set_dap4_constraint(dhi);
779  bes_dmr.set_dap4_function(dhi);
780  hdf5_dmr->set_factory(0);
781 
782  return true;
783 }
784 #endif
785 
787 {
789  BESInfo *info = dynamic_cast<BESInfo *>(response);
790  if( !info )
791  throw BESInternalError( "cast error", __FILE__, __LINE__ ) ;
792 
793  map<string,string> attrs ;
794  attrs["name"] = MODULE_NAME ;
795  attrs["version"] = MODULE_VERSION ;
796 #if 0
797  attrs["name"] = PACKAGE_NAME;
798  attrs["version"] = PACKAGE_VERSION;
799 #endif
800  list<string> services ;
802  if( services.size() > 0 )
803  {
804  string handles = BESUtil::implode( services, ',' ) ;
805  attrs["handles"] = handles ;
806  }
807  info->begin_tag( "module", &attrs ) ;
808  info->end_tag( "module" ) ;
809 
810  return true;
811 }
812 
814 {
816  BESVersionInfo *info = dynamic_cast < BESVersionInfo * >(response);
817  if( !info )
818  throw BESInternalError( "cast error", __FILE__, __LINE__ ) ;
819 
820 #if 0
822 #endif
823  info->add_module(MODULE_NAME, MODULE_VERSION);
824 
825  return true;
826 }
brief represents simple text information in a response object, such as version and help inforamtion...
error thrown if the resource requested cannot be found
void read_cfdas(DAS &das, const string &filename, hid_t fileid)
Definition: h5cfdap.cc:83
#define DAP4DATA_RESPONSE
Definition: BESDapNames.h:86
void set_dds(DataDDS *ddsIn)
Set the response object's DDS.
exception thrown if an internal error is found and is fatal to the BES
static bool hdf5_build_data_with_IDs(BESDataHandlerInterface &dhi)
static bool hdf5_build_data(BESDataHandlerInterface &dhi)
exception thrown if inernal error encountered
#define DMR_RESPONSE
Definition: BESDapNames.h:81
string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:197
static string lowercase(const string &s)
Convert a string to all lower case.
Definition: BESUtil.cc:182
Represents an OPeNDAP DDS DAP2 data object within the BES.
virtual void clear_container()
clear the container in the DAP response object
STL namespace.
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
static bool check_beskeys(const string key)
Definition: h5cfdaputil.cc:39
static bool hdf5_build_version(BESDataHandlerInterface &dhi)
static bool hdf5_build_help(BESDataHandlerInterface &dhi)
virtual ~HDF5RequestHandler(void)
static class NCMLUtil overview
virtual string access()=0
returns the true name of this container
virtual void clear_container()
clear the container in the DAP response object
The main header of the HDF5 OPeNDAP handler.
#define HELP_RESPONSE
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
informational response object
Definition: BESInfo.h:68
static string implode(const list< string > &values, char delim)
implode a list of values into a single string delimited by delim
Definition: BESUtil.cc:602
#define HDF5_NAME
virtual BESResponseObject * get_response_object()
return the current response object
#define PACKAGE_NAME
Definition: config.h:244
#define DATA_RESPONSE
Definition: BESDapNames.h:70
static BESServiceRegistry * TheRegistry()
void find_gloattr(hid_t file, DAS &das)
will fill in attributes of the root group into one DAS table.
Definition: h5das.cc:683
BESResponseHandler * response_handler
static bool hdf5_build_das(BESDataHandlerInterface &dhi)
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void begin_tag(const string &tag_name, map< string, string > *attrs=0)
Definition: BESInfo.cc:127
Represents an OPeNDAP DMR DAP4 data object within the BES.
virtual void set_container(const string &cn)
set the container in the DAP response object
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:51
include the entry functions to execute the handlers
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
void close_fileid(hid_t fid)
closes HDF5 file reffered by fid.
Definition: h5get.cc:356
void depth_first(hid_t pid, const char *gname, DAS &das)
depth first traversal of hdf5 file attributes.
Definition: h5das.cc:60
hid_t get_fileid(const char *filename)
gets HDF5 file id.
Definition: h5get.cc:334
virtual void clear_container()
clear the container in the DAP response object
Represents a specific data type request handler.
static bool hdf5_build_dds(BESDataHandlerInterface &dhi)
Helper functions for generating DAS attributes and a function to check BES Key.
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: BESKeys.cc:453
void set_dmr(DMR *dmr)
Structure storing information used by the BES to handle the request.
void read_cfdds(DDS &dds, const string &filename, hid_t fileid)
Definition: h5cfdap.cc:44
HDF5RequestHandler(const string &name)
This specialization of DDS is used to manage the 'resource' of the open HDF5 dataset handle so that t...
Definition: HDF5_DDS.h:38
#define VERS_RESPONSE
virtual void set_container(const string &cn)
set the container in the DAP response object
virtual bool add_handler(const string &handler_name, p_request_handler handler_method)
add a handler method to the request handler that knows how to fill in a specific response object ...
#define PACKAGE_VERSION
Definition: config.h:256
Represents an OPeNDAP DAS DAP2 data object within the BES.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
void setHDF5Dataset(const hid_t fileid_in)
Definition: HDF5_DDS.h:70
Helper functions to generate DDS/DAS/DODS for the default option.
static BESKeys * TheKeys()
Definition: TheBESKeys.cc:48
virtual void set_container(const string &cn)
set the container in the DAP response object
virtual void add_module(const string &n, const string &v)
Abstract base class representing a specific set of information in response to a request to the BES...
#define DDS_RESPONSE
Definition: BESDapNames.h:60
BESContainer * container
pointer to current container in this interface
#define DAS_RESPONSE
Definition: BESDapNames.h:55
virtual void end_tag(const string &tag_name)
Definition: BESInfo.cc:132
virtual void services_handled(const string &handler, list< string > &services)
returns the list of servies provided by the handler in question