Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_XMLParameterListReader.cpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
44 #include "Teuchos_Assert.hpp"
45 #include "Teuchos_ParameterEntryXMLConverterDB.hpp"
48 
49 
50 namespace Teuchos {
51 
52 
54 : _allowDuplicateSublists(true)
55 {;}
56 
58 { return _allowDuplicateSublists; }
59 
61 { _allowDuplicateSublists = policy; }
62 
64  const XMLObject& xml, RCP<DependencySheet> depSheet) const
65 {
67  xml.getTag()
68  !=
71  "XMLParameterListReader expected tag " <<
73  <<", found " << xml.getTag());
75  IDtoValidatorMap validatorIDsMap;
76  int validatorsIndex =
78  if(validatorsIndex != -1){
79  convertValidators(xml.getChild(validatorsIndex), validatorIDsMap);
80  }
81  EntryIDsMap entryIDsMap;
82  convertParameterList(xml, rtn, entryIDsMap, validatorIDsMap);
83 
84  int dependencyIndex = xml.findFirstChild(
86  if(dependencyIndex != -1){
87  convertDependencies(
88  depSheet,
89  xml.getChild(dependencyIndex),
90  entryIDsMap,
91  validatorIDsMap);
92  }
93  return rtn;
94 }
95 
96 
99 {
101  xml.getTag()
102  !=
105  "XMLParameterListReader expected tag " <<
107  <<", found " << xml.getTag());
109  IDtoValidatorMap validatorIDsMap;
110  int validatorsIndex =
112  if(validatorsIndex != -1){
113  convertValidators(xml.getChild(validatorsIndex), validatorIDsMap);
114  }
115  EntryIDsMap entryIDsMap;
116  convertParameterList(xml, rtn, entryIDsMap, validatorIDsMap);
117  ParameterList toReturn = ParameterList(*rtn);
118  return toReturn;
119 }
120 
121 
122 void XMLParameterListReader::convertValidators(
123  const XMLObject& xml, IDtoValidatorMap& validatorIDsMap) const
124 {
125  std::set<const XMLObject*> validatorsWithPrototypes;
126  for (int i=0; i<xml.numChildren(); ++i){
127  if (xml.getChild(i).hasAttribute(
129  {
130  validatorsWithPrototypes.insert(&xml.getChild(i));
131  }
132  else{
133  RCP<ParameterEntryValidator> insertedValidator =
135  xml.getChild(i), validatorIDsMap);
139  testForDuplicateValidatorIDs(xmlID, validatorIDsMap);
141  xmlID,
142  insertedValidator));
143  }
144  }
145 
146  for (
147  std::set<const XMLObject*>::const_iterator it =
148  validatorsWithPrototypes.begin();
149  it!=validatorsWithPrototypes.end();
150  ++it)
151  {
152  RCP<ParameterEntryValidator> insertedValidator =
153  ValidatorXMLConverterDB::convertXML(*(*it), validatorIDsMap);
155  (*it)->getRequired<ParameterEntryValidator::ValidatorID>(
157  testForDuplicateValidatorIDs(xmlID, validatorIDsMap);
159  xmlID, insertedValidator));
160  }
161 }
162 
163 
164 void
165 XMLParameterListReader::convertParameterList(const XMLObject& xml,
166  RCP<ParameterList> parentList,
167  EntryIDsMap& entryIDsMap, const IDtoValidatorMap& validatorIDsMap) const
168 {
171  BadParameterListElementException,
172  "XMLParameterListReader expected tag " <<
174  <<", found the tag "
175  << xml.getTag());
176 
177  if(xml.hasAttribute(XMLParameterListWriter::getNameAttributeName())){
178  parentList->setName(
180  }
181 
182  for (int i=0; i<xml.numChildren(); i++) {
183 
184  XMLObject child = xml.getChild(i);
185 
188  &&
189  child.getTag() != ParameterEntry::getTagName()
190  &&
192  &&
194  BadParameterListElementException,
195  "XMLParameterListReader expected tag "
197  << ParameterEntry::getTagName() << ", but found "
198  << child.getTag() << " tag.");
199 
200 
201  if(
203  ||
204  child.getTag() == ParameterEntry::getTagName()
205  )
206  {
207 
208  std::string name;
209  if (child.getTag()==XMLParameterListWriter::getParameterListTagName()) {
210  if ( child.hasAttribute(XMLParameterListWriter::getNameAttributeName()) ) {
211  name = child.getRequired(XMLParameterListWriter::getNameAttributeName());
212  }
213  else {
214  // the name needs to be unique: generate one
215  std::ostringstream ss;
216  ss << "child" << i;
217  name = ss.str();
218  }
220  _allowDuplicateSublists == false
221  &&
222  parentList->isSublist(name) == true,
223  DuplicateParameterSublist,
224  "XMLParameterListReader encountered duplicate sublist \"" << name << "\", in violation"
225  << " of the policy specified by XMLParameterListReader::setAllowsDuplicateSublists()." );
226  RCP<ParameterList> newList = sublist(parentList, name);
227  convertParameterList(child, newList, entryIDsMap, validatorIDsMap);
228  }
229  else if (child.getTag() == ParameterEntry::getTagName()) {
231  !child.hasAttribute(XMLParameterListWriter::getNameAttributeName()),
232  NoNameAttributeExecption,
233  "All child nodes of a ParameterList must have a name attribute!" <<
234  std::endl << std::endl);
235  name = child.getRequired(XMLParameterListWriter::getNameAttributeName());
236  parentList->setEntry(
238  if(child.hasAttribute(ValidatorXMLConverter::getIdAttributeName())){
239  IDtoValidatorMap::const_iterator result = validatorIDsMap.find(
240  child.getRequired<ParameterEntryValidator::ValidatorID>(
242  TEUCHOS_TEST_FOR_EXCEPTION(result == validatorIDsMap.end(),
243  MissingValidatorDefinitionException,
244  "Could not find validator with id: "
245  << child.getRequired(
247  << std::endl <<
248  "Bad Parameter: " << name << std::endl << std::endl);
249  parentList->getEntryRCP(name)->setValidator(result->second);
250  }
251  }
252  if(child.hasAttribute(ParameterEntryXMLConverter::getIdAttributeName())){
253  insertEntryIntoMap(child, parentList->getEntryRCP(name), entryIDsMap);
254  }
255  }
256  }
257 }
258 
259 void XMLParameterListReader::testForDuplicateValidatorIDs(
261  const IDtoValidatorMap& currentMap) const
262 {
263  TEUCHOS_TEST_FOR_EXCEPTION(currentMap.find(potentialNewID) != currentMap.end(),
264  DuplicateValidatorIDsException,
265  "Validators with duplicate ids found!" << std::endl <<
266  "Bad ID: " << potentialNewID);
267 }
268 
269 void XMLParameterListReader::convertDependencies(
270  RCP<DependencySheet> depSheet,
271  const XMLObject& xml,
272  const EntryIDsMap& entryIDsMap,
273  const IDtoValidatorMap& validatorIDsMap) const
274 {
275  if(xml.hasAttribute(DependencySheet::getNameAttributeName())){
276  depSheet->setName(
277  xml.getAttribute(DependencySheet::getNameAttributeName()));
278  }
279  for(int i = 0; i < xml.numChildren(); ++i){
280  RCP<Dependency> currentDep = DependencyXMLConverterDB::convertXML(
281  xml.getChild(i),
282  entryIDsMap,
283  validatorIDsMap);
284  depSheet->addDependency(currentDep);
285  }
286 }
287 
288 void XMLParameterListReader::insertEntryIntoMap(
289  const XMLObject& xmlObj,
290  RCP<ParameterEntry> entryToInsert,
291  EntryIDsMap& entryIDsMap) const
292 {
293  if(xmlObj.hasAttribute(ParameterEntryXMLConverter::getIdAttributeName()))
294  {
296  xmlObj.getRequired<ParameterEntry::ParameterEntryID>(
298  TEUCHOS_TEST_FOR_EXCEPTION(entryIDsMap.find(xmlID) != entryIDsMap.end(),
299  DuplicateParameterIDsException,
300  "Parameters/ParameterList with duplicate ids found!" << std::endl <<
301  "Bad ID: " << xmlID << std::endl << std::endl);
302  entryIDsMap.insert(EntryIDsMap::value_type(xmlID, entryToInsert));
303  }
304 }
305 
306 
307 } // namespace Teuchos
308 
A database for DependencyXMLConverters.
A database for ValidatorXMLConverters.
Writes an XML object to a parameter list.
Writes a ParameterList to an XML object.
Thrown when the root xml tag for a parameter list is incorrect.
static const std::string & getNameAttributeName()
When serializing to XML, this string should be used as the name of the name attribute.
static RCP< Dependency > convertXML(const XMLObject &xmlObject, const XMLParameterListReader::EntryIDsMap &entryIDsMap, const IDtoValidatorMap &validatorIDsMap)
Given an XMLObject converts the XMLObject to a Dependency.
Maps Validators to integers.
ValidatorMap::const_iterator const_iterator
std::pair< ParameterEntryValidator::ValidatorID, RCP< ParameterEntryValidator > > IDValidatorPair
void insert(IDValidatorPair toInsert)
inserts an IDValidatorPair into the map.
static ParameterEntry convertXML(const XMLObject &xmlObj)
Converts XML to a ParameterEntry.
static const std::string & getTagName()
Get the string that should be used as the tag name for all parameters when they are serialized to xml...
A list of parameters of arbitrary type.
Smart reference counting pointer class for automatic garbage collection.
static RCP< ParameterEntryValidator > convertXML(const XMLObject &xmlObject, const IDtoValidatorMap &validatorIDsMap)
Given an XMLObject converts the XMLObject to a ParameterEntryValidator and inserts the validator into...
static const std::string & getPrototypeIdAttributeName()
static const std::string & getIdAttributeName()
Representation of an XML data tree. XMLObject is a ref-counted handle to a XMLObjectImplem object,...
const std::string & getRequired(const std::string &name) const
Get an attribute, throwing an std::exception if it is not found.
const std::string & getTag() const
Return the tag of the current node.
const XMLObject & getChild(int i) const
Return the i-th child node.
bool hasAttribute(const std::string &name) const
Find out if the current node has an attribute of the specified name.
int findFirstChild(std::string tagName) const
Returns the index of the first child found with the given tag name. Returns -1 if no child is found.
int numChildren() const
Return the number of child nodes owned by this node.
bool getAllowsDuplicateSublists() const
Specifies the current policy regarding duplicated sublists. See setAllowsDuplicateSublists() for more...
void setAllowsDuplicateSublists(bool policy)
Set policy regarding duplicated sublists.
RCP< ParameterList > toParameterList(const XMLObject &xml, RCP< DependencySheet > depSheet) const
std::map< ParameterEntry::ParameterEntryID, RCP< ParameterEntry > > EntryIDsMap
Convenience typedef.
static const std::string & getParameterListTagName()
static const std::string & getValidatorsTagName()
static const std::string & getDependenciesTagName()
static const std::string & getNameAttributeName()
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.