Teuchos_ObjectBuilder.hpp

Go to the documentation of this file.
00001 //@HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Teuchos Package
00005 //                 Copyright (2006) 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 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Todd S. Coffey (tscoffe@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 //@HEADER
00028 
00029 #ifndef Teuchos_OBJECT_BUILDER_H
00030 #define Teuchos_OBJECT_BUILDER_H
00031 
00032 #include "Teuchos_ParameterList.hpp"
00033 #include "Teuchos_ParameterListAcceptor.hpp"
00034 #include "Teuchos_AbstractFactoryStd.hpp"
00035 #include "Teuchos_StandardParameterEntryValidators.hpp"
00036 
00037 // 03/03/09 Todd Coffey <tscoffe@sandia.gov>:
00038 // This is a generic builder class that provides a validated parameter list and
00039 // can build anything that can be constructed with a default constructor and
00040 // accepts a parameter list through setParameterList (e.g. it derives from
00041 // ParameterListAcceptor).
00042 // Note the following:
00043 // * The default object name is "Object" (this can be changed through setObjectName)
00044 // * The default object type name is "Object Type" (this can be changed through setObjectTypeName)
00045 // * The valid parameter list has a parameter named "Object Type" with a default value of "None"
00046 // * The builder will create a null RCP if no factories have been set on it with setObjectFactory
00047 // * A parameter list need not be set on the builder to call create, it will
00048 // simply create the default factory which is either "None" if no factories
00049 // have been set or it will be the last factory that was set.  
00050 // * Setting a parameter list on the builder allows you to specify which object
00051 // will be created by default.
00052 
00053 
00054 namespace Teuchos {
00055 
00056 template<class ObjectType>
00057 class ObjectBuilder : virtual public ParameterListAcceptor
00058 {
00059 public:
00060 
00062   ObjectBuilder();
00063 
00065   ~ObjectBuilder();
00066 
00068   void setObjectName(
00069       const std::string &objectName
00070       );
00071 
00073   void setObjectTypeName(
00074       const std::string &objectTypeName
00075       );
00076 
00078   void setObjectFactory(
00079     const RCP<const AbstractFactory<ObjectType> > &objectFactory,
00080     const std::string &objectFactoryName
00081     );
00082 
00086   std::string getObjectName() const;
00087 
00092   void setDefaultObject( const std::string &defaultObject_name );
00093 
00095   RCP<ObjectType> create(
00096     const std::string &objectName = ""
00097     ) const;
00098   
00101 
00103   void setParameterList(const RCP<ParameterList> & paramList);
00104   
00106   RCP<ParameterList> getNonconstParameterList();
00107   
00109   RCP<ParameterList> unsetParameterList();
00110   
00112   RCP<const ParameterList> getParameterList() const;
00113 
00115   RCP<const ParameterList> getValidParameters() const;
00116  
00118   
00119 private:
00120 
00121   // //////////////////////////////////////
00122   // Private types
00123 
00124   typedef RCP<const AbstractFactory<ObjectType > > object_fcty_t;
00125 
00126   // //////////////////////////////////////
00127   // Private data members
00128 
00129   RCP<ParameterList> paramList_;
00130   mutable RCP<const ParameterList> validParamList_;
00131   mutable RCP<const StringToIntegralParameterEntryValidator<int> > objectValidator_;
00132 
00133   std::string object_name_;
00134   std::string objectType_name_;
00135 
00136   Array<std::string> validObjectNames_;
00137   Array<object_fcty_t> objectArray_;
00138   std::string defaultObject_name_;
00139 
00140   // //////////////////////////////////////
00141   // Private member functions
00142 
00143   void initializeDefaults_();
00144 
00145 };
00146 
00147 
00148 // Nonmember constructors
00149 
00150 
00151 template<class ObjectType>
00152 RCP<ObjectBuilder<ObjectType> > objectBuilder()
00153 {
00154   RCP<ObjectBuilder<ObjectType> > ob = rcp(new ObjectBuilder<ObjectType>() );
00155   return ob;
00156 }
00157 
00158 
00159 template<class ObjectType>
00160 RCP<ObjectBuilder<ObjectType> >
00161 objectBuilder(const std::string& objectName, const std::string& objectTypeName)
00162 {
00163   RCP<ObjectBuilder<ObjectType> > ob = rcp(new ObjectBuilder<ObjectType>() );
00164   ob->setObjectName(objectName);
00165   ob->setObjectTypeName(objectTypeName);
00166   return ob;
00167 }
00168 
00169 
00170 template<class ObjectType>
00171 ObjectBuilder<ObjectType>::ObjectBuilder()
00172 {
00173   this->initializeDefaults_();
00174 }
00175 
00176 
00177 template<class ObjectType>
00178 ObjectBuilder<ObjectType>::~ObjectBuilder()
00179 {
00180 #ifdef TEUCHOS_DEBUG
00181   // Validate that we read the parameters correctly!
00182   if(!is_null(paramList_)) {
00183     paramList_->validateParameters(*this->getValidParameters());
00184   }
00185 #endif    
00186 }
00187 
00188 
00189 template<class ObjectType>
00190 void ObjectBuilder<ObjectType>::setObjectFactory(
00191   const RCP<const AbstractFactory<ObjectType > > &objectFactory,
00192   const std::string &objectName
00193   )
00194 {
00195   TEST_FOR_EXCEPT( objectName.length() == 0 );
00196   validObjectNames_.push_back(objectName);
00197   objectArray_.push_back(objectFactory);
00198   defaultObject_name_ = objectName;
00199   validParamList_ = null;
00200 #ifdef TEUCHOS_DEBUG
00201   this->getValidParameters();
00202 #endif // TEUCHOS_DEBUG
00203 }
00204 
00205 
00206 template<class ObjectType>
00207 std::string
00208 ObjectBuilder<ObjectType>::getObjectName() const
00209 {
00210   if(is_null(validParamList_)) {
00211     this->getValidParameters();
00212   }
00213   // If the user has not specified a ParameterList, then use the ValidParameterList.
00214   RCP<ParameterList> pl = null;
00215   if (!is_null(paramList_)) {
00216     pl = paramList_;
00217   } else {
00218     pl = parameterList();
00219     pl->setParameters(*this->getValidParameters());
00220   }
00221   return objectValidator_->getStringValue(*pl, objectType_name_, defaultObject_name_);
00222 }
00223 
00224 
00225 template<class ObjectType>
00226 void ObjectBuilder<ObjectType>::setParameterList(
00227   RCP<ParameterList> const& paramList
00228   )
00229 {
00230   if (!is_null(paramList)) {
00231     paramList->validateParameters(*this->getValidParameters());
00232     paramList_ = paramList;
00233   }
00234 }
00235 
00236 
00237 template<class ObjectType>
00238 RCP<ParameterList>
00239 ObjectBuilder<ObjectType>::getNonconstParameterList()
00240 {
00241   return paramList_;
00242 }
00243 
00244 
00245 template<class ObjectType>
00246 RCP<ParameterList>
00247 ObjectBuilder<ObjectType>::unsetParameterList()
00248 {
00249 #ifdef TEUCHOS_DEBUG
00250   // Validate that we read the parameters correctly!
00251   if(!is_null(paramList_))
00252     paramList_->validateParameters(*this->getValidParameters());
00253 #endif    
00254   RCP<ParameterList> _paramList = paramList_;
00255   paramList_ = null;
00256   return _paramList;
00257 }
00258 
00259 
00260 template<class ObjectType>
00261 RCP<const ParameterList>
00262 ObjectBuilder<ObjectType>::getParameterList() const
00263 {
00264   return paramList_;
00265 }
00266 
00267 
00268 template<class ObjectType>
00269 RCP<const ParameterList>
00270 ObjectBuilder<ObjectType>::getValidParameters() const
00271 {
00272   if(!validParamList_.get()) {
00273     RCP<ParameterList> validParamList = parameterList();
00274     // Object Types
00275     objectValidator_ = rcp(
00276       new StringToIntegralParameterEntryValidator<int>(
00277         validObjectNames_, objectType_name_
00278         )
00279       );
00280     objectValidator_->validateString(defaultObject_name_,objectType_name_);
00281     validParamList->set(
00282       objectType_name_, defaultObject_name_,
00283       (std::string("Determines the type of " + object_name_ + " object that will be built.\n")
00284         + "The parameters for each " + objectType_name_ + " are specified in this sublist" 
00285         ).c_str(),
00286       objectValidator_
00287       );
00288     for( int i = 0; i < static_cast<int>(objectArray_.size()); ++i ) {
00289       const std::string
00290         &sname = validObjectNames_[i+1];
00291       const RCP<ObjectType >
00292         object = objectArray_[i]->create();
00293       validParamList->sublist(sname).setParameters(
00294         *object->getValidParameters()).disableRecursiveValidation();
00295     }
00296     validParamList_ = validParamList;
00297   }
00298   return validParamList_;
00299 }
00300 
00301 template<class ObjectType>
00302 void ObjectBuilder<ObjectType>::setDefaultObject(
00303     const std::string &defaultObject_name
00304     )
00305 {
00306 #ifdef TEUCHOS_DEBUG
00307   if (is_null(validParamList_)) { // We need the objectValidator_
00308     this->getValidParameters();
00309   }
00310   objectValidator_->validateString(defaultObject_name,objectType_name_);
00311 #endif // TEUCHOS_DEBUG
00312   defaultObject_name_ = defaultObject_name;
00313   // This is necessary to change the default in the valid parameter list 
00314   validParamList_ = null; 
00315 }
00316 
00317 template<class ObjectType>
00318 RCP<ObjectType >
00319 ObjectBuilder<ObjectType>::create(
00320   const std::string &objectName
00321   ) const
00322 {
00323   if (is_null(validParamList_)) { // We need the objectValidator_
00324     this->getValidParameters();
00325   }
00326   const std::string
00327     sname = ( objectName.length()
00328              ? objectName
00329              : this->getObjectName() );
00330   RCP<ObjectType> object = null; 
00331   // Get the index of this object factory (this will validate!)
00332   const int
00333     s_idx = objectValidator_->getIntegralValue(sname, objectType_name_);
00334   if (s_idx != 0) {
00335     // Create the uninitialized object
00336     object = objectArray_[s_idx-1]->create(); 
00337     TEST_FOR_EXCEPTION( is_null(object), std::logic_error,
00338         (std::string("Error!  ObjectBuilder attempted to create an object of type ") 
00339          + validObjectNames_[s_idx] + " and it came back as a null RCP!").c_str()
00340         );
00341     // Allow the user to not set a parameterlist (this requires copying the
00342     // parameters in the valid parameter list into a new parameter list:
00343     RCP<ParameterList> pl = null;
00344     if (is_null(paramList_)) {
00345       pl = parameterList();
00346       pl->setParameters(this->getValidParameters()->sublist(sname));
00347     } else {
00348 #ifdef TEUCHOS_DEBUG
00349       // We're validating the parameter list here again because we're storing a
00350       // pointer to it and the user could have changed it.
00351       paramList_->validateParameters(*this->getValidParameters());
00352 #endif // TEUCHOS_DEBUG
00353       pl = sublist(paramList_,sname);
00354     }
00355     // Now set the parameters for the object 
00356     object->setParameterList(pl);
00357   }
00358   return object;
00359 }
00360 
00361 
00362 template<class ObjectType>
00363 void ObjectBuilder<ObjectType>::setObjectName(
00364     const std::string &objectName
00365     )
00366 {
00367   TEST_FOR_EXCEPT(objectName.length() == 0);
00368   object_name_ = objectName;
00369   validParamList_ = null;
00370 }
00371 
00372 
00373 template<class ObjectType>
00374 void ObjectBuilder<ObjectType>::setObjectTypeName(
00375     const std::string &objectTypeName
00376     )
00377 {
00378   TEST_FOR_EXCEPT(objectTypeName.length() == 0);
00379   objectType_name_ = objectTypeName;
00380   validParamList_ = null;
00381 }
00382 
00383 
00384 template<class ObjectType>
00385 void ObjectBuilder<ObjectType>::initializeDefaults_()
00386 {
00387 
00388   object_name_ = "Object";
00389   objectType_name_ = "Object Type";
00390 
00391   defaultObject_name_ = "None";
00392   validObjectNames_.resize(0);
00393   validObjectNames_.push_back(defaultObject_name_);
00394 
00395 }
00396 
00397 
00398 } // namespace Teuchos
00399 
00400 
00401 #endif //Teuchos_OBJECT_BUILDER_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Tue Oct 20 10:14:00 2009 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.1