#ifndef __XMLIO_OBJECT_TEMPLATE__ #define __XMLIO_OBJECT_TEMPLATE__ #include "declare_attribut.hpp" #include "attribut_registrar.hpp" // Classes utilisées issues de la STL using std::pair; using std::string; using std::ostream; using XMLIOSERVER::StrHashMap; using XMLIOSERVER::XML::XMLNode; using XMLIOSERVER::XML::THashAttributes; namespace XMLIOSERVER { template class ObjectTemplate : public AbstractObject, public virtual AttributRegistrar { public : friend ostream& operator<< (ostream& out, const T& c) { const AttributRegistrar &ar = c; if (c.baseObject != NULL) out << IncIndent << "<-- Référence résolu sur l'instance de "<< T::GetName() << " nommée \"" << c.baseObject->getId() << "\" -->" << DecEndl << std::endl; if (c.isDefinition()) { out << NIndent << std::endl; out << NIndent << "" << std::endl; } if (c.hasChild()) { out << IncIndent << "<" << c.getName() << c.printId() << ar << ">" << std::endl; c.printChild(out); // << Ecriture des objets enfants ici. if (c.hasId() && (c.getName().compare("context") == 0)) out << NIndent << std::endl; out << NIndent << "" << DecEndl; } else out << IncIndent << "<" << c.getName() << c.printId() << ar << "/>" << DecEndl; return (out); } bool isDefinition(void) const { if (!this->hasId()) return (false); return (this->getName().compare(this->getId()) == 0); } string getName(void) const { if (this->hasId()) if (T::GetDefName().compare(getId()) == 0) return (T::GetDefName()); return (T::GetName()); } T* getBaseObject(void) const { return (baseObject); } const vector& getVectRefObject(void) const { return (refObject); } bool hasRefObject(void) const { return (!refObject.empty()); } const T* addRefObject(T* obj) { refObject.push_back (obj); return (obj); } public : /* virtual */ virtual T* getReference(void) const { return (NULL); } virtual bool hasChild(void) const { return (false); } virtual void printChild(ostream& out) const { out << NIndent << "" << std::endl; } virtual void resolveDescInheritance(const AttributRegistrar* _parent = 0) { this->addAttributes(*_parent); } virtual void resolveRefInheritance (void) { std::set sset; T* refer = (T*)this; // On remonte le fil des héritages par référence. while((refer = refer->getReference()) != NULL) { if(sset.end() != sset.find(refer)) { WARNING ("Dépendance circulaire stoppée pour l'objet de type "+T::GetName()+" sur \""+refer->getId()+"\" !"); break; } addAttributes(*refer); sset.insert(baseObject = refer); } } virtual void parse (XMLNode& _node) { string name = _node.getElementName(); THashAttributes attributes; /// PARSING GESTION DES ATTRIBUTS /// _node.getAttributes(attributes); this->setAttributes(attributes); attributes.clear(); /// PARSING POUR GESION DES ENFANTS /// // Rien à faire ici. } virtual ~ObjectTemplate(void) {/* Ne rien faire de plus */} public : /* static */ static T* CreateObject(const string& _id) throw (XMLIOUndefinedValueException) { // Si l'identifiant est répertorié, on retourne l'élément existant. if(ObjectTemplate::HasObject(_id)) return (ObjectTemplate::GetObject(_id)); // Ajout d'un nouvel objet si l'identifiant n'est pas répertorié. ObjectTemplate::AllListObj[CurrContext].addObject(new T(_id)); return (ObjectTemplate::GetObject(_id)); } static T* CreateObject(void) { T* value = new T; ObjectTemplate::AllListObj[CurrContext].addObject(value); return (value); } static T* GetObject(const string& _id) throw (XMLIOUndefinedValueException) { return (ObjectTemplate::AllListObj[CurrContext][_id]); } static bool HasObject(const string& _id) { if(ObjectTemplate::AllListObj.find(CurrContext) == ObjectTemplate::AllListObj.end()) return (false); return (ObjectTemplate::AllListObj[CurrContext].hasMappedValue(_id)); } static const StrHashMap& GetCurrentListObject(void) { return (AllListObj[CurrContext]); } static Poco::HashMap >& GetAllListObject(void) { return (AllListObj); } static void SetContext(const string& id) { ObjectTemplate::CurrContext = id; } static string& GetCurrentContextId(void) { return (ObjectTemplate::CurrContext); } protected : ObjectTemplate(void) : AttributRegistrar(), AbstractObject(), baseObject(NULL), refObject() { /* Ne rien faire de plus */ } ObjectTemplate(const string& _id) : AttributRegistrar(), AbstractObject(_id), baseObject(NULL), refObject() { /* Ne rien faire de plus */ } ObjectTemplate(const ObjectTemplate& _ot, bool _withAttrList = true, bool _withId = true) : AttributRegistrar(), AbstractObject(), baseObject(_ot.baseObject), refObject(_ot.refObject) { // Si requis, ajout de l'identifiant lors de la copie. if (_ot.hasId() && _withId) this->setId(_ot.getId()); // Si requis, ajout des attributs lors de la copie. if (_withAttrList) this->addAttributes(_ot); } XML::XMLNode getNodeIncludedFile(const string& path, const string& _rootName) { ifstream istr( path.c_str() , ifstream::in ); return (XML::XMLNode::CreateNode(istr, _rootName)); } template static V* CreateInstanceAndParse(XMLNode& _node, const char* defaultId, bool parseAttr = true ) { V* instance_ptr = NULL; string did(defaultId); if (defaultId != NULL) { if (V::HasObject(did)) WARNING("Le noeud nommé \""+ did +"\" existe déjà pour les instances de type "+ V::GetName()+", le dernier défini complétera le premier dans le context actuel!"); instance_ptr = (V*)V::CreateObject(did); instance_ptr->parse(_node, parseAttr); } return (instance_ptr); } private : T* baseObject; std::vector refObject; private : /* static */ static string CurrContext; static Poco::HashMap > AllListObj; };// class ObjectTemplate // Initialisation des variables statiques de la classe ObjectTemplate. template string ObjectTemplate::CurrContext ; template Poco::HashMap > ObjectTemplate::AllListObj; }// namespace XMLIOSERVER #endif // __XMLIO_OBJECT_TEMPLATE__