bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
get_xml_data.cc
1// -*- mode: c++; c-basic-offset:4 -*-
2
3// Copyright (c) 2006 OPeNDAP, Inc.
4// Author: James Gallagher <jgallagher@opendap.org>
5//
6// This is free software; you can redistribute it and/or modify it under the
7// terms of the GNU Lesser General Public License as published by the Free
8// Software Foundation; either version 2.1 of the License, or (at your
9// option) any later version.
10//
11// This is distributed in the hope that it will be useful, but WITHOUT ANY
12// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
14// more details.
15//
16// You should have received a copy of the GNU Lesser General Public
17// License along with this library; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19//
20// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
21
22// This file holds the interface for the 'get data as ascii' function of the
23// OPeNDAP/HAO data server. This function is called by the BES when it loads
24// this as a module. The functions in the file ascii_val.cc also use this, so
25// the same basic processing software can be used both by Hyrax and tie older
26// Server3.
27
28#include <stdio.h>
29
30#include <iostream>
31
32#include <libxml/xmlerror.h>
33
34using std::cerr;
35using std::endl;
36
37#include <libdap/DDS.h>
38
39#include <BESDebug.h>
40#include <RequestServiceTimer.h>
41
42#include "get_xml_data.h"
43#include "XDOutput.h"
44
45#include "XDByte.h"
46#include "XDInt16.h"
47#include "XDUInt16.h"
48#include "XDInt32.h"
49#include "XDUInt32.h"
50#include "XDFloat32.h"
51#include "XDFloat64.h"
52#include "XDStr.h"
53#include "XDUrl.h"
54#include "XDArray.h"
55#include "XDStructure.h"
56#include "XDSequence.h"
57#include "XDGrid.h"
58
59const char *DAP_SCHEMA = "http://xml.opendap.org/ns/dap/3.3#";
60
61using namespace libdap;
62
63#define MODULE "xml_data"
64#define prolog string("get_xml_data::").append(__func__).append("() - ")
65
66namespace xml_data {
67
75void get_data_values_as_xml(DDS *dds, XMLWriter *writer)
76{
77 try {
78 /* Start an element named "Dataset". Since this is the first element,
79 * this will be the root element of the document */
80 if (xmlTextWriterStartElementNS(writer->get_writer(), NULL, (const xmlChar*)"Dataset", (const xmlChar*)DAP_SCHEMA) < 0)
81 throw InternalErr(__FILE__, __LINE__, "Error starting the Dataset element for response ");
82
83 DDS::Vars_iter i = dds->var_begin();
84 while (i != dds->var_end()) {
85 if ((*i)->send_p()) {
86 RequestServiceTimer::TheTimer()->throw_if_timeout_expired(prolog + "ERROR: bes-timeout expired before transmit " + (*i)->name() , __FILE__, __LINE__);
87
88 BESDEBUG("xd", "Printing the values for " << (*i)->name() << " (" << (*i)->type_name() << ")" << endl);
89 dynamic_cast<XDOutput &>(**i).print_xml_data(writer, true);
90 }
91 ++i;
92 }
93
94 if (xmlTextWriterEndElement(writer->get_writer()) < 0)
95 throw InternalErr(__FILE__, __LINE__, "Error ending Dataset element.");
96
97 }
98 catch (InternalErr &e) {
99 const xmlError *error = xmlGetLastError();
100 if (error && error->message)
101 throw InternalErr(e.get_error_message() + "; libxml: " + error->message);
102 else
103 throw InternalErr(e.get_error_message() + "; libxml: no message");
104 }
105}
106
107DDS *dds_to_xd_dds(DDS * dds)
108{
109 BESDEBUG("xd", "In datadds_to_xd_datadds" << endl);
110 // Should the following use XDOutputFactory instead of the source DDS'
111 // factory class? It doesn't matter for the following since the function
112 // basetype_to_asciitype() doesn't use the factory. So long as no other
113 // code uses the DDS' factory, this is fine. jhrg 9/5/06
114 DDS *xd_dds = new DDS(dds->get_factory(), dds->get_dataset_name());
115
116 DDS::Vars_iter i = dds->var_begin();
117 while (i != dds->var_end()) {
118 BaseType *abt = basetype_to_xd(*i);
119 xd_dds->add_var(abt);
120 // add_var makes a copy of the base type passed to it, so delete
121 // it here
122 delete abt;
123 ++i;
124 }
125
126 // Calling tag_nested_sequences() makes it easier to figure out if a
127 // sequence has parent or child sequences or if it is a 'flat' sequence.
128 xd_dds->tag_nested_sequences();
129
130 return xd_dds;
131}
132
133BaseType *
134basetype_to_xd(BaseType *bt)
135{
136 if (!bt)
137 throw InternalErr(__FILE__, __LINE__, "Null BaseType to XD factory");
138
139 switch (bt->type()) {
140 case dods_byte_c:
141 return new XDByte(dynamic_cast<Byte *>(bt));
142
143 case dods_int16_c:
144 return new XDInt16(dynamic_cast<Int16 *>(bt));
145
146 case dods_uint16_c:
147 return new XDUInt16(dynamic_cast<UInt16 *>(bt));
148
149 case dods_int32_c:
150 return new XDInt32(dynamic_cast<Int32 *>(bt));
151
152 case dods_uint32_c:
153 return new XDUInt32(dynamic_cast<UInt32 *>(bt));
154
155 case dods_float32_c:
156 return new XDFloat32(dynamic_cast<Float32 *>(bt));
157
158 case dods_float64_c:
159 return new XDFloat64(dynamic_cast<Float64 *>(bt));
160
161 case dods_str_c:
162 return new XDStr(dynamic_cast<Str *>(bt));
163
164 case dods_url_c:
165 return new XDUrl(dynamic_cast<Url *>(bt));
166
167 case dods_array_c:
168 return new XDArray(dynamic_cast<Array *>(bt));
169
170 case dods_structure_c:
171 return new XDStructure(dynamic_cast<Structure *>(bt));
172
173 case dods_sequence_c:
174 return new XDSequence(dynamic_cast<Sequence *>(bt));
175
176 case dods_grid_c:
177 return new XDGrid(dynamic_cast<Grid *>(bt));
178
179 default:
180 throw InternalErr(__FILE__, __LINE__, "Unknown type");
181 }
182}
183
184} // namespace xml_data
static RequestServiceTimer * TheTimer()
Return a pointer to a singleton timer instance. If an instance does not exist it will create and init...
void throw_if_timeout_expired(const std::string &message, const std::string &file, const int line)
Checks the RequestServiceTimer to determine if the time spent servicing the request at this point has...