Changeset 151

Show
Ignore:
Timestamp:
08/22/08 20:57:40 (16 years ago)
Author:
mido
Message:

UserInfo?, finalni verze, cas vznaset pripominky ( krom komentaru, ty zatim nejsou hotove, a netreba to pripominat:)

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • bdm/userinfo.cpp

    r142 r151  
    1313#include "userinfo.h" 
    1414 
    15 XercesConnector::XercesConnector() 
     15BindingFrame::BindingFrame() 
     16        : dummy() 
    1617{ 
    17         // initialize the XML library 
    18         XMLPlatformUtils::Initialize(); 
     18} 
    1919 
     20string BindingFrame::XMLCh2str( const XMLCh* const  XMLCh_str ) 
     21{ 
     22        char *local = XMLString::transcode( XMLCh_str ); 
     23        string res = local;              
     24        XMLString::release( &local ); 
     25        return res; 
     26} 
     27 
     28 
     29Attribute::Attribute( string attributeName ) 
     30        : dummy(),       
     31        transcodedAttributeName( XMLString::transcode( attributeName.c_str() ) ) 
     32{ 
     33} 
     34 
     35Attribute::~Attribute() 
     36{                        
     37        XMLString::release( (XMLCh**)&transcodedAttributeName ); 
     38} 
     39 
     40string& Attribute::Get( DOMElement &element ) const 
     41{ 
     42        const XMLCh* const transcoded_str = element.getAttribute( transcodedAttributeName ); 
     43        return *new string( XMLString::transcode( transcoded_str ) ); 
     44} 
     45 
     46void Attribute::Set( DOMElement &element, const string &str ) const 
     47{ 
     48        if( !str.length() ) return;      
     49        const XMLCh* transcoded_str = XMLString::transcode(str.c_str()); 
     50        element.setAttribute( transcodedAttributeName, transcoded_str ); 
     51        XMLString::release( (XMLCh**) &transcoded_str ); 
     52} 
     53 
     54const Attribute Attribute::help( "help" ); 
     55  
     56const Attribute Attribute::type( "type" ); 
     57 
     58const Attribute Attribute::value( "value" ); 
     59 
     60 
     61UserInfo::StringToUIMap::MappedString2UI& UserInfo::StringToUIMap::privateMap() 
     62{ 
     63        static MappedString2UI var; 
     64        return var; 
     65} 
     66 
     67void UserInfo::StringToUIMap::Add( string key, pUserInfo pInstance ) 
     68{ 
     69        privateMap().insert( make_pair( key, pInstance ) ); 
     70} 
     71 
     72UserInfo::pUserInfo UserInfo::StringToUIMap::Retrieve( string key ) 
     73{ 
     74        MappedString2UI::const_iterator iter = privateMap().find( key ); 
     75        if( iter == privateMap().end()) return NULL; 
     76        else return iter->second; 
     77}        
     78 
     79RootElement::RootElement( char* fileName ) 
     80        : dummy(), 
     81        transcodedFileName( XMLString::transcode( fileName ) ) 
     82{                
    2083        // get a serializer, an instance of DOMWriter (the "LS" stands for load-save). 
    2184        pImplementation = DOMImplementationRegistry::getDOMImplementation( XMLString::transcode( "LS" )); 
     
    2790        if (pSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true)) 
    2891                pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true); 
     92 
     93        pDoc = NULL; 
     94        Clean(); 
    2995} 
    3096 
    31 XercesConnector::~XercesConnector() 
     97RootElement::~RootElement() 
    3298{ 
    33         delete pSerializer; 
     99        XMLString::release( (XMLCh**)&transcodedFileName ); 
     100        pSerializer->release(); 
     101        pDoc->release(); 
    34102 
    35         // terminate the XML library 
    36         XMLPlatformUtils::Terminate(); 
     103        AssertXercesIsAlive dummy; // TODO je zde treba? 
    37104} 
    38105 
    39 string XercesConnector::XMLCh2str( const XMLCh* const  XMLCh_str ) 
     106void RootElement::Clean() 
    40107{ 
    41         char *local = XMLString::transcode( XMLCh_str ); 
    42         string res = local;              
    43         XMLString::release( &local ); 
    44         return res; 
     108        if( pDoc ) pDoc->release(); 
     109        pDoc = pImplementation->createDocument(  
     110                XMLString::transcode( "M3K USER INFO" ),  
     111                XMLString::transcode( "ROOT" ), NULL ); 
    45112} 
    46113 
    47 bool XercesConnector::Comparator::operator()( const XMLCh* const a , const XMLCh* const b) const 
     114//! loads root element from a file 
     115bool RootElement::Load( void )  
    48116{ 
    49         return ( XMLString::compareString(a,b) > 0); 
     117        const LocalFileInputSource inputSource( transcodedFileName );            
     118 
     119        //! This DOMWriter is used to import external data from xml files 
     120        XercesDOMParser parser; 
     121 
     122        parser.setValidationScheme(XercesDOMParser::Val_Auto); 
     123        parser.setDoNamespaces(false); 
     124        parser.setDoSchema(false); 
     125 
     126        parser.parse( inputSource ); 
     127        if( parser.getErrorCount() ) 
     128                return false; 
     129 
     130        DOMDocument * newDoc = parser.adoptDocument();   
     131        if( newDoc == NULL )                                     
     132                return false; 
     133 
     134        if( pDoc )  
     135                pDoc->release(); 
     136 
     137        pDoc = newDoc;                   
     138        return true;             
     139} 
     140 
     141 
     142//! Save UserInfo to the file (typically with an XML extension) 
     143void RootElement::Save ( void ) 
     144{ 
     145        LocalFileFormatTarget outputTarget( transcodedFileName );        
     146        pSerializer->writeNode( &outputTarget, *pDoc); 
    50147}        
    51148 
     149RootElement::operator DOMElement& () 
     150{ 
     151        return *(pDoc->getDocumentElement()); 
     152} 
  • bdm/userinfo.h

    r150 r151  
    3131This class is used to interact with the Xerces library. 
    3232*/ 
    33 class XercesConnector 
    34 { 
    35 public: 
    36         //! DOMImplementation is a base class for the all DOM oparations 
    37         DOMImplementation *pImplementation; 
    38         //! This DOMWriter is used to export internal data into xml files 
    39         DOMWriter *pSerializer; 
    40  
    41 private: 
    42         //!default constructor 
    43         XercesConnector(); 
    44         //!destructor 
    45         ~XercesConnector(); 
    46         //!forbidden copy constructor 
    47         XercesConnector( XercesConnector& ref ); 
    48 public: 
    49  
    50         DOMDocument* Parse( const LocalFileInputSource & inputSource ) 
    51         { 
    52                 //! This DOMWriter is used to import external data from xml files 
    53                 XercesDOMParser parser; 
    54  
    55                 parser.setValidationScheme(XercesDOMParser::Val_Auto); 
    56                 parser.setDoNamespaces(false); 
    57                 parser.setDoSchema(false); 
    58  
    59                 parser.parse( inputSource ); 
    60                 if( parser.getErrorCount() ) 
    61                         return NULL; 
    62                  
    63                 return parser.adoptDocument();   
    64         } 
    65  
     33/// TODO slo by i bez vnorene tridy? 
     34class AssertXercesIsAlive 
     35{ 
     36private: 
     37        class XercesConnector 
     38        { 
     39        private: 
     40                //!default constructor 
     41                XercesConnector() 
     42                { 
     43                        // initialize the XML library 
     44                        XMLPlatformUtils::Initialize(); 
     45                } 
     46 
     47                ~XercesConnector() 
     48                { 
     49                        // terminate the XML library 
     50                        XMLPlatformUtils::Terminate(); 
     51                } 
     52 
     53        public: 
     54                //! The only global instance of the XercesConnector class 
     55                // potrebujeme inicializaci hned v okamziku zavolani!! 
     56                static void StayAlive() 
     57                { 
     58                        static XercesConnector xc;               
     59                }; 
     60        }; 
     61 
     62 
     63public: 
     64        AssertXercesIsAlive() 
     65        { 
     66                XercesConnector::StayAlive(); 
     67        } 
     68}; 
     69 
     70 
     71class BindingFrame 
     72{ 
     73private: 
     74        // okomentovat, ze musi byt prvni 
     75        AssertXercesIsAlive dummy; 
     76protected: 
     77        BindingFrame(); 
    6678 
    6779        //! function transcodes Xerces' XMLCh-based strings into C++ strings 
    6880        string XMLCh2str( const XMLCh* const  XMLCh_str ); 
    6981 
    70         class Comparator 
    71         { 
    72         public: 
    73                 //! operator compares two XMLCh strings and wheather the first is alphabethically higher 
    74                 bool operator()( const XMLCh* const a , const XMLCh* const b) const; 
    75         }; 
    76  
    77         //! The only global instance of the XercesConnector class 
    78         // potrebujeme inicializaci hned v okamziku zavolani!! 
    79         static XercesConnector& instance() 
    80         { 
    81                 static XercesConnector gxc; 
    82                 return gxc; 
    83         }; 
    84 }; 
    85  
    86 class BindingFrame 
    87 { 
    88 protected: 
    89         BindingFrame() 
    90         { 
    91                 // trik, chci jen to, aby se ZAVCAS inicializoval!! 
    92                 // tj pred vsema UI apod.. hlavne pred praci s XMLStringem 
    93                 XercesConnector::instance(); 
    94         } 
    95  
    96 public: 
    97          
     82public:  
    9883        // nacpe na prislusne pointery, kdyztak da NULL 
    99         virtual void AssemblyBindedData( DOMElement &element ) = 0; 
     84        virtual void AssemblyFromXML( DOMElement &element ) = 0; 
    10085 
    10186        // uvolneni pameti po slozeni objektu, tj. lze jedine po AssemblyBD 
    102         virtual void ReleaseUsedMemory() 
    103         { 
    104         } 
     87        virtual void ReleaseMemory() {} 
    10588 
    10689        // vrati bool, pokud se povedlo rozebrat a naplnit element 
    10790        // nebude tu nahodou jeste ten help - string?? 
    108         virtual bool DisassemblyBindedData( DOMElement &element ) = 0;           
    109 }; 
    110  
    111 class BindedAttribute : public BindingFrame 
    112 { 
    113 private:                 
     91        virtual bool DisassamblyToXML( DOMElement &element ) = 0;                
     92}; 
     93 
     94class Attribute  
     95{                
     96private: 
     97        // okomentovat, ze musi byt prvni 
     98        AssertXercesIsAlive dummy; 
     99 
    114100        const XMLCh* const transcodedAttributeName; 
    115101 
    116102public: 
    117         BindedAttribute( string attributeName ) 
    118                 : transcodedAttributeName( XMLString::transcode( attributeName.c_str() ) ) 
    119         { 
    120         } 
    121  
    122         ~BindedAttribute() 
    123         {                        
    124                 XMLString::release( (XMLCh**)&transcodedAttributeName ); 
    125         } 
    126  
    127         // TAM JSOU TY HODNOTY 
    128         string str; 
     103        Attribute( string attributeName ); 
     104 
     105        ~Attribute(); 
    129106 
    130107        // nacpe na prislusne pointery, kdyztak da NULL 
    131         void AssemblyBindedData( DOMElement &element ) 
    132         { 
    133                 const XMLCh* const transcoded_str = element.getAttribute( transcodedAttributeName ); 
    134                 str = string( XMLString::transcode( transcoded_str ) ); 
    135         } 
    136  
    137         bool DisassemblyBindedData( DOMElement &element ) 
    138         { 
    139                 const XMLCh* transcoded_str = XMLString::transcode(str.c_str()); 
    140                 element.setAttribute( transcodedAttributeName, transcoded_str ); 
    141                 XMLString::release( (XMLCh**) &transcoded_str ); 
    142                 return true; 
    143         } 
    144 }; 
     108        string& Get( DOMElement &element ) const; 
     109 
     110        void Set( DOMElement &element, const string &str ) const;        
     111 
     112        static const Attribute help; 
     113 
     114        static const Attribute type; 
     115 
     116        static const Attribute value; 
     117}; 
     118 
     119 
    145120 
    146121/*! 
     
    150125CompoundUserInfo<T> objects even for different generic types. 
    151126*/ 
    152  
    153 class UserInfo : public BindingFrame 
    154 { 
    155 private: 
    156         //! Type definition of mapping which transforms type names to the related user infors 
    157         typedef map< const string, UserInfo*> MappedString2UI; 
     127class UserInfo : protected BindingFrame 
     128{ 
     129private: 
     130        typedef UserInfo* const pUserInfo; 
     131 
     132        // immediately initialized map..!! 
     133        static class StringToUIMap 
     134        { 
     135        private: 
     136                //! Type definition of mapping which transforms type names to the related user infors 
     137                typedef map< const string, pUserInfo > MappedString2UI; 
     138 
     139                static MappedString2UI& privateMap(); 
     140 
     141        public: 
     142                static void Add( string key, pUserInfo pInstance ); 
     143 
     144                static pUserInfo Retrieve( string key ); 
     145        }; 
     146                                 
     147        virtual void* AssemblyTypelessInstance() = 0; 
    158148         
    159         //! Mapped  
    160         static MappedString2UI& userFriendlyNames2UI() 
    161         { 
    162                 static MappedString2UI var; 
    163                 return var; 
    164         } 
    165  
    166         //! Mapped  
    167         static MappedString2UI& namesByRTTI2UI() 
    168         { 
    169                 static MappedString2UI var; 
    170                 return var; 
    171         } 
    172  
    173         BindedAttribute nameAttribute; 
    174  
    175         BindedAttribute typeAttribute; 
     149        virtual bool DisassemblyTypelessInstance(void* pInstance) = 0; 
    176150 
    177151        const string userFriendlyTypeName; 
    178 public: 
     152 
    179153        const string typeNameByRTTI; 
     154 
     155protected: 
    180156 
    181157        //! The only constructor which fills both the transcodedTypeName and the help attribute 
    182158        UserInfo( const string& userFriendlyTypeName, const string& typeNameByRTTI ) 
    183                 : userFriendlyTypeName ( userFriendlyTypeName ), 
    184                 typeNameByRTTI( typeNameByRTTI ), 
    185                 nameAttribute( "name"), 
    186                 typeAttribute( "type") 
     159                : userFriendlyTypeName ( userFriendlyTypeName ), typeNameByRTTI( typeNameByRTTI ) 
    187160        {        
    188                 userFriendlyNames2UI().insert( make_pair( userFriendlyTypeName, this ) ); 
    189                 namesByRTTI2UI().insert( make_pair( typeNameByRTTI, this ) ); 
    190         } 
    191  
    192         ~UserInfo() 
    193         {                
    194         } 
    195  
    196 public: 
    197          
    198         virtual void BuildInternal(void* &pInstance) = 0; 
    199          
    200         virtual void AbsorbInternal(void* &pInstance) = 0; 
    201  
     161                StringToUIMap::Add( userFriendlyTypeName, this ); 
     162                // we do not care which name it is, therfore we have common map, 
     163                // and it is no use to pass the same string again 
     164                if( userFriendlyTypeName != typeNameByRTTI ) 
     165                        StringToUIMap::Add( typeNameByRTTI, this ); 
     166        } 
     167 
     168public:  
    202169        //! returns object of templated type filled with data stored in this CompoundUserInfo instance 
    203         // NULL if error.. 
     170        // NULL if error.. TODO nekam dat error message..! 
    204171        template<class T> 
    205         static void Assembly( T* &pInstance, DOMElement &element, const string tagName ) 
     172        static T* Assembly( DOMElement &element, const string tagName ) 
    206173        {        
    207                 pInstance = NULL; 
    208  
    209174                XMLCh* transcodedTagName = XMLString::transcode( tagName.c_str() );              
    210175                XMLString::upperCase( transcodedTagName ); 
     
    213178                DOMNodeList* const nodeList = element.getElementsByTagName( transcodedTagName ); 
    214179                XMLString::release( (XMLCh**)&transcodedTagName ); 
    215  
    216                 if( nodeList == NULL || nodeList->getLength() != 1 ) 
    217                         return; 
     180                if( !nodeList || nodeList->getLength() == 0 ) 
     181                { 
     182                        cerr << "There is not any tag named """ << tagName << """ in the passed DOM element of a XML docmument!"; 
     183                        return NULL; 
     184                } 
     185 
     186                if( nodeList->getLength() > 1 ) 
     187                { 
     188                        cerr << "There is to many elements named """ << tagName << """ in the passed DOM element of a XML docmument. But the tag name has to be unique!"; 
     189                        return NULL; 
     190                } 
    218191 
    219192                // TAKZE MAME V RUCE ELEMENT SE JMENEM "tagName" 
    220                 DOMElement* selectedElement = (DOMElement*) nodeList->item(0); 
    221  
    222                 // COZ O TO, UDELAL BYCH TO STATICKOU KONSTANTOU, ALE JAK JI PAK SMAZU?? 
    223                 XMLCh* transcodedTypeAttributeName = XMLString::transcode("type"); 
    224                 const XMLCh* const transcodedType = selectedElement->getAttribute( transcodedTypeAttributeName ); 
    225                 XMLString::release( (XMLCh**)&transcodedTypeAttributeName ); 
    226  
    227                 if( !XMLString::stringLen( transcodedType ) ) 
    228                         return; 
     193                DOMElement* pTheOnlyElement = (DOMElement*) nodeList->item(0); 
    229194 
    230195                // TED MAME V RUCE JMENO TYPU Z ATRIBUTU TYPE 
    231                 string userFriendlyTypeName = XercesConnector::instance().XMLCh2str( transcodedType ); 
     196                string userFriendlyTypeName = Attribute::type.Get( *pTheOnlyElement ); 
    232197         
    233                 MappedString2UI::const_iterator iter = userFriendlyNames2UI().find( userFriendlyTypeName ); 
    234                 if( iter == userFriendlyNames2UI().end()) 
    235                         return; 
    236  
    237198                // A TED PRISLUSNE UI 
    238                 UserInfo *relatedUI = iter->second; 
    239                 relatedUI->AssemblyBindedData( *selectedElement );               
    240                 relatedUI->BuildInternal( (void*&)pInstance ); 
    241                 relatedUI->ReleaseUsedMemory(); 
    242  
    243                 if( pInstance == NULL ) 
    244                         return; 
    245  
     199                pUserInfo pRelatedUI = StringToUIMap::Retrieve( userFriendlyTypeName ); 
     200                if( !pRelatedUI ) 
     201                { 
     202                        cerr << "There is not any UserInfo related to type named """ << userFriendlyTypeName << """, instance assembling terminated!"; 
     203                        return NULL; 
     204                } 
     205 
     206                pRelatedUI->AssemblyFromXML( *pTheOnlyElement );                 
     207                void* pTypelessInstance = pRelatedUI->AssemblyTypelessInstance(); 
     208                pRelatedUI->ReleaseMemory(); 
     209 
     210                if( pTypelessInstance == NULL ) 
     211                { 
     212                        // TODO lepe specifikovat 
     213                        cerr << "Unknown error, instance assembling terminated!"; 
     214                        return NULL; 
     215                } 
     216 
     217                T* pInstance = NULL; 
    246218                try 
    247219                { 
    248220                        // typova kontrola "do it yourself":) 
     221                        pInstance = (T*) pTypelessInstance; 
    249222                        string resultingTypeNameByRTTI = typeid( *pInstance ).name(); 
    250                         if( resultingTypeNameByRTTI != relatedUI->typeNameByRTTI ) 
     223                        if( resultingTypeNameByRTTI != pRelatedUI->typeNameByRTTI ) 
    251224                        { 
    252                                 cout << "FATAL ERROR!!" << endl; 
    253                                 pInstance = NULL; 
    254                         }                        
     225                                cerr << "Fatal error, UserInfo related to type """ << userFriendlyTypeName << """ have just returned instance of a different type!"; 
     226                                return NULL; // TODO hlaska OK?? 
     227                        } 
    255228                } 
    256229                catch(...) 
    257230                { 
    258                         // delete? ale jak na to? asi tezko 
    259                         pInstance = NULL; 
     231                        pInstance = NULL; // TODO chybovou hlasku 
    260232                }                
    261                 return; 
     233 
     234                return pInstance; 
    262235        }        
    263236 
    264         //! returns object of templated type filled with data stored in this CompoundUserInfo instance 
    265         // NULL if error.. 
    266237        template<class T> 
    267         static bool Disassembly( T* pInstance, DOMElement &element, const string tagName, const string help) 
     238        static bool Disassembly( T& instance, DOMElement &element, const string tagName, const string help) 
    268239        {        
    269                 if( pInstance == NULL) 
     240                pUserInfo pRelatedUI = StringToUIMap::Retrieve( typeid(instance).name() ); 
     241                if( !pRelatedUI ) 
    270242                        return false; 
    271243 
     244                // add a new element named according the passed tagName 
    272245                XMLCh* transcodedTagName = XMLString::transcode( tagName.c_str() );              
    273246                XMLString::upperCase( transcodedTagName ); 
    274  
    275                 // ADD NEW ELEMENT 
    276247                DOMDocument* pDoc = element.getOwnerDocument(); 
    277                 DOMElement* selectedElement = pDoc->createElement( transcodedTagName );          
    278                 element.appendChild( selectedElement ); 
     248                DOMElement* pCreatedElement = pDoc->createElement( transcodedTagName );          
     249                element.appendChild( pCreatedElement ); 
    279250                XMLString::release( (XMLCh**)&transcodedTagName ); 
    280  
    281251                         
    282                 // hledame vhodne UI - co ty mapy jeste nejako zapouzdrit?!?!  
    283                 MappedString2UI::const_iterator iter = namesByRTTI2UI().find( typeid(*pInstance).name() ); 
    284                 if( iter == namesByRTTI2UI().end()) 
     252                // add attributes "type" and "help" 
     253                Attribute::type.Set( *pCreatedElement, pRelatedUI->userFriendlyTypeName );               
     254                Attribute::help.Set( *pCreatedElement, help ); 
     255 
     256                // NASMERUJE UKAZATELE BindingFrames.. rozloz na pointery..  
     257                bool result =  pRelatedUI->DisassemblyTypelessInstance( (void*) &instance ); 
     258                if( result ) 
     259                        result = pRelatedUI->DisassamblyToXML( *pCreatedElement );               
     260                return result; 
     261        }        
     262 
     263        template<class T> 
     264        static bool Disassembly( T &instance, DOMElement &element, const string tagName ) 
     265        { 
     266                return Disassembly( instance, element, tagName, "" ); 
     267        } 
     268}; 
     269 
     270template<typename T> class TypedUserInfo : public UserInfo 
     271{ 
     272private: 
     273 
     274        bool DisassemblyTypelessInstance(void* pInstance) 
     275        { 
     276                try 
     277                { 
     278                        return DisassemblyInstance( *(T*) pInstance ); 
     279                } 
     280                catch (...) 
     281                { 
    285282                        return false; 
    286                 UserInfo *relatedUI = iter->second; 
    287  
    288                 // PRIDAM ATRIBUT TYPE - UDELAT NA TO METODU!! NEBO JESTE LEPE SPECIALNI BINDOVACI OBJEKT.. 
    289                 // opet obousmernej, jen na stringy.. pouziju i u valuedUI.. 
    290                 const XMLCh* transcodedTypeAttributeName = XMLString::transcode("type"); 
    291                 const XMLCh* transcodedUserFriendlyTypeName = XMLString::transcode(relatedUI->userFriendlyTypeName.c_str()); 
    292                 selectedElement->setAttribute( transcodedTypeAttributeName, transcodedUserFriendlyTypeName ); 
    293                 XMLString::release( (XMLCh**)&transcodedTypeAttributeName ); 
    294                 XMLString::release( (XMLCh**)&transcodedUserFriendlyTypeName ); 
    295  
    296                 if( help.length() ) 
    297                 { 
    298                         // PRIDAM ATRIBUT TYPE 
    299                         const XMLCh* transcodedHelpAttributeName = XMLString::transcode("help"); 
    300                         const XMLCh* transcodedHelpString = XMLString::transcode( help.c_str() ); 
    301                         selectedElement->setAttribute( transcodedHelpAttributeName, transcodedHelpString ); 
    302                         XMLString::release( (XMLCh**)&transcodedHelpAttributeName ); 
    303                         XMLString::release( (XMLCh**)&transcodedHelpString ); 
    304                 } 
    305  
    306  
    307                 // A TED PRISLUSNE UI 
    308                 // NASMERUJE UKAZATELE BindingFrames.. nejak lip pojmenovat 
    309                 // sloz z pointeru, rozloz na pointery..  
    310                 relatedUI->AbsorbInternal( (void*&)pInstance ); 
    311                 // rozebere soucastky 
    312                 return relatedUI->DisassemblyBindedData( *selectedElement );             
    313         }        
    314  
    315         //! returns object of templated type filled with data stored in this CompoundUserInfo instance 
    316         // NULL if error.. 
    317         template<class T> 
    318         static bool Disassembly( T* pInstance, DOMElement &element, const string tagName ) 
    319         { 
    320                 return Disassembly( pInstance, element, tagName, "" ); 
    321         } 
    322 }; 
    323  
    324  
    325 template<typename T> class TypedUserInfo : public UserInfo 
    326 { 
     283                } 
     284        } 
     285 
     286        void* AssemblyTypelessInstance() 
     287        { 
     288                return (void*) AssemblyInstance( ); 
     289        } 
     290 
     291        virtual T* AssemblyInstance() = 0; 
     292 
     293        virtual bool DisassemblyInstance(T& instance) = 0; 
     294 
    327295protected: 
    328296 
     
    339307 
    340308public: 
    341         // FRIEND radeji 
    342         void BuildInternal(void* &pInstance) 
    343         { 
    344                 T* &pTypedInstance = (T*&) pInstance; 
    345                 Build( pTypedInstance ); 
    346         } 
    347  
    348         virtual void Build(T* &pTypedInstance) = 0; 
    349  
    350         // FRIEND radeji 
    351         void AbsorbInternal(void* &pInstance) 
    352         { 
    353                 T* &pTypedInstance = (T*&) pInstance; 
    354                 Absorb( pTypedInstance ); 
    355         } 
    356  
    357         virtual void Absorb(T* &pTypedInstance) = 0; 
    358  
    359         static const TypedUserInfo<T> * pInstance; 
    360 }; 
    361  
     309        static const TypedUserInfo<T>& instance; 
     310 
     311}; 
    362312 
    363313 
     
    374324 
    375325protected: 
    376         template<typename U> class BindedType: public BindingFrame 
     326        template<typename U> class BindedElement: public BindingFrame 
    377327        { 
    378328        private: 
    379                 const TypedUserInfo<U> &factory; 
    380329                string name; 
    381                 string help; 
    382  
     330                string help;                             
     331                bool release; 
     332 
     333                U* pValue; 
     334 
     335                const U defaultValue; 
     336                 
    383337        public: 
    384                 U* pInstance; 
    385  
    386                 BindedType<U>( CompoundUserInfo<T> *parent, string name, string help )  
    387                         : name( name), help(help) 
    388                         factory( TypedUserInfo<U>::instance )            
     338                U value; 
     339 
     340                BindedElement<U>( CompoundUserInfo<T> *parent, string name, U defaultValue, string help )  
     341                        : name( name), help(help), defaultValue( defaultValue ) 
    389342                { 
    390343                        parent->bindedElements.push_back( this ); 
    391                         pInstance = NULL; 
    392                 } 
    393  
    394                 BindedType<U>( CompoundUserInfo<T> *parent, string name )  
    395                         : name( name), help(""), 
    396                         factory( *TypedUserInfo<U>::pInstance )          
     344                        pValue = NULL; 
     345                        value = defaultValue; 
     346                } 
     347 
     348                BindedElement<U>( CompoundUserInfo<T> *parent, string name, U defaultValue )  
     349                        : name( name), help(""), defaultValue( defaultValue ), value( defaultValue) 
    397350                { 
    398351                        parent->bindedElements.push_back( this ); 
    399                         pInstance = NULL; 
    400                 } 
    401  
    402                 void AssemblyBindedData( DOMElement &element ) 
    403                 { 
    404                         factory.Assembly( pInstance, element, name ); 
    405                 } 
    406  
    407                 void ReleaseUsedMemory() 
    408                 { 
    409                         if( pInstance != NULL ) 
    410                                 delete pInstance; 
    411                 } 
    412  
    413                 bool DisassemblyBindedData( DOMElement &element ) 
    414                 { 
    415                         return factory.Disassembly( pInstance, element, name, help ); 
     352                        pValue = NULL; 
     353                        value = defaultValue; 
     354                } 
     355 
     356                ~BindedElement<U>() 
     357                { 
     358                } 
     359 
     360                void AssemblyFromXML( DOMElement &element ) 
     361                { 
     362                        pValue = UserInfo::Assembly<U>( element, name ); 
     363                        if( pValue ) value = *pValue;                    
     364                } 
     365 
     366                void ReleaseMemory() 
     367                { 
     368                        if( pValue != NULL ) 
     369                                delete pValue; 
     370                } 
     371 
     372                bool DisassamblyToXML( DOMElement &element ) 
     373                { 
     374                        return UserInfo::Disassembly( value, element, name, help ); 
    416375                } 
    417376        }; 
     
    422381        } 
    423382 
    424  
    425 public: 
    426  
    427         void AssemblyBindedData( DOMElement &element ) 
     383public: 
     384 
     385        void AssemblyFromXML( DOMElement &element ) 
    428386        { 
    429387                for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) 
    430                         bindedElements[ind]->AssemblyBindedData( element ); 
    431         } 
    432  
    433         void ReleaseUsedMemory() 
     388                        bindedElements[ind]->AssemblyFromXML( element ); 
     389        } 
     390 
     391        void ReleaseMemory() 
    434392        {                        
    435393                for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) 
    436                         bindedElements[ind]->ReleaseUsedMemory(); 
    437         } 
    438  
    439         bool DisassemblyBindedData( DOMElement &element ) 
     394                        bindedElements[ind]->ReleaseMemory(); 
     395        } 
     396 
     397        bool DisassamblyToXML( DOMElement &element ) 
    440398        { 
    441399                for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) 
    442                         if( !bindedElements[ind]->DisassemblyBindedData( element ) ) 
     400                        if( !bindedElements[ind]->DisassamblyToXML( element ) ) 
    443401                                return false; 
    444402                return true; 
     
    449407template<typename T> class ValuedUserInfo : public TypedUserInfo<T> 
    450408{ 
    451  
    452 private: 
    453         const XMLCh* const transcodedValueName; 
    454  
    455 public: 
    456         // Value nemusi byt pointer, na rozdil od ostatnich binding framu.. 
     409protected: 
     410        ValuedUserInfo<T>( string userFriendlyTypeName ) 
     411                : TypedUserInfo<T>( userFriendlyTypeName ) 
     412        { 
     413        } 
     414 
     415        ~ValuedUserInfo<T>() 
     416        { 
     417        } 
     418 
     419public: 
     420        // zde nemusi byt pointer 
    457421        string value; 
    458422 
    459         ValuedUserInfo<T>( string userFriendlyTypeName ) 
    460                 : TypedUserInfo<T>( userFriendlyTypeName ), 
    461                   transcodedValueName( XMLString::transcode( "value" )) 
    462         { 
    463         } 
    464  
    465         ~ValuedUserInfo<T>() 
    466         { 
    467                 XMLString::release( (XMLCh**)&transcodedValueName ); 
    468         } 
    469  
    470         void AssemblyBindedData( DOMElement &element ) 
     423        void AssemblyFromXML( DOMElement &element ) 
    471424        {                
    472                 const XMLCh* const transcodedValue = element.getAttribute( transcodedValueName ); 
    473                 value = XercesConnector::instance().XMLCh2str( transcodedValue ); 
    474         } 
    475  
    476         bool DisassemblyBindedData( DOMElement &element ) 
    477         { 
    478                 if( value.length() ) 
    479                 { 
    480                         const XMLCh* transcodedValueString = XMLString::transcode( value.c_str() ); 
    481                         element.setAttribute( transcodedValueName, transcodedValueString ); 
    482                         XMLString::release( (XMLCh**)&transcodedValueString ); 
    483                 } 
     425                value = Attribute::value.Get( element ); 
     426        } 
     427 
     428        bool DisassamblyToXML( DOMElement &element ) 
     429        { 
     430                Attribute::value.Set( element, value ); 
    484431                return true; 
    485432        } 
     
    487434 
    488435 
    489 class RootElement  
    490 { 
    491436// umi se pretypovat na DOMElement &element      
    492437// a to vzdy, save a load se muze udelat az pak!! 
    493  
    494 private: 
    495         DOMElement * pRoot; 
     438class RootElement  
     439{ 
     440 
     441private: 
     442        // TODO musi byt prvni!! zkusit schvalne prehodit, 
     443        // za jmeno, a zarucit, ze Xerces jeste nebezi.. hraje to fakt roli?? 
     444        const AssertXercesIsAlive dummy; 
     445 
    496446        DOMDocument* pDoc; 
    497447 
    498         const XMLCh* const transcodedFileName ; 
    499  
    500 public: 
    501  
    502         RootElement( char* fileName ) 
    503                 : transcodedFileName( XMLString::transcode( fileName ) ) 
    504         {                
    505                 pDoc = XercesConnector::instance().pImplementation->createDocument(  
    506                         XMLString::transcode( "M3K USER INFO" ),  
    507                         XMLString::transcode( "ROOT" ), NULL ); 
    508                 pRoot = pDoc->getDocumentElement(); 
    509         } 
    510  
    511         ~RootElement() 
    512         { 
    513                 XMLString::release( (XMLCh**)&transcodedFileName ); 
    514                 if( pDoc )  
    515                         delete pDoc;             
    516         } 
     448        const XMLCh* const transcodedFileName; 
     449 
     450        //! DOMImplementation is a base class for the all DOM oparations 
     451        DOMImplementation *pImplementation; 
     452 
     453        //! This DOMWriter is used to export internal data into xml files 
     454        DOMWriter *pSerializer; 
     455 
     456public: 
     457        RootElement( char* fileName ); 
     458 
     459        ~RootElement(); 
     460 
     461        void Clean(); 
    517462 
    518463        //! loads root element from a file 
    519         bool Load( void )  
    520         { 
    521                 const LocalFileInputSource inputSource( transcodedFileName );            
    522                 DOMDocument * newDoc = XercesConnector::instance().Parse( inputSource ); 
    523                 if( newDoc == NULL )                                     
    524                         return false; 
    525  
    526                 if( pDoc )  
    527                         delete pDoc;             
    528  
    529                 pDoc = newDoc;                   
    530                 pRoot = pDoc->getDocumentElement(); 
    531                 return true;             
    532         } 
    533  
     464        bool Load( void ) ; 
    534465 
    535466        //! Save UserInfo to the file (typically with an XML extension) 
    536         void Save ( void ) 
    537         { 
    538                 LocalFileFormatTarget outputTarget( transcodedFileName );        
    539                 XercesConnector::instance().pSerializer->writeNode( &outputTarget, *pDoc); 
    540         }        
    541  
    542         operator DOMElement&() 
    543         { 
    544                 return *pRoot; 
    545         } 
     467        void Save ( void ); 
     468 
     469        operator DOMElement&(); 
    546470}; 
    547471 
  • tests/testUI.cpp

    r150 r151  
    11#include "userinfo.h" 
    22 
     3////////////////////////////////////////////////////////////////////////////////////////////// 
     4////////////////////////////////////////// BASIC VALUED USER INFOS /////////////////////////// 
     5////////////////////////////////////////////////////////////////////////////////////////////// 
     6 
     7class BoolUI: public ValuedUserInfo<bool> 
     8{ 
     9private: 
     10 
     11        bool* AssemblyInstance() 
     12        {                
     13                if( value == "true" ) 
     14                        return new bool( true ); 
     15                else 
     16                        return new bool( false ); 
     17        } 
     18 
     19        bool DisassemblyInstance(bool &instance) 
     20        { 
     21                if( instance ) 
     22                        value = "true"; 
     23                else 
     24                        value = "false"; 
     25                return true;  
     26        } 
     27 
     28public: 
     29 
     30        BoolUI() 
     31                : ValuedUserInfo<bool>("bool") 
     32        { 
     33        } 
     34}; 
     35 
     36const TypedUserInfo<bool>& TypedUserInfo<bool>::instance = BoolUI(); 
     37 
     38 
    339class IntUI: public ValuedUserInfo<int> 
    440{ 
     41private: 
     42 
     43        int* AssemblyInstance() 
     44        { 
     45                return new int( atoi( value.c_str()) ); 
     46        } 
     47 
     48        bool DisassemblyInstance(int &instance) 
     49        { 
     50                char buff[30]; 
     51                sprintf(buff, "%d", instance ); 
     52                value = buff; 
     53                return true;  
     54        } 
     55 
    556public: 
    657        IntUI():ValuedUserInfo<int>("int") 
    758        { 
    859        } 
    9  
    10         void Build(int* &pInstance) 
    11         { 
    12                 pInstance = new int( atoi( value.c_str()) ); 
    13         } 
    14  
    15         void Absorb(int* &pInstance) 
     60}; 
     61 
     62const TypedUserInfo<int>& TypedUserInfo<int>::instance = IntUI(); 
     63 
     64 
     65class DoubleUI: public ValuedUserInfo<double> 
     66{ 
     67private: 
     68 
     69        double* AssemblyInstance() 
     70        { 
     71                return new double( atof( value.c_str()) ); 
     72        } 
     73 
     74        bool DisassemblyInstance(double &instance) 
    1675        { 
    1776                char buff[30]; 
    18                 sprintf(buff, "%d", *pInstance ); 
     77                sprintf(buff, "%f", instance ); 
    1978                value = buff; 
    20         } 
    21 }; 
    22  
    23 const TypedUserInfo<int>* TypedUserInfo<int>::pInstance = new IntUI(); 
     79                return true;  
     80        } 
     81 
     82public: 
     83        DoubleUI():ValuedUserInfo<double>("double") 
     84        { 
     85        } 
     86}; 
     87 
     88const TypedUserInfo<double>& TypedUserInfo<double>::instance = DoubleUI(); 
    2489 
    2590 
    2691class StringUI: public ValuedUserInfo<string> 
    2792{ 
     93private: 
     94        string* AssemblyInstance() 
     95        { 
     96                return new string( value ); 
     97        } 
     98 
     99        bool DisassemblyInstance(string &instance) 
     100        { 
     101                value = instance; 
     102                return true; 
     103        } 
     104 
    28105public: 
    29106        StringUI():ValuedUserInfo<string>("string") 
    30107        { 
    31108        } 
    32  
    33         void Build(string* &pInstance) 
    34         { 
    35                 pInstance  = new string( value ); 
    36         } 
    37  
    38         void Absorb(string* &pInstance) 
    39         { 
    40                 value = *pInstance; 
    41         } 
    42 }; 
    43  
    44 const TypedUserInfo<string>* TypedUserInfo<string>::pInstance = new StringUI(); 
    45  
    46 class Car 
    47 { 
    48 public: 
    49         int age; 
    50         string brand; 
    51  
    52         Car( int age, string brand) 
    53                 : age( age), brand( brand) 
    54         { 
    55         } 
    56 }; 
     109}; 
     110 
     111const TypedUserInfo<string>& TypedUserInfo<string>::instance = StringUI(); 
     112 
     113////////////////////////////////////////////////////////////////////////////////////////////// 
     114////////////////////////////////////////// EXAMPLE CLASSES DEFINITION //////////////////////// 
     115////////////////////////////////////////////////////////////////////////////////////////////// 
     116class Transport 
     117{ 
     118public: 
     119        const int year; 
     120        const string manufacturer; 
     121 
     122        Transport( int year, string manufacturer ) 
     123                : year( year ), manufacturer( manufacturer ) 
     124        { 
     125        } 
     126 
     127        virtual public void ToString() = 0; 
     128}; 
     129 
     130class Car : public Transport 
     131{ 
     132public: 
     133        const int kilometers; 
     134 
     135        Car( int year, string manufacturer, int kilometers ) 
     136                : Transport( year, manufacturer ), kilometers( kilometers ) 
     137        { 
     138        } 
     139 
     140        void ToString() 
     141        { 
     142                cout << "a car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock." << endl; 
     143        } 
     144}; 
     145 
     146class Bike : public Transport 
     147{ 
     148public: 
     149        const bool electricLights; 
     150 
     151        Bike( int age, string manufacturer, bool electricLights ) 
     152                : Transport( age, manufacturer ), electricLights( electricLights ) 
     153        { 
     154        } 
     155 
     156        void ToString() 
     157        { 
     158                cout << "a bike made in " << year << " by " << manufacturer; 
     159                if( electricLights ) cout << " with electric lights included";                                           
     160                cout << endl;            
     161        } 
     162}; 
     163 
     164////////////////////////////////////////////////////////////////////////////////////////////// 
     165////////////////////////////////////////// AND RELATED USER INFOS //////////////////////////// 
     166////////////////////////////////////////////////////////////////////////////////////////////// 
     167 
    57168 
    58169class CarUI: public CompoundUserInfo<Car> 
    59170{ 
    60 public: 
    61         BindedType<int> age; 
    62         BindedType<string> brand; 
    63  
     171private: 
     172        BindedElement<int> year;  
     173        BindedElement<int> kilometers;  
     174        BindedElement<string> manufacturer;  
     175public: 
    64176        CarUI() 
    65177                :CompoundUserInfo<Car>("car"), 
    66                 age( this, "age" ), 
    67                 brand( this, "brand") 
    68         { 
    69         } 
    70  
    71         void Build(Car* &pInstance) 
    72         { 
    73                 if( age.pInstance == NULL ) age.pInstance = new int (0); 
    74                 if( brand.pInstance == NULL ) brand.pInstance = new string("noname"); 
    75                 pInstance  = new Car( *age.pInstance, *brand.pInstance ); 
    76         } 
    77  
    78         void Absorb(Car* &pInstance) 
    79         { 
    80                 age.pInstance = &pInstance->age; 
    81                 brand.pInstance = &pInstance->brand; 
    82         } 
    83 }; 
    84  
    85 const TypedUserInfo<Car>* TypedUserInfo<Car>::pInstance = new CarUI( ); 
     178                year( this, "year", 0 ), 
     179                kilometers( this, "kilometers", 0 ), 
     180                manufacturer( this, "manufacturer", "unknown") 
     181        { 
     182        } 
     183private: 
     184 
     185        Car* AssemblyInstance() 
     186        { 
     187                // assembly new instance 
     188                return new Car( year.value, manufacturer.value, kilometers.value ); 
     189        } 
     190 
     191        bool DisassemblyInstance(Car& instance) 
     192        { 
     193                year.value = instance.year; 
     194                manufacturer.value = instance.manufacturer; 
     195                kilometers.value = instance.kilometers; 
     196                return true; 
     197        } 
     198}; 
     199 
     200const TypedUserInfo<Car>& TypedUserInfo<Car>::instance = CarUI( ); 
     201 
     202 
     203class BikeUI: public CompoundUserInfo<Bike> 
     204{ 
     205private: 
     206        BindedElement<int> year;  
     207        BindedElement<bool> lights;  
     208        BindedElement<string> manufacturer;  
     209public: 
     210        BikeUI() 
     211                :CompoundUserInfo<Bike>("bike"), 
     212                year( this, "year", 0 ), 
     213                lights( this, "electric_lights", false ), // jen jedno slovo! 
     214                manufacturer( this, "manufacturer", "unknown") 
     215        { 
     216        } 
     217private: 
     218 
     219        Bike* AssemblyInstance() 
     220        { 
     221                // assembly new instance 
     222                return new Bike( year.value, manufacturer.value, lights.value ); 
     223        } 
     224 
     225        bool DisassemblyInstance(Bike& instance) 
     226        { 
     227                year.value = instance.year; 
     228                manufacturer.value = instance.manufacturer; 
     229                lights.value = instance.electricLights; 
     230                return true; 
     231        } 
     232}; 
     233 
     234const TypedUserInfo<Bike>& TypedUserInfo<Bike>::instance = BikeUI( ); 
    86235 
    87236 
    88237int main() 
    89238{ 
     239        Car audi( 1998, "audi", 25000); 
     240        Car liaz( 1992, "liaz", 1555000); 
     241        Bike author( 1996, "author", true ); 
     242 
    90243        /////////////////////////////////// SAVING /////////////////////////// 
    91         Car newCar( 20, "audina" ); 
    92  
    93         RootElement root("car.xml"); 
    94         // NESLO BY TAM MISTO POINTERU PRIMO REFERENCI, 
    95         // NEBO TAK NECO?!?! ASI JO..! 
    96         if( !UserInfo::Disassembly( &newCar,root,"kara") ) 
     244 
     245        RootElement root("transport.xml"); 
     246 
     247        if( !UserInfo::Disassembly( audi, root, "pepikovo")  
     248                || !UserInfo::Disassembly( liaz, root, "jardovo")  
     249                || !UserInfo::Disassembly( author, root, "ondrejovo") ) 
    97250        { 
    98251                cout << "there was some error!" << endl; 
     
    102255 
    103256        root.Save(); 
    104         cout << "the new car was saved correctly!" << endl;                              
     257        cout << "all the transport means were saved correctly" << endl;                          
    105258        getchar(); 
    106259 
    107260        //////////////////////////////////// LOADING //////////////////////////////// 
    108261 
    109  
    110         Car *loadedCar; 
     262        string whichone = "pepikovo"; 
     263//      whichone = "jardovo"; 
     264        whichone = "ondrejovo"; 
     265 
    111266        root.Load(); 
    112         UserInfo::Assembly(loadedCar,root,"kara"); 
     267        Transport *loaded = UserInfo::Assembly<Transport>( root,whichone); 
    113268         
    114         if( loadedCar ) 
    115                 cout << "loaded car: age=" << loadedCar->age << ", brand=" << loadedCar->brand << endl; 
     269        if( loaded ) 
     270                loaded->ToString(); 
    116271        else 
    117                 cout << "there was some error during car loading!" << endl; 
     272                cout << "there was some error during loading!" << endl; 
    118273                 
    119274        getchar();