bes  Updated for version 3.20.6
RemoveElement.cc
1 // This file is part of the "NcML Module" project, a BES module designed
3 // to allow NcML files to be used to be used as a wrapper to add
4 // AIS to existing datasets of any format.
5 //
6 // Copyright (c) 2009 OPeNDAP, Inc.
7 // Author: Michael Johnson <m.johnson@opendap.org>
8 //
9 // For more information, please also see the main website: http://opendap.org/
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // Please see the files COPYING and COPYRIGHT for more information on the GLPL.
26 //
27 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
29 #include "RemoveElement.h"
30 #include "NCMLDebug.h"
31 #include "NCMLParser.h"
32 #include "NCMLUtil.h"
33 
34 #include "NetcdfElement.h"
35 
36 using namespace libdap;
37 
38 namespace ncml_module {
39 // The element name
40 const string RemoveElement::_sTypeName = "remove";
41 const vector<string> RemoveElement::_sValidAttributes = getValidAttributes();
42 
43 RemoveElement::RemoveElement() :
44  RCObjectInterface(), NCMLElement(0), _name(""), _type("")
45 {
46 }
47 
48 RemoveElement::RemoveElement(const RemoveElement& proto) :
49  RCObjectInterface(), NCMLElement(proto)
50 {
51  _name = proto._name;
52  _type = proto._type;
53 }
54 
55 RemoveElement::~RemoveElement()
56 {
57 }
58 
59 const string&
60 RemoveElement::getTypeName() const
61 {
62  return _sTypeName;
63 }
64 
66 RemoveElement::clone() const
67 {
68  // We rely on the copy ctor here, so make sure it's valid
69  RemoveElement* newElt = new RemoveElement(*this);
70  return newElt;
71 }
72 
73 void RemoveElement::setAttributes(const XMLAttributeMap& attrs)
74 {
75  validateAttributes(attrs, _sValidAttributes);
76 
77  _name = attrs.getValueForLocalNameOrDefault("name");
78  _type = attrs.getValueForLocalNameOrDefault("type");
79 
80  // We do other validation on the actual values later, so no need here.
81 }
82 
83 void RemoveElement::handleBegin()
84 {
85  VALID_PTR(_parser);
86  processRemove(*_parser);
87 }
88 
89 void RemoveElement::handleContent(const string& content)
90 {
91  if (!NCMLUtil::isAllWhitespace(content)) {
92  THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
93  "Got non-whitespace for element content and didn't expect it. "
94  "Element=" + toString() + " content=\"" + content + "\"");
95  }
96 }
97 
98 void RemoveElement::handleEnd()
99 {
100 }
101 
102 string RemoveElement::toString() const
103 {
104  return "<" + _sTypeName + " " + "name=\"" + _name + "\" type=\"" + _type + "\" >";
105 }
106 
109 
110 void RemoveElement::processRemove(NCMLParser& p)
111 {
112  if (!(_type.empty() || _type == "attribute" || _type == "variable" || _type == "dimension")) {
113  THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
114  "Illegal type in remove element: type=" + _type
115  + " This version of the parser can only remove type=\"attribute\", type=\"variable\" or type=\"dimension\".");
116  }
117 
118  if (_type == "attribute") {
119  processRemoveAttribute(p);
120  }
121  else if (_type == "variable") {
122  processRemoveVariable(p);
123  }
124  else if (_type == "dimension") {
125  processRemoveDimension(p);
126  }
127  else {
128  THROW_NCML_INTERNAL_ERROR(
129  toString() + " had type that wasn't attribute, variable or dimension. We shouldn't be calling this if so.");
130  }
131 }
132 
133 void RemoveElement::processRemoveAttribute(NCMLParser& p)
134 {
135  AttrTable::Attr_iter it;
136  bool gotIt = p.findAttribute(_name, it);
137  if (!gotIt) {
138  THROW_NCML_PARSE_ERROR(_parser->getParseLineNumber(),
139  "In remove element, could not find attribute to remove name=" + _name + " at the current scope="
140  + p.getScopeString());
141  }
142 
143  // Nuke it. This call works with containers too, and will recursively delete the children.
144  BESDEBUG("ncml", "Removing attribute name=" << _name << " at scope=" << p.getScopeString() << endl);
145  AttrTable* pTab = p.getCurrentAttrTable();
146  VALID_PTR(pTab);
147  pTab->del_attr(_name);
148 }
149 
150 void RemoveElement::processRemoveVariable(NCMLParser& p)
151 {
152  BESDEBUG("ncml", "Removing variable name=" + _name + " at scope=" + p.getScopeString());
153 
154  // Remove the variable from the current container scope, either the dataset variable list or the current variable container.
155  p.deleteVariableAtCurrentScope(_name);
156 }
157 
158 void RemoveElement::processRemoveDimension(NCMLParser& p)
159 {
160  BESDEBUG("ncml", "Removing dimension name=" + _name + " at scope=" + p.getScopeString() << endl);
161 
162  BaseType* pOrgVar = p.getCurrentVariable();
163  // inside variable remove only dimension with name = _name
164  if(pOrgVar){
165  pOrgVar->set_send_p(true);
166  pOrgVar->set_send_p(true);
167  pOrgVar->read();
168  Array* varArray = dynamic_cast<Array *>(pOrgVar);
169  RemoveElement::removeDimension(varArray, _name);
170  }
171  // outside variable remove all dimensions with name = _name
172  // and remove variable with name = _name
173  else
174  {
175  p.deleteVariableAtCurrentScope(_name);
176  DDS* cDDS = p.getDDSForCurrentDataset();
177  for (DDS::Vars_iter varit = cDDS->var_begin(); varit != cDDS->var_end(); varit++) {
178  Array* varArray = 0;
179  if ((*varit)->type() == dods_array_c){
180  varArray = dynamic_cast<Array *>(*varit);
181  RemoveElement::removeDimension(varArray, _name);
182  }
183  }
184  }
185 }
186 
187 void RemoveElement::removeDimension(Array* arr, string name)
188 {
189  Array::Dim_iter ait;
190  // Loop over dimensions
191  for (ait = arr->dim_begin(); ait != arr->dim_end(); ++ait) {
192  if((*ait).name == name){
193  arr->rename_dim(name, "");
194  }
195  }
196 }
197 
198 vector<string> RemoveElement::getValidAttributes()
199 {
200  vector<string> validAttrs;
201  validAttrs.reserve(2);
202  validAttrs.push_back("name");
203  validAttrs.push_back("type");
204  return validAttrs;
205 }
206 
207 } // ncml_module
ncml_module::NCMLParser
Definition: NCMLParser.h:158
ncml_module::RemoveElement
Definition: RemoveElement.h:40
ncml_module::XMLAttributeMap
Definition: XMLHelpers.h:93
libdap
Definition: BESDapFunctionResponseCache.h:35
ncml_module
NcML Parser for adding/modifying/removing metadata (attributes) to existing local datasets using NcML...
Definition: AggregationElement.cc:72
ncml_module::XMLAttributeMap::getValueForLocalNameOrDefault
const std::string getValueForLocalNameOrDefault(const std::string &localname, const std::string &defVal="") const
Definition: XMLHelpers.cc:181