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_TestForException.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 {;}
00055 
00056 RCP<ParameterList> XMLParameterListReader::toParameterList(
00057   const XMLObject& xml, RCP<DependencySheet> depSheet) const 
00058 {
00059   TEST_FOR_EXCEPTION(
00060     xml.getTag() 
00061     != 
00062     XMLParameterListWriter::getParameterListTagName(), 
00063     BadXMLParameterListRootElementException,
00064     "XMLParameterListReader expected tag " << 
00065     XMLParameterListWriter::getParameterListTagName()
00066     <<", found " << xml.getTag());
00067   RCP<ParameterList> rtn = rcp(new ParameterList);
00068   IDtoValidatorMap validatorIDsMap;
00069   int validatorsIndex = 
00070     xml.findFirstChild(XMLParameterListWriter::getValidatorsTagName());
00071   if(validatorsIndex != -1){
00072     convertValidators(xml.getChild(validatorsIndex), validatorIDsMap);
00073   }
00074   EntryIDsMap entryIDsMap; 
00075   convertParameterList(xml, rtn, entryIDsMap, validatorIDsMap);
00076   
00077   int dependencyIndex = xml.findFirstChild(
00078     XMLParameterListWriter::getDependenciesTagName());
00079   if(dependencyIndex != -1){
00080     convertDependencies(
00081       depSheet, 
00082       xml.getChild(dependencyIndex), 
00083       entryIDsMap,
00084       validatorIDsMap);
00085   }
00086   return rtn;
00087 }
00088 
00089 
00090 ParameterList 
00091 XMLParameterListReader::toParameterList(const XMLObject& xml) const
00092 {
00093   TEST_FOR_EXCEPTION(
00094     xml.getTag() 
00095     != 
00096     XMLParameterListWriter::getParameterListTagName(), 
00097     BadXMLParameterListRootElementException,
00098     "XMLParameterListReader expected tag " << 
00099     XMLParameterListWriter::getParameterListTagName()
00100     <<", found " << xml.getTag());
00101   RCP<ParameterList> rtn = rcp(new ParameterList);
00102   IDtoValidatorMap validatorIDsMap;
00103   int validatorsIndex = 
00104     xml.findFirstChild(XMLParameterListWriter::getValidatorsTagName());
00105   if(validatorsIndex != -1){
00106     convertValidators(xml.getChild(validatorsIndex), validatorIDsMap);
00107   }
00108   EntryIDsMap entryIDsMap; 
00109   convertParameterList(xml, rtn, entryIDsMap, validatorIDsMap);
00110   ParameterList toReturn = ParameterList(*rtn);
00111   return toReturn;
00112 }
00113 
00114 
00115 void XMLParameterListReader::convertValidators(
00116   const XMLObject& xml, IDtoValidatorMap& validatorIDsMap) const
00117 {
00118   std::set<const XMLObject*> validatorsWithPrototypes;
00119   for (int i=0; i<xml.numChildren(); ++i){
00120     if (xml.getChild(i).hasAttribute(
00121       ValidatorXMLConverter::getPrototypeIdAttributeName()))
00122     {
00123       validatorsWithPrototypes.insert(&xml.getChild(i));
00124     }
00125     else{
00126       RCP<ParameterEntryValidator> insertedValidator = 
00127         ValidatorXMLConverterDB::convertXML(
00128           xml.getChild(i), validatorIDsMap);
00129       ParameterEntryValidator::ValidatorID xmlID = 
00130         xml.getChild(i).getRequired<ParameterEntryValidator::ValidatorID>(
00131         ValidatorXMLConverter::getIdAttributeName());
00132       testForDuplicateValidatorIDs(xmlID, validatorIDsMap);
00133       validatorIDsMap.insert(IDtoValidatorMap::IDValidatorPair(
00134        xmlID,
00135        insertedValidator));
00136     }
00137   }
00138 
00139   for (
00140     std::set<const XMLObject*>::const_iterator it = 
00141       validatorsWithPrototypes.begin();
00142     it!=validatorsWithPrototypes.end();
00143     ++it)
00144   {
00145     RCP<ParameterEntryValidator> insertedValidator =
00146       ValidatorXMLConverterDB::convertXML(*(*it), validatorIDsMap);
00147     ParameterEntryValidator::ValidatorID xmlID = 
00148       (*it)->getRequired<ParameterEntryValidator::ValidatorID>(
00149          ValidatorXMLConverter::getIdAttributeName());
00150     testForDuplicateValidatorIDs(xmlID, validatorIDsMap);
00151     validatorIDsMap.insert(IDtoValidatorMap::IDValidatorPair(
00152       xmlID, insertedValidator));
00153   }
00154 }
00155 
00156       
00157 void
00158 XMLParameterListReader::convertParameterList(const XMLObject& xml, 
00159   RCP<ParameterList> parentList,
00160   EntryIDsMap& entryIDsMap, const IDtoValidatorMap& validatorIDsMap) const
00161 {
00162   TEST_FOR_EXCEPTION(
00163     xml.getTag() != XMLParameterListWriter::getParameterListTagName(), 
00164     BadParameterListElementException,
00165     "XMLParameterListReader expected tag " << 
00166     XMLParameterListWriter::getParameterListTagName()
00167     <<", found the tag "
00168     << xml.getTag());
00169         
00170   if(xml.hasAttribute(XMLParameterListWriter::getNameAttributeName())){
00171     parentList->setName(
00172       xml.getRequired(XMLParameterListWriter::getNameAttributeName()));
00173   }
00174 
00175   for (int i=0; i<xml.numChildren(); i++) {
00176 
00177       XMLObject child = xml.getChild(i);
00178       
00179       TEST_FOR_EXCEPTION(
00180         child.getTag() != XMLParameterListWriter::getParameterListTagName() 
00181         &&
00182         child.getTag() != ParameterEntry::getTagName()
00183         &&
00184         child.getTag() != XMLParameterListWriter::getValidatorsTagName()
00185         &&
00186         child.getTag() != XMLParameterListWriter::getDependenciesTagName(),
00187         BadParameterListElementException,
00188         "XMLParameterListReader expected tag "
00189         << XMLParameterListWriter::getParameterListTagName() << " or "
00190         << ParameterEntry::getTagName() << ", but found "
00191         << child.getTag() << " tag.");
00192 
00193 
00194       if(
00195         child.getTag() == XMLParameterListWriter::getParameterListTagName() 
00196         || 
00197         child.getTag() == ParameterEntry::getTagName()
00198         )
00199       {
00200         TEST_FOR_EXCEPTION(
00201           !child.hasAttribute(XMLParameterListWriter::getNameAttributeName()),
00202           NoNameAttributeExecption,
00203           "All child nodes of a ParameterList must have a name attribute!" <<
00204           std::endl << std::endl);
00205 
00206         const std::string& name =
00207           child.getRequired(XMLParameterListWriter::getNameAttributeName());
00208         
00209         if (child.getTag()==XMLParameterListWriter::getParameterListTagName()) {
00210           RCP<ParameterList> newList = sublist(parentList, name);
00211             convertParameterList(child, newList, entryIDsMap, validatorIDsMap);
00212         }
00213         else if (child.getTag() == ParameterEntry::getTagName()) {
00214           parentList->setEntry(
00215             name, ParameterEntryXMLConverterDB::convertXML(child));
00216           if(child.hasAttribute(ValidatorXMLConverter::getIdAttributeName())){
00217             IDtoValidatorMap::const_iterator result = validatorIDsMap.find(
00218               child.getRequired<ParameterEntryValidator::ValidatorID>(
00219                 ValidatorXMLConverter::getIdAttributeName()));
00220             TEST_FOR_EXCEPTION(result == validatorIDsMap.end(), 
00221               MissingValidatorDefinitionException,
00222               "Could not find validator with id: "
00223               << child.getRequired(
00224                 ValidatorXMLConverter::getIdAttributeName())
00225               << std::endl << 
00226               "Bad Parameter: " << name << std::endl << std::endl);
00227             parentList->getEntryRCP(name)->setValidator(result->second);
00228         }  
00229       } 
00230       if(child.hasAttribute(ParameterEntryXMLConverter::getIdAttributeName())){
00231         insertEntryIntoMap(child, parentList->getEntryRCP(name), entryIDsMap);
00232       }
00233     }  
00234   }
00235 }
00236 
00237 void XMLParameterListReader::testForDuplicateValidatorIDs(
00238   ParameterEntryValidator::ValidatorID potentialNewID,
00239   const IDtoValidatorMap& currentMap) const
00240 {
00241   TEST_FOR_EXCEPTION(currentMap.find(potentialNewID) != currentMap.end(),
00242   DuplicateValidatorIDsException,
00243   "Validators with duplicate ids found!" << std::endl <<
00244   "Bad ID: " << potentialNewID);
00245 }
00246 
00247 void XMLParameterListReader::convertDependencies(
00248   RCP<DependencySheet> depSheet, 
00249   const XMLObject& xml, 
00250   const EntryIDsMap& entryIDsMap,
00251   const IDtoValidatorMap& validatorIDsMap) const
00252 {
00253   if(xml.hasAttribute(DependencySheet::getNameAttributeName())){
00254     depSheet->setName(
00255       xml.getAttribute(DependencySheet::getNameAttributeName()));
00256   }
00257   for(int i = 0; i < xml.numChildren(); ++i){
00258     RCP<Dependency> currentDep = DependencyXMLConverterDB::convertXML(
00259       xml.getChild(i), 
00260       entryIDsMap, 
00261       validatorIDsMap);
00262     depSheet->addDependency(currentDep);
00263   }
00264 }
00265 
00266 void XMLParameterListReader::insertEntryIntoMap(
00267   const XMLObject& xmlObj,
00268   RCP<ParameterEntry> entryToInsert,
00269   EntryIDsMap& entryIDsMap) const
00270 {
00271   if(xmlObj.hasAttribute(ParameterEntryXMLConverter::getIdAttributeName()))
00272   {
00273      ParameterEntry::ParameterEntryID xmlID = 
00274        xmlObj.getRequired<ParameterEntry::ParameterEntryID>(
00275           ParameterEntryXMLConverter::getIdAttributeName());
00276      TEST_FOR_EXCEPTION(entryIDsMap.find(xmlID) != entryIDsMap.end(),
00277         DuplicateParameterIDsException,
00278        "Parameters/ParameterList with duplicate ids found!" << std::endl <<
00279        "Bad ID: " << xmlID << std::endl << std::endl);
00280      entryIDsMap.insert(EntryIDsMap::value_type(xmlID, entryToInsert));
00281   }
00282 }
00283 
00284 
00285 } // namespace Teuchos
00286 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines