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