PropertyInterface.hpp

Go to the documentation of this file.
00001 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00002 //
00003 //        This file is part of E-Cell Simulation Environment package
00004 //
00005 //                Copyright (C) 1996-2002 Keio University
00006 //
00007 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00008 //
00009 //
00010 // E-Cell is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2 of the License, or (at your option) any later version.
00014 // 
00015 // E-Cell is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 // See the GNU General Public License for more details.
00019 // 
00020 // You should have received a copy of the GNU General Public
00021 // License along with E-Cell -- see the file COPYING.
00022 // If not, write to the Free Software Foundation, Inc.,
00023 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 // 
00025 //END_HEADER
00026 //
00027 // written by Koichi Takahashi <shafi@e-cell.org>,
00028 // E-Cell Project.
00029 //
00030 
00031 #ifndef __PROPERTYINTERFACE_HPP
00032 #define __PROPERTYINTERFACE_HPP
00033 
00034 #include "AssocVector.h"
00035 
00036 #include "libecs.hpp"
00037 #include "PropertySlot.hpp"
00038 #include "PropertySlotProxy.hpp"
00039 
00040 #define PROPERTY_FIELD  "Property__"
00041 #define PROPERTYLIST_FIELD  "PropertyList"
00042 
00043 namespace libecs
00044 {
00045 
00046   /** @addtogroup property The Inter-object Communication.
00047    *  The Interobject Communication.
00048    *@{
00049 
00050   */
00051 
00052   /** @file */
00053 
00054   class PropertyInterfaceBase
00055   {
00056   public:
00057 
00058     ~PropertyInterfaceBase()
00059     {
00060       ; // do nothing
00061     }
00062 
00063   protected:
00064 
00065     PropertyInterfaceBase()
00066     {
00067       ; // do nothing
00068     }
00069 
00070     static void throwNoSlot( StringCref aClassName, StringCref aPropertyName );
00071 
00072     static void throwNotLoadable( PropertiedClassCref aClassName, 
00073                                   StringCref aPropertyName );
00074     static void throwNotSavable( PropertiedClassCref aClassName, 
00075                                  StringCref aPropertyName );
00076 
00077 
00078 
00079     // info-related helper methods.
00080 
00081     /*
00082     static void setInfoField( StringMapRef anInfoMap,
00083                               StringCref aFieldName, StringCref anInfoString );
00084 
00085     Polymorph getClassInfoAsPolymorph()
00086     {
00087       return convertInfoMapToPolymorph( getClassInfoMap() );
00088     }
00089 
00090     static const Polymorph 
00091     convertInfoMapToPolymorph( StringMapCref anInfoMap );
00092 
00093     virtual StringMapCref getClassInfoMap() = 0;
00094 
00095     */
00096 
00097   };
00098 
00099 
00100   template
00101   <
00102     class T
00103   >
00104   class PropertyInterface
00105     :
00106     public PropertyInterfaceBase
00107   {
00108 
00109   public:
00110 
00111     typedef PropertySlot<T> PropertySlot_;
00112     DECLARE_TYPE( PropertySlot_, PropertySlot );
00113 
00114     DECLARE_ASSOCVECTOR_TEMPLATE( String, PropertySlotPtr,
00115                                   std::less<const String>, PropertySlotMap );
00116 
00117     PropertyInterface()
00118     {
00119           theInfoMap[ String( PROPERTYLIST_FIELD )] = Polymorph( PolymorphVector() ) ;
00120       T::initializePropertyInterface( Type2Type<T>() );
00121     }
00122 
00123     ~PropertyInterface()
00124     {
00125       // This object is never deleted.
00126       /*
00127         for( PropertySlotMapIterator i( thePropertySlotMap.begin() ); 
00128         i != thePropertySlotMap.end() ; ++i )
00129         {
00130         delete i->second;
00131         }
00132       */
00133     }
00134 
00135 
00136         /**
00137            get InfoMap 
00138 
00139         */
00140         static PolymorphMapCref getInfoMap( void ) 
00141         {
00142           return  theInfoMap;
00143         }
00144 
00145         /** 
00146                 set Info field
00147                 if info field key begins with "Property_" then append PropertyName to "PropertyList" infofield
00148                 
00149         */
00150         static void setInfoField( StringCref aFieldName, PolymorphCref aValue )
00151         {
00152           theInfoMap[ aFieldName ] = aValue;
00153 
00154         }
00155 
00156         /**
00157            set property info field ( type, setflag, getflag, saveflag, loadflag are the params
00158 
00159         */
00160 
00161 
00162         static void setPropertyInfoField( StringCref aPropertyName, StringCref aTypeString,
00163                                                                           Integer setFlag, Integer getFlag, 
00164                                                                           Integer saveFlag, Integer loadFlag )
00165         {
00166           String PROP_FIELD( PROPERTY_FIELD );
00167           String PROPLIST_FIELD ( PROPERTYLIST_FIELD );
00168 
00169           PolymorphVector aPropertyDescriptor;
00170           aPropertyDescriptor.push_back( aTypeString );
00171           aPropertyDescriptor.push_back( setFlag );
00172           aPropertyDescriptor.push_back( getFlag );
00173           aPropertyDescriptor.push_back( saveFlag );
00174           aPropertyDescriptor.push_back( loadFlag );
00175           String aPropertyNameField( aPropertyName );
00176           aPropertyNameField.insert( 0, PROP_FIELD );
00177           setInfoField( aPropertyNameField, aPropertyDescriptor );
00178 
00179 
00180           PolymorphVector aPolymorphVector( getInfoField(  PROPLIST_FIELD  ).asPolymorphVector());
00181           aPolymorphVector.push_back( aPropertyName );
00182           setInfoField( PROPLIST_FIELD, Polymorph( aPolymorphVector ) );
00183                 
00184         }
00185 
00186         /**
00187            get Field from info map
00188         */
00189 
00190         static PolymorphCref getInfoField( StringCref aFieldName ) 
00191           {
00192                 return theInfoMap[ aFieldName ];
00193           }
00194 
00195 
00196     /**
00197        Get a PropertySlot by name.
00198 
00199        @param aPropertyName the name of the PropertySlot.
00200 
00201        @return a borrowed pointer to the PropertySlot with that name.
00202     */
00203 
00204     static PropertySlotPtr getPropertySlot( StringCref aPropertyName )
00205     {
00206       PropertySlotMapConstIterator i( findPropertySlot( aPropertyName ) );
00207 
00208       if( i == thePropertySlotMap.end() )
00209         {
00210           throwNoSlot( "This class", aPropertyName );
00211         }
00212 
00213       return i->second;
00214     }
00215 
00216     static PropertySlotProxyPtr 
00217     createPropertySlotProxy( T& anObject,
00218                              StringCref aPropertyName )
00219     {
00220       try
00221         {
00222           PropertySlotPtr aPropertySlot( getPropertySlot( aPropertyName ) );
00223           return new ConcretePropertySlotProxy<T>( anObject, *aPropertySlot );
00224         }
00225       catch( NoSlotCref )
00226         {
00227           throwNoSlot( anObject.getClassName(), aPropertyName );
00228         }
00229     }
00230 
00231 
00232     /**
00233        Set a value of a property slot.
00234 
00235        This method checks if the property slot exists, and throws
00236        NoSlot exception if not.
00237 
00238        @param aPropertyName the name of the property.
00239        @param aValue the value to set as a Polymorph.
00240        @throw NoSlot 
00241     */
00242 
00243     static void setProperty( T& anObject, StringCref aPropertyName, 
00244                              PolymorphCref aValue )
00245     {
00246       PropertySlotMapConstIterator 
00247         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00248       
00249       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00250         {
00251           aPropertySlotMapIterator->second->setPolymorph( anObject, aValue );
00252         }
00253       else
00254         {
00255           anObject.defaultSetProperty( aPropertyName, aValue );   
00256         }
00257     }
00258     
00259 
00260     /**
00261        Get a property value from this object via a PropertySlot.
00262 
00263        This method checks if the property slot exists, and throws
00264        NoSlot exception if not.
00265 
00266        @param aPropertyName the name of the property.
00267        @return the value as a Polymorph.
00268        @throw NoSlot
00269     */
00270 
00271     static const Polymorph getProperty( const T& anObject,
00272                                         StringCref aPropertyName )
00273     {
00274       PropertySlotMapConstIterator 
00275         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00276       
00277       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00278         {
00279           return aPropertySlotMapIterator->second->getPolymorph( anObject );
00280         }
00281       else
00282         {
00283           return anObject.defaultGetProperty( aPropertyName );
00284         }
00285     }
00286 
00287 
00288     static void loadProperty( T& anObject, StringCref aPropertyName, 
00289                               PolymorphCref aValue )
00290     {
00291       PropertySlotMapConstIterator 
00292         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00293 
00294       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00295         {
00296           PropertySlotPtr aPropertySlotPtr( aPropertySlotMapIterator->second );
00297 
00298           if( aPropertySlotPtr->isLoadable() )
00299             {
00300               aPropertySlotPtr->loadPolymorph( anObject, aValue );
00301             }
00302           else
00303             {
00304               throwNotLoadable( anObject, aPropertyName );
00305             }
00306         }
00307       else
00308         {
00309           anObject.defaultSetProperty( aPropertyName, aValue );
00310         }
00311     }
00312     
00313 
00314     static const Polymorph
00315     saveProperty( const T& anObject, StringCref aPropertyName )
00316     {
00317       PropertySlotMapConstIterator 
00318         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00319 
00320       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00321         {
00322           PropertySlotPtr aPropertySlotPtr( aPropertySlotMapIterator->second );
00323           if( aPropertySlotPtr->isSavable() )
00324             {
00325               return aPropertySlotPtr->savePolymorph( anObject );
00326             }
00327           else
00328             {
00329               throwNotSavable( anObject, aPropertyName );
00330             }
00331         }
00332       else
00333         {
00334           return anObject.defaultGetProperty( aPropertyName );
00335         }
00336     }
00337 
00338     static const Polymorph getPropertyList( const T& anObject )
00339     {
00340       PolymorphVector aVector1, aVector2;
00341       // aVector.reserve( thePropertySlotMap.size() );
00342       
00343       for( PropertySlotMapConstIterator i( thePropertySlotMap.begin() ); 
00344            i != thePropertySlotMap.end() ; ++i )
00345         {
00346           aVector1.push_back( i->first );
00347         }
00348 
00349       aVector2 = anObject.defaultGetPropertyList();
00350 
00351       if( aVector2.size() > 0 )
00352         {
00353           for( PolymorphVectorIterator i( aVector2.begin() );
00354                i != aVector2.end(); ++i )
00355             {
00356               aVector1.push_back( i->asString() );
00357             }
00358         }
00359 
00360       return aVector1;
00361     }
00362 
00363     
00364     static void 
00365     registerPropertySlot( StringCref aName, PropertySlotPtr aPropertySlotPtr )
00366     {
00367       if( findPropertySlot( aName ) != thePropertySlotMap.end() )
00368         {
00369           // it already exists. take the latter one.
00370           delete thePropertySlotMap[ aName ];
00371           thePropertySlotMap.erase( aName );
00372         }
00373 
00374       //      thePropertySlotMap[ aName ] = aPropertySlotPtr;
00375       thePropertySlotMap.insert( std::make_pair( aName, aPropertySlotPtr ) );
00376     }
00377 
00378 
00379     static const Polymorph
00380     getPropertyAttributes( const T& anObject, StringCref aPropertyName )
00381     {
00382       PropertySlotMapConstIterator i( findPropertySlot( aPropertyName ) );
00383 
00384       if( i != thePropertySlotMap.end() )
00385         {
00386           PropertySlotBasePtr 
00387             aPropertySlotPtr( getPropertySlot( aPropertyName ) );
00388           
00389           PolymorphVector aVector;
00390           
00391           // is setable?
00392           aVector.push_back
00393             ( static_cast<Integer>( aPropertySlotPtr->isSetable() ) );
00394       
00395           // is getable?
00396           aVector.push_back
00397             ( static_cast<Integer>( aPropertySlotPtr->isGetable() ) );
00398       
00399           // is getable?
00400           aVector.push_back
00401             ( static_cast<Integer>( aPropertySlotPtr->isLoadable() ) );
00402       
00403           // is getable?
00404           aVector.push_back
00405             ( static_cast<Integer>( aPropertySlotPtr->isSavable() ) );
00406       
00407           return aVector;
00408         }
00409       else
00410         {
00411           return anObject.defaultGetPropertyAttributes( aPropertyName );
00412         }
00413     }
00414 
00415 
00416     /*
00417     static void removePropertySlot( StringCref aName );
00418     {
00419       if( thePropertySlotMap.find( aName ) == thePropertySlotMap.end() )
00420         {
00421           THROW_EXCEPTION( NoSlot,
00422                            getClassName() + String( ":no slot for keyword [" ) +
00423                            aName + String( "] found.\n" ) );
00424         }
00425       
00426       delete thePropertySlotMap[ aName ];
00427       thePropertySlotMap.erase( aName );
00428     }
00429     */
00430 
00431     static PropertySlotMapCref getPropertySlotMap()
00432     {
00433       return thePropertySlotMap;
00434     }
00435 
00436 
00437 
00438     // info-related methods
00439 
00440     /*
00441     static void 
00442     setClassInfo( StringCref aFieldName, StringCref anInfoString )
00443     {
00444       PropertyInterface::setInfoField( theClassInfoMap, 
00445                                        aFieldName, anInfoString );
00446     }
00447 
00448     virtual StringMapCref getClassInfoMap()
00449     {
00450       return theClassInfoMap;
00451     }
00452     */
00453 
00454     /*
00455     static void 
00456     setPropertySlotInfo( StringCref aPropertySlotName, StringCref aFieldName,
00457                          StringCref anInfoString )
00458     {
00459       PropertySlotCptr 
00460         aPropertySlotPtr( getPropertySlot( aPropertySlotName ) );
00461       aPropertySlotPtr->setClassInfo( aFieldName, anInfoString );
00462     }
00463 
00464     static StringMapCref
00465     getPropertySlotInfoMap( StringCref aPropertySlotName )
00466     {
00467       PropertySlotCptr 
00468         aPropertySlotPtr( getPropertySlot( aPropertySlotName ) );
00469       aPropertySlotPtr->setClassInfo();
00470     }
00471 
00472     static const Polymorph
00473     getPropertySlotInfoAsPolymorph( StringCref aPropertySlotName )
00474     {
00475       PropertySlotCptr 
00476         aPropertySlotPtr( getPropertySlot( aPropertySlotName ) );
00477       aPropertySlotPtr->getClassInfoAsPolymorph();
00478     }
00479     */
00480 
00481   private:
00482 
00483     static PropertySlotMapConstIterator 
00484     findPropertySlot( StringCref aPropertyName )
00485     {
00486       return thePropertySlotMap.find( aPropertyName );
00487     }
00488 
00489   private:
00490 
00491     static PropertySlotMap  thePropertySlotMap;
00492 
00493     static PolymorphMap     theInfoMap;
00494 
00495   };
00496 
00497 
00498   // This is necessary for the static data member of 
00499   // the PropertyInterface template class to be instantiated
00500   // when the class is specialized (in LIBECS_DM_INIT_STATIC()).
00501   template< class T > class libecs::PropertyInterface< T>::PropertySlotMap
00502     libecs::PropertyInterface< T>::thePropertySlotMap;
00503   template< class T > class std::map<const String, Polymorph, std::less<const String> > libecs::PropertyInterface< T>::theInfoMap;
00504  
00505 
00506 
00507   /*@}*/
00508   
00509 } // namespace libecs
00510 
00511 #endif /* __PROPERTYINTERFACE_HPP */
00512 
00513 /*
00514   Do not modify
00515   $Author: shafi $
00516   $Revision: 2529 $
00517   $Date: 2005-11-19 10:36:40 +0100 (Sat, 19 Nov 2005) $
00518   $Locker$
00519 */

Generated on Fri Sep 1 10:55:57 2006 for E-CELL C++ libraries (libecs and libemc) 3.1.105 by  doxygen 1.4.7