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 ECELL_API 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     DECLARE_ASSOCVECTOR_TEMPLATE( String, Polymorph,
00118                                   std::less<const String>, PolymorphAssocVector);
00119 
00120     PropertyInterface()
00121     {
00122           theInfoMap[ String( PROPERTYLIST_FIELD )] = Polymorph( PolymorphVector() ) ;
00123       T::initializePropertyInterface( Type2Type<T>() );
00124     }
00125 
00126     ~PropertyInterface()
00127     {
00128       // This object is never deleted.
00129       /*
00130         for( PropertySlotMapIterator i( thePropertySlotMap.begin() ); 
00131         i != thePropertySlotMap.end() ; ++i )
00132         {
00133         delete i->second;
00134         }
00135       */
00136     }
00137 
00138 
00139         /**
00140            get InfoMap 
00141 
00142         */
00143         static PolymorphMapCref getInfoMap( void ) 
00144         {
00145       static PolymorphMap aPolymorphMap;
00146       for (PolymorphAssocVectorIterator i(theInfoMap.begin()); i != theInfoMap.end() ; ++i)
00147       {
00148         aPolymorphMap[i->first] = i->second;
00149       }
00150       return aPolymorphMap;
00151         }
00152 
00153         /** 
00154                 set Info field
00155                 if info field key begins with "Property_" then append PropertyName to "PropertyList" infofield
00156                 
00157         */
00158         static void setInfoField( StringCref aFieldName, PolymorphCref aValue )
00159         {
00160           theInfoMap[ aFieldName ] = aValue;
00161 
00162         }
00163 
00164         /**
00165            set property info field ( type, setflag, getflag, saveflag, loadflag are the params
00166 
00167         */
00168 
00169 
00170         static void setPropertyInfoField( StringCref aPropertyName, StringCref aTypeString,
00171                                                                           Integer setFlag, Integer getFlag, 
00172                                                                           Integer saveFlag, Integer loadFlag )
00173         {
00174           String PROP_FIELD( PROPERTY_FIELD );
00175           String PROPLIST_FIELD ( PROPERTYLIST_FIELD );
00176 
00177           PolymorphVector aPropertyDescriptor;
00178           aPropertyDescriptor.push_back( aTypeString );
00179           aPropertyDescriptor.push_back( setFlag );
00180           aPropertyDescriptor.push_back( getFlag );
00181           aPropertyDescriptor.push_back( saveFlag );
00182           aPropertyDescriptor.push_back( loadFlag );
00183           String aPropertyNameField( aPropertyName );
00184           aPropertyNameField.insert( 0, PROP_FIELD );
00185           setInfoField( aPropertyNameField, aPropertyDescriptor );
00186 
00187 
00188           PolymorphVector aPolymorphVector( getInfoField(  PROPLIST_FIELD  ).asPolymorphVector());
00189           aPolymorphVector.push_back( aPropertyName );
00190           setInfoField( PROPLIST_FIELD, Polymorph( aPolymorphVector ) );
00191                 
00192         }
00193 
00194         /**
00195            get Field from info map
00196         */
00197 
00198         static PolymorphCref getInfoField( StringCref aFieldName ) 
00199           {
00200                 return theInfoMap[ aFieldName ];
00201           }
00202 
00203 
00204     /**
00205        Get a PropertySlot by name.
00206 
00207        @param aPropertyName the name of the PropertySlot.
00208 
00209        @return a borrowed pointer to the PropertySlot with that name.
00210     */
00211 
00212     static PropertySlotPtr getPropertySlot( StringCref aPropertyName )
00213     {
00214       PropertySlotMapConstIterator i( findPropertySlot( aPropertyName ) );
00215 
00216       if( i == thePropertySlotMap.end() )
00217         {
00218           throwNoSlot( "This class", aPropertyName );
00219         }
00220 
00221       return i->second;
00222     }
00223 
00224     static PropertySlotProxyPtr 
00225     createPropertySlotProxy( T& anObject,
00226                              StringCref aPropertyName )
00227     {
00228       try
00229         {
00230           PropertySlotPtr aPropertySlot( getPropertySlot( aPropertyName ) );
00231           return new ConcretePropertySlotProxy<T>( anObject, *aPropertySlot );
00232         }
00233       catch( NoSlotCref )
00234         {
00235           throwNoSlot( anObject.getClassName(), aPropertyName );
00236         }
00237     }
00238 
00239 
00240     /**
00241        Set a value of a property slot.
00242 
00243        This method checks if the property slot exists, and throws
00244        NoSlot exception if not.
00245 
00246        @param aPropertyName the name of the property.
00247        @param aValue the value to set as a Polymorph.
00248        @throw NoSlot 
00249     */
00250 
00251     static void setProperty( T& anObject, StringCref aPropertyName, 
00252                              PolymorphCref aValue )
00253     {
00254       PropertySlotMapConstIterator 
00255         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00256       
00257       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00258         {
00259           aPropertySlotMapIterator->second->setPolymorph( anObject, aValue );
00260         }
00261       else
00262         {
00263           anObject.defaultSetProperty( aPropertyName, aValue );   
00264         }
00265     }
00266     
00267 
00268     /**
00269        Get a property value from this object via a PropertySlot.
00270 
00271        This method checks if the property slot exists, and throws
00272        NoSlot exception if not.
00273 
00274        @param aPropertyName the name of the property.
00275        @return the value as a Polymorph.
00276        @throw NoSlot
00277     */
00278 
00279     static const Polymorph getProperty( const T& anObject,
00280                                         StringCref aPropertyName )
00281     {
00282       PropertySlotMapConstIterator 
00283         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00284       
00285       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00286         {
00287           return aPropertySlotMapIterator->second->getPolymorph( anObject );
00288         }
00289       else
00290         {
00291           return anObject.defaultGetProperty( aPropertyName );
00292         }
00293     }
00294 
00295 
00296     static void loadProperty( T& anObject, StringCref aPropertyName, 
00297                               PolymorphCref aValue )
00298     {
00299       PropertySlotMapConstIterator 
00300         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00301 
00302       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00303         {
00304           PropertySlotPtr aPropertySlotPtr( aPropertySlotMapIterator->second );
00305 
00306           if( aPropertySlotPtr->isLoadable() )
00307             {
00308               aPropertySlotPtr->loadPolymorph( anObject, aValue );
00309             }
00310           else
00311             {
00312               throwNotLoadable( anObject, aPropertyName );
00313             }
00314         }
00315       else
00316         {
00317           anObject.defaultSetProperty( aPropertyName, aValue );
00318         }
00319     }
00320     
00321 
00322     static const Polymorph
00323     saveProperty( const T& anObject, StringCref aPropertyName )
00324     {
00325       PropertySlotMapConstIterator 
00326         aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00327 
00328       if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00329         {
00330           PropertySlotPtr aPropertySlotPtr( aPropertySlotMapIterator->second );
00331           if( aPropertySlotPtr->isSavable() )
00332             {
00333               return aPropertySlotPtr->savePolymorph( anObject );
00334             }
00335           else
00336             {
00337               throwNotSavable( anObject, aPropertyName );
00338             }
00339         }
00340       else
00341         {
00342           return anObject.defaultGetProperty( aPropertyName );
00343         }
00344     }
00345 
00346     static const Polymorph getPropertyList( const T& anObject )
00347     {
00348       PolymorphVector aVector1, aVector2;
00349       // aVector.reserve( thePropertySlotMap.size() );
00350       
00351       for( PropertySlotMapConstIterator i( thePropertySlotMap.begin() ); 
00352            i != thePropertySlotMap.end() ; ++i )
00353         {
00354           aVector1.push_back( i->first );
00355         }
00356 
00357       aVector2 = anObject.defaultGetPropertyList();
00358 
00359       if( aVector2.size() > 0 )
00360         {
00361           for( PolymorphVectorIterator i( aVector2.begin() );
00362                i != aVector2.end(); ++i )
00363             {
00364               aVector1.push_back( i->asString() );
00365             }
00366         }
00367 
00368       return aVector1;
00369     }
00370 
00371     
00372     static void 
00373     registerPropertySlot( StringCref aName, PropertySlotPtr aPropertySlotPtr )
00374     {
00375       if( findPropertySlot( aName ) != thePropertySlotMap.end() )
00376         {
00377           // it already exists. take the latter one.
00378           delete thePropertySlotMap[ aName ];
00379           thePropertySlotMap.erase( aName );
00380         }
00381 
00382       //      thePropertySlotMap[ aName ] = aPropertySlotPtr;
00383       thePropertySlotMap.insert( std::make_pair( aName, aPropertySlotPtr ) );
00384     }
00385 
00386 
00387     static const Polymorph
00388     getPropertyAttributes( const T& anObject, StringCref aPropertyName )
00389     {
00390       PropertySlotMapConstIterator i( findPropertySlot( aPropertyName ) );
00391 
00392       if( i != thePropertySlotMap.end() )
00393         {
00394           PropertySlotBasePtr 
00395             aPropertySlotPtr( getPropertySlot( aPropertyName ) );
00396           
00397           PolymorphVector aVector;
00398           
00399           // is setable?
00400           aVector.push_back
00401             ( static_cast<Integer>( aPropertySlotPtr->isSetable() ) );
00402       
00403           // is getable?
00404           aVector.push_back
00405             ( static_cast<Integer>( aPropertySlotPtr->isGetable() ) );
00406       
00407           // is getable?
00408           aVector.push_back
00409             ( static_cast<Integer>( aPropertySlotPtr->isLoadable() ) );
00410       
00411           // is getable?
00412           aVector.push_back
00413             ( static_cast<Integer>( aPropertySlotPtr->isSavable() ) );
00414       
00415           return aVector;
00416         }
00417       else
00418         {
00419           return anObject.defaultGetPropertyAttributes( aPropertyName );
00420         }
00421     }
00422 
00423 
00424     /*
00425     static void removePropertySlot( StringCref aName );
00426     {
00427       if( thePropertySlotMap.find( aName ) == thePropertySlotMap.end() )
00428         {
00429           THROW_EXCEPTION( NoSlot,
00430                            getClassName() + String( ":no slot for keyword [" ) +
00431                            aName + String( "] found.\n" ) );
00432         }
00433       
00434       delete thePropertySlotMap[ aName ];
00435       thePropertySlotMap.erase( aName );
00436     }
00437     */
00438 
00439     static PropertySlotMapCref getPropertySlotMap()
00440     {
00441       return thePropertySlotMap;
00442     }
00443 
00444 
00445 
00446     // info-related methods
00447 
00448     /*
00449     static void 
00450     setClassInfo( StringCref aFieldName, StringCref anInfoString )
00451     {
00452       PropertyInterface::setInfoField( theClassInfoMap, 
00453                                        aFieldName, anInfoString );
00454     }
00455 
00456     virtual StringMapCref getClassInfoMap()
00457     {
00458       return theClassInfoMap;
00459     }
00460     */
00461 
00462     /*
00463     static void 
00464     setPropertySlotInfo( StringCref aPropertySlotName, StringCref aFieldName,
00465                          StringCref anInfoString )
00466     {
00467       PropertySlotCptr 
00468         aPropertySlotPtr( getPropertySlot( aPropertySlotName ) );
00469       aPropertySlotPtr->setClassInfo( aFieldName, anInfoString );
00470     }
00471 
00472     static StringMapCref
00473     getPropertySlotInfoMap( StringCref aPropertySlotName )
00474     {
00475       PropertySlotCptr 
00476         aPropertySlotPtr( getPropertySlot( aPropertySlotName ) );
00477       aPropertySlotPtr->setClassInfo();
00478     }
00479 
00480     static const Polymorph
00481     getPropertySlotInfoAsPolymorph( StringCref aPropertySlotName )
00482     {
00483       PropertySlotCptr 
00484         aPropertySlotPtr( getPropertySlot( aPropertySlotName ) );
00485       aPropertySlotPtr->getClassInfoAsPolymorph();
00486     }
00487     */
00488 
00489   private:
00490 
00491     static PropertySlotMapConstIterator 
00492     findPropertySlot( StringCref aPropertyName )
00493     {
00494       return thePropertySlotMap.find( aPropertyName );
00495     }
00496 
00497   private:
00498 
00499     static PropertySlotMap  thePropertySlotMap;
00500 
00501     static PolymorphAssocVector theInfoMap;
00502   };
00503 
00504 
00505   // This is necessary for the static data member of 
00506   // the PropertyInterface template class to be instantiated
00507   // when the class is specialized (in LIBECS_DM_INIT_STATIC()).
00508   template< class T > typename libecs::PropertyInterface< T>::PropertySlotMap
00509     libecs::PropertyInterface< T>::thePropertySlotMap;
00510   template< class T > typename libecs::PropertyInterface< T>::PolymorphAssocVector
00511     libecs::PropertyInterface< T>::theInfoMap;
00512 
00513 
00514   /*@}*/
00515   
00516 } // namespace libecs
00517 
00518 #endif /* __PROPERTYINTERFACE_HPP */
00519 
00520 /*
00521   Do not modify
00522   $Author: sachiboo $
00523   $Revision: 2625 $
00524   $Date: 2006-11-24 13:36:17 +0100 (Fri, 24 Nov 2006) $
00525   $Locker$
00526 */

Generated on Fri Aug 31 18:32:07 2007 for E-CELL C++ libraries (libecs and libemc) 3.1.105 by  doxygen 1.5.3