46#include <libdap/Array.h>
47#include <libdap/Structure.h>
48#include <libdap/Sequence.h>
49#include <libdap/Grid.h>
50#include <libdap/Ancillary.h>
51#include <libdap/DAS.h>
52#include <libdap/util.h>
61using namespace dap_usage;
65static const BESRegex dim(
".*_dim_[0-9]*", 1);
66static const BESRegex global(
"(.*global.*)|(.*dods.*)", 1);
69name_in_kill_file(
const string &name) {
70 return dim.match(name.c_str(), (
int)name.size()) != -1;
74name_is_global(
string &name) {
76 return global.match(name.c_str(), (
int)name.size()) != -1;
85write_global_attributes(ostringstream &oss, AttrTable *attr,
const string &prefix =
"") {
87 AttrTable::Attr_iter a;
88 for (a = attr->attr_begin(); a != attr->attr_end(); a++) {
89 if (attr->is_container(a))
90 write_global_attributes(oss, attr->get_attr_table(a),
91 (prefix ==
"") ? attr->get_name(a)
92 : prefix +
string(
".") + attr->get_name(a));
94 oss <<
"\n<tr><td align=right valign=top><b>";
96 oss << prefix <<
"." << attr->get_name(a);
98 oss << attr->get_name(a);
99 oss <<
"</b>:</td>\n";
101 int num_attr = attr->get_attr_num(a) - 1;
102 oss <<
"<td align=left>";
103 for (
int i = 0; i < num_attr; ++i)
104 oss << attr->get_attr(a, i) <<
", ";
105 oss << attr->get_attr(a, num_attr) <<
"<br></td></tr>\n";
112write_attributes(ostringstream &oss, AttrTable *attr,
const string &prefix =
"") {
114 for (
auto a = attr->attr_begin(); a != attr->attr_end(); a++) {
115 if (attr->is_container(a)) {
116 write_attributes(oss, attr->get_attr_table(a),
117 (prefix ==
"") ? attr->get_name(a)
118 : prefix +
string(
".") + attr->get_name(a));
122 oss << prefix <<
"." << attr->get_name(a);
124 oss << attr->get_name(a);
127 unsigned int num_attr = attr->get_attr_num(a) - 1;
128 for (
int i = 0; i < num_attr; ++i)
129 oss << attr->get_attr(a, i) <<
", ";
130 oss << attr->get_attr(a, num_attr) <<
"<br>\n";
149build_global_attributes(DAS &das,
const DDS &) {
153 ga <<
"<h3>Dataset Information</h3>\n<center>\n<table>\n";
155 for (
auto p = das.var_begin(); p != das.var_end(); p++) {
156 string name = das.get_name(p);
162 if (!name_in_kill_file(name)) {
163 if (name_is_global(name)) {
164 AttrTable *attr = das.get_table(p);
166 write_global_attributes(ga, attr,
"");
171 ga <<
"</table>\n</center><p>\n";
180fancy_typename(BaseType *v) {
186 return "16 bit Integer";
188 return "16 bit Unsigned integer";
190 return "32 bit Integer";
192 return "32 bit Unsigned integer";
194 return "32 bit Real";
196 return "64 bit Real";
203 Array *a = (Array *) v;
204 type <<
"Array of " << fancy_typename(a->var()) <<
"s ";
205 for (Array::Dim_iter p = a->dim_begin(); p != a->dim_end(); p++) {
206 type <<
"[" << a->dimension_name(p) <<
" = 0.."
207 << a->dimension_size(p,
false) - 1 <<
"]";
212 case dods_structure_c:
214 case dods_sequence_c:
224write_variable(BaseType *btp, DAS &das, ostringstream &vs) {
225 vs <<
"<td align=right valign=top><b>" << btp->name()
227 <<
"<td align=left valign=top>" << fancy_typename(btp)
230 AttrTable *attr = das.get_table(btp->name());
232 write_attributes(vs, attr,
"");
234 switch (btp->type()) {
248 case dods_structure_c: {
250 Structure *sp =
dynamic_cast<Structure *
>(btp);
251 for (Constructor::Vars_iter p = sp->var_begin(); p != sp->var_end(); p++) {
253 write_variable((*p), das, vs);
260 case dods_sequence_c: {
262 Sequence *sp =
dynamic_cast<Sequence *
>(btp);
263 for (Constructor::Vars_iter p = sp->var_begin(); p != sp->var_end(); p++) {
265 write_variable((*p), das, vs);
274 Grid *gp =
dynamic_cast<Grid *
>(btp);
275 write_variable(gp->array_var(), das, vs);
277 for (p = gp->map_begin(); p != gp->map_end(); p++) {
279 write_variable((*p), das, vs);
287 throw InternalErr(__FILE__, __LINE__,
"Unknown type");
300build_variable_summaries(DAS &das, DDS &dds) {
302 vs <<
"<h3>Variables in this Dataset</h3>\n<center>\n<table>\n";
305 for (DDS::Vars_iter p = dds.var_begin(); p != dds.var_end(); p++) {
307 write_variable((*p), das, vs);
311 vs <<
"</table>\n</center><p>\n";
317html_header(ostream &strm) {
318 strm <<
"HTTP/1.0 200 OK\r\n";
319 strm <<
"XDODS-Server: " << PACKAGE_VERSION <<
"\r\n";
320 strm <<
"XDAP: " << DAP_PROTOCOL_VERSION <<
"\r\n";
321 strm <<
"Content-type: text/html\r\n";
322 strm <<
"Content-Description: dods_description\r\n";
343write_usage_response(ostream &strm, DDS &dds, DAS &das,
const string &dataset_name,
const string &server_name,
347 string user_html = get_user_supplied_docs(dataset_name, server_name);
349 string global_attrs = build_global_attributes(das, dds);
351 string variable_sum = build_variable_summaries(das, dds);
358 strm <<
"<html><head><title>Dataset Information</title></head>"
359 <<
"\n" <<
"<body>" <<
"\n";
361 if (global_attrs.size()) {
362 strm << global_attrs.c_str() <<
"\n" <<
"<hr>" <<
"\n";
365 strm << variable_sum.c_str() <<
"\n";
369 strm << user_html.c_str() <<
"\n";
371 strm <<
"</body>\n</html>\n";
397get_user_supplied_docs(
const string &name,
const string &cgi) {
400 ifstream ifs((cgi +
".html").c_str());
404 ifs.getline(tmp, 255);
417 ifs.open((name +
".html").c_str());
421 string new_name = Ancillary::find_group_ancillary_file(name,
".html");
423 ifs.open(new_name.c_str());
428 ifs.getline(tmp, 255);