00001 #ifndef UI_H
00002 #define UI_H
00003 
00004 #include <sstream>
00005 #include <iostream>
00006 #include <stdio.h>
00007 #include <string>
00008 #include <map>
00009 #include <utility>
00010 #include <xercesc/dom/DOM.hpp>
00011 #include <xercesc/util/PlatformUtils.hpp>
00012 #include <xercesc/util/XMLString.hpp>
00013 #include <iostream>
00014 #include <xercesc/framework/LocalFileFormatTarget.hpp>
00015 #include <xercesc/framework/LocalFileInputSource.hpp>
00016 #include <xercesc/dom/DOMWriter.hpp>
00017 #include <xercesc/parsers/XercesDOMParser.hpp>
00018 
00019 #ifdef XERCES_CPP_NAMESPACE_USE
00020 XERCES_CPP_NAMESPACE_USE
00021 #endif
00022 
00023 using std::string;
00024 using namespace std;
00025 
00026 
00032 class GlobalXercesConnector
00033 {
00034 public:
00036         DOMImplementation *pImplementation;
00038         DOMWriter *pSerializer;
00040         XercesDOMParser *pParser;
00041 
00042 
00044         GlobalXercesConnector();
00046         ~GlobalXercesConnector();
00047 
00048 
00050         static string XMLCh2str( const XMLCh* const  XMLCh_str );
00051 
00052         class Comparator
00053         {
00054         public:
00056                 bool operator()( const XMLCh* const a , const XMLCh* const b) const;
00057         };
00058 };
00059 
00061 extern const GlobalXercesConnector XMLConnector;
00062 
00063 
00070 class Attribute 
00071 {
00072 private:
00075         XMLCh* const transcodedName;
00076 
00077 public:
00079         typedef map<const XMLCh* const, Attribute* const, GlobalXercesConnector::Comparator> MappedAttributes;
00080 
00082         Attribute( const string name );
00084         ~Attribute();
00085 
00087         virtual void Set( const string str ) = 0;
00089         virtual const string Get() = 0; 
00091         void Attach( MappedAttributes &externalAttributes);
00093         void FillAttribute(DOMElement &element);
00094 };
00095 
00099 class DoubleAttribute: public Attribute
00100 {
00101 public:
00102         double value;
00103         DoubleAttribute( const string name);
00104         void Set( const string str );
00105         const string Get();
00106 };
00107 
00108 
00112 class IntAttribute : public Attribute
00113 {
00114 public:
00115         int value;
00116         IntAttribute( const string name );
00117         void Set( const string str );
00118         const string Get();
00119 };
00120 
00124 class StringAttribute : public Attribute
00125 {
00126 public:
00127         string value;
00128         StringAttribute( const string name );
00129         void Set( const string str );
00130         const string Get();
00131 };
00132 
00139 class UserInfoCore
00140 {
00141 public:
00143         virtual void ParseElement(DOMElement *element) = 0;
00144 
00146         virtual void FillElement(DOMElement &element) = 0;
00147 };
00148 
00154 template<typename T> class UserInfo : public UserInfoCore
00155 {
00156 private:
00159         XMLCh* transcodedName;
00160         
00162         typedef map<const XMLCh* const, UserInfoCore* const, GlobalXercesConnector::Comparator> MappedElements;
00163 
00164 protected:
00166         MappedElements elements;
00168         Attribute::MappedAttributes attributes;
00169 
00170 public:
00172         StringAttribute help;
00173 
00175         UserInfo<T>( 
00176                 const string name, 
00177                 const string help_msg = "" ) 
00178                 : help("help"),         
00179                 transcodedName( XMLString::transcode( name.c_str() ) )
00180         {       
00181                 XMLString::upperCase( transcodedName );
00182                 help.Attach( attributes );
00183                 help.value = help_msg;
00184         };
00186         ~UserInfo<T>()
00187         {
00188                 XMLString::release( (XMLCh**)&transcodedName );
00189         }
00190 
00192         virtual T* build(void) = 0;
00193 
00195         void Save ( char* fileName )
00196         {
00197                 XMLCh* transcodedFileName = XMLString::transcode( fileName );
00198                 LocalFileFormatTarget outputTarget( transcodedFileName );
00199                 XMLString::release( &transcodedFileName );
00200 
00201                 DOMDocument* pDoc = XMLConnector.pImplementation->createDocument( 
00202                         XMLString::transcode( "M3K USER INFO" ), 
00203                         XMLString::transcode( "ROOT" ), NULL );
00204                 DOMElement *pRoot = pDoc->getDocumentElement();
00205 
00206                 FillElement( *pRoot );
00207 
00208                 XMLConnector.pSerializer->writeNode( &outputTarget, *pDoc);
00209                 delete pDoc;
00210         }       
00212         void Load ( char* fileName ) 
00213         {
00214                 bool bFailed = false;
00215 
00216                 try
00217                 {
00218                         XMLCh* transcodedFileName = XMLString::transcode( fileName ) ;
00219                         const LocalFileInputSource inputSource( transcodedFileName );           
00220                         XMLString::release( &transcodedFileName );
00221 
00222                         XMLConnector.pParser->parse( inputSource );
00223                         bFailed = ( XMLConnector.pParser->getErrorCount() != 0 );
00224                 }
00225                 catch (...)
00226                 {
00227                         bFailed = true;
00228                 }
00229 
00230                 if( !bFailed)
00231                 {
00232                         DOMDocument *pDoc = XMLConnector.pParser->getDocument();                
00233                         DOMElement *pRoot = pDoc->getDocumentElement();
00234                         bFailed = true;
00235                         for( DOMNode* node = pRoot->getFirstChild(); node != NULL; node = node->getNextSibling() )
00236                                 if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00237                                 {
00238                                         ParseElement( (DOMElement*) node );
00239                                         bFailed = false;
00240                                         break;
00241                                 }
00242                 }
00243 
00244                 if( bFailed )
00245                 {
00246                         
00247                 }               
00248         }
00250         void Attach( MappedElements &externalElements)
00251         {
00252                 pair<const XMLCh* const, UserInfoCore* const> newPair( transcodedName, this );
00253                 externalElements.insert(newPair);
00254         }
00255         
00256         void ParseElement(DOMElement *element) 
00257         {
00258                 DOMNodeList* nodeList = element->getChildNodes();
00259                 if( nodeList )
00260                         for( int i = 0; i < nodeList->getLength(); i++ )
00261                         {
00262                                 DOMNode* node = nodeList->item(i);
00263                                 if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00264                                 {
00265                                         DOMElement* childElement = (DOMElement*) node;
00266                                         MappedElements::const_iterator iter = elements.find( childElement->getTagName() );
00267 
00268                                         if( iter != elements.end())
00269                                                 iter->second->ParseElement( childElement );
00270                                 }
00271                         }
00272                         
00273                 DOMNamedNodeMap* nodeMap = element->getAttributes();
00274                 if( nodeMap )
00275                         for( int i = 0; i < nodeMap->getLength(); i++ )
00276                         {
00277                                 DOMNode* node = nodeMap->item(i);
00278                                 if( node->getNodeType() == DOMNode::ATTRIBUTE_NODE )
00279                                 {
00280                                         DOMAttr* attribute = (DOMAttr*) node;
00281                                         Attribute::MappedAttributes::const_iterator iter = attributes.find( attribute->getName() );
00282 
00283                                         if( iter != attributes.end())
00284                                         {
00285                                                 string attributeValue = GlobalXercesConnector::XMLCh2str( attribute->getValue() );
00286                                                 iter->second->Set( attributeValue );
00287                                         }
00288                                 }
00289                         }
00290         }
00291         
00292         void FillElement(DOMElement &element)
00293         {
00294                 DOMDocument* pDoc = element.getOwnerDocument();
00295 
00296                 DOMElement* pHead = pDoc->createElement( transcodedName );              
00297                 element.appendChild( pHead );
00298 
00299                 for( MappedElements::const_iterator iter = elements.begin(); iter != elements.end(); iter++)
00300                         iter->second->FillElement( *pHead );
00301 
00302                 for( Attribute::MappedAttributes::iterator iter = attributes.begin(); iter != attributes.end(); iter++)
00303                         iter->second->FillAttribute( *pHead );
00304         }
00305 };
00306 
00307 #endif // #ifndef UI_H