|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
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
1.7.6.1