OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BESXDTransmit.cc
Go to the documentation of this file.
1 // BESXDTransmit.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,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 // Authors:
27 // pwest Patrick West <pwest@ucar.edu>
28 // jgarcia Jose Garcia <jgarcia@ucar.edu>
29 
30 #include <BaseType.h>
31 #include <Sequence.h>
32 #include <ConstraintEvaluator.h>
33 #include <XMLWriter.h>
34 #include <DODSFilter.h>
35 #include <escaping.h>
36 #include <InternalErr.h>
37 #include <util.h>
38 #include <mime_util.h>
39 #include <XMLWriter.h>
40 
41 #include <BESDapTransmit.h>
42 #include <BESContainer.h>
43 #include <BESDataNames.h>
44 #include <BESDataDDSResponse.h>
45 #include <BESDapError.h>
46 #include <BESInternalFatalError.h>
47 #include <BESDebug.h>
48 
49 #include "BESXDTransmit.h"
50 #include "get_xml_data.h"
51 
52 using namespace xml_data;
53 
55 {
56  BESDEBUG("xd", "BESXDTransmit::send_base_ascii" << endl);
57  BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(obj);
58  DataDDS *dds = bdds->get_dds();
59  ConstraintEvaluator & ce = bdds->get_ce();
60 
61  dhi.first_container();
62 
63  string constraint = www2id(dhi.data[POST_CONSTRAINT], "%", "%20%26");
64 
65  try {
66  BESDEBUG("xd", "BESXDTransmit::send_base_ascii - " "parsing constraint: " << constraint << endl);
67  ce.parse_constraint(constraint, *dds);
68  }
69  catch (InternalErr &e) {
70  string err = "Failed to parse the constraint expression: " + e.get_error_message();
71  throw BESDapError(err, true, e.get_error_code(), __FILE__, __LINE__);
72  }
73  catch (Error &e) {
74  string err = "Failed to parse the constraint expression: " + e.get_error_message();
75  throw BESDapError(err, false, e.get_error_code(), __FILE__, __LINE__);
76  }
77  catch (...) {
78  string err = (string) "Failed to parse the constraint expression: " + "Unknown exception caught";
79  throw BESInternalFatalError(err, __FILE__, __LINE__);
80  }
81 
82  BESDEBUG("xd", "BESXDTransmit::send_base_ascii - " "tagging sequences" << endl);
83  dds->tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
84 
85  BESDEBUG("xd", "BESXDTransmit::send_base_ascii - " "accessing container" << endl);
86  string dataset_name = dhi.container->access();
87 
88  BESDEBUG("xd", "BESXDTransmit::send_base_ascii - dataset_name = " << dataset_name << endl);
89 
90  bool functional_constraint = false;
91  try {
92  // Handle *functional* constraint expressions specially
93  if (ce.functional_expression()) {
94  BESDEBUG("xd", "processing a functional constraint." << endl);
95  // This returns a new BaseType, not a pointer to one in the DataDDS
96  // So once the data has been read using this var create a new
97  // DataDDS and add this new var to the it.
98  BaseType *var = ce.eval_function(*dds, dataset_name);
99  if (!var)
100  throw Error(unknown_error, "Error calling the CE function.");
101 
102  var->read();
103 
104  dds = new DataDDS(NULL, "virtual");
105  functional_constraint = true;
106  dds->add_var(var);
107  }
108  else {
109  // Iterate through the variables in the DataDDS and read in the data
110  // if the variable has the send flag set.
111  for (DDS::Vars_iter i = dds->var_begin(); i != dds->var_end(); i++) {
112  BESDEBUG("xd", "processing var: " << (*i)->name() << endl);
113  if ((*i)->send_p()) {
114  BESDEBUG("xd", "reading some data for: " << (*i)->name() << endl);
115  (**i).intern_data(ce, *dds);
116  }
117  }
118  }
119  }
120  catch (InternalErr &e) {
121  if (functional_constraint)
122  delete dds;
123  string err = "Failed to read data: " + e.get_error_message();
124  throw BESDapError(err, true, e.get_error_code(), __FILE__, __LINE__);
125  }
126  catch (Error & e) {
127  if (functional_constraint)
128  delete dds;
129  string err = "Failed to read data: " + e.get_error_message();
130  throw BESDapError(err, false, e.get_error_code(), __FILE__, __LINE__);
131  }
132  catch (...) {
133  if (functional_constraint)
134  delete dds;
135  string err = "Failed to read data: Unknown exception caught";
136  throw BESInternalFatalError(err, __FILE__, __LINE__);
137  }
138 
139  try {
140  // Now that we have constrained the DataDDS and read in the data,
141  // send it as ascii
142  BESDEBUG("xd", "converting to xd datadds" << endl);
143  DataDDS *xd_dds = datadds_to_xd_datadds(dds);
144 
145  BESDEBUG("xd", "getting xd values" << endl);
146  XMLWriter writer;
147  get_data_values_as_xml(xd_dds, &writer);
148  dhi.get_output_stream() << writer.get_doc();
149 
150  BESDEBUG("xd", "got the ascii values" << endl);
151  dhi.get_output_stream() << flush;
152  delete xd_dds;
153 
154  BESDEBUG("xd", "done transmitting ascii" << endl);
155  }
156  catch (InternalErr &e) {
157  if (functional_constraint)
158  delete dds;
159  string err = "Failed to get values as ascii: " + e.get_error_message();
160  throw BESDapError(err, true, e.get_error_code(), __FILE__, __LINE__);
161  }
162  catch (Error &e) {
163  if (functional_constraint)
164  delete dds;
165  string err = "Failed to get values as ascii: " + e.get_error_message();
166  throw BESDapError(err, false, e.get_error_code(), __FILE__, __LINE__);
167  }
168  catch (...) {
169  if (functional_constraint)
170  delete dds;
171  string err = "Failed to get values as ascii: Unknown exception caught";
172  throw BESInternalFatalError(err, __FILE__, __LINE__);
173  }
174 
175  if (functional_constraint)
176  delete dds;
177 }
178 
179 
exception thrown if an internal error is found and is fatal to the BES
virtual string access()=0
returns the true name of this container
static void send_basic_ascii(BESResponseObject *obj, BESDataHandlerInterface &dhi)
#define NULL
Definition: wcsUtil.h:65
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:51
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
#define POST_CONSTRAINT
Definition: BESDataNames.h:43
ConstraintEvaluator & get_ce()
Structure storing information used by the BES to handle the request.
map< string, string > data
the map of string data that will be required for the current request.
void first_container()
set the container pointer to the first container in the containers list
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
void get_data_values_as_xml(DataDDS *dds, XMLWriter *writer)
Using the XDOutput::print_ascii(), write the data values to an output file/stream as ASCII...
Definition: get_xml_data.cc:69
DataDDS * datadds_to_xd_datadds(DataDDS *dds)
Definition: get_xml_data.cc:99
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