29 #include "DimensionElement.h"
30 #include "NCMLDebug.h"
31 #include "NCMLParser.h"
33 #include "NetcdfElement.h"
38 using std::stringstream;
42 const string DimensionElement::_sTypeName =
"dimension";
43 const vector<string> DimensionElement::_sValidAttributes = getValidAttributes();
45 DimensionElement::DimensionElement() :
46 NCMLElement(0), _length(
"0"), _orgName(
""), _isUnlimited(
""), _isShared(
""), _isVariableLength(
""), _dim()
50 DimensionElement::DimensionElement(
const DimensionElement& proto) :
51 RCObjectInterface(), NCMLElement(proto), _length(proto._length), _orgName(proto._orgName), _isUnlimited(
52 proto._isUnlimited), _isShared(proto._isShared), _isVariableLength(proto._isVariableLength), _dim(proto._dim)
57 NCMLElement(0), _length(
"0"), _orgName(
""), _isUnlimited(
""), _isShared(
""), _isVariableLength(
""), _dim(dim)
65 DimensionElement::~DimensionElement()
69 const string& DimensionElement::getTypeName()
const
75 DimensionElement::clone()
const
90 validateAttributes(attrs, _sValidAttributes);
93 parseValidateAndCacheDimension();
96 void DimensionElement::handleBegin()
98 BESDEBUG(
"ncml",
"DimensionElement::handleBegin called..." << endl);
102 if (!_parser->isScopeNetcdf()) {
103 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
104 "Got dimension element = " + toString()
105 +
" at an invalid parse location. Expected it as a direct child of <netcdf> element only." +
" scope="
106 + _parser->getScopeString());
116 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
117 "Tried to add dimension at " + toString() +
" but a dimension with name=" + name()
118 +
" already exists in this scope=" + _parser->getScopeString());
123 if(!_orgName.empty()){
124 processRenameDimension(*_parser);
128 void DimensionElement::processRenameDimension(
NCMLParser& p)
131 "DimensionElement::processRenameDimension() called on " + toString() <<
" at scope=" << p.getTypedScopeString() << endl);
133 BESDEBUG(
"ncml",
"Renaming dimension " << _orgName <<
" to " << name() << endl);
135 DDS* cDDS = p.getDDSForCurrentDataset();
136 DDS::Vars_iter varit;
137 for (varit = cDDS->var_begin(); varit != cDDS->var_end(); varit++) {
139 if ((*varit)->type() == dods_array_c)
140 varArray =
dynamic_cast<Array *
>(*varit);
143 for (ait = varArray->dim_begin(); ait != varArray->dim_end(); ++ait) {
144 if((*ait).name == name()){
145 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
146 "Renaming dimension failed for element=" + toString() +
" since a dimension with name=" + (*ait).name
147 +
" already exists at current parser scope=" + p.getScopeString());
149 if((*ait).name == _orgName){
150 varArray->rename_dim(_orgName, name());
156 void DimensionElement::handleContent(
const string& content)
159 if (!NCMLUtil::isAllWhitespace(content)) {
160 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
161 "Got illegal (non-whitespace) content in element " + toString());
165 void DimensionElement::handleEnd()
170 string DimensionElement::toString()
const
172 string ret =
"<" + _sTypeName +
" ";
173 ret += NCMLElement::printAttributeIfNotEmpty(
"name", name());
174 ret += NCMLElement::printAttributeIfNotEmpty(
"length", _length);
175 ret += NCMLElement::printAttributeIfNotEmpty(
"isShared", _isShared);
176 ret += NCMLElement::printAttributeIfNotEmpty(
"isVariableLength", _isVariableLength);
177 ret += NCMLElement::printAttributeIfNotEmpty(
"isUnlimited", _isUnlimited);
178 ret += NCMLElement::printAttributeIfNotEmpty(
"orgName", _orgName);
185 return ((this->name() == rhs.name()) && (this->getSize() == rhs.getSize()));
189 DimensionElement::name()
const
194 unsigned int DimensionElement::getLengthNumeric()
const
199 unsigned int DimensionElement::getSize()
const
201 return getLengthNumeric();
207 void DimensionElement::parseAndCacheDimension()
213 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
214 "Element " + toString() +
" failed to parse the length attribute into a proper unsigned int!");
218 _dim.isSizeConstant =
true;
220 if (_isShared ==
"true") {
221 _dim.isShared =
true;
223 else if (_isShared ==
"false") {
224 _dim.isShared =
false;
226 else if (!_isShared.empty()) {
227 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
"dimension@isShared did not have value in {true,false}.");
232 void DimensionElement::validateOrThrow()
235 if (!_isShared.empty() || !_isUnlimited.empty() || !_isVariableLength.empty() || !_orgName.empty()) {
236 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
237 "Dimension element " + toString() +
" has unexpected unimplemented attributes. "
238 "This version of the module only handles name, orgName and length.");
239 }
else if(!_length.empty() && !_orgName.empty()){
240 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
241 "Dimension element " + toString() +
" has unexpected attributes orgName or length.");
246 void DimensionElement::parseValidateAndCacheDimension()
249 if (_dim.name.empty()) {
250 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
251 "Dimension element " + toString() +
"Can't have an empty name.");
254 else if (!_isShared.empty() || !_isUnlimited.empty() || !_isVariableLength.empty()) {
255 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
256 "Dimension element " + toString() +
" has unexpected unimplemented attributes. "
257 "This version of the module only handles name, orgName and length.");
260 else if (_length.empty() && _orgName.empty()) {
261 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
262 "Dimension element " + toString() +
" has no expected length value for new dimension or orgName value for renaming.");
265 else if(!_length.empty() && !_orgName.empty()){
266 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
267 "Dimension element " + toString() +
" should not has attributes orgName and length together.");
271 if(!_length.empty()){
275 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
276 "Element " + toString() +
" failed to parse the length attribute into a proper unsigned int!");
281 _dim.isSizeConstant =
true;
283 if (_isShared ==
"true") {
284 _dim.isShared =
true;
286 else if (_isShared ==
"false") {
287 _dim.isShared =
false;
289 else if (!_isShared.empty()) {
290 THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
"dimension@isShared did not have value in {true,false}.");
296 vector<string> DimensionElement::getValidAttributes()
298 vector<string> validAttrs;
299 validAttrs.reserve(10);
300 validAttrs.push_back(
"name");
301 validAttrs.push_back(
"length");
302 validAttrs.push_back(
"isUnlimited");
303 validAttrs.push_back(
"isVariableLength");
304 validAttrs.push_back(
"isShared");
305 validAttrs.push_back(
"orgName");