58 const string NetcdfElement::_sTypeName =
"netcdf";
59 const vector<string> NetcdfElement::_sValidAttributes = getValidAttributes();
61 NetcdfElement::NetcdfElement()
71 , _gotMetadataDirective(false)
72 , _weOwnResponse(false)
78 , _variableValidator(this)
87 , _location(proto._location)
89 , _title(proto._title)
90 , _ncoords(proto._ncoords)
91 , _enhance(proto._enhance)
92 , _addRecords(proto._addRecords)
93 , _coordValue(proto._coordValue)
94 , _fmrcDefinition(proto._fmrcDefinition)
95 , _gotMetadataDirective(false)
96 , _weOwnResponse(false)
102 , _variableValidator(this)
113 if (proto._aggregation.get())
119 vector<DimensionElement*>::const_iterator endIt = proto._dimensions.end();
120 vector<DimensionElement*>::const_iterator it;
121 for (it = proto._dimensions.begin(); it != endIt; ++it)
130 BESDEBUG(
"ncml:memory",
"~NetcdfElement called...");
172 throwOnUnsupportedAttributes();
182 if (p.getRootDataset() && !p.isScopeAggregation())
185 "Got a nested <netcdf> element which was NOT a direct child of an <aggregation>!");
190 p.pushCurrentDataset(
this);
194 validateAttributeContextOrThrow();
203 "Got non-whitespace for element content and didn't expect it. Element=" +
toString() +
" content=\"" +
211 BESDEBUG(
"ncml",
"NetcdfElement::handleEnd called!" << endl);
216 "Got close of <netcdf> node while not within one!");
222 if (_aggregation.get())
224 _aggregation->processParentDatasetComplete();
234 _parser->popCurrentDataset(
this);
245 "location=\"" + _location +
"\"" +
295 "NetcdfElement::getNCoords(): called illegally when no ncoords attribute was specified!");
296 unsigned int num = 0;
300 "A <netcdf> element has an invalid ncoords attribute set. Bad value was:"
301 "\"" + _ncoords +
"\"");
309 NCML_ASSERT_MSG(!_response,
"_response object should be NULL for proper logic of borrowResponseObject call!");
310 _response = pResponse;
311 _weOwnResponse =
false;
317 NCML_ASSERT_MSG(pResponse == _response,
"NetcdfElement::unborrowResponseObject() called with a response we are not borrowing.");
326 THROW_NCML_INTERNAL_ERROR(
"NetcdfElement::createResponseObject(): Called when we already had a _response! Logic error!");
334 _response = newResponse.release();
335 _weOwnResponse =
true;
345 if (_pDatasetWrapper.
empty())
347 if (_location.empty())
371 return _pDatasetWrapper.
lock();
378 vector<DimensionElement*>::const_iterator endIt = _dimensions.end();
379 for (vector<DimensionElement*>::const_iterator it = _dimensions.begin(); it != endIt; ++it)
383 if (pElt->
name() == name)
418 _dimensions.push_back(dim);
427 string ret =
"Dimensions = {\n";
428 vector<DimensionElement*>::const_iterator endIt = _dimensions.end();
429 vector<DimensionElement*>::const_iterator it;
430 for (it = _dimensions.begin(); it != endIt; ++it)
432 ret += (*it)->toString() +
"\n";
441 while (!_dimensions.empty())
445 _dimensions.pop_back();
447 _dimensions.resize(0);
450 const std::vector<DimensionElement*>&
459 if (_aggregation.get() && throwIfExists)
461 THROW_NCML_INTERNAL_ERROR(
"NetcdfElement::setAggregation: We were called but we already contain a non-NULL aggregation! Previous="
462 + _aggregation->toString() +
" and the new one is: " + agg->
toString());
469 _aggregation->setParentDataset(
this);
498 return _aggregation.get();
502 #if 0 // not sure we need this yet...
503 template <
typename T>
505 NetcdfElement::getCoordValueVector(vector<T>& values)
const
511 vector<string> tokens;
513 values.reserve(numToks);
515 for (
int i=0; i<numToks; ++i)
517 stringstream iss(tokens[i]);
523 "NetcdfElement::getCoordValueVector(): "
524 "Could not parse the token \"" + tokens[i] +
"\""
525 " into the required data type.");
529 values.push_back(val);
538 if (_coordValue.empty())
543 std::istringstream iss(_coordValue);
547 if (iss.fail() || !iss.eof() )
605 NetcdfElement::loadLocation()
607 if (_location.empty())
616 "NetcdfElement::loadLocation(): Requires a valid _response via borrowResponseObject() or createResponseObject() prior to call!");
622 _parser->loadLocation(_location,
_parser->_responseType, _response);
628 NetcdfElement::throwOnUnsupportedAttributes()
630 const string msgStart =
"NetcdfElement: unsupported attribute: ";
631 const string msgEnd =
" was declared.";
632 if (!_enhance.empty())
635 msgStart +
"enhance" + msgEnd);
637 if (!_addRecords.empty())
640 msgStart +
"addRecords" + msgEnd);
644 if (!_fmrcDefinition.empty())
647 msgStart +
"fmrcDefinition" + msgEnd);
652 NetcdfElement::validateAttributeContextOrThrow()
const
658 !( pParentAgg->isJoinExistingAggregation()) )
661 "Cannot specify netcdf@ncoords attribute while not within a "
662 "joinExisting aggregation!");
669 NetcdfElement::getValidAttributes()
671 vector<string> validAttrs;
672 validAttrs.reserve(9);
674 validAttrs.push_back(
"location");
675 validAttrs.push_back(
"id");
676 validAttrs.push_back(
"title");
677 validAttrs.push_back(
"enhance");
678 validAttrs.push_back(
"addRecords");
680 validAttrs.push_back(
"ncoords");
681 validAttrs.push_back(
"coordValue");
682 validAttrs.push_back(
"fmrcDefinition");
689 typedef vector<NetcdfElement::VariableValueValidator::VVVEntry>
VVVEntries;
700 VVVEntries::iterator it;
701 VVVEntries::iterator endIt = _entries.end();
702 for (it = _entries.begin(); it != endIt; ++it)
717 VVVEntry* pExisting = findEntryByLibdapVar(pNewVar);
718 NCML_ASSERT_MSG(!pExisting,
"NetcdfElement::VariableValueValidator::addVariableToValidate: var was already added!");
723 _entries.push_back(
VVVEntry(pNewVar, pVE));
729 for (
unsigned int i=0; i<_entries.size(); ++i)
731 if (_entries[i]._pNewVar == pVarToRemove)
733 _entries[i]._pVarElt->unref();
734 _entries[i] = _entries[_entries.size()-1];
745 VVVEntry* pEntry = findEntryByLibdapVar(pVarToValidate);
746 NCML_ASSERT_MSG(pEntry,
"NetcdfElement::VariableValueValidator::setVariableGotValues: expected to find the var name=" +
747 pVarToValidate->name() +
" but we did not!");
760 VVVEntries::iterator it;
761 VVVEntries::iterator endIt = _entries.end();
762 for (it = _entries.begin(); it != endIt; ++it)
769 "On closing the <netcdf> element, we found a new variable name=" +
772 " to the dataset but which never had values set on it. This is illegal!"
773 " Please make sure all variables in this dataset have values set on them"
774 " or that they are new coordinate variables for a joinNew aggregation.");
781 NetcdfElement::VariableValueValidator::findEntryByLibdapVar(libdap::BaseType* pVarToFind)
784 VVVEntry* pRetVal = 0;
785 VVVEntries::iterator it;
786 VVVEntries::iterator endIt = _entries.end();
787 for (it = _entries.begin(); it != endIt; ++it)
789 VVVEntry& entry = *it;
790 if (entry._pNewVar == pVarToFind)
803 VVVEntry* pRetVal = findEntryByLibdapVar(pVarToFind);
~VariableValueValidator()
Will decrement the ref count of all contained VariableElement's.
virtual const string & getTypeName() const
Return the type of the element, which should be: the same as ConcreteClassName::getTypeName() ...
static std::auto_ptr< BESDapResponse > makeResponseForType(ResponseType type)
Make a new response object for the requested type.
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...
void addVariableToValidateOnClose(libdap::BaseType *pNewVar, VariableElement *pVE)
Add the pNewvar created by pVE to this dataset's list of variables to validate for having values set ...
ResponseType
For telling the loader what type of BESDapResponse to load and return.
virtual string toString() const
Return a string describing the element.
VariableElement * _pVarElt
static bool isCoordValueLexicographicallyLessThan(const NetcdfElement *pLHS, const NetcdfElement *pRHS)
Compare the coordvalue fields of the two arguments and return true if lhs.coordValue() < rhs...
class AggMemberDatasetUsingLocationRef: Concrete subclass of AggMemberDataset for lazy-loading a loca...
bool empty() const
Will getting a lock() return a null?
const string & location() const
void setParentAggregation(AggregationElement *parent)
Set my parent AggregationElement to parent.
void addDimension(DimensionElement *dim)
Add the given element to this scope.
#define NCML_ASSERT(cond)
void setChildAggregation(AggregationElement *agg, bool throwIfExists=true)
Set our aggregation to the given agg.
virtual int unref() const
Decrease the reference count by one.
An abstract superclass for NCMLArray that handles the non-parameterized functionality and allows u...
const string & coordValue() const
void clearDimensions()
Clear the dimension table, releasing all strong references.
virtual void handleEnd()
Handle the closing of this element.
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
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 ?
static libdap::DDS * getDDSFromEitherResponse(BESDapResponse *response)
Return the DDS* for the given response object.
virtual void handleContent(const string &content)
Handle the characters content for the element.
#define NCML_ASSERT_MSG(cond, msg)
Concrete class for NcML element.
libdap::BaseType * _pNewVar
static bool toUnsignedInt(const std::string &stringVal, unsigned int &oVal)
Convert the string to an unsigned int into oVal.
Interface class for any object that can contains a DDS.
virtual const libdap::DDS * getDDS() const
Return the DDS for this dataset, loading it in if needed.
const DimensionElement * getDimensionInLocalScope(const string &name) const
static const vector< string > _sValidAttributes
static const string _sTypeName
virtual NetcdfElement * clone() const
Make and return a copy of this.
void setVariableGotValues(libdap::BaseType *pVarToValidate)
Lookup the VariableElement pVE associated with the given pVarToValidate and call pVE->setGotValues() ...
RCPtr< agg_util::AggMemberDataset > getAggMemberDataset() const
Return a shared reference to the AggMemberDataset that encapsulates this dataset. ...
string printDimensions() const
"Print" out the dimensions to a string
bool validate()
Make sure all the entries has had their values set else throw a parse error explaining which variable...
virtual string toString() const
Return a string describing the element.
static bool isLocationLexicographicallyLessThan(const NetcdfElement *pLHS, const NetcdfElement *pRHS)
Compare the location fields of the two arguments and return true if lhs.location() < rhs...
AggregationElement * getChildAggregation() const
Return the raw pointer (or NULL) to our contained aggregation.
virtual void handleBegin()
Handle a begin on this element.
class AggMemberDatasetSharedDDSWrapper: concrete subclass of AggMemberDataset designed to hold a ref-...
Mixture interface for when we a reference-counted DDS container.
bool checkGotValues() const
int getParseLineNumber() const
Get the line of the NCML file the parser is currently parsing.
static std::string printAttributeIfNotEmpty(const std::string &attrName, const std::string &attrValue)
Helper for subclasses implementing toString().
const std::vector< DimensionElement * > & getDimensionElements() const
Get the list of dimension elements local to only this dataset, not its enclosing scope.
NetcdfElement * getParentDataset() const
const DimensionElement * getDimensionInFullScope(const string &name) const
#define THROW_NCML_PARSE_ERROR(parseLine, msg)
virtual int ref() const
Increase the reference count by one.
void removeVariableToValidate(libdap::BaseType *pVarToRemove)
Remove an entry previously added under the key pVarToRemove with addVariableToValidate.
void createResponseObject(agg_util::DDSLoader::ResponseType type)
Called if this is a member of an aggregation (i.e.
unsigned int getNcoordsAsUnsignedInt() const
Get the ncoords() field as a valid size.
A reference to an RCObject which automatically ref() and deref() on creation and destruction.
bool getCoordValueAsDouble(double &val) const
Parse the netcdf attribute as a double.
VariableElement * findVariableElementForLibdapVar(libdap::BaseType *pNewVar)
If a VariableElement has been associated with a new var to validate, return it.
void setVariableGotValues(libdap::BaseType *pVarToValidate, bool removeEntry)
Lookup the VariableElement* associated with pVarToValidate via a previous addVariableToValidateOnClos...
void unborrowResponseObject(BESDapResponse *pResponse)
Kind of superfluous, but tells this object to clear its reference to pReponse, which had better match...
Base class for NcML element concrete classes.
virtual DimensionElement * clone() const
Make and return a copy of this.
int line() const
Return the current parse line number.
Represents an OPeNDAP DAP response object within the BES.
#define THROW_NCML_INTERNAL_ERROR(msg)
Concrete class for NcML element.
virtual void setAttributes(const XMLAttributeMap &attrs)
Set the attributes of this from the map.
vector< NetcdfElement::VariableValueValidator::VVVEntry > VVVEntries
VariableValueValidator(NetcdfElement *pParent)
AggregationElement * getParentAggregation() const
A variant of boost::weak_ptr that uses our intrusive RCObject counting.
void addVariableToValidate(libdap::BaseType *pNewVar, VariableElement *pVE)
Add a validation entry for the given VariableElement and the actual variable that it has created and ...
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
NetcdfElement * getParentDataset() const
Return the next enclosing dataset for this, or NULL if we're the root.
virtual string toString() const
Return a string describing the element.
static const std::string WHITESPACE
Delimiter set for tokenizing whitespace separated data.
void borrowResponseObject(BESDapResponse *pResponse)
Used by the NCMLParser to let us know to borrow the response object and not own it.
void setGotValues()
Called once we set the values from ValuesElement so we are aware.
Interface class for a reference counted object.
static int tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" \t")
Split str into tokens using the characters in delimiters as split boundaries.
const string & name() const
VariableElement * findVariableElementForLibdapVar(libdap::BaseType *pNewVar)
If a VariableElement has been associated with a new var to validate, return it.