|
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 #ifndef Teuchos_OBJECT_BUILDER_H 00043 #define Teuchos_OBJECT_BUILDER_H 00044 00045 #include "Teuchos_ParameterList.hpp" 00046 #include "Teuchos_ParameterListAcceptor.hpp" 00047 #include "Teuchos_AbstractFactoryStd.hpp" 00048 #include "Teuchos_StandardParameterEntryValidators.hpp" 00049 00050 00051 namespace Teuchos { 00052 00053 00088 template<class ObjectType> 00089 class ObjectBuilder : virtual public ParameterListAcceptor 00090 { 00091 public: 00092 00094 ObjectBuilder(); 00095 00097 ~ObjectBuilder(); 00098 00100 void setObjectName( 00101 const std::string &objectName 00102 ); 00103 00105 void setObjectTypeName( 00106 const std::string &objectTypeName 00107 ); 00108 00110 void setObjectFactory( 00111 const RCP<const AbstractFactory<ObjectType> > &objectFactory, 00112 const std::string &objectFactoryName 00113 ); 00114 00118 std::string getObjectName() const; 00119 00124 void setDefaultObject( const std::string &defaultObject_name ); 00125 00127 RCP<ObjectType> create( 00128 const std::string &objectName = "" 00129 ) const; 00130 00133 00135 void setParameterList(const RCP<ParameterList> & paramList); 00136 00138 RCP<ParameterList> getNonconstParameterList(); 00139 00141 RCP<ParameterList> unsetParameterList(); 00142 00144 RCP<const ParameterList> getParameterList() const; 00145 00147 RCP<const ParameterList> getValidParameters() const; 00148 00150 00151 private: 00152 00153 // ////////////////////////////////////// 00154 // Private types 00155 00156 typedef RCP<const AbstractFactory<ObjectType > > object_fcty_t; 00157 00158 // ////////////////////////////////////// 00159 // Private data members 00160 00161 RCP<ParameterList> paramList_; 00162 mutable RCP<const ParameterList> validParamList_; 00163 mutable RCP<const StringToIntegralParameterEntryValidator<int> > objectValidator_; 00164 00165 std::string object_name_; 00166 std::string objectType_name_; 00167 00168 Array<std::string> validObjectNames_; 00169 Array<object_fcty_t> objectArray_; 00170 std::string defaultObject_name_; 00171 00172 // ////////////////////////////////////// 00173 // Private member functions 00174 00175 void initializeDefaults_(); 00176 00177 }; 00178 00179 00180 // Nonmember constructors 00181 00182 00183 template<class ObjectType> 00184 RCP<ObjectBuilder<ObjectType> > objectBuilder() 00185 { 00186 RCP<ObjectBuilder<ObjectType> > ob = rcp(new ObjectBuilder<ObjectType>() ); 00187 return ob; 00188 } 00189 00190 00191 template<class ObjectType> 00192 RCP<ObjectBuilder<ObjectType> > 00193 objectBuilder(const std::string& objectName, const std::string& objectTypeName) 00194 { 00195 RCP<ObjectBuilder<ObjectType> > ob = rcp(new ObjectBuilder<ObjectType>() ); 00196 ob->setObjectName(objectName); 00197 ob->setObjectTypeName(objectTypeName); 00198 return ob; 00199 } 00200 00201 00202 // 00203 // Implementation 00204 // 00205 00206 00207 template<class ObjectType> 00208 ObjectBuilder<ObjectType>::ObjectBuilder() 00209 { 00210 this->initializeDefaults_(); 00211 } 00212 00213 00214 template<class ObjectType> 00215 ObjectBuilder<ObjectType>::~ObjectBuilder() 00216 { 00217 #ifdef TEUCHOS_DEBUG 00218 // Validate that we read the parameters correctly! 00219 if(!is_null(paramList_)) { 00220 paramList_->validateParameters(*this->getValidParameters()); 00221 } 00222 #endif 00223 } 00224 00225 00226 template<class ObjectType> 00227 void ObjectBuilder<ObjectType>::setObjectFactory( 00228 const RCP<const AbstractFactory<ObjectType > > &objectFactory, 00229 const std::string &objectName 00230 ) 00231 { 00232 TEUCHOS_TEST_FOR_EXCEPT( objectName.length() == 0 ); 00233 validObjectNames_.push_back(objectName); 00234 objectArray_.push_back(objectFactory); 00235 defaultObject_name_ = objectName; 00236 validParamList_ = null; 00237 #ifdef TEUCHOS_DEBUG 00238 this->getValidParameters(); 00239 #endif // TEUCHOS_DEBUG 00240 } 00241 00242 00243 template<class ObjectType> 00244 std::string 00245 ObjectBuilder<ObjectType>::getObjectName() const 00246 { 00247 if(is_null(validParamList_)) { 00248 this->getValidParameters(); 00249 } 00250 // If the user has not specified a ParameterList, then use the ValidParameterList. 00251 RCP<ParameterList> pl = null; 00252 if (!is_null(paramList_)) { 00253 pl = paramList_; 00254 } else { 00255 pl = parameterList(); 00256 pl->setParameters(*this->getValidParameters()); 00257 } 00258 return objectValidator_->getStringValue(*pl, objectType_name_, defaultObject_name_); 00259 } 00260 00261 00262 template<class ObjectType> 00263 void ObjectBuilder<ObjectType>::setParameterList( 00264 RCP<ParameterList> const& paramList 00265 ) 00266 { 00267 if (!is_null(paramList)) { 00268 paramList->validateParameters(*this->getValidParameters()); 00269 paramList_ = paramList; 00270 } 00271 } 00272 00273 00274 template<class ObjectType> 00275 RCP<ParameterList> 00276 ObjectBuilder<ObjectType>::getNonconstParameterList() 00277 { 00278 return paramList_; 00279 } 00280 00281 00282 template<class ObjectType> 00283 RCP<ParameterList> 00284 ObjectBuilder<ObjectType>::unsetParameterList() 00285 { 00286 #ifdef TEUCHOS_DEBUG 00287 // Validate that we read the parameters correctly! 00288 if(!is_null(paramList_)) 00289 paramList_->validateParameters(*this->getValidParameters()); 00290 #endif 00291 RCP<ParameterList> _paramList = paramList_; 00292 paramList_ = null; 00293 return _paramList; 00294 } 00295 00296 00297 template<class ObjectType> 00298 RCP<const ParameterList> 00299 ObjectBuilder<ObjectType>::getParameterList() const 00300 { 00301 return paramList_; 00302 } 00303 00304 00305 template<class ObjectType> 00306 RCP<const ParameterList> 00307 ObjectBuilder<ObjectType>::getValidParameters() const 00308 { 00309 if(!validParamList_.get()) { 00310 RCP<ParameterList> validParamList = parameterList(); 00311 // Object Types 00312 objectValidator_ = rcp( 00313 new StringToIntegralParameterEntryValidator<int>( 00314 validObjectNames_, objectType_name_ 00315 ) 00316 ); 00317 objectValidator_->validateString(defaultObject_name_,objectType_name_); 00318 validParamList->set( 00319 objectType_name_, defaultObject_name_, 00320 (std::string("Determines the type of " + object_name_ + " object that will be built.\n") 00321 + "The parameters for each " + objectType_name_ + " are specified in this sublist" 00322 ).c_str(), 00323 objectValidator_ 00324 ); 00325 for( int i = 0; i < static_cast<int>(objectArray_.size()); ++i ) { 00326 const std::string 00327 &sname = validObjectNames_[i+1]; 00328 const RCP<ObjectType > 00329 object = objectArray_[i]->create(); 00330 validParamList->sublist(sname).setParameters( 00331 *object->getValidParameters()).disableRecursiveValidation(); 00332 } 00333 validParamList_ = validParamList; 00334 } 00335 return validParamList_; 00336 } 00337 00338 template<class ObjectType> 00339 void ObjectBuilder<ObjectType>::setDefaultObject( 00340 const std::string &defaultObject_name 00341 ) 00342 { 00343 #ifdef TEUCHOS_DEBUG 00344 if (is_null(validParamList_)) { // We need the objectValidator_ 00345 this->getValidParameters(); 00346 } 00347 objectValidator_->validateString(defaultObject_name,objectType_name_); 00348 #endif // TEUCHOS_DEBUG 00349 defaultObject_name_ = defaultObject_name; 00350 // This is necessary to change the default in the valid parameter list 00351 validParamList_ = null; 00352 } 00353 00354 template<class ObjectType> 00355 RCP<ObjectType > 00356 ObjectBuilder<ObjectType>::create( 00357 const std::string &objectName 00358 ) const 00359 { 00360 if (is_null(validParamList_)) { // We need the objectValidator_ 00361 this->getValidParameters(); 00362 } 00363 const std::string 00364 sname = ( objectName.length() 00365 ? objectName 00366 : this->getObjectName() ); 00367 RCP<ObjectType> object = null; 00368 // Get the index of this object factory (this will validate!) 00369 const int 00370 s_idx = objectValidator_->getIntegralValue(sname, objectType_name_); 00371 if (s_idx != 0) { 00372 // Create the uninitialized object 00373 object = objectArray_[s_idx-1]->create(); 00374 TEUCHOS_TEST_FOR_EXCEPTION( is_null(object), std::logic_error, 00375 (std::string("Error! ObjectBuilder attempted to create an object of type ") 00376 + validObjectNames_[s_idx] + " and it came back as a null RCP!").c_str() 00377 ); 00378 // Allow the user to not set a parameterlist (this requires copying the 00379 // parameters in the valid parameter list into a new parameter list: 00380 RCP<ParameterList> pl = null; 00381 if (is_null(paramList_)) { 00382 pl = parameterList(); 00383 pl->setParameters(this->getValidParameters()->sublist(sname)); 00384 } else { 00385 #ifdef TEUCHOS_DEBUG 00386 // We're validating the parameter list here again because we're storing a 00387 // pointer to it and the user could have changed it. 00388 paramList_->validateParameters(*this->getValidParameters()); 00389 #endif // TEUCHOS_DEBUG 00390 pl = sublist(paramList_,sname); 00391 } 00392 // Now set the parameters for the object 00393 object->setParameterList(pl); 00394 } 00395 return object; 00396 } 00397 00398 00399 template<class ObjectType> 00400 void ObjectBuilder<ObjectType>::setObjectName( 00401 const std::string &objectName 00402 ) 00403 { 00404 TEUCHOS_TEST_FOR_EXCEPT(objectName.length() == 0); 00405 object_name_ = objectName; 00406 validParamList_ = null; 00407 } 00408 00409 00410 template<class ObjectType> 00411 void ObjectBuilder<ObjectType>::setObjectTypeName( 00412 const std::string &objectTypeName 00413 ) 00414 { 00415 TEUCHOS_TEST_FOR_EXCEPT(objectTypeName.length() == 0); 00416 objectType_name_ = objectTypeName; 00417 validParamList_ = null; 00418 } 00419 00420 00421 template<class ObjectType> 00422 void ObjectBuilder<ObjectType>::initializeDefaults_() 00423 { 00424 00425 object_name_ = "Object"; 00426 objectType_name_ = "Object Type"; 00427 00428 defaultObject_name_ = "None"; 00429 validObjectNames_.resize(0); 00430 validObjectNames_.push_back(defaultObject_name_); 00431 00432 } 00433 00434 00435 } // namespace Teuchos 00436 00437 00438 #endif //Teuchos_OBJECT_BUILDER_H
1.7.6.1