bes Updated for version 3.20.13
RemoveElement.cc
1
2// 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
36using namespace libdap;
37
38namespace ncml_module {
39// The element name
40const string RemoveElement::_sTypeName = "remove";
41const vector<string> RemoveElement::_sValidAttributes = getValidAttributes();
42
43RemoveElement::RemoveElement() :
44 RCObjectInterface(), NCMLElement(0), _name(""), _type("")
45{
46}
47
48RemoveElement::RemoveElement(const RemoveElement& proto) :
49 RCObjectInterface(), NCMLElement(proto)
50{
51 _name = proto._name;
52 _type = proto._type;
53}
54
55RemoveElement::~RemoveElement()
56{
57}
58
59const string&
60RemoveElement::getTypeName() const
61{
62 return _sTypeName;
63}
64
66RemoveElement::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
73void 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
83void RemoveElement::handleBegin()
84{
85 VALID_PTR(_parser);
86 processRemove(*_parser);
87}
88
89void 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
98void RemoveElement::handleEnd()
99{
100}
101
102string RemoveElement::toString() const
103{
104 return "<" + _sTypeName + " " + "name=\"" + _name + "\" type=\"" + _type + "\" >";
105}
106
109
110void 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
133void 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
150void 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
158void 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
187void 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
198vector<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
const std::string getValueForLocalNameOrDefault(const std::string &localname, const std::string &defVal="") const
Definition: XMLHelpers.cc:181
NcML Parser for adding/modifying/removing metadata (attributes) to existing local datasets using NcML...