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