Changeset 151
- Timestamp:
- 08/22/08 20:57:40 (16 years ago)
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
bdm/userinfo.cpp
r142 r151 13 13 #include "userinfo.h" 14 14 15 XercesConnector::XercesConnector() 15 BindingFrame::BindingFrame() 16 : dummy() 16 17 { 17 // initialize the XML library 18 XMLPlatformUtils::Initialize(); 18 } 19 19 20 string 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 29 Attribute::Attribute( string attributeName ) 30 : dummy(), 31 transcodedAttributeName( XMLString::transcode( attributeName.c_str() ) ) 32 { 33 } 34 35 Attribute::~Attribute() 36 { 37 XMLString::release( (XMLCh**)&transcodedAttributeName ); 38 } 39 40 string& 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 46 void 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 54 const Attribute Attribute::help( "help" ); 55 56 const Attribute Attribute::type( "type" ); 57 58 const Attribute Attribute::value( "value" ); 59 60 61 UserInfo::StringToUIMap::MappedString2UI& UserInfo::StringToUIMap::privateMap() 62 { 63 static MappedString2UI var; 64 return var; 65 } 66 67 void UserInfo::StringToUIMap::Add( string key, pUserInfo pInstance ) 68 { 69 privateMap().insert( make_pair( key, pInstance ) ); 70 } 71 72 UserInfo::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 79 RootElement::RootElement( char* fileName ) 80 : dummy(), 81 transcodedFileName( XMLString::transcode( fileName ) ) 82 { 20 83 // get a serializer, an instance of DOMWriter (the "LS" stands for load-save). 21 84 pImplementation = DOMImplementationRegistry::getDOMImplementation( XMLString::transcode( "LS" )); … … 27 90 if (pSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true)) 28 91 pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true); 92 93 pDoc = NULL; 94 Clean(); 29 95 } 30 96 31 XercesConnector::~XercesConnector()97 RootElement::~RootElement() 32 98 { 33 delete pSerializer; 99 XMLString::release( (XMLCh**)&transcodedFileName ); 100 pSerializer->release(); 101 pDoc->release(); 34 102 35 // terminate the XML library 36 XMLPlatformUtils::Terminate(); 103 AssertXercesIsAlive dummy; // TODO je zde treba? 37 104 } 38 105 39 string XercesConnector::XMLCh2str( const XMLCh* const XMLCh_str)106 void RootElement::Clean() 40 107 { 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 ); 45 112 } 46 113 47 bool XercesConnector::Comparator::operator()( const XMLCh* const a , const XMLCh* const b) const 114 //! loads root element from a file 115 bool RootElement::Load( void ) 48 116 { 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) 143 void RootElement::Save ( void ) 144 { 145 LocalFileFormatTarget outputTarget( transcodedFileName ); 146 pSerializer->writeNode( &outputTarget, *pDoc); 50 147 } 51 148 149 RootElement::operator DOMElement& () 150 { 151 return *(pDoc->getDocumentElement()); 152 } -
bdm/userinfo.h
r150 r151 31 31 This class is used to interact with the Xerces library. 32 32 */ 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? 34 class AssertXercesIsAlive 35 { 36 private: 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 63 public: 64 AssertXercesIsAlive() 65 { 66 XercesConnector::StayAlive(); 67 } 68 }; 69 70 71 class BindingFrame 72 { 73 private: 74 // okomentovat, ze musi byt prvni 75 AssertXercesIsAlive dummy; 76 protected: 77 BindingFrame(); 66 78 67 79 //! function transcodes Xerces' XMLCh-based strings into C++ strings 68 80 string XMLCh2str( const XMLCh* const XMLCh_str ); 69 81 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 82 public: 98 83 // nacpe na prislusne pointery, kdyztak da NULL 99 virtual void Assembly BindedData( DOMElement &element ) = 0;84 virtual void AssemblyFromXML( DOMElement &element ) = 0; 100 85 101 86 // uvolneni pameti po slozeni objektu, tj. lze jedine po AssemblyBD 102 virtual void ReleaseUsedMemory() 103 { 104 } 87 virtual void ReleaseMemory() {} 105 88 106 89 // vrati bool, pokud se povedlo rozebrat a naplnit element 107 90 // 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 94 class Attribute 95 { 96 private: 97 // okomentovat, ze musi byt prvni 98 AssertXercesIsAlive dummy; 99 114 100 const XMLCh* const transcodedAttributeName; 115 101 116 102 public: 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(); 129 106 130 107 // 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 145 120 146 121 /*! … … 150 125 CompoundUserInfo<T> objects even for different generic types. 151 126 */ 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; 127 class UserInfo : protected BindingFrame 128 { 129 private: 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; 158 148 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; 176 150 177 151 const string userFriendlyTypeName; 178 public: 152 179 153 const string typeNameByRTTI; 154 155 protected: 180 156 181 157 //! The only constructor which fills both the transcodedTypeName and the help attribute 182 158 UserInfo( const string& userFriendlyTypeName, const string& typeNameByRTTI ) 183 : userFriendlyTypeName ( userFriendlyTypeName ), 184 typeNameByRTTI( typeNameByRTTI ), 185 nameAttribute( "name"), 186 typeAttribute( "type") 159 : userFriendlyTypeName ( userFriendlyTypeName ), typeNameByRTTI( typeNameByRTTI ) 187 160 { 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 168 public: 202 169 //! 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..! 204 171 template<class T> 205 static void Assembly( T* &pInstance,DOMElement &element, const string tagName )172 static T* Assembly( DOMElement &element, const string tagName ) 206 173 { 207 pInstance = NULL;208 209 174 XMLCh* transcodedTagName = XMLString::transcode( tagName.c_str() ); 210 175 XMLString::upperCase( transcodedTagName ); … … 213 178 DOMNodeList* const nodeList = element.getElementsByTagName( transcodedTagName ); 214 179 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 } 218 191 219 192 // 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); 229 194 230 195 // TED MAME V RUCE JMENO TYPU Z ATRIBUTU TYPE 231 string userFriendlyTypeName = XercesConnector::instance().XMLCh2str( transcodedType);196 string userFriendlyTypeName = Attribute::type.Get( *pTheOnlyElement ); 232 197 233 MappedString2UI::const_iterator iter = userFriendlyNames2UI().find( userFriendlyTypeName );234 if( iter == userFriendlyNames2UI().end())235 return;236 237 198 // 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; 246 218 try 247 219 { 248 220 // typova kontrola "do it yourself":) 221 pInstance = (T*) pTypelessInstance; 249 222 string resultingTypeNameByRTTI = typeid( *pInstance ).name(); 250 if( resultingTypeNameByRTTI != relatedUI->typeNameByRTTI )223 if( resultingTypeNameByRTTI != pRelatedUI->typeNameByRTTI ) 251 224 { 252 c out << "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 } 255 228 } 256 229 catch(...) 257 230 { 258 // delete? ale jak na to? asi tezko 259 pInstance = NULL; 231 pInstance = NULL; // TODO chybovou hlasku 260 232 } 261 return; 233 234 return pInstance; 262 235 } 263 236 264 //! returns object of templated type filled with data stored in this CompoundUserInfo instance265 // NULL if error..266 237 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) 268 239 { 269 if( pInstance == NULL) 240 pUserInfo pRelatedUI = StringToUIMap::Retrieve( typeid(instance).name() ); 241 if( !pRelatedUI ) 270 242 return false; 271 243 244 // add a new element named according the passed tagName 272 245 XMLCh* transcodedTagName = XMLString::transcode( tagName.c_str() ); 273 246 XMLString::upperCase( transcodedTagName ); 274 275 // ADD NEW ELEMENT276 247 DOMDocument* pDoc = element.getOwnerDocument(); 277 DOMElement* selectedElement = pDoc->createElement( transcodedTagName );278 element.appendChild( selectedElement );248 DOMElement* pCreatedElement = pDoc->createElement( transcodedTagName ); 249 element.appendChild( pCreatedElement ); 279 250 XMLString::release( (XMLCh**)&transcodedTagName ); 280 281 251 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 270 template<typename T> class TypedUserInfo : public UserInfo 271 { 272 private: 273 274 bool DisassemblyTypelessInstance(void* pInstance) 275 { 276 try 277 { 278 return DisassemblyInstance( *(T*) pInstance ); 279 } 280 catch (...) 281 { 285 282 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 327 295 protected: 328 296 … … 339 307 340 308 public: 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 }; 362 312 363 313 … … 374 324 375 325 protected: 376 template<typename U> class Binded Type: public BindingFrame326 template<typename U> class BindedElement: public BindingFrame 377 327 { 378 328 private: 379 const TypedUserInfo<U> &factory;380 329 string name; 381 string help; 382 330 string help; 331 bool release; 332 333 U* pValue; 334 335 const U defaultValue; 336 383 337 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 ) 389 342 { 390 343 parent->bindedElements.push_back( this ); 391 p Instance = 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) 397 350 { 398 351 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 ); 416 375 } 417 376 }; … … 422 381 } 423 382 424 425 public: 426 427 void AssemblyBindedData( DOMElement &element ) 383 public: 384 385 void AssemblyFromXML( DOMElement &element ) 428 386 { 429 387 for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) 430 bindedElements[ind]->Assembly BindedData( element );431 } 432 433 void Release UsedMemory()388 bindedElements[ind]->AssemblyFromXML( element ); 389 } 390 391 void ReleaseMemory() 434 392 { 435 393 for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) 436 bindedElements[ind]->Release UsedMemory();437 } 438 439 bool Disass emblyBindedData( DOMElement &element )394 bindedElements[ind]->ReleaseMemory(); 395 } 396 397 bool DisassamblyToXML( DOMElement &element ) 440 398 { 441 399 for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) 442 if( !bindedElements[ind]->Disass emblyBindedData( element ) )400 if( !bindedElements[ind]->DisassamblyToXML( element ) ) 443 401 return false; 444 402 return true; … … 449 407 template<typename T> class ValuedUserInfo : public TypedUserInfo<T> 450 408 { 451 452 private: 453 const XMLCh* const transcodedValueName; 454 455 public: 456 // Value nemusi byt pointer, na rozdil od ostatnich binding framu.. 409 protected: 410 ValuedUserInfo<T>( string userFriendlyTypeName ) 411 : TypedUserInfo<T>( userFriendlyTypeName ) 412 { 413 } 414 415 ~ValuedUserInfo<T>() 416 { 417 } 418 419 public: 420 // zde nemusi byt pointer 457 421 string value; 458 422 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 ) 471 424 { 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 ); 484 431 return true; 485 432 } … … 487 434 488 435 489 class RootElement490 {491 436 // umi se pretypovat na DOMElement &element 492 437 // a to vzdy, save a load se muze udelat az pak!! 493 494 private: 495 DOMElement * pRoot; 438 class RootElement 439 { 440 441 private: 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 496 446 DOMDocument* pDoc; 497 447 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 456 public: 457 RootElement( char* fileName ); 458 459 ~RootElement(); 460 461 void Clean(); 517 462 518 463 //! 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 ) ; 534 465 535 466 //! 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&(); 546 470 }; 547 471 -
tests/testUI.cpp
r150 r151 1 1 #include "userinfo.h" 2 2 3 ////////////////////////////////////////////////////////////////////////////////////////////// 4 ////////////////////////////////////////// BASIC VALUED USER INFOS /////////////////////////// 5 ////////////////////////////////////////////////////////////////////////////////////////////// 6 7 class BoolUI: public ValuedUserInfo<bool> 8 { 9 private: 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 28 public: 29 30 BoolUI() 31 : ValuedUserInfo<bool>("bool") 32 { 33 } 34 }; 35 36 const TypedUserInfo<bool>& TypedUserInfo<bool>::instance = BoolUI(); 37 38 3 39 class IntUI: public ValuedUserInfo<int> 4 40 { 41 private: 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 5 56 public: 6 57 IntUI():ValuedUserInfo<int>("int") 7 58 { 8 59 } 9 10 void Build(int* &pInstance) 11 { 12 pInstance = new int( atoi( value.c_str()) ); 13 } 14 15 void Absorb(int* &pInstance) 60 }; 61 62 const TypedUserInfo<int>& TypedUserInfo<int>::instance = IntUI(); 63 64 65 class DoubleUI: public ValuedUserInfo<double> 66 { 67 private: 68 69 double* AssemblyInstance() 70 { 71 return new double( atof( value.c_str()) ); 72 } 73 74 bool DisassemblyInstance(double &instance) 16 75 { 17 76 char buff[30]; 18 sprintf(buff, "% d", *pInstance );77 sprintf(buff, "%f", instance ); 19 78 value = buff; 20 } 21 }; 22 23 const TypedUserInfo<int>* TypedUserInfo<int>::pInstance = new IntUI(); 79 return true; 80 } 81 82 public: 83 DoubleUI():ValuedUserInfo<double>("double") 84 { 85 } 86 }; 87 88 const TypedUserInfo<double>& TypedUserInfo<double>::instance = DoubleUI(); 24 89 25 90 26 91 class StringUI: public ValuedUserInfo<string> 27 92 { 93 private: 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 28 105 public: 29 106 StringUI():ValuedUserInfo<string>("string") 30 107 { 31 108 } 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 111 const TypedUserInfo<string>& TypedUserInfo<string>::instance = StringUI(); 112 113 ////////////////////////////////////////////////////////////////////////////////////////////// 114 ////////////////////////////////////////// EXAMPLE CLASSES DEFINITION //////////////////////// 115 ////////////////////////////////////////////////////////////////////////////////////////////// 116 class Transport 117 { 118 public: 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 130 class Car : public Transport 131 { 132 public: 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 146 class Bike : public Transport 147 { 148 public: 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 57 168 58 169 class CarUI: public CompoundUserInfo<Car> 59 170 { 60 public: 61 BindedType<int> age; 62 BindedType<string> brand; 63 171 private: 172 BindedElement<int> year; 173 BindedElement<int> kilometers; 174 BindedElement<string> manufacturer; 175 public: 64 176 CarUI() 65 177 :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 } 183 private: 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 200 const TypedUserInfo<Car>& TypedUserInfo<Car>::instance = CarUI( ); 201 202 203 class BikeUI: public CompoundUserInfo<Bike> 204 { 205 private: 206 BindedElement<int> year; 207 BindedElement<bool> lights; 208 BindedElement<string> manufacturer; 209 public: 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 } 217 private: 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 234 const TypedUserInfo<Bike>& TypedUserInfo<Bike>::instance = BikeUI( ); 86 235 87 236 88 237 int main() 89 238 { 239 Car audi( 1998, "audi", 25000); 240 Car liaz( 1992, "liaz", 1555000); 241 Bike author( 1996, "author", true ); 242 90 243 /////////////////////////////////// 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") ) 97 250 { 98 251 cout << "there was some error!" << endl; … … 102 255 103 256 root.Save(); 104 cout << " the new car was saved correctly!" << endl;257 cout << "all the transport means were saved correctly" << endl; 105 258 getchar(); 106 259 107 260 //////////////////////////////////// LOADING //////////////////////////////// 108 261 109 110 Car *loadedCar; 262 string whichone = "pepikovo"; 263 // whichone = "jardovo"; 264 whichone = "ondrejovo"; 265 111 266 root.Load(); 112 UserInfo::Assembly(loadedCar,root,"kara");267 Transport *loaded = UserInfo::Assembly<Transport>( root,whichone); 113 268 114 if( loaded Car)115 cout << "loaded car: age=" << loadedCar->age << ", brand=" << loadedCar->brand << endl;269 if( loaded ) 270 loaded->ToString(); 116 271 else 117 cout << "there was some error during carloading!" << endl;272 cout << "there was some error during loading!" << endl; 118 273 119 274 getchar();