Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Teuchos_XMLParameterListReader.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_XMLParameterListReader.hpp"
00043 #include "Teuchos_XMLParameterListWriter.hpp"
00044 #include "Teuchos_Assert.hpp"
00045 #include "Teuchos_ParameterEntryXMLConverterDB.hpp"
00046 #include "Teuchos_ValidatorXMLConverterDB.hpp"
00047 #include "Teuchos_DependencyXMLConverterDB.hpp"
00048 
00049 
00050 namespace Teuchos {
00051 
00052 
00053 XMLParameterListReader::XMLParameterListReader()
00054 : _allowDuplicateSublists(true)
00055 {;}
00056 
00057 bool XMLParameterListReader::getAllowsDuplicateSublists() const
00058 { return _allowDuplicateSublists; }
00059 
00060 void XMLParameterListReader::setAllowsDuplicateSublists(bool policy) 
00061 { _allowDuplicateSublists = policy; }
00062 
00063 RCP<ParameterList> XMLParameterListReader::toParameterList(
00064   const XMLObject& xml, RCP<DependencySheet> depSheet) const 
00065 {
00066   TEUCHOS_TEST_FOR_EXCEPTION(
00067     xml.getTag() 
00068     != 
00069     XMLParameterListWriter::getParameterListTagName(), 
00070     BadXMLParameterListRootElementException,
00071     "XMLParameterListReader expected tag " << 
00072     XMLParameterListWriter::getParameterListTagName()
00073     <<", found " << xml.getTag());
00074   RCP<ParameterList> rtn = rcp(new ParameterList);
00075   IDtoValidatorMap validatorIDsMap;
00076   int validatorsIndex = 
00077     xml.findFirstChild(XMLParameterListWriter::getValidatorsTagName());
00078   if(validatorsIndex != -1){
00079     convertValidators(xml.getChild(validatorsIndex), validatorIDsMap);
00080   }
00081   EntryIDsMap entryIDsMap; 
00082   convertParameterList(xml, rtn, entryIDsMap, validatorIDsMap);
00083   
00084   int dependencyIndex = xml.findFirstChild(
00085     XMLParameterListWriter::getDependenciesTagName());
00086   if(dependencyIndex != -1){
00087     convertDependencies(
00088       depSheet, 
00089       xml.getChild(dependencyIndex), 
00090       entryIDsMap,
00091       validatorIDsMap);
00092   }
00093   return rtn;
00094 }
00095 
00096 
00097 ParameterList 
00098 XMLParameterListReader::toParameterList(const XMLObject& xml) const
00099 {
00100   TEUCHOS_TEST_FOR_EXCEPTION(
00101     xml.getTag() 
00102     != 
00103     XMLParameterListWriter::getParameterListTagName(), 
00104     BadXMLParameterListRootElementException,
00105     "XMLParameterListReader expected tag " << 
00106     XMLParameterListWriter::getParameterListTagName()
00107     <<", found " << xml.getTag());
00108   RCP<ParameterList> rtn = rcp(new ParameterList);
00109   IDtoValidatorMap validatorIDsMap;
00110   int validatorsIndex = 
00111     xml.findFirstChild(XMLParameterListWriter::getValidatorsTagName());
00112   if(validatorsIndex != -1){
00113     convertValidators(xml.getChild(validatorsIndex), validatorIDsMap);
00114   }
00115   EntryIDsMap entryIDsMap; 
00116   convertParameterList(xml, rtn, entryIDsMap, validatorIDsMap);
00117   ParameterList toReturn = ParameterList(*rtn);
00118   return toReturn;
00119 }
00120 
00121 
00122 void XMLParameterListReader::convertValidators(
00123   const XMLObject& xml, IDtoValidatorMap& validatorIDsMap) const
00124 {
00125   std::set<const XMLObject*> validatorsWithPrototypes;
00126   for (int i=0; i<xml.numChildren(); ++i){
00127     if (xml.getChild(i).hasAttribute(
00128       ValidatorXMLConverter::getPrototypeIdAttributeName()))
00129     {
00130       validatorsWithPrototypes.insert(&xml.getChild(i));
00131     }
00132     else{
00133       RCP<ParameterEntryValidator> insertedValidator = 
00134         ValidatorXMLConverterDB::convertXML(
00135           xml.getChild(i), validatorIDsMap);
00136       ParameterEntryValidator::ValidatorID xmlID = 
00137         xml.getChild(i).getRequired<ParameterEntryValidator::ValidatorID>(
00138         ValidatorXMLConverter::getIdAttributeName());
00139       testForDuplicateValidatorIDs(xmlID, validatorIDsMap);
00140       validatorIDsMap.insert(IDtoValidatorMap::IDValidatorPair(
00141        xmlID,
00142        insertedValidator));
00143     }
00144   }
00145 
00146   for (
00147     std::set<const XMLObject*>::const_iterator it = 
00148       validatorsWithPrototypes.begin();
00149     it!=validatorsWithPrototypes.end();
00150     ++it)
00151   {
00152     RCP<ParameterEntryValidator> insertedValidator =
00153       ValidatorXMLConverterDB::convertXML(*(*it), validatorIDsMap);
00154     ParameterEntryValidator::ValidatorID xmlID = 
00155       (*it)->getRequired<ParameterEntryValidator::ValidatorID>(
00156          ValidatorXMLConverter::getIdAttributeName());
00157     testForDuplicateValidatorIDs(xmlID, validatorIDsMap);
00158     validatorIDsMap.insert(IDtoValidatorMap::IDValidatorPair(
00159       xmlID, insertedValidator));
00160   }
00161 }
00162 
00163       
00164 void
00165 XMLParameterListReader::convertParameterList(const XMLObject& xml, 
00166   RCP<ParameterList> parentList,
00167   EntryIDsMap& entryIDsMap, const IDtoValidatorMap& validatorIDsMap) const
00168 {
00169   TEUCHOS_TEST_FOR_EXCEPTION(
00170     xml.getTag() != XMLParameterListWriter::getParameterListTagName(), 
00171     BadParameterListElementException,
00172     "XMLParameterListReader expected tag " << 
00173     XMLParameterListWriter::getParameterListTagName()
00174     <<", found the tag "
00175     << xml.getTag());
00176         
00177   if(xml.hasAttribute(XMLParameterListWriter::getNameAttributeName())){
00178     parentList->setName(
00179       xml.getRequired(XMLParameterListWriter::getNameAttributeName()));
00180   }
00181 
00182   for (int i=0; i<xml.numChildren(); i++) {
00183 
00184       XMLObject child = xml.getChild(i);
00185       
00186       TEUCHOS_TEST_FOR_EXCEPTION(
00187         child.getTag() != XMLParameterListWriter::getParameterListTagName() 
00188         &&
00189         child.getTag() != ParameterEntry::getTagName()
00190         &&
00191         child.getTag() != XMLParameterListWriter::getValidatorsTagName()
00192         &&
00193         child.getTag() != XMLParameterListWriter::getDependenciesTagName(),
00194         BadParameterListElementException,
00195         "XMLParameterListReader expected tag "
00196         << XMLParameterListWriter::getParameterListTagName() << " or "
00197         << ParameterEntry::getTagName() << ", but found "
00198         << child.getTag() << " tag.");
00199 
00200 
00201       if(
00202         child.getTag() == XMLParameterListWriter::getParameterListTagName() 
00203         || 
00204         child.getTag() == ParameterEntry::getTagName()
00205         )
00206       {
00207         
00208         std::string name;
00209         if (child.getTag()==XMLParameterListWriter::getParameterListTagName()) {
00210           if ( child.hasAttribute(XMLParameterListWriter::getNameAttributeName()) ) {
00211             name = child.getRequired(XMLParameterListWriter::getNameAttributeName());
00212           }
00213           else {
00214             // the name needs to be unique: generate one
00215             std::ostringstream ss;
00216             ss << "child" << i;
00217             name = ss.str();
00218           }
00219           TEUCHOS_TEST_FOR_EXCEPTION( 
00220             _allowDuplicateSublists == false
00221             &&
00222             parentList->isSublist(name) == true, 
00223             DuplicateParameterSublist,
00224             "XMLParameterListReader encountered duplicate sublist \"" << name << "\", in violation"
00225             << " of the policy specified by XMLParameterListReader::setAllowsDuplicateSublists()." );
00226           RCP<ParameterList> newList = sublist(parentList, name);
00227           convertParameterList(child, newList, entryIDsMap, validatorIDsMap);
00228         }
00229         else if (child.getTag() == ParameterEntry::getTagName()) {
00230           TEUCHOS_TEST_FOR_EXCEPTION(
00231               !child.hasAttribute(XMLParameterListWriter::getNameAttributeName()),
00232               NoNameAttributeExecption,
00233               "All child nodes of a ParameterList must have a name attribute!" <<
00234               std::endl << std::endl);
00235           name = child.getRequired(XMLParameterListWriter::getNameAttributeName());
00236           parentList->setEntry(
00237             name, ParameterEntryXMLConverterDB::convertXML(child));
00238           if(child.hasAttribute(ValidatorXMLConverter::getIdAttributeName())){
00239             IDtoValidatorMap::const_iterator result = validatorIDsMap.find(
00240               child.getRequired<ParameterEntryValidator::ValidatorID>(
00241                 ValidatorXMLConverter::getIdAttributeName()));
00242             TEUCHOS_TEST_FOR_EXCEPTION(result == validatorIDsMap.end(), 
00243               MissingValidatorDefinitionException,
00244               "Could not find validator with id: "
00245               << child.getRequired(
00246                 ValidatorXMLConverter::getIdAttributeName())
00247               << std::endl << 
00248               "Bad Parameter: " << name << std::endl << std::endl);
00249             parentList->getEntryRCP(name)->setValidator(result->second);
00250         }  
00251       } 
00252       if(child.hasAttribute(ParameterEntryXMLConverter::getIdAttributeName())){
00253         insertEntryIntoMap(child, parentList->getEntryRCP(name), entryIDsMap);
00254       }
00255     }  
00256   }
00257 }
00258 
00259 void XMLParameterListReader::testForDuplicateValidatorIDs(
00260   ParameterEntryValidator::ValidatorID potentialNewID,
00261   const IDtoValidatorMap& currentMap) const
00262 {
00263   TEUCHOS_TEST_FOR_EXCEPTION(currentMap.find(potentialNewID) != currentMap.end(),
00264   DuplicateValidatorIDsException,
00265   "Validators with duplicate ids found!" << std::endl <<
00266   "Bad ID: " << potentialNewID);
00267 }
00268 
00269 void XMLParameterListReader::convertDependencies(
00270   RCP<DependencySheet> depSheet, 
00271   const XMLObject& xml, 
00272   const EntryIDsMap& entryIDsMap,
00273   const IDtoValidatorMap& validatorIDsMap) const
00274 {
00275   if(xml.hasAttribute(DependencySheet::getNameAttributeName())){
00276     depSheet->setName(
00277       xml.getAttribute(DependencySheet::getNameAttributeName()));
00278   }
00279   for(int i = 0; i < xml.numChildren(); ++i){
00280     RCP<Dependency> currentDep = DependencyXMLConverterDB::convertXML(
00281       xml.getChild(i), 
00282       entryIDsMap, 
00283       validatorIDsMap);
00284     depSheet->addDependency(currentDep);
00285   }
00286 }
00287 
00288 void XMLParameterListReader::insertEntryIntoMap(
00289   const XMLObject& xmlObj,
00290   RCP<ParameterEntry> entryToInsert,
00291   EntryIDsMap& entryIDsMap) const
00292 {
00293   if(xmlObj.hasAttribute(ParameterEntryXMLConverter::getIdAttributeName()))
00294   {
00295      ParameterEntry::ParameterEntryID xmlID = 
00296        xmlObj.getRequired<ParameterEntry::ParameterEntryID>(
00297           ParameterEntryXMLConverter::getIdAttributeName());
00298      TEUCHOS_TEST_FOR_EXCEPTION(entryIDsMap.find(xmlID) != entryIDsMap.end(),
00299         DuplicateParameterIDsException,
00300        "Parameters/ParameterList with duplicate ids found!" << std::endl <<
00301        "Bad ID: " << xmlID << std::endl << std::endl);
00302      entryIDsMap.insert(EntryIDsMap::value_type(xmlID, entryToInsert));
00303   }
00304 }
00305 
00306 
00307 } // namespace Teuchos
00308 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines