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"
49 #include "NCMLDebug.h"
56 const std::string NCMLUtil::WHITESPACE =
" \t\n";
58 int NCMLUtil::tokenize(
const string& str, vector<string>& tokens,
const string& delimiters)
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);
82 int NCMLUtil::tokenizeChars(
const string& str, vector<string>& tokens)
86 for (
unsigned int i = 0; i < str.size(); ++i) {
89 tokens.push_back(val);
94 bool NCMLUtil::isAscii(
const string& str)
96 string::const_iterator endIt = str.end();
97 for (string::const_iterator it = str.begin(); it != endIt; ++it) {
105 bool NCMLUtil::isAllWhitespace(
const string& str)
107 return (str.find_first_not_of(
" \t\n") == string::npos);
110 void NCMLUtil::trimLeft(std::string& input,
const std::string& trimChars )
112 size_t firstValid = input.find_first_not_of(trimChars);
113 input.erase(0, firstValid);
119 void NCMLUtil::trimRight(std::string& input,
const std::string& trimChars )
121 size_t lastValid = input.find_last_not_of(trimChars);
122 if (lastValid != string::npos) {
123 input.erase(lastValid + 1, string::npos);
127 void NCMLUtil::trimAll(std::vector<std::string>& tokens,
const std::string& trimChars )
129 unsigned int num = tokens.size();
130 for (
unsigned int i = 0; i < num; ++i) {
131 trim(tokens[i], trimChars);
135 bool NCMLUtil::toUnsignedInt(
const std::string& stringVal,
unsigned int& oVal)
139 istringstream iss(stringVal);
141 if (iss.fail() || (stringVal[0] ==
'-')
160 has_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))) {
184 has_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;
211 static 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);
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);
276 void NCMLUtil::populateDASFromDDS(DAS* das,
const DDS& dds_const)
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);
332 void NCMLUtil::copyVariablesAndAttributesInto(DDS* dds_out,
const DDS& dds_in)
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();
386 void 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();
462 void NCMLUtil::setVariableNameProperly(libdap::BaseType* pVar,
const std::string& name)
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
NcML Parser for adding/modifying/removing metadata (attributes) to existing local datasets using NcML...