From 984d1dd9993aa5beffa4270b6421dea05ab04faa Mon Sep 17 00:00:00 2001 From: deva Date: Thu, 14 Jan 2010 13:48:52 +0000 Subject: Made EntityList superclass for the Macro and TemplateList classes. --- server/src/Makefile.am | 3 + server/src/entitylist.cc | 206 +++++++++++++++++++++++++++++++++++++++++++++ server/src/entitylist.h | 88 +++++++++++++++++++ server/src/macrolist.cc | 147 +------------------------------- server/src/macrolist.h | 49 +---------- server/src/templatelist.cc | 83 +++--------------- server/src/templatelist.h | 42 +-------- 7 files changed, 322 insertions(+), 296 deletions(-) create mode 100644 server/src/entitylist.cc create mode 100644 server/src/entitylist.h diff --git a/server/src/Makefile.am b/server/src/Makefile.am index efe1413..668ca0c 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -14,6 +14,7 @@ pracrod_SOURCES = \ configurationparser.cc \ connectionpool.cc \ debug.cc \ + entitylist.cc \ environment.cc \ exception.cc \ inotify.cc \ @@ -58,6 +59,7 @@ macrotool_SOURCES = \ configuration.cc \ configurationparser.cc \ database.cc \ + entitylist.cc \ exception.cc \ inotify.cc \ log.cc \ @@ -86,6 +88,7 @@ EXTRA_DIST = \ dbtypes.h \ debug.h \ environment.h \ + entitylist.h \ exception.h \ inotify.h \ journal_commit.h \ diff --git a/server/src/entitylist.cc b/server/src/entitylist.cc new file mode 100644 index 0000000..64bd49d --- /dev/null +++ b/server/src/entitylist.cc @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * entitylist.cc + * + * Thu Jan 14 14:17:34 CET 2010 + * Copyright 2010 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "entitylist.h" + +#include +#include +#include +#include + +#include + +#include "debug.h" + +static inline bool isdir(std::string name) +{ + struct stat s; + stat(name.c_str(), &s); + return S_ISDIR(s.st_mode); +} + +static inline bool isfile(std::string name) +{ + struct stat s; + stat(name.c_str(), &s); + return S_ISREG(s.st_mode); +} + +static std::vector listdir(std::string path) +{ + std::vector files; + + DIR* dir = opendir(path.c_str()); + if(!dir) { + PRACRO_ERR(entitylist, "Could not open directory: %s\n", path.c_str()); + return files; + } + + struct dirent *d; + while((d = readdir(dir)) != 0) { + if(std::string(d->d_name) == "." || std::string(d->d_name) == "..") continue; + + if(isdir(path + "/" + d->d_name)) { + std::vector sub = listdir(path + "/" + d->d_name); + files.insert(files.end(), sub.begin(), sub.end()); + continue; + } + + if(isfile(path + "/" + d->d_name)) { + std::string name = d->d_name; + if(name.length() >= 4 && name.substr(name.length() - 4) == ".xml") + files.push_back(path + "/" + name); + } + } + closedir(dir); + + return files; +} + +EntityList::EntityList(std::string entityname) +{ + MutexAutolock lock(mutex); + + this->entityname = entityname; +} + +EntityList::~EntityList() +{ +} + +void EntityList::rescan(std::string entitypath) +{ + MutexAutolock lock(mutex); + + clear(); + // inotify.clear(); + + inotify.addDirectory(entitypath, WATCH_DEEP_FOLLOW, + IN_CLOSE_WRITE | + IN_MOVED_FROM | IN_MOVED_TO | IN_MOVE_SELF | + IN_DELETE | IN_DELETE_SELF); + + + + + std::vector entitys = listdir(entitypath); + std::vector::iterator i = entitys.begin(); + while(i != entitys.end()) { + addFile(*i); + i++; + } + + { + iterator i = begin(); + while(i != end()) { + EntityListItem::iterator j = i->second.begin(); + while(j != i->second.end()) { + PRACRO_DEBUG(entitylist, "%s - v%s file: %s\n", + i->first.c_str(), + ((std::string)j->first).c_str(), + j->second.c_str()); + j++; + } + i++; + } + } +} + +bool EntityList::removeFile(std::string file) +{ + // Check if the file is already in the tree. + iterator i = begin(); + while(i != end()) { + EntityListItem::iterator j = i->second.begin(); + while(j != i->second.end()) { + if(file == j->second) { + PRACRO_DEBUG(entitylist, "Removing file: %s\n", file.c_str()); + i->second.erase(j->first); + if(i->second.size() == 0) erase(i->first); + return true; + } + j++; + } + i++; + } + + return false; +} + +void EntityList::updateFile(std::string file) +{ + removeFile(file); + addFile(file); +} + +void EntityList::updateList() +{ + while(inotify.hasEvents()) { + INotify::Event event = inotify.getNextEvent(); + if(event.isCloseWriteEvent()) updateFile(event.name()+"/"+event.file()); + if(event.isMovedFromEvent()) removeFile(event.name()+"/"+event.file()); + if(event.isMovedToEvent()) updateFile(event.name()+"/"+event.file()); + if(event.isDeleteEvent()) removeFile(event.name()+"/"+event.file()); + + if(event.isMoveSelfEvent()) {/* TODO: what to do here? */} + if(event.isDeleteSelfEvent()) {/* TODO: what to do here? */} + } +} + +std::string EntityList::getLatestVersion(std::string entity) throw(Exception) +{ + MutexAutolock lock(mutex); + + updateList(); + + if(find(entity) == end()) throw Exception("Entity ("+entityname+") ["+entity+"] does not exist"); + EntityListItem mli = (*this)[entity]; + if(mli.size() == 0) throw Exception("Entity ("+entityname+") ["+entity+"] does not exist."); + PRACRO_DEBUG(entitylist, "Search for %s - found %s v%s\n", + entity.c_str(), + mli.begin()->second.c_str(), + ((std::string)mli.begin()->first).c_str()); + + return mli.begin()->second; +} + +#ifdef TEST_ENTITYLIST +//Additional dependency files +//deps: +//Required cflags (autoconf vars may be used) +//cflags: +//Required link options (autoconf vars may be used) +//libs: +#include "test.h" + +TEST_BEGIN; + +// TODO: Put some testcode here (see test.h for usable macros). + +TEST_END; + +#endif/*TEST_ENTITYLIST*/ diff --git a/server/src/entitylist.h b/server/src/entitylist.h new file mode 100644 index 0000000..b596c07 --- /dev/null +++ b/server/src/entitylist.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * entitylist.h + * + * Thu Jan 14 14:17:34 CET 2010 + * Copyright 2010 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PRACRO_ENTITYLIST_H__ +#define __PRACRO_ENTITYLIST_H__ + +#include +#include +#include "versionstr.h" +#include "mutex.h" + +#include "inotify.h" + +#include "exception.h" + +/** + * The Items contained in the EntityList. + */ +typedef std::map EntityListItem; + +/** + * The EntityList class is intended for entity file caching, so that all entitys + * do not need to be parsed on each entity query. + * It builds a list of entitys and versions based on the informations read from + * the EntityHeaderParser. + * This means that just because a entity gets into the list doesn't means that it + * will validate as a correct entity (not even nessecarily correct XML). + */ +class EntityList : public std::map { +public: + /** + * Constructor. + * @param entitypath A std::string containing the path in which we should look + * for xml files. + */ + EntityList(std::string entityname); + virtual ~EntityList(); + + /** + * Convenience method, to gain the filename of the latest version of a given entity. + * This method throws an Exception if the entity does not exist in the tree. + * @param entity A std::string containing the name of the wanted entity. + * @return A std::string containing the file containing the entity with full path + * included. + */ + std::string getLatestVersion(std::string entity) throw(Exception); + +protected: + void rescan(std::string entitypath); + +private: + virtual void addFile(std::string file) = 0; + + bool removeFile(std::string file); + void updateFile(std::string file); + void updateList(); + + Mutex mutex; + INotify inotify; + + std::string entityname; +}; + +#endif/*__PRACRO_ENTITYLIST_H__*/ diff --git a/server/src/macrolist.cc b/server/src/macrolist.cc index 89abfe8..86584d4 100644 --- a/server/src/macrolist.cc +++ b/server/src/macrolist.cc @@ -27,118 +27,16 @@ */ #include "macrolist.h" -#include -#include - -#include "debug.h" #include "macroheaderparser.h" -#include -#include -#include - -static inline bool isdir(std::string name) -{ - struct stat s; - stat(name.c_str(), &s); - return S_ISDIR(s.st_mode); -} - -static inline bool isfile(std::string name) -{ - struct stat s; - stat(name.c_str(), &s); - return S_ISREG(s.st_mode); -} +#include "debug.h" -static std::vector listdir(std::string path) +MacroList::MacroList(std::string path) + : EntityList("macro") { - std::vector files; - - DIR* dir = opendir(path.c_str()); - if(!dir) { - PRACRO_ERR(dump, "Could not open directory: %s\n", path.c_str()); - return files; - } - - struct dirent *d; - while((d = readdir(dir)) != 0) { - if(std::string(d->d_name) == "." || std::string(d->d_name) == "..") continue; - - PRACRO_DEBUG(macrolist, "d_name: %s - d_type: %d\n", d->d_name, d->d_type); - - if(isdir(path + "/" + d->d_name)) { - std::vector sub = listdir(path + "/" + d->d_name); - files.insert(files.end(), sub.begin(), sub.end()); - continue; - } - - if(isfile(path + "/" + d->d_name)) { - std::string name = d->d_name; - if(name.length() >= 4 && name.substr(name.length() - 4) == ".xml") - files.push_back(path + "/" + name); - } - } - closedir(dir); - - return files; + rescan(path); } -MacroList::MacroList(std::string macropath) -{ - MutexAutolock lock(mutex); - - inotify.addDirectory(macropath, WATCH_DEEP_FOLLOW, - IN_CLOSE_WRITE | - IN_MOVED_FROM | IN_MOVED_TO | IN_MOVE_SELF | - IN_DELETE | IN_DELETE_SELF); - - this->macropath = macropath; - std::vector macros = listdir(macropath); - std::vector::iterator i = macros.begin(); - while(i != macros.end()) { - addFile(*i); - i++; - } - - { - iterator i = begin(); - while(i != end()) { - MacroListItem::iterator j = i->second.begin(); - while(j != i->second.end()) { - PRACRO_DEBUG(macrolist, "%s - v%s file: %s\n", - i->first.c_str(), - ((std::string)j->first).c_str(), - j->second.c_str()); - j++; - } - i++; - } - } -} - -bool MacroList::removeFile(std::string file) -{ - // Check if the file is already in the tree. - iterator i = begin(); - while(i != end()) { - MacroListItem::iterator j = i->second.begin(); - while(j != i->second.end()) { - if(file == j->second) { - PRACRO_DEBUG(macrolist, "Removing file: %s\n", file.c_str()); - i->second.erase(j->first); - /* - if(i->second.size() == 0) erase(i->first); - */ - return true; - } - j++; - } - i++; - } - - return false; -} void MacroList::addFile(std::string file) { @@ -153,43 +51,6 @@ void MacroList::addFile(std::string file) } } -void MacroList::updateFile(std::string file) -{ - removeFile(file); - addFile(file); -} - -void MacroList::updateList() -{ - while(inotify.hasEvents()) { - INotify::Event event = inotify.getNextEvent(); - if(event.isCloseWriteEvent()) updateFile(event.name()+"/"+event.file()); - if(event.isMovedFromEvent()) removeFile(event.name()+"/"+event.file()); - if(event.isMovedToEvent()) updateFile(event.name()+"/"+event.file()); - if(event.isDeleteEvent()) removeFile(event.name()+"/"+event.file()); - - if(event.isMoveSelfEvent()) {/* TODO: what to do here? */} - if(event.isDeleteSelfEvent()) {/* TODO: what to do here? */} - } -} - -std::string MacroList::getLatestVersion(std::string macro) throw(Exception) -{ - MutexAutolock lock(mutex); - - updateList(); - - if(find(macro) == end()) throw Exception("Macro ["+macro+"] does not exist"); - MacroListItem mli = (*this)[macro]; - if(mli.size() == 0) throw Exception("Macro ["+macro+"] does not exist"); - PRACRO_DEBUG(macrolist, "Search for %s - found %s v%s\n", - macro.c_str(), - mli.begin()->second.c_str(), - ((std::string)mli.begin()->first).c_str()); - - return mli.begin()->second; -} - #ifdef TEST_MACROLIST #define MACRODIR "/home" // We assume this directory exists and does not contain any xml files! diff --git a/server/src/macrolist.h b/server/src/macrolist.h index 4c73ded..51a30ec 100644 --- a/server/src/macrolist.h +++ b/server/src/macrolist.h @@ -28,55 +28,14 @@ #ifndef __PRACRO_MACROLIST_H__ #define __PRACRO_MACROLIST_H__ -#include -#include -#include "versionstr.h" -#include "mutex.h" +#include "entitylist.h" -#include "inotify.h" - -#include "exception.h" - -/** - * The Items contained in the MacroList. - */ -typedef std::map MacroListItem; - -/** - * The MacroList class is intended for macro file caching, so that all macros - * do not need to be parsed on each macro query. - * It builds a list of macros and versions based on the informations read from - * the MacroHeaderParser. - * This means that just because a macro gets into the list doesn't means that it - * will validate as a correct macro (not even nessecarily correct XML). - */ -class MacroList : public std::map { +class MacroList : public EntityList { public: - /** - * Constructor. - * @param macropath A std::string containing the path in which we should look - * for xml files. - */ - MacroList(std::string macropath); - - /** - * Convenience method, to gain the filename of the latest version of a given macro. - * This method throws an Exception if the macro does not exist in the tree. - * @param macro A std::string containing the name of the wanted macro. - * @return A std::string containing the file containing the macro with full path - * included. - */ - std::string getLatestVersion(std::string macro) throw(Exception); + MacroList(std::string path); -private: - bool removeFile(std::string file); +protected: void addFile(std::string file); - void updateFile(std::string file); - void updateList(); - - Mutex mutex; - INotify inotify; - std::string macropath; }; #endif/*__PRACRO_MACROLIST_H__*/ diff --git a/server/src/templatelist.cc b/server/src/templatelist.cc index bbaefc3..b952467 100644 --- a/server/src/templatelist.cc +++ b/server/src/templatelist.cc @@ -27,84 +27,27 @@ */ #include "templatelist.h" -#include -#include +#include "templateheaderparser.h" #include "debug.h" -#include "templateheaderparser.h" -static std::vector listdir(std::string path) +TemplateList::TemplateList(std::string path) + : EntityList("template") { - std::vector files; - - DIR* dir = opendir(path.c_str()); - if(!dir) { - PRACRO_ERR(dump, "Could not open directory: %s\n", path.c_str()); - return files; - } - - struct dirent *d; - while((d = readdir(dir)) != 0) { - //if(d->d_type == DT_DIR) { - std::string name = d->d_name; - if(name.length() >= 4 && name.substr(name.length() - 4) == ".xml") - files.push_back(name); - //} - } - closedir(dir); - - return files; + rescan(path); } -TemplateList::TemplateList(std::string templatepath) +void TemplateList::addFile(std::string file) { - MutexAutolock lock(mutex); - - this->templatepath = templatepath; - std::vector templates = listdir(templatepath); - std::vector::iterator i = templates.begin(); - while(i != templates.end()) { - TemplateHeaderParser parser(templatepath + "/" + *i); - try { - parser.parse(); - Template *templ = parser.getTemplate(); - (*this)[templ->attributes["name"]][VersionStr(templ->attributes["version"])] = *i; - } catch(Exception &e) { - PRACRO_WARN(templatelist, "Skipping %s: %s\n", i->c_str(), e.what()); - } - - i++; - } - - { - iterator i = begin(); - while(i != end()) { - TemplateListItem::iterator j = i->second.begin(); - while(j != i->second.end()) { - PRACRO_DEBUG(templatelist, "%s - v%s file: %s\n", - i->first.c_str(), - ((std::string)j->first).c_str(), - j->second.c_str()); - j++; - } - i++; - } + PRACRO_DEBUG(templatelist, "Adding file: %s\n", file.c_str()); + TemplateHeaderParser parser(file); + try { + parser.parse(); + Template *templ = parser.getTemplate(); + (*this)[templ->attributes["name"]][VersionStr(templ->attributes["version"])] = file; + } catch(Exception &e) { + PRACRO_WARN(templatelist, "Skipping %s: %s\n", file.c_str(), e.what()); } - -} - -std::string TemplateList::getLatestVersion(std::string templ) throw(Exception) -{ - MutexAutolock lock(mutex); - - if(find(templ) == end()) throw Exception("Template ["+templ+"] does not exist"); - TemplateListItem mli = (*this)[templ]; - if(mli.size() == 0) return ""; - PRACRO_DEBUG(templatelist, "Search for %s - found %s v%s\n", - templ.c_str(), - (templatepath + "/" + mli.begin()->second).c_str(), - ((std::string)mli.begin()->first).c_str()); - return templatepath + "/" + mli.begin()->second; } #ifdef TEST_TEMPLATELIST diff --git a/server/src/templatelist.h b/server/src/templatelist.h index a037956..ce2d1b3 100644 --- a/server/src/templatelist.h +++ b/server/src/templatelist.h @@ -28,48 +28,14 @@ #ifndef __PRACRO_TEMPLATELIST_H__ #define __PRACRO_TEMPLATELIST_H__ -#include -#include -#include "versionstr.h" -#include "templatelist.h" -#include "mutex.h" +#include "entitylist.h" -#include "exception.h" - -/** - * The Items contained in the TemplateList. - */ -typedef std::map TemplateListItem; - -/** - * The TemplateList class is intended for template file caching, so that all templates - * do not need to be parsed on each template query. - * It builds a list of templates and versions based on the informations read from - * the TemplateHeaderParser. - * This means that just because a template gets into the list doesn't means that it - * will validate as a correct template (not even nessecarily correct XML). - */ -class TemplateList : public std::map { +class TemplateList : public EntityList { public: - /** - * Constructor. - * @param templatepath A std::string containing the path in which we should look - * for xml files. - */ - TemplateList(std::string templatepath); - - /** - * Convenience method, to gain the filename of the latest version of a given template. - * This method throws an Exception if the template does not exist in the tree. - * @param template A std::string containing the name of the wanted template. - * @return A std::string containing the file containing the template with full path - * included. - */ - std::string getLatestVersion(std::string templ) throw(Exception); + TemplateList(std::string path); private: - Mutex mutex; - std::string templatepath; + void addFile(std::string file); }; #endif/*__PRACRO_TEMPLATELIST_H__*/ -- cgit v1.2.3