39 #include <sys/types.h>
48 #include <ConstraintEvaluator.h>
65 #define FO_JSON_TEMP_DIR "/tmp"
68 string FoInstanceJsonTransmitter::temp_dir;
86 if (FoInstanceJsonTransmitter::temp_dir.empty()) {
89 string key =
"FoJson.Tempdir";
91 if (!found || FoInstanceJsonTransmitter::temp_dir.empty()) {
94 string::size_type len = FoInstanceJsonTransmitter::temp_dir.length();
95 if (FoInstanceJsonTransmitter::temp_dir[len - 1] ==
'/') {
96 FoInstanceJsonTransmitter::temp_dir = FoInstanceJsonTransmitter::temp_dir.substr(0, len - 1);
124 throw BESInternalError(
"Cast to BESDDSResponse error.", __FILE__, __LINE__);
129 throw BESInternalError(
"No DataDDS has been created for transmit", __FILE__, __LINE__);
131 BESDEBUG(
"fojson",
"FoJsonTransmitter::send_metadata - parsing the constraint" << endl);
133 ConstraintEvaluator &eval = bdds->
get_ce();
136 throw BESInternalError(
"Output stream is not set, can not return as JSON", __FILE__, __LINE__);
141 eval.parse_constraint(ce, *dds);
144 throw BESInternalError(
"Failed to parse the constraint expression: " + e.get_error_message(), __FILE__, __LINE__);
147 throw BESInternalError(
"Failed to parse the constraint expression: Unknown exception caught", __FILE__, __LINE__);
151 BESDEBUG(
"fojson",
"FoJsonTransmitter::send_data - reading data into DataDDS" << endl);
155 if (eval.function_clauses()) {
156 BESDEBUG(
"fojson",
"processing a functional constraint clause(s)." << endl);
157 DDS *tmp_dds = eval.eval_function_clauses(*dds);
166 for (DDS::Vars_iter i = dds->var_begin(); i != dds->var_end(); i++) {
167 if ((*i)->send_p()) {
168 (*i)->intern_data(eval, *dds);
174 throw BESInternalError(
"Failed to read data: " + e.get_error_message(), __FILE__, __LINE__);
177 throw BESInternalError(
"Failed to read data: Unknown exception caught", __FILE__, __LINE__);
183 ft.transform(
false );
189 throw BESInternalError(
"fileout_json: Failed to transform to JSON, unknown error", __FILE__, __LINE__);
192 BESDEBUG(
"fojson",
"FoJsonTransmitter::send_data - done transmitting JSON" << endl);
217 DataDDS *dds = bdds->
get_dds();
219 throw BESInternalError(
"No DataDDS has been created for transmit", __FILE__, __LINE__);
221 BESDEBUG(
"fojson",
"FoJsonTransmitter::send_data - parsing the constraint" << endl);
223 ConstraintEvaluator &eval = bdds->
get_ce();
227 throw BESInternalError(
"Output stream is not set, can not return as JSON", __FILE__, __LINE__);
232 eval.parse_constraint(ce, *dds);
235 throw BESInternalError(
"Failed to parse the constraint expression: " + e.get_error_message(), __FILE__, __LINE__);
238 throw BESInternalError(
"Failed to parse the constraint expression: Unknown exception caught", __FILE__, __LINE__);
242 BESDEBUG(
"fojson",
"FoJsonTransmitter::send_data - reading data into DataDDS" << endl);
246 if (eval.function_clauses()) {
247 BESDEBUG(
"fojson",
"processing a functional constraint clause(s)." << endl);
248 DataDDS *tmp_dds = eval.eval_function_clauses(*dds);
257 for (DDS::Vars_iter i = dds->var_begin(); i != dds->var_end(); i++) {
258 if ((*i)->send_p()) {
259 (*i)->intern_data(eval, *dds);
266 throw BESInternalError(
"Failed to read data: " + e.get_error_message(), __FILE__, __LINE__);
269 throw BESInternalError(
"Failed to read data: Unknown exception caught", __FILE__, __LINE__);
272 string temp_file_name = FoJsonTransmitter::temp_dir +
'/' +
"jsonXXXXXX";
273 vector<char> temp_full(temp_file_name.length() + 1);
274 string::size_type len = temp_file_name.copy(&temp_full[0], temp_file_name.length());
275 temp_full[len] =
'\0';
279 mode_t original_mode = umask(077);
280 int fd = mkstemp(&temp_full[0]);
281 umask(original_mode);
283 throw BESInternalError(
"Failed to open the temporary file: " + temp_file_name, __FILE__, __LINE__);
286 BESDEBUG(
"fojson",
"FoJsonTransmitter::send_data - transforming into temporary file " << &temp_full[0] << endl);
291 ft.transform(
true );
298 (void) unlink(&temp_full[0]);
305 (void) unlink(&temp_full[0]);
307 throw BESInternalError(
"fileout_json: Failed to transform to JSON, unknown error", __FILE__, __LINE__);
313 BESDEBUG(
"fojson",
"FoJsonTransmitter::send_data - done transmitting JSON" << endl);
325 void FoInstanceJsonTransmitter::return_temp_stream(
const string &filename, ostream &strm)
328 os.open(filename.c_str(), ios::binary | ios::in);
330 string err =
"Can not connect to file " + filename;
337 os.read(block,
sizeof block);
338 nbytes = os.gcount();
340 strm.write(block, nbytes);
346 string err = (string)
"0XAAE234F: failed to stream. Internal server "
347 +
"error, got zero count on stream buffer." + filename;
352 os.read(block,
sizeof block);
353 nbytes = os.gcount();
354 strm.write(block, nbytes);
void set_dds(DDS *ddsIn)
Set the response object's DDS.
void set_dds(DataDDS *ddsIn)
Set the response object's DDS.
exception thrown if inernal error encountered
ConstraintEvaluator & get_ce()
ostream & get_output_stream()
Represents an OPeNDAP DDS DAP2 data object within the BES.
virtual bool add_method(string method_name, p_transmitter trans_method)
static void send_data(BESResponseObject *obj, BESDataHandlerInterface &dhi)
The static method registered to transmit OPeNDAP data objects as a JSON file.
static class NCMLUtil overview
FoInstanceJsonTransmitter()
Construct the FoJsonTransmitter.
Abstract exception class for the BES with basic string message.
static void send_metadata(BESResponseObject *obj, BESDataHandlerInterface &dhi)
The static method registered to transmit OPeNDAP data objects as a JSON file.
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
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.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
static BESKeys * TheKeys()
Abstract base class representing a specific set of information in response to a request to the BES...