UniSet  2.6.0
UHelpers.h
00001 /*
00002  * Copyright (c) 2015 Pavel Vainerman.
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as
00006  * published by the Free Software Foundation, version 2.1.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00011  * Lesser General Lesser Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 // --------------------------------------------------------------------------
00017 #ifndef UHelpers_H_
00018 #define UHelpers_H_
00019 // --------------------------------------------------------------------------
00020 #include "UniSetTypes.h"
00021 #include "Configuration.h"
00022 // --------------------------------------------------------------------------
00023 namespace uniset
00024 {
00025 // Шаблон для "универсальной инициализации объекта(процесса)".
00026 // Использование:
00027 // auto m = make_object<MyClass>("ObjectId","secname",...);
00028 // --
00029 // Где MyClass должен содержать конструктор MyClass( const ObjetctId id, xmlNode* cnode, ...any args.. );
00030 // ---------------
00031 // Если secname задан, то ищется: <secname name="ObjectId" ....>
00032 // Если secname не задан, то: <idname name="idname" ...>
00033 //----------------
00034 template<typename T, typename... _Args>
00035 std::shared_ptr<T> make_object( const std::string& idname, const std::string& secname, _Args&& ... __args )
00036 {
00037     auto conf = uniset::uniset_conf();
00038     uniset::ObjectId id = conf->getObjectID(idname);
00039 
00040     if( id == uniset::DefaultObjectId )
00041         throw uniset::SystemError("(make_object<" + string(typeid(T).name()) + ">): Not found ID for '" + idname + "'");
00042 
00043     auto xml = conf->getConfXML();
00044     std::string s( (secname.empty() ? idname : secname) );
00045     xmlNode* cnode = conf->findNode(xml->getFirstNode(), s, idname);
00046 
00047     if( cnode == 0 )
00048         throw uniset::SystemError("(make_object<" + string(typeid(T).name()) + ">): Not found xmlnode <" + s + " name='" + idname + "' ... >");
00049 
00050     std::shared_ptr<T> obj = std::make_shared<T>(id, cnode, std::forward<_Args>(__args)...);
00051 
00052     if (obj == nullptr)
00053         throw uniset::SystemError("(make_object<T>  == nullptr" + string(typeid(T).name()));
00054 
00055     return obj;
00056 }
00057 // -----------------------------------------------------------------------------
00058 // версия с указанием начального xml-узла, с которого ведётся поиск xmlNode
00059 // а ID берётся из поля name="" у найденного xmlnode.
00060 template<typename T, typename... _Args>
00061 std::shared_ptr<T> make_object_x( xmlNode* root, const std::string& secname, _Args&& ... __args )
00062 {
00063     auto conf = uniset::uniset_conf();
00064     auto xml = conf->getConfXML();
00065     xmlNode* cnode = conf->findNode(root, secname, "");
00066 
00067     if( cnode == 0 )
00068         throw uniset::SystemError("(make_object_x<" + string(typeid(T).name()) + ">): Not found xmlnode <" + secname + " ... >");
00069 
00070     string idname = conf->getProp(cnode, "name");
00071     uniset::ObjectId id = conf->getObjectID(idname);
00072 
00073     if( id == uniset::DefaultObjectId )
00074         throw uniset::SystemError("(make_object_x<" + string(typeid(T).name()) + ">): Not found ID for '" + idname + "'");
00075 
00076     return std::make_shared<T>(id, cnode, std::forward<_Args>(__args)...);
00077 
00078 }
00079 // -----------------------------------------------------------------------------
00080 // Просто обёртка для удобства вывода сообщений об ошибке в лог "объекта"..
00081 // "по задумке" позволяет не загромаждать код..
00082 // T - тип создаваемого объекта
00083 // M - (master) - класс который создаёт объект (подразумевается, что он UniSetManager)
00084 // Использование
00085 // auto m = make_child_object<MyClass,MyMasterClass>(master, "ObjectId","secname",...);
00086 template<typename T, typename M, typename... _Args>
00087 std::shared_ptr<T> make_child_object( M* m, const std::string& idname, const std::string& secname, _Args&& ... __args )
00088 {
00089     try
00090     {
00091         m->log()->info() << m->getName() << "(" << __FUNCTION__ << "): " << "create " << idname << "..." << std::endl;
00092         auto o = uniset::make_object<T>(idname, secname, std::forward<_Args>(__args)...);
00093         m->add(o);
00094         m->logAgregator()->add(o->logAgregator());
00095         return std::move(o);
00096     }
00097     catch( const uniset::Exception& ex )
00098     {
00099         m->log()->crit() << m->getName() << "(" << __FUNCTION__ << "): " << "(create " << idname << "): " << ex << std::endl;
00100         throw;
00101     }
00102 }
00103 // -----------------------------------------------------------------------------
00104 // Версия использующая make_object_x<>
00105 template<typename T, typename M, typename... _Args>
00106 std::shared_ptr<T> make_child_object_x( M* m, xmlNode* root, const std::string& secname, _Args&& ... __args )
00107 {
00108     try
00109     {
00110         auto o = uniset::make_object_x<T>(root, secname, std::forward<_Args>(__args)...);
00111         m->add(o);
00112         m->logAgregator()->add(o->logAgregator());
00113         return std::move(o);
00114     }
00115     catch( const uniset::Exception& ex )
00116     {
00117         m->log()->crit() << m->getName() << "(" << __FUNCTION__ << "): " << "(create " << string(typeid(T).name()) << "): " << ex << std::endl;
00118         throw;
00119     }
00120 }
00121 // -----------------------------------------------------------------------------------------
00122 } // endof namespace uniset
00123 // -----------------------------------------------------------------------------------------
00124 #endif // UHelpers_H_