/* -*- 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); if(i->second.size() == 0) erase(i); 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*/