40 #define USE_NC_GLOBAL_CONTAINER 0
68 _value = proto._value;
69 _separator = proto._separator;
70 _orgName = proto._orgName;
71 _tokens = proto._tokens;
77 delete _pOtherXMLParser;
114 if (
_parser->isScopeAtomicAttribute())
116 BESDEBUG(
"ncml2",
"Adding attribute values as characters content for atomic attribute=" << _name <<
117 " value=\"" << content <<
"\"" << endl);
124 "Got characters content for a non-atomic attribute!"
125 " attribute@value is not allowed for attribute@type=Structure!");
140 ret +=
"name=\"" + _name +
"\"";
144 ret +=
" type=\"" + _type +
"\" ";
149 ret +=
" separator=\"" + _separator +
"\" ";
152 if (!_orgName.empty())
154 ret +=
" orgName=\"" + _orgName +
"\" ";
159 ret +=
" value=\"" + _value +
"\" ";
171 AttributeElement::processAttribute(
NCMLParser& p)
173 BESDEBUG(
"ncml2",
"handleBeginAttribute called for attribute name=" << _name << endl);
177 if (!p.withinNetcdf())
180 "Got <attribute> element while not within a <netcdf> node!");
183 if (p.isScopeAtomicAttribute())
187 "Got new <attribute> while in a leaf <attribute> at scope=" + p.getScopeString() +
188 " Hierarchies of attributes are only allowed for attribute containers with type=Structure");
194 if (internalType.empty())
198 "Unknown NCML type=" + _type +
" for attribute name=" + _name +
" at scope=" + p.getScopeString());
206 BESDEBUG(
"ncml2",
"Processing an attribute element with type Structure." << endl);
207 processAttributeContainerAtCurrentScope(p);
211 processAtomicAttributeAtCurrentScope(p);
216 AttributeElement::processAtomicAttributeAtCurrentScope(NCMLParser& p)
220 if (_orgName.empty())
222 if (p.attributeExistsAtCurrentScope(_name))
224 BESDEBUG(
"ncml",
"Found existing attribute named: " << _name <<
" with type=" << _type <<
" at scope=" <<
225 p.getScopeString() << endl);
231 BESDEBUG(
"ncml",
"Didn't find attribute: " << _name <<
" so adding it with type=" << _type <<
" and value=" << _value << endl );
238 renameAtomicAttribute(p);
242 if (_type ==
"OtherXML")
244 startOtherXMLParse(p);
252 AttributeElement::processAttributeContainerAtCurrentScope(NCMLParser& p)
255 BESDEBUG(
"ncml",
"Processing attribute container with name:" << _name << endl);
261 "Found non empty() value attribute for attribute container at scope=" + p.getTypedScopeString());
269 if (!_orgName.empty())
271 pAT = renameAttributeContainer(p);
276 AttrTable* pCurrentTable = p.getCurrentAttrTable();
279 pAT = pCurrentTable->simple_find_container(_name);
283 if (p.getVariableInCurrentVariableContainer(_name))
286 "Cannot create a new attribute container with name=" + _name +
287 " at current scope since a variable with that name already exists. Scope=" +
292 pAT = pCurrentTable->append_container(_name);
293 BESDEBUG(
"ncml",
"Attribute container was not found, creating new one name=" << _name <<
" at scope=" << p.getScopeString() << endl);
297 BESDEBUG(
"ncml",
"Found an attribute container name=" << _name <<
" at scope=" << p.getScopeString() << endl);
303 p.setCurrentAttrTable(pAT);
308 AttributeElement::getInternalType()
const
314 AttributeElement::addNewAttribute(NCMLParser& p)
318 string internalType = getInternalType();
321 if (internalType !=
"OtherXML")
324 p.tokenizeAttrValues(_tokens, _value, internalType, _separator);
325 BESDEBUG(
"ncml2",
"Adding the attribute '" << _name <<
"' to the current table" << endl);
326 BESDEBUG(
"ncml2",
"The Current attribute table is at: '" << p.getCurrentAttrTable() <<
"'" << endl);
327 p.getCurrentAttrTable()->append_attr(_name, internalType, &(_tokens));
332 BESDEBUG(
"ncml",
"Addinng new attribute of type OtherXML data." << endl);
336 "Adding new Attribute of type=OtherXML: Cannot specify"
337 " an attribute@value for OtherXML --- it must be set in the content! Scope was: "
338 + p.getScopeString() );
341 p.getCurrentAttrTable()->append_attr(_name, internalType, _value);
346 AttributeElement::mutateAttributeAtCurrentScope(NCMLParser& p,
const string& name,
const string& type,
const string& value)
348 AttrTable* pTable = p.getCurrentAttrTable();
351 "Logic error. mutateAttributeAtCurrentScope called when attribute name=" + name +
" didn't exist at scope=" + p.getTypedScopeString());
354 string actualType = type;
357 actualType = pTable->get_type(name);
361 actualType = p.convertNcmlTypeToCanonicalType(actualType);
364 pTable->del_attr(name);
367 if (actualType ==
"OtherXML")
369 BESDEBUG(
"ncml_attr",
"Setting OtherXML data to: " << endl << _value << endl);
370 pTable->append_attr(name, actualType, _value);
374 p.tokenizeAttrValues(_tokens, value, actualType, _separator);
375 #if USE_NC_GLOBAL_CONTAINER
392 BESDEBUG(
"ncml_attr",
"mutateAttributeAtCurrentScope: Looking at table: " << pTable->get_name() << endl);
393 BESDEBUG(
"ncml_attr",
"Looking at attribute named: " << _name << endl);
394 BESDEBUG(
"ncml_attr",
"isScopeGlobal(): " << p.isScopeGlobal() << endl);
395 BESDEBUG(
"ncml_attr",
"isScopeNetcdf(): " << p.isScopeNetcdf() << endl);
396 BESDEBUG(
"ncml_attr",
"isScopeAtomicAttribute(): " << p.isScopeAtomicAttribute() << endl);
397 BESDEBUG(
"ncml_attr",
"isScopeAttributeContainer(): " << p.isScopeAttributeContainer() << endl);
398 BESDEBUG(
"ncml_attr",
"isScopeVariable(): " << p.isScopeVariable() << endl);
399 BESDEBUG(
"ncml_attr",
"getTypedScopeString(): " << p.getTypedScopeString() << endl);
400 BESDEBUG(
"ncml_attr",
"getScopeDepth(): " << p.getScopeDepth() << endl);
401 BESDEBUG(
"ncml_attr",
"DAP version: " << p.getDDSForCurrentDataset()->get_dap_major() <<
"." << p.getDDSForCurrentDataset()->get_dap_minor() << endl);
406 if (p.getScopeDepth() < 2 && p.getDDSForCurrentDataset()->get_dap_major() < 4)
416 BESDEBUG(
"ncml_attr",
" not found; adding." << endl);
421 BESDEBUG(
"ncml_attr",
" found; using" << endl);
424 at->append_attr(_name, actualType, &(_tokens));
428 BESDEBUG(
"ncml_attr",
"Found parent container..." << endl);
429 pTable->append_attr(_name, actualType, &(_tokens));
432 pTable->append_attr(name, actualType, &(_tokens));
438 AttributeElement::renameAtomicAttribute(NCMLParser& p)
440 AttrTable* pTable = p.getCurrentAttrTable();
444 if (!p.attributeExistsAtCurrentScope(_orgName))
447 "Failed to change name of non-existent attribute with orgName=" + _orgName +
448 " and new name=" + _name +
" at the current scope=" + p.getScopeString());
453 if (p.isNameAlreadyUsedAtCurrentScope(_name))
456 "Failed to change name of existing attribute orgName=" + _orgName +
457 " because an attribute or variable with the new name=" + _name +
458 " already exists at the current scope=" + p.getScopeString());
461 AttrTable::Attr_iter it;
462 bool gotIt = p.findAttribute(_orgName, it);
467 "LOGIC ERROR: renameAtomicAttribute() got an attribute container where it expected an atomic attribute!");
470 vector<string>* pAttrVec = pTable->get_attr_vector(it);
473 vector<string> orgData = *pAttrVec;
474 AttrType orgType = pTable->get_attr_type(it);
477 pTable->del_attr(_orgName);
480 string typeToUse = AttrType_to_String(orgType);
481 if (!_type.empty() && _type != typeToUse)
483 BESDEBUG(
"ncml",
"Warning: renameAtomicAttribute(). New type did not match old type, using new type." << endl);
490 pTable->append_attr(_name, typeToUse, &orgData);
496 mutateAttributeAtCurrentScope(p, _name, typeToUse, _value);
501 AttributeElement::renameAttributeContainer(NCMLParser& p)
503 AttrTable* pTable = p.getCurrentAttrTable();
505 AttrTable* pAT = pTable->simple_find_container(_orgName);
509 "renameAttributeContainer: Failed to find attribute container with orgName=" + _orgName +
510 " at scope=" + p.getScopeString());
513 if (p.isNameAlreadyUsedAtCurrentScope(_name))
516 "Renaming attribute container with orgName=" + _orgName +
517 " to new name=" + _name +
518 " failed since an attribute or variable already exists with that name at scope=" + p.getScopeString());
521 BESDEBUG(
"ncml",
"Renaming attribute container orgName=" << _orgName <<
" to name=" << _name <<
" at scope="
522 << p.getTypedScopeString() << endl);
525 AttrTable::Attr_iter it;
526 bool gotIt = p.findAttribute(_orgName, it);
527 NCML_ASSERT_MSG(gotIt,
"Logic error. renameAttributeContainer expected to find attribute but didn't.");
530 pTable->del_attr_table(it);
533 pAT->set_name(_name);
534 pTable->append_container(pAT, _name);
541 AttributeElement::processEndAttribute(NCMLParser& p)
544 BESDEBUG(
"ncml",
"AttributeElement::handleEnd called at scope:" << p.getScopeString() << endl);
546 if (p.isScopeAtomicAttribute())
549 if (_type ==
"OtherXML")
557 if (_orgName.empty() ||
558 (!_orgName.empty() && !_value.empty()) )
560 mutateAttributeAtCurrentScope(*
_parser, _name, _type, _value);
565 else if (p.isScopeAttributeContainer())
569 p.setCurrentAttrTable(p.getCurrentAttrTable()->get_parent());
571 NCML_ASSERT_MSG(p.getCurrentAttrTable(),
"ERROR: Null p.getCurrentAttrTable() unexpected while leaving scope of attribute container!");
576 "Got end of attribute element while not parsing an attribute!");
581 AttributeElement::startOtherXMLParse(NCMLParser& p)
584 _pOtherXMLParser =
new OtherXMLParser(p);
585 p.enterOtherXMLParsingState(_pOtherXMLParser);
589 AttributeElement::getValidAttributes()
591 vector<string> attrs;
593 attrs.push_back(
"name");
594 attrs.push_back(
"type");
595 attrs.push_back(
"value");
596 attrs.push_back(
"orgName");
597 attrs.push_back(
"separator");
virtual bool validateAttributes(const XMLAttributeMap &attrs, const vector< string > &validAttrs, vector< string > *pInvalidAttrs=0, bool printInvalid=true, bool throwOnError=true)
Check that the given attributes are all in the valid set, otherwise fill in *pInvalidAttrs with the p...
virtual void handleEnd()
Handle the closing of this element.
virtual string toString() const
Return a string describing the element.
#define NCML_ASSERT(cond)
An abstract superclass for NCMLArray that handles the non-parameterized functionality and allows u...
const string getValueForLocalNameOrDefault(const string &localname, const string &defVal="") const
If there is an attribute with localname, return its value, else return default.
static bool isAllWhitespace(const std::string &str)
Is all the string whitespace as defined by chars in WHITESPACE ?
#define NCML_ASSERT_MSG(cond, msg)
static const string STRUCTURE_TYPE
The string describing the type "Structure".
int getParseLineNumber() const
Get the line of the NCML file the parser is currently parsing.
const std::string & getString() const
Get the parsed data as big string that we've been parsing in.
static const string _sTypeName
#define THROW_NCML_PARSE_ERROR(parseLine, msg)
static const vector< string > _sValidAttributes
virtual void handleBegin()
Handle a begin on this element.
Static class of utility functions.
virtual AttributeElement * clone() const
Make and return a copy of this.
Base class for NcML element concrete classes.
int line() const
Return the current parse line number.
static const string _default_global_container
virtual const string & getTypeName() const
Return the type of the element, which should be: the same as ConcreteClassName::getTypeName() ...
static string convertNcmlTypeToCanonicalType(const string &ncmlType)
Convert the NCML type in ncmlType into a canonical type we will use in the parser.
virtual void handleContent(const string &content)
Handle the characters content for the element.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
static const std::string WHITESPACE
Delimiter set for tokenizing whitespace separated data.
Concrete class for NcML
element.
virtual void setAttributes(const XMLAttributeMap &attrs)
Set the attributes of this from the map.
virtual ~AttributeElement()