34#include <libdap/Array.h>
35#include <libdap/Constructor.h>
36#include <libdap/DAS.h>
37#include <libdap/DDS.h>
38#include <libdap/Grid.h>
39#include <libdap/DataDDS.h>
40#include <libdap/AttrTable.h>
42#include "BESDapResponse.h"
43#include "BESDataDDSResponse.h"
44#include "BESDDSResponse.h"
46#include "BESInternalError.h"
60 BESDEBUG(
"ncml",
"NCMLUtil::tokenize value of str:" << str << endl);
65 string::size_type lastPos = str.find_first_not_of(delimiters, 0);
67 string::size_type pos = str.find_first_of(delimiters, lastPos);
70 while (string::npos != pos || string::npos != lastPos) {
72 tokens.push_back(str.substr(lastPos, pos - lastPos));
75 lastPos = str.find_first_not_of(delimiters, pos);
77 pos = str.find_first_of(delimiters, lastPos);
86 for (
unsigned int i = 0; i < str.size(); ++i) {
89 tokens.push_back(val);
96 string::const_iterator endIt = str.end();
97 for (string::const_iterator it = str.begin(); it != endIt; ++it) {
107 return (str.find_first_not_of(
" \t\n") == string::npos);
112 size_t firstValid = input.find_first_not_of(trimChars);
113 input.erase(0, firstValid);
121 size_t lastValid = input.find_last_not_of(trimChars);
122 if (lastValid != string::npos) {
123 input.erase(lastValid + 1, string::npos);
129 unsigned int num = tokens.size();
130 for (
unsigned int i = 0; i < num; ++i) {
131 trim(tokens[i], trimChars);
139 istringstream iss(stringVal);
141 if (iss.fail() || (stringVal[0] ==
'-')
160has_dap2_attributes(AttrTable &a)
162 for (AttrTable::Attr_iter i = a.attr_begin(), e = a.attr_end(); i != e; ++i) {
163 if (a.get_attr_type(i) != Attr_container) {
166 else if (has_dap2_attributes(*a.get_attr_table(i))) {
184has_dap2_attributes(BaseType *btp)
186 if (btp->get_attr_table().get_size() && has_dap2_attributes(btp->get_attr_table())) {
190 Constructor *cons =
dynamic_cast<Constructor *
>(btp);
192 Grid* grid =
dynamic_cast<Grid*
>(btp);
194 return has_dap2_attributes(grid->get_array());
197 for (Constructor::Vars_iter i = cons->var_begin(), e = cons->var_end(); i != e; i++) {
198 if (has_dap2_attributes(*i))
return true;
211static void populateAttrTableForContainerVariableRecursive(AttrTable* dasTable, Constructor* consVar)
216 if(!has_dap2_attributes(consVar))
220 Grid* grid =
dynamic_cast<Grid*
>(consVar);
225 BESDEBUG(
"ncml", __func__ <<
"() The variable " << grid->name() <<
" is a Grid. So, we promote the Grid Array AttrTable content to the DAS container for Grid " << grid->name() << endl);
226 Array *gArray = grid->get_array();
227 AttrTable arrayAT = gArray->get_attr_table();
228 for( AttrTable::Attr_iter atIter = arrayAT.attr_begin(); atIter!=arrayAT.attr_end(); ++atIter){
229 AttrType type = arrayAT.get_attr_type(atIter);
230 string childName = arrayAT.get_name(atIter);
231 if (type == Attr_container){
232 BESDEBUG(
"ncml", __func__ <<
"() Adding child AttrTable '" << childName <<
"' to Grid " << grid->name() << endl);
233 dasTable->append_container(
new AttrTable(*arrayAT.get_attr_table(atIter)), childName);
236 vector<string>* pAttrTokens = arrayAT.get_attr_vector(atIter);
238 BESDEBUG(
"ncml", __func__ <<
"() Adding child Attrbute '" << childName <<
"' to Grid " << grid->name() << endl);
239 dasTable->append_attr(childName, AttrType_to_String(type), pAttrTokens);
245 BESDEBUG(
"ncml", __func__ <<
"() Adding attribute tables for children of a Constructor type variable " << consVar->name() << endl);
246 Constructor::Vars_iter endIt = consVar->var_end();
247 for (Constructor::Vars_iter it = consVar->var_begin(); it != endIt; ++it) {
251 if(has_dap2_attributes(var)){
252 BESDEBUG(
"ncml", __func__ <<
"() Adding attribute table for var: " << var->name() << endl);
254 AttrTable* newTable =
new AttrTable(var->get_attr_table());
256 dasTable->append_container(newTable, var->name());
259 if (var->is_constructor_type()) {
260 Constructor* child =
dynamic_cast<Constructor*
>(var);
262 throw BESInternalError(
"Type cast error", __FILE__, __LINE__);
264 BESDEBUG(
"ncml", __func__ <<
"() Var " << child->name() <<
" is Constructor type, recursively adding attribute tables" << endl);
265 populateAttrTableForContainerVariableRecursive(newTable, child);
269 BESDEBUG(
"ncml", __func__ <<
"() Variable '" << var->name() <<
"' has no dap2 attributes,. Skipping."<< endl);
278 BESDEBUG(
"ncml",
"Populating a DAS from a DDS...." << endl);
286 DDS& dds =
const_cast<DDS&
>(dds_const);
290 if (dds.container()) {
291 BESDEBUG(
"ncml", __func__ <<
"() Got unexpected container " << dds.container_name() <<
" and is failing." << endl);
292 throw BESInternalError(
"Unexpected Container Error creating DAS from DDS in NCMLHandler", __FILE__, __LINE__);
297 *(das->get_top_level_attributes()) = dds.get_attr_table();
302 DDS::Vars_iter endIt = dds.var_end();
303 for (DDS::Vars_iter it = dds.var_begin(); it != endIt; ++it) {
309 if(has_dap2_attributes(var)){
310 BESDEBUG(
"ncml",
"Adding attribute table for variable: " << var->name() << endl);
311 AttrTable* clonedVarTable =
new AttrTable(var->get_attr_table());
312 VALID_PTR(clonedVarTable);
313 das->add_table(var->name(), clonedVarTable);
316 if (var->is_constructor_type()) {
317 Constructor* consVar =
dynamic_cast<Constructor*
>(var);
321 populateAttrTableForContainerVariableRecursive(clonedVarTable, consVar);
325 BESDEBUG(
"ncml", __func__ <<
"() Variable '" << var->name() <<
"' has no dap2 attributes,. Skipping."<< endl);
337 if (dds_out == &dds_in) {
342 DDS& dds =
const_cast<DDS&
>(dds_in);
345 dds_out->get_attr_table() = dds.get_attr_table();
350 for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); ++i) {
351 dds_out->add_var(*i);
363 pDDS = pDDXResponse->
get_dds();
365 else if (pDataDDSResponse) {
366 pDDS = pDataDDSResponse->get_dds();
386void NCMLUtil::hackGlobalAttributesForDAP2(libdap::AttrTable &global_attributes,
387 const std::string &global_container_name)
389 if (global_container_name.empty())
return;
398 bool simple_attribute_found =
false;
399 AttrTable::Attr_iter i = global_attributes.attr_begin();
400 while (!simple_attribute_found && i != global_attributes.attr_end()) {
401 if (!global_attributes.is_container(i)) simple_attribute_found =
true;
406 if (!simple_attribute_found)
return;
409 bool only_simple_attributes =
true;
410 i = global_attributes.attr_begin();
411 while (only_simple_attributes && i != global_attributes.attr_end()) {
412 if (global_attributes.is_container(i))
413 only_simple_attributes =
false;
421 if (only_simple_attributes)
423 AttrTable *new_global_attr_container =
new AttrTable();
424 AttrTable *new_attr_container = new_global_attr_container->append_container(global_container_name);
425 *new_attr_container = global_attributes;
426 global_attributes = *new_global_attr_container;
432 AttrTable *new_attr_container = global_attributes.find_container(global_container_name);
433 if (!new_attr_container) new_attr_container = global_attributes.append_container(global_container_name);
436 i = global_attributes.attr_begin();
437 while (i != global_attributes.attr_end()) {
438 if (!global_attributes.is_container(i)) {
439 new_attr_container->append_attr(global_attributes.get_name(i), global_attributes.get_type(i),
440 global_attributes.get_attr_vector(i));
447 i = global_attributes.attr_begin();
448 while (i != global_attributes.attr_end()) {
449 if (!global_attributes.is_container(i)) {
450 global_attributes.del_attr(global_attributes.get_name(i));
452 i = global_attributes.attr_begin();
465 pVar->set_name(name);
467 BaseType* pTemplate = pVar->var();
469 pTemplate->set_name(name);
Holds a DDS object within the BES.
Represents an OPeNDAP DAP response object within the BES.
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
exception thrown if internal error encountered
static int tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" \t")
static libdap::DDS * getDDSFromEitherResponse(BESDapResponse *response)
static bool isAllWhitespace(const std::string &str)
static void trim(std::string &str, const std::string &trimChars=WHITESPACE)
static int tokenizeChars(const std::string &str, std::vector< std::string > &tokens)
static bool toUnsignedInt(const std::string &stringVal, unsigned int &oVal)
static void populateDASFromDDS(libdap::DAS *das, const libdap::DDS &dds_const)
static void trimRight(std::string &str, const std::string &trimChars=WHITESPACE)
static void copyVariablesAndAttributesInto(libdap::DDS *dds_out, const libdap::DDS &dds_in)
static const std::string WHITESPACE
static void setVariableNameProperly(libdap::BaseType *pVar, const std::string &name)
static void trimAll(std::vector< std::string > &tokens, const std::string &trimChars=WHITESPACE)
static bool isAscii(const std::string &str)
static void trimLeft(std::string &str, const std::string &trimChars=WHITESPACE)
NcML Parser for adding/modifying/removing metadata (attributes) to existing local datasets using NcML...