Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
Writes an XML object to a parameter list.
static const std::string & getIdAttributeName()
const std::string & getTag() const
Return the tag of the current node.
Maps Validators to integers.
bool getAllowsDuplicateSublists() const
Specifies the current policy regarding duplicated sublists. See setAllowsDuplicateSublists() for more...
A database for DependencyXMLConverters.
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...
ValidatorMap::const_iterator const_iterator
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
static const std::string & getValidatorsTagName()
static const std::string & getPrototypeIdAttributeName()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
Representation of an XML data tree. XMLObject is a ref-counted handle to a XMLObjectImplem object...
static const std::string & getDependenciesTagName()
A database for ValidatorXMLConverters.
Writes a ParameterList to an XML object.
RCP< ParameterList > toParameterList(const XMLObject &xml, RCP< DependencySheet > depSheet) const
A list of parameters of arbitrary type.
static RCP< ParameterEntryValidator > convertXML(const XMLObject &xmlObject, const IDtoValidatorMap &validatorIDsMap)
Given an XMLObject converts the XMLObject to a ParameterEntryValidator and inserts the validator into...
std::map< ParameterEntry::ParameterEntryID, RCP< ParameterEntry > > EntryIDsMap
Convenience typedef.
static ParameterEntry convertXML(const XMLObject &xmlObj)
Converts XML to a ParameterEntry.
Thrown when the root xml tag for a parameter list is incorrect.
std::pair< ParameterEntryValidator::ValidatorID, RCP< ParameterEntryValidator > > IDValidatorPair
int numChildren() const
Return the number of child nodes owned by this node.
Smart reference counting pointer class for automatic garbage collection.
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...
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.
static const std::string & getParameterListTagName()
static const std::string & getNameAttributeName()
static RCP< Dependency > convertXML(const XMLObject &xmlObject, const XMLParameterListReader::EntryIDsMap &entryIDsMap, const IDtoValidatorMap &validatorIDsMap)
Given an XMLObject converts the XMLObject to a Dependency.
const std::string & getRequired(const std::string &name) const
Get an attribute, throwing an std::exception if it is not found.
void insert(IDValidatorPair toInsert)
inserts an IDValidatorPair into the map.
static const std::string & getNameAttributeName()
When serializing to XML, this string should be used as the name of the name attribute.
void setAllowsDuplicateSublists(bool policy)
Set policy regarding duplicated sublists.