DataFields.h

Go to the documentation of this file.
00001 /**
00002  * @file    DataFields.h
00003  * @brief   
00004  *
00005  ****************************************************************************
00006  * @version 0.8.534 $Id: DataFields.h 3775 2011-01-01 16:38:17Z alex $
00007  * @author  Alessandro Polo
00008  ****************************************************************************/
00009 /* Copyright (c) 2007-2011, WOSH - Wide Open Smart Home 
00010  * by Alessandro Polo - OpenSmartHome.com
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *     * Redistributions of source code must retain the above copyright
00016  *       notice, this list of conditions and the following disclaimer.
00017  *     * 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  *     * Neither the name of the OpenSmartHome.com WOSH nor the
00021  *       names of its contributors may be used to endorse or promote products
00022  *       derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
00025  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
00028  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  ****************************************************************************/
00035 
00036 #ifndef __WOSH_Core_DataFields_H__
00037  #define __WOSH_Core_DataFields_H__
00038 
00039  #include <woshDefs.h>
00040  #include <core/Permission.h>
00041  #include <core/Comparison.h>
00042  #include <core/Mutex.h>
00043  #include <core/DataWrappers.h>
00044  #include <vector>
00045  #include <algorithm>
00046 
00047 
00048 namespace wosh {
00049 
00050 class IDataFieldCollection;
00051 class IObjectReader;
00052 class IObjectWriter;
00053 
00054 class ISerializable;
00055 class SecurityToken;
00056 
00057 ///----------------------------------------------------------------------------------------------------------------------
00058 /**
00059  * @class   wosh::IDataFieldHolder
00060  * @brief   interface to expose fields definition and their wrappers, support field-listing
00061  *
00062  * Most implementations refer to \def WOSH_DF_STATIC_MEYER
00063  * Convenient definitions provided by wosh::IDataFieldReadable and wosh::IDataFieldWritable
00064  * interfaces are based on this \c MACRO.
00065  *
00066  * @see     wosh::IDataFieldCollection
00067  ****************************************************************************/
00068  
00069  #define WOSH_DF_STATIC_MEYER(CLASSNAME, STATIC_NAME)                                                                       \
00070         public: static void initializeDataFields( wosh::DataFieldCollection<CLASSNAME>* fields);                            \
00071         public: static void retrieveDataFields( wosh::DataFieldCollection<CLASSNAME>** fields) {                            \
00072                     if ( fields == NULL ) return;                                                                           \
00073                     *fields = &getDataFieldsStatic_##STATIC_NAME();                                                         \
00074                  }                                                                                                          \
00075         public: static wosh::DataFieldCollection<CLASSNAME>& getDataFieldsStatic_##STATIC_NAME() {                          \
00076                     static wosh::DataFieldCollection<CLASSNAME> my_fields_##STATIC_NAME;                                    \
00077                     if ( !my_fields_##STATIC_NAME.isInitialized() ) initializeDataFields(&my_fields_##STATIC_NAME);         \
00078                     return my_fields_##STATIC_NAME;                                                                         \
00079                  }                                                                                                          \
00080         public: virtual inline const wosh::IDataFieldCollection* getDataFields() const { return &getDataFieldsStatic_##STATIC_NAME(); }
00081 
00082 
00083 class IDataFieldHolder
00084  {
00085 /** @name IDataFieldHolder Interface
00086  * @{
00087  ******************************************************************************/
00088     public:
00089         ///@brief  implementation should create a meyer singleton static proxy, so IDataFieldCollection object
00090         ///        is created once (static, meyer)
00091         ///@note   IDataFieldCollection has no references to current object and cannot be edited once created
00092         virtual const wosh::IDataFieldCollection* getDataFields() const = 0;
00093 //@}
00094     public:
00095         virtual ~IDataFieldHolder() { }
00096 }; // class def
00097 ///----------------------------------------------------------------------------------------------------------------------
00098 ///----------------------------------------------------------------------------------------------------------------------
00099 
00100 ///----------------------------------------------------------------------------------------------------------------------
00101 /**
00102  * @class   wosh::IDataFieldReadable
00103  * @brief   interface to expose fields-reading support
00104  *
00105  * A generic client (such as a DataExtractor ) may read fields through the provided
00106  * wosh::IObjectReader interface. IObjectReader is created dynamically be the implementation
00107  * and associated with current object and its fields-collector.
00108  *
00109  * Implemented by the object itself, may provide a custom IObjectReader implementation.
00110  * Most implementations refer to \def WOSH_DF_READERT,
00111  * these MACRO definitions are based on WOSH_DF_STATIC_MEYER definition (it must be present).
00112  *
00113  * Example:
00114  * \code
00115 public myObject : public IDataFieldReadable {
00116     WOSH_DF_STATIC_MEYER(myObject)
00117     WOSH_DF_READERT(myObject, getPermission)
00118  }
00119 \endcode
00120  *
00121  * @see     wosh::IObjectReader
00122  * @see     wosh::IDataFieldHolder
00123  * @see     wosh::IDataFieldWritable
00124  ****************************************************************************/
00125 
00126  #define WOSH_DF_READERT(CLASSNAME, STATIC_NAME)                                                        \
00127         public: virtual inline wosh::IObjectReader* createObjectReader() const {                        \
00128                     return new wosh::ObjectReaderT<CLASSNAME>(this, &getDataFieldsStatic_##STATIC_NAME());  \
00129                  }
00130 
00131 class IDataFieldReadable
00132  {
00133 /** @name IDataFieldReadable Interface
00134  * @{
00135  ******************************************************************************/
00136     public:
00137         ///@brief a (custom) IObjectReader implementation is created on each call and bound to current object
00138         ///       reference is const, as this call against the object (inherited class)
00139         ///@see   \ref WOSH_DF_READERT
00140         virtual wosh::IObjectReader* createObjectReader() const = 0;
00141 //@}
00142     public:
00143         virtual ~IDataFieldReadable() { }
00144 
00145 }; // class def
00146 ///----------------------------------------------------------------------------------------------------------------------
00147 ///----------------------------------------------------------------------------------------------------------------------
00148 
00149 ///----------------------------------------------------------------------------------------------------------------------
00150 /**
00151  * @class   wosh::IDataFieldWritable
00152  * @brief   interface to expose fields-writing support
00153  *
00154  * A generic client (such as a DataExtractor ) may write/update fields through the provided
00155  * wosh::IObjectWriter interface. IObjectWriter is created dynamically be the implementation
00156  * and associated with current object and its fields-collector.
00157  *
00158  * Implemented by the object itself, may provide a custom IObjectWriter implementation.
00159  * Most implementations refer to \def WOSH_DF_WRITERT,
00160  * these MACRO definitions are based on WOSH_DF_STATIC_MEYER definition (it must be present).
00161  *
00162  * Example:
00163  * \code
00164 public myObject : public IDataFieldWritable {
00165     WOSH_DF_STATIC_MEYER(myObject)
00166     WOSH_DF_WRITERT(myObject, getPermission)
00167  }
00168 \endcode
00169  *
00170  * @see     wosh::IObjectWriter
00171  * @see     wosh::IDataFieldHolder
00172  * @see     wosh::IDataFieldReadable
00173  ****************************************************************************/
00174 
00175  #define WOSH_DF_WRITERT(CLASSNAME, STATIC_NAME)                                                        \
00176         public: virtual inline wosh::IObjectWriter* createObjectWriter() {                                  \
00177                     return new wosh::ObjectWriterT<CLASSNAME>(this, &getDataFieldsStatic_##STATIC_NAME());  \
00178                  }
00179 
00180 class IDataFieldWritable
00181  {
00182 /** @name IDataFieldWritable Interface
00183  * @{
00184  ******************************************************************************/
00185     public:
00186         ///@brief a (custom) IObjectWriter implementation is created on each call and bound to current object
00187         ///@note  NOT const: since the object may be edited by writer
00188         ///@see   \ref WOSH_DF_WRITERT
00189         ///@warning IObjectWriter instance must be destroyed by the caller
00190         virtual wosh::IObjectWriter* createObjectWriter() = 0;
00191 //@}
00192     public:
00193         virtual ~IDataFieldWritable() { }
00194 
00195 }; // class def
00196 ///----------------------------------------------------------------------------------------------------------------------
00197 ///----------------------------------------------------------------------------------------------------------------------
00198 
00199  #define WOSH_DF_MEYER_RW(CLASSNAME, STATIC_NAME)       \
00200     WOSH_DF_STATIC_MEYER(CLASSNAME, STATIC_NAME)        \
00201     WOSH_DF_READERT(CLASSNAME, STATIC_NAME)             \
00202     WOSH_DF_WRITERT(CLASSNAME, STATIC_NAME)
00203 
00204 
00205 class IDataFieldRW :    public virtual wosh::IDataFieldHolder,
00206                         public virtual wosh::IDataFieldReadable,
00207                         public virtual wosh::IDataFieldWritable
00208 {
00209     public:
00210         virtual ~IDataFieldRW() { }
00211 
00212 }; // class def
00213 
00214 ///----------------------------------------------------------------------------------------------------------------------
00215 ///----------------------------------------------------------------------------------------------------------------------
00216 /**
00217  * @class   wosh::IObjectReader
00218  * @brief   data-field reading interface,  allow an external object to read object's fields
00219  *          in a standardized protocol based on wosh::ISerializable class.
00220  *
00221  * Implementations are able to read generic object's fields and convert them to a standard
00222  * interface (as wosh::ISerializable).
00223  * \c Fields are defined (in a IDataFieldCollection) and mapped to Read(/Write) wrappers
00224  * (function pointers) through a set of (template) adapters working as proxy.
00225  *
00226  * In short, once configured, the architecture is able to map:
00227  * \code
00228 public myObject  {
00229     // [..]
00230         const std::string& getStringValue() const;
00231     // [..]
00232  }
00233 \endcode
00234  * to
00235  * \code
00236 void external_function( IDataFieldReadable* object ) {
00237     IObjectReader* tmpReader = object->createObjectReader();
00238     ISerializable* field_value = tmp_reader->read("MyStringField");
00239     if ( field_value->isKindOf<Variant>() )
00240         printf("Value= %s", field_value->as<Variant>()->toString().c_str() );
00241     delete field_value;
00242     delete tmpReader;
00243  }
00244 \endcode
00245  * 
00246  * Configuration stands for 'field definition', the code required to enable previous example is:
00247  * \code
00248 void myObject::initializeDataFields( DataFieldCollection<myObject>* fields ) {
00249     if ( fields == NULL ) return;
00250     DataFieldDefinitionT<myObject>* df_str = fields->add("MyStringField");
00251     df_str->setWrapperRead<const std::string&, Variant>(&myObject::getStringValue);
00252  }
00253 \endcode
00254  *
00255  * This proxy-skeleton based architecture comes for two reasons:
00256  *  - Read/Write field-wrappers (class/instance which binds real object-function) requires
00257  *    information about the object's \c class (in other words must be a template or a custom implementation).
00258  *    That's why read-wrapper skeleton (IDataFieldWrapperRead) is a template <class OBJECT_TYPE>.
00259  *  - It allows object to provide or select their own custom implementation.
00260  *
00261  * Because of that, similar to IDataCollector case), the implementation of IObjectReader are \c compilation-dependent
00262  * to the object (we are accessing to), so the \c reader must be created by the object (class) itself (that's why common defines
00263  * MACROS are provided).
00264  * 
00265  * In order to expose a standard interface (not dependent on the object type/instance), the \c reader
00266  * must keep a must keep a (const) reference to the object (which owns real fields)
00267  * and a const reference to its IDataFieldCollection (casted-implementation/instance), collection
00268  * is required in order to recognize and access to the fields (though wrappers).
00269  *
00270  * In fact, since the \c reader implementation know the OBJECT_TYPE, it can (be initialized and) access
00271  * to the OBJECT_TYPE-related implementation (template) of fields-definition (DataFieldDefinitionT<OBJECT_TYPE>)
00272  * and so its wrappers. Again, as said, IDataFieldDefinition cannot store neither access to wrappers since they are
00273  * class dependent.
00274  *
00275  * \par Security
00276  *  wosh::IObjectReader implementation may enable \c security-checks when a valid security-session context (wosh::SecurityToken by caller)
00277  *  and a wosh::Permission reference for the object (by the wosh::IDataFieldReadable implementation) are provided.
00278  *
00279  * Refer to default imlementation wosh::ObjectReaderT.
00280  *
00281  * @see     wosh::IDataFieldReadable
00282  * @see     wosh::IDataFieldWrapperRead
00283  * @see     wosh::IDataFieldCollection
00284  * @see     wosh::IObjectWriter
00285  ****************************************************************************/
00286 class IObjectReader
00287  {
00288     public:
00289         IObjectReader() { }
00290         virtual ~IObjectReader() { }
00291 
00292     public:
00293         virtual WRESULT setObject( const IReflection* ptr ) = 0;
00294     public:
00295         ///@brief read field and return a ISerializable representation, NULL on failure
00296         virtual ISerializable* read( const char* field_name ) const = 0;
00297     public:
00298         ///@brief allocate an empty object, able (used as default proxy) to store passed filed, NULL on failure
00299         virtual ISerializable* alloc( const char* field_name ) const = 0;
00300         ///@brief set the security token of the current operation, it may be validated against field/object permissions
00301         virtual void setSecurityToken( const SecurityToken* token ) = 0;
00302 
00303 virtual void setMutex( MutexRW* access_mutex ) = 0;
00304 
00305     public:
00306         ///@brief Evaluate if Reader supports security check (SecurityToken vs. Permission)
00307         virtual bool isSecure() const = 0;
00308 
00309 virtual bool isReentrant() const = 0;
00310 
00311         ///@brief Evaluate if Reader is properly configured and able to read fields
00312         virtual bool isReadable() const = 0;
00313         ///@brief Retrieve the pointer of current data-field collection, down-casted to base interface,
00314         ///       so its useful only for field(name-index) mapping, listing (but not for execution!)
00315         virtual const IDataFieldCollection* getFieldCollection() const = 0;
00316 }; // class def
00317 ///----------------------------------------------------------------------------------------------------------------------
00318 ///----------------------------------------------------------------------------------------------------------------------
00319 
00320 ///----------------------------------------------------------------------------------------------------------------------
00321 /**
00322  * @class   wosh::IObjectWriter
00323  * @brief   data-field writing interface,  allow an external object to write(update) object's fields
00324  *          in a standardized protocol based on wosh::ISerializable class.
00325  *
00326  * Implementations are able to write generic object's fields and convert them to a standard
00327  * interface (as wosh::ISerializable).
00328  * \c Fields are defined (in a IDataFieldCollection) and mapped to Write(/Read) wrappers
00329  * (function pointers) through a set of (template) adapters working as proxy.
00330  *
00331  * In short, once configured, the architecture is able to map:
00332  * \code
00333 public myObject  {
00334     // [..]
00335         void setStringValue( const std::string& value );
00336     // [..]
00337  }
00338 \endcode
00339  * to
00340  * \code
00341 void external_function( IDataFieldWritable* object ) {
00342     Variant field_updated_value("my new string value");
00343     IObjectWriter* tmp_writer = object->createObjectWriter();
00344     tmp_writer->write("MyStringField", &field_updated_value );
00345     delete tmp_writer;
00346  }
00347 \endcode
00348  * 
00349  * Configuration stands for 'field definition', the code required to enable previous example is:
00350  * \code
00351 void myObject::initializeDataFields( DataFieldCollection<myObject>* fields ) {
00352     if ( fields == NULL ) return;
00353     DataFieldDefinitionT<myObject>* df_str = fields->add("MyStringField");
00354     df_str->setWrapperWrite<const std::string&, Variant, std::string>(&myObject::setStringValue, &Variant::toString );
00355  }
00356 \endcode
00357  * 
00358  * In order to expose a standard interface (not dependent on the object type/instance), the \c writer
00359  * must keep a must keep a (non-const) reference to the object (which owns real fields)
00360  * and a const reference to its IDataFieldCollection (casted-implementation/instance), collection
00361  * is required in order to recognize and access to the fields (though wrappers).
00362  *
00363  * \par Security
00364  *  wosh::IObjectWriter implementation may enable \c security-checks when a valid security-session context (wosh::SecurityToken by caller)
00365  *  and a wosh::Permission reference for the object (by the wosh::IDataFieldWritable implementation) are provided.
00366  *
00367  * @see     wosh::IDataFieldWritable
00368  * @see     wosh::IDataFieldWrapperWriter
00369  * @see     wosh::IDataFieldCollection
00370  * @see     wosh::IObjectReader
00371  ****************************************************************************/
00372 class IObjectWriter
00373  {
00374     public:
00375         IObjectWriter() { }
00376         virtual ~IObjectWriter() { }
00377 
00378     public:
00379         virtual WRESULT setObject( IReflection* ptr ) = 0;
00380     public:
00381         ///@brief write field converting(interpreting) ISerializable representation to real field-type
00382         virtual WRESULT write( const char* field_name, const ISerializable* data ) = 0;
00383     public:
00384         ///@brief allocate an empty object, able (used as default proxy) to store passed filed, NULL on failure
00385         virtual ISerializable* alloc( const char* field_name ) const = 0;
00386         ///@brief set the security token of the current operation, it may be validated against field/object permissions
00387         virtual void setSecurityToken( const SecurityToken* token ) = 0;
00388 
00389 virtual void setMutex( MutexRW* access_mutex ) = 0;
00390 
00391     public:
00392         ///@brief Evaluate if Writer supports security check (SecurityToken vs. Permission)
00393         virtual bool isSecure() const = 0;
00394 
00395 virtual bool isReentrant() const = 0;
00396 
00397         ///@brief Evaluate if Writer is properly configured and able to read fields
00398         virtual bool isWritable() const = 0;
00399         ///@brief Retrieve the pointer of current data-field collection, down-casted to base interface,
00400         ///       so its useful only for field(name-index) mapping, listing (but not for execution!)
00401         virtual const IDataFieldCollection* getFieldCollection() const = 0;
00402 }; // class def
00403 ///----------------------------------------------------------------------------------------------------------------------
00404 ///----------------------------------------------------------------------------------------------------------------------
00405 
00406 
00407 ///----------------------------------------------------------------------------------------------------------------------
00408 ///----------------------------------------------------------------------------------------------------------------------
00409 //
00410 #define DataFieldDefinition_MinPriority     -254
00411 
00412 class DataFieldDefinition
00413  {
00414     public:
00415         DataFieldDefinition( const char* _field_name = NULL, int index = -1 );
00416         DataFieldDefinition( const char* _field_name, int index, int uid, short priority );
00417         DataFieldDefinition( const DataFieldDefinition& m );
00418         virtual ~DataFieldDefinition();
00419 
00420     public:
00421         void setHeader( ISerializable* new_header );
00422 
00423     public:
00424         DataFieldDefinition& operator=(const DataFieldDefinition& m);
00425         bool operator==(const DataFieldDefinition &other) const;
00426         bool operator>(const DataFieldDefinition& other) const {
00427             return ( this->index>other.index );
00428          }
00429         bool operator<(const DataFieldDefinition& other) const {
00430             return ( this->index<other.index );
00431          }
00432 
00433     public:
00434         // after these calls fields will be ordered by INDEX
00435         static int filterFields( std::vector<DataFieldDefinition>& fields, short min_priority, int max_count = -1 );
00436         static int fixFieldsIndex( std::vector<DataFieldDefinition>& fields );
00437 
00438     public:
00439         int uid;
00440         std::string field_name;
00441         ISerializable* header;
00442         int index;
00443         short priority;
00444         short sort_mode;
00445 
00446 }; // class def
00447 bool DataFieldDefinition_compareIndex( const DataFieldDefinition* obj1, const DataFieldDefinition* obj2 );
00448 bool DataFieldDefinition_comparePriority( const DataFieldDefinition& obj1, const DataFieldDefinition& obj2 );
00449 
00450 ///----------------------------------------------------------------------------------------------------------------------
00451 //
00452 template <class OBJECT_TYPE>
00453 class DataFieldDefinitionT : public DataFieldDefinition {
00454     public:
00455         typedef IDataFieldWrapperRead<OBJECT_TYPE> tDataFieldWrapperRead;
00456         typedef IDataFieldWrapperWrite<OBJECT_TYPE> tDataFieldWrapperWrite;
00457         
00458     public:
00459         DataFieldDefinitionT( const char* _field_name = NULL )
00460             : DataFieldDefinition(_field_name), dw_reader(NULL), dw_writer(NULL), dw_allocator(NULL) {}
00461         virtual ~DataFieldDefinitionT() {
00462             if ( this->dw_reader != NULL ) delete this->dw_reader; this->dw_reader = NULL;
00463             if ( this->dw_writer != NULL ) delete this->dw_writer; this->dw_writer = NULL;
00464             if ( this->dw_allocator != NULL ) delete this->dw_allocator; this->dw_allocator = NULL;
00465          }
00466 
00467     public:
00468         template <class ALLOCATOR_TYPE>
00469         void setWrapperAlloc() {
00470             if ( this->dw_allocator != NULL ) delete this->dw_allocator; this->dw_allocator = NULL;
00471             this->dw_allocator = new DataFieldWrapperAllocT<ALLOCATOR_TYPE>();
00472          }
00473 
00474     public:
00475         inline void setWrapperRead( tDataFieldWrapperRead* reader )     { this->dw_reader = reader; }
00476 
00477         template <typename RETURN_TYPE, class ALLOCATOR_TYPE>
00478         void setWrapperRead( typename IDataFieldWrapperReadT<OBJECT_TYPE, RETURN_TYPE, ALLOCATOR_TYPE>::FieldReader fptr ) {
00479             if ( this->dw_reader != NULL ) delete this->dw_reader; this->dw_reader = NULL;
00480             IDataFieldWrapperReadT<OBJECT_TYPE, RETURN_TYPE, ALLOCATOR_TYPE>* dfw;
00481             dfw = new IDataFieldWrapperReadT<OBJECT_TYPE, RETURN_TYPE, ALLOCATOR_TYPE>(fptr);
00482             this->dw_reader = dfw;
00483             if ( this->dw_allocator == NULL )
00484                 this->dw_allocator = new DataFieldWrapperAllocT<ALLOCATOR_TYPE>();
00485          }
00486 
00487     public:
00488         inline void setWrapperRead( tDataFieldWrapperWrite* writer )    { this->dw_writer = writer; }
00489 
00490         template <typename ARGUMENT_TYPE, class PROXY_TYPE>
00491         void setWrapperWrite( typename IDataFieldWrapperWriteT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE>::FieldWriter fptr ) {
00492             if ( this->dw_writer != NULL ) delete this->dw_writer; this->dw_writer = NULL;
00493             IDataFieldWrapperWriteT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE>* dfw;
00494             dfw = new IDataFieldWrapperWriteT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE>(fptr);
00495             this->dw_writer = dfw;
00496             if ( this->dw_allocator == NULL )
00497                 this->dw_allocator = new DataFieldWrapperAllocT<PROXY_TYPE>();
00498          }
00499 
00500         template <typename ARGUMENT_TYPE, class PROXY_TYPE, class PROXY_RETURN_TYPE>
00501         void setWrapperWrite( typename IDataFieldWrapperWriteProxyT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE>::FieldWriter fptr,
00502                                 typename IDataFieldWrapperWriteProxyT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE>::ArgumentWrapper fptr_arg ) {
00503             if ( this->dw_writer != NULL ) delete this->dw_writer; this->dw_writer = NULL;
00504             IDataFieldWrapperWriteProxyT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE>* dfw;
00505             dfw = new IDataFieldWrapperWriteProxyT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE>(fptr,fptr_arg);
00506             this->dw_writer = dfw;
00507             if ( this->dw_allocator == NULL )
00508                 this->dw_allocator = new DataFieldWrapperAllocT<PROXY_TYPE>();
00509          }
00510 
00511         template <typename ARGUMENT_TYPE, class PROXY_TYPE, class PROXY_RETURN_TYPE, class PROXY_ARGUMENT_TYPE>
00512         void setWrapperWrite( typename IDataFieldWrapperWriteWithArgT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE, PROXY_ARGUMENT_TYPE>::FieldWriter fptr,
00513                                 typename IDataFieldWrapperWriteWithArgT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE, PROXY_ARGUMENT_TYPE>::ArgumentWrapper fptr_arg,
00514                                 const PROXY_ARGUMENT_TYPE& arg_value ) {
00515             if ( this->dw_writer != NULL ) delete this->dw_writer; this->dw_writer = NULL;
00516             IDataFieldWrapperWriteWithArgT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE, PROXY_ARGUMENT_TYPE>* dfw;
00517             dfw = new IDataFieldWrapperWriteWithArgT<OBJECT_TYPE, ARGUMENT_TYPE, PROXY_TYPE, PROXY_RETURN_TYPE, PROXY_ARGUMENT_TYPE>(fptr,fptr_arg, arg_value);
00518             this->dw_writer = dfw;
00519          }
00520 
00521     public:
00522         inline bool hasWrapperRead() const                  { return (this->dw_reader != NULL); }
00523         inline bool hasWrapperWrite() const                 { return (this->dw_writer != NULL); }
00524         inline bool hasWrapperAlloc() const                 { return (this->dw_allocator != NULL); }
00525 
00526         inline const tDataFieldWrapperRead* reader() const  { return this->dw_reader; }
00527         inline const tDataFieldWrapperWrite* writer() const { return this->dw_writer; }
00528         inline tDataFieldWrapperRead* reader()              { return this->dw_reader; }
00529         inline tDataFieldWrapperWrite* writer()             { return this->dw_writer; }
00530         inline IDataFieldWrapperAlloc* allocator() const    { return this->dw_allocator; }
00531 
00532     protected:
00533         mutable tDataFieldWrapperRead* dw_reader;
00534         mutable tDataFieldWrapperWrite* dw_writer;
00535         mutable IDataFieldWrapperAlloc* dw_allocator;
00536 
00537 }; // class def
00538 
00539 
00540 ///----------------------------------------------------------------------------------------------------------------------
00541 ///----------------------------------------------------------------------------------------------------------------------
00542 //
00543 class IDataFieldCollection
00544  {
00545     public:
00546         IDataFieldCollection() : initialized(false) { }
00547         virtual ~IDataFieldCollection() { }
00548     public:
00549         virtual const DataFieldDefinition* getField( int index ) const = 0;
00550         virtual DataFieldDefinition* getField( int index ) = 0;
00551         virtual const DataFieldDefinition* getField( const char* field_name ) const = 0;
00552         virtual DataFieldDefinition* getField( const char* field_name ) = 0;
00553 
00554         virtual int getFields( std::vector<DataFieldDefinition>& fields_out ) const = 0;
00555 
00556         virtual WRESULT finalize() = 0;
00557 
00558     public:
00559         virtual bool isInitialized() const          { return this->initialized; }
00560 //      virtual void setInitialized( bool value )   { this->initialized = value; }
00561     protected:
00562         bool initialized;
00563 
00564 }; // class def
00565 ///----------------------------------------------------------------------------------------------------------------------
00566 //
00567 template <class OBJECT_TYPE>
00568 class DataFieldCollection : public virtual IDataFieldCollection
00569  {
00570     public:
00571         typedef DataFieldDefinitionT<OBJECT_TYPE> tDataFieldDefinition;
00572     public:
00573         DataFieldCollection() : IDataFieldCollection() { }
00574         virtual ~DataFieldCollection() {
00575             clear();
00576          }
00577 
00578     public:
00579         int add( tDataFieldDefinition* dfw ) {
00580             if ( dfw == NULL ) return -1;
00581             dfw->uid = this->fields.size();
00582             this->fields.push_back(dfw);
00583             return this->fields.size();
00584          }
00585         tDataFieldDefinition* add( const char* field_name, short priority = 0, short force_index = -1 ) {
00586             tDataFieldDefinition* dfw = new tDataFieldDefinition(field_name);
00587             dfw->priority = priority;
00588             if ( force_index != -1 ) dfw->index = force_index;
00589             add(dfw);
00590             return dfw;
00591          }
00592 
00593     public:
00594         void clear() {
00595             typename std::vector<tDataFieldDefinition*>::iterator it;
00596             for( it=this->fields.begin(); it!=this->fields.end(); ++it ) {
00597                 if ( *it == NULL ) continue;
00598                 delete *it;
00599              }
00600             this->fields.clear();
00601          }
00602 
00603         inline const std::vector<tDataFieldDefinition*>& getFields() const  { return this->fields; }
00604         inline std::vector<tDataFieldDefinition*>& getFields()              { return this->fields; }
00605 
00606         virtual int getFields( std::vector<DataFieldDefinition>& fields_out ) const {
00607             typename std::vector<tDataFieldDefinition*>::const_iterator it;
00608             for( it=this->fields.begin(); it!=this->fields.end(); ++it ) {
00609                 if ( *it == NULL ) continue;
00610                 fields_out.push_back(DataFieldDefinition(*(*it)));
00611              }
00612             return fields_out.size();
00613          }
00614 
00615         virtual inline const tDataFieldDefinition* getField( int index ) const {
00616             if ( index < 0 || index > (int)this->fields.size() ) return NULL;
00617             return this->fields.at(index);
00618          }
00619         virtual inline tDataFieldDefinition* getField( int index ) {
00620             if ( index < 0 || index > (int)this->fields.size() ) return NULL;
00621             return this->fields.at(index);
00622          }
00623 
00624         virtual inline const tDataFieldDefinition* getField( const char* field_name ) const {
00625             if ( field_name == NULL ) return NULL;
00626             typename std::vector<tDataFieldDefinition*>::const_iterator it;
00627             for( it=this->fields.begin(); it!=this->fields.end(); ++it ) {
00628                 if ( *it == NULL ) continue;
00629                 if ( strcmp(field_name, (*it)->field_name.c_str()) == 0 ) return *it;
00630              }
00631             return NULL;
00632          }
00633         virtual inline tDataFieldDefinition* getField( const char* field_name ) {
00634             if ( field_name == NULL ) return NULL;
00635             typename std::vector<tDataFieldDefinition*>::const_iterator it;
00636             for( it=this->fields.begin(); it!=this->fields.end(); ++it ) {
00637                 if ( *it == NULL ) continue;
00638                 if ( strcmp(field_name, (*it)->field_name.c_str()) == 0 ) return *it;
00639              }
00640             return NULL;
00641          }
00642 
00643     public:
00644         virtual WRESULT finalize() {
00645             this->initialized = true;
00646 
00647             tDataFieldDefinition* cField = NULL;
00648             typename std::vector<tDataFieldDefinition*>::const_iterator it;
00649             for( int cIndex=0; cIndex<(int)this->fields.size(); ++cIndex ) {
00650                 cField = NULL;
00651                 for( it=this->fields.begin(); it!=this->fields.end(); ++it ) {
00652                     if ( *it == NULL ) continue;
00653 
00654                     if ( cField == NULL ) {
00655                         if ( (*it)->index == cIndex )
00656                             cField = *it;
00657                      }
00658                     else {
00659                         if ( (*it)->index == cIndex )
00660                             ++(*it)->index;
00661                      }
00662                  }
00663              }
00664             int offset = 0;
00665             std::sort(this->fields.begin(), this->fields.end(), DataFieldDefinition_compareIndex );
00666             for( it=this->fields.begin(); it!=this->fields.end(); ++it ) {
00667                 if ( *it == NULL ) continue;
00668                 if ( (*it)->index == -1 )
00669                     (*it)->index = this->fields.back()->index + ++offset;
00670              }
00671             std::sort(this->fields.begin(), this->fields.end(), DataFieldDefinition_compareIndex );
00672             int cIndex=0;
00673             for( it=this->fields.begin(); it!=this->fields.end(); ++it, ++cIndex ) {
00674                 if ( *it == NULL ) continue;
00675                 (*it)->index = cIndex;
00676              }
00677 
00678             return WRET_OK;
00679          }
00680 
00681     protected:
00682         std::vector<tDataFieldDefinition*> fields;
00683 
00684 }; // class def
00685 
00686 
00687 
00688 
00689 ///----------------------------------------------------------------------------------------------------------------------
00690 //
00691 template <class OBJECT_TYPE>
00692 class ObjectReaderT : public IObjectReader
00693  {
00694     public:
00695         typedef DataFieldCollection<OBJECT_TYPE> tDataFieldCollection;
00696     public:
00697 
00698     public:
00699         ObjectReaderT( const OBJECT_TYPE* obj = NULL, const tDataFieldCollection* fields_def = NULL, Permission* obj_permission = NULL )
00700             : IObjectReader(), object(obj), permission(obj_permission), fields(fields_def), access_token(NULL), access_mutex(NULL) { }
00701         virtual ~ObjectReaderT() {
00702             if ( this->permission != NULL ) delete this->permission;
00703          }
00704 
00705     public:
00706         virtual ISerializable* read( const char* field_name ) const {
00707             const typename tDataFieldCollection::tDataFieldDefinition* field_def;
00708             field_def = fields->getField(field_name);
00709             if ( field_def == NULL ) return NULL;
00710             if ( this->object == NULL ) return NULL;
00711             if ( !field_def->hasWrapperRead() ) return NULL;
00712             return field_def->reader()->read(this->object);
00713          }
00714 
00715 
00716     public:
00717         virtual WRESULT setObject( const IReflection* ptr ) {
00718             if ( ptr == NULL ) this->object = NULL;
00719             else {
00720                 const OBJECT_TYPE* objTmp = dynamic_cast<const OBJECT_TYPE*>(ptr);
00721                 if ( objTmp == NULL ) return WRET_ERR_PARAM;
00722                 this->object = objTmp;
00723              }
00724             return WRET_OK;
00725          }
00726 
00727         virtual inline void setObjectT( const OBJECT_TYPE* ptr )                { this->object = ptr; }
00728         virtual inline void setSecurityToken( const SecurityToken* token )      { this->access_token = token; }
00729         virtual inline void setMutex( MutexRW* mutex )                          { this->access_mutex = mutex; }
00730 
00731         virtual ISerializable* alloc( const char* field_name ) const {
00732             const typename tDataFieldCollection::tDataFieldDefinition* field_def;
00733             field_def = fields->getField(field_name);
00734             if ( field_def == NULL ) return NULL;
00735             if ( !field_def->hasWrapperAlloc() ) return NULL;
00736             return field_def->allocator()->alloc();
00737          }
00738     public:
00739         virtual inline bool isSecure() const                                    { return ( this->permission != NULL ); }
00740         virtual inline bool isReentrant() const                                 { return ( this->access_mutex != NULL ); }
00741         virtual inline bool isReadable() const {
00742             if ( this->object == NULL || this->fields == NULL) return false;
00743             return true;
00744         }
00745         virtual inline const IDataFieldCollection* getFieldCollection() const   { return this->fields; }
00746 
00747     protected:
00748         const OBJECT_TYPE* object;
00749         Permission* permission;
00750         const tDataFieldCollection* fields;
00751         const SecurityToken* access_token;
00752         MutexRW* access_mutex;
00753 }; // class def
00754 ///----------------------------------------------------------------------------------------------------------------------
00755 //
00756 template <class OBJECT_TYPE>
00757 class ObjectWriterT : public IObjectWriter
00758  {
00759     public:
00760         typedef DataFieldCollection<OBJECT_TYPE> tDataFieldCollection;
00761     public:
00762 
00763     public:
00764         ObjectWriterT( OBJECT_TYPE* obj = NULL, const tDataFieldCollection* fields_def = NULL, Permission* obj_permission = NULL )
00765             : IObjectWriter(), object(obj), permission(obj_permission), fields(fields_def), access_token(NULL), access_mutex(NULL) { }
00766         virtual ~ObjectWriterT() { }
00767 
00768     public:
00769         virtual WRESULT write( const char* field_name, const ISerializable* data ) {
00770             const typename tDataFieldCollection::tDataFieldDefinition* field_def;
00771             field_def = fields->getField(field_name);
00772             if ( field_def == NULL ) return WRET_ERR_PARAM;
00773             if ( this->object == NULL ) return WRET_ERR_ILLEGAL_USE;
00774             if ( !field_def->hasWrapperWrite() ) return WRET_ERR_ILLEGAL_USE;
00775             return field_def->writer()->write(this->object, data);
00776         }
00777 
00778     public:
00779         virtual WRESULT setObject( IReflection* ptr ) {
00780             if ( ptr == NULL ) this->object = NULL;
00781             else {
00782                 OBJECT_TYPE* objTmp = dynamic_cast<OBJECT_TYPE*>(ptr);
00783                 if ( objTmp == NULL ) return WRET_ERR_PARAM;
00784                 this->object = objTmp;
00785              }
00786             return WRET_OK;
00787          }
00788         virtual inline void setObjectT( OBJECT_TYPE* ptr )                      { this->object = ptr; }
00789 
00790         virtual inline void setSecurityToken( const SecurityToken* token )      { this->access_token = token; }
00791         virtual inline void setMutex( MutexRW* mutex )                          { this->access_mutex = mutex; }
00792 
00793         virtual ISerializable* alloc( const char* field_name ) const {
00794             const typename tDataFieldCollection::tDataFieldDefinition* field_def;
00795             field_def = fields->getField(field_name);
00796             if ( field_def == NULL ) return NULL;
00797             if ( !field_def->hasWrapperAlloc() ) return NULL;
00798             return field_def->allocator()->alloc();
00799          }
00800 
00801     public:
00802         virtual inline bool isSecure() const                                    { return ( this->permission != NULL ); }
00803         virtual inline bool isReentrant() const                                 { return ( this->access_mutex != NULL ); }
00804         virtual inline bool isWritable() const {
00805             if ( this->object == NULL || this->fields == NULL) return false;
00806             return true;
00807         }
00808         virtual inline const IDataFieldCollection* getFieldCollection() const   { return this->fields; }
00809 
00810     protected:
00811         OBJECT_TYPE* object;
00812         Permission* permission;
00813         const tDataFieldCollection* fields;
00814         const SecurityToken* access_token;
00815         MutexRW* access_mutex;
00816 }; // class def
00817 
00818 
00819 ///----------------------------------------------------------------------------------------------------------------------
00820 ///----------------------------------------------------------------------------------------------------------------------
00821 ///----------------------------------------------------------------------------------------------------------------------
00822 
00823 
00824 
00825 
00826 }; // namespace wosh
00827 
00828 #endif //__WOSH_Core_DataFields_H__

Generated on Tue Feb 8 2011 09:32:49 for WOSH system 0.8.888 [wolf] by Alessandro Polo, using DoxyGen 1.7.2 hosted by WOSH Framework