00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __PION_VOCABULARYMANAGER_HEADER__
00021 #define __PION_VOCABULARYMANAGER_HEADER__
00022
00023 #include <string>
00024 #include <boost/bind.hpp>
00025 #include <boost/signal.hpp>
00026 #include <boost/shared_ptr.hpp>
00027 #include <boost/thread/mutex.hpp>
00028 #include <pion/PionConfig.hpp>
00029 #include <pion/PionException.hpp>
00030 #include <pion/PionHashMap.hpp>
00031 #include <pion/platform/ConfigManager.hpp>
00032 #include <pion/platform/VocabularyConfig.hpp>
00033
00034
00035 namespace pion {
00036 namespace platform {
00037
00038
00042 class PION_PLATFORM_API VocabularyManager
00043 : public ConfigManager
00044 {
00045 public:
00046
00048 class EmptyVocabularyConfigException : public PionException {
00049 public:
00050 EmptyVocabularyConfigException(const std::string& config_file)
00051 : PionException("Configuration file defines an empty Vocabulary config element: ", config_file) {}
00052 };
00053
00055 class MissingVocabularyPathException : public PionException {
00056 public:
00057 MissingVocabularyPathException(const std::string& config_file)
00058 : PionException("Configuration file does not define a Vocabulary path: ", config_file) {}
00059 };
00060
00062 class DuplicateVocabularyException : public PionException {
00063 public:
00064 DuplicateVocabularyException(const std::string& vocab_id)
00065 : PionException("Vocabulary has already been loaded: ", vocab_id) {}
00066 };
00067
00069 class VocabularyNotFoundException : public PionException {
00070 public:
00071 VocabularyNotFoundException(const std::string& vocab_id)
00072 : PionException("Vocabulary has not been defined: ", vocab_id) {}
00073 };
00074
00076 class AddVocabularyConfigException : public PionException {
00077 public:
00078 AddVocabularyConfigException(const std::string& vocab_id)
00079 : PionException("Unable to add a Vocabulary to the configuration file: ", vocab_id) {}
00080 };
00081
00083 class RemoveVocabularyConfigException : public PionException {
00084 public:
00085 RemoveVocabularyConfigException(const std::string& vocab_id)
00086 : PionException("Unable to remove a Vocabulary from the configuration file: ", vocab_id) {}
00087 };
00088
00090 class UpdateVocabularyPathException : public PionException {
00091 public:
00092 UpdateVocabularyPathException(const std::string& config_file)
00093 : PionException("Unable to update Vocabulary path in the configuration file: ", config_file) {}
00094 };
00095
00096
00098 VocabularyManager(void);
00099
00101 virtual ~VocabularyManager() {}
00102
00104 virtual void createConfigFile(void);
00105
00107 virtual void openConfigFile(void);
00108
00114 virtual void writeConfigXML(std::ostream& out) const {
00115 boost::mutex::scoped_lock manager_lock(m_mutex);
00116 ConfigManager::writeConfigXMLHeader(out);
00117 ConfigManager::writeConfigXML(out, m_config_node_ptr, true);
00118 }
00119
00128 bool writeConfigXML(std::ostream& out, const std::string& vocab_id) const;
00129
00139 bool writeTermConfigXML(std::ostream& out, const std::string& term_id) const;
00140
00146 void writeTermConfigXML(std::ostream& out) const;
00147
00155 void addVocabulary(const std::string& vocab_id,
00156 const std::string& vocab_name,
00157 const std::string& vocab_comment);
00158
00166 void addVocabulary(const std::string& vocab_id, const char *content_buf,
00167 std::size_t content_length);
00168
00174 void removeVocabulary(const std::string& vocab_id);
00175
00181 void setVocabularyPath(const std::string& vocab_path);
00182
00190 void setVocabularyConfig(const std::string& vocab_id,
00191 const xmlNodePtr config_ptr)
00192 {
00193 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::setConfig,
00194 _1, config_ptr));
00195 }
00196
00203 inline void setName(const std::string& vocab_id,
00204 const std::string& new_name)
00205 {
00206 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::setName,
00207 _1, boost::cref(new_name)));
00208 }
00209
00216 inline void setComment(const std::string& vocab_id,
00217 const std::string& new_comment)
00218 {
00219 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::setComment,
00220 _1, boost::cref(new_comment)));
00221 }
00222
00229 inline void setLocked(const std::string& vocab_id, bool locked_setting)
00230 {
00231 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::setLocked,
00232 _1, locked_setting));
00233 }
00234
00241 inline void addTerm(const std::string& vocab_id,
00242 const Vocabulary::Term& new_term)
00243 {
00244 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::addTerm,
00245 _1, boost::cref(new_term)));
00246 }
00247
00256 inline void addTerm(const std::string& vocab_id,
00257 const std::string& term_id,
00258 const xmlNodePtr config_ptr)
00259 {
00260 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::addTerm,
00261 _1, boost::cref(term_id), config_ptr));
00262 }
00263
00270 inline void updateTerm(const std::string& vocab_id,
00271 const Vocabulary::Term& t)
00272 {
00273 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::updateTerm,
00274 _1, boost::cref(t)));
00275 }
00276
00285 inline void updateTerm(const std::string& vocab_id,
00286 const std::string& term_id,
00287 const xmlNodePtr config_ptr)
00288 {
00289 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::updateTerm,
00290 _1, boost::cref(term_id), config_ptr));
00291 }
00292
00299 inline void removeTerm(const std::string& vocab_id,
00300 const std::string& term_id)
00301 {
00302 updateVocabulary(vocab_id, boost::bind(&VocabularyConfig::removeTerm,
00303 _1, boost::cref(term_id)));
00304 }
00305
00312 template <typename VocabularyUpdateFunction>
00313 inline boost::signals::connection registerForUpdates(VocabularyUpdateFunction f) const {
00314 boost::mutex::scoped_lock signal_lock(m_signal_mutex);
00315 return m_signal_vocabulary_updated.connect(f);
00316 }
00317
00324 inline const std::string& getName(const std::string& vocab_id) const {
00325 boost::mutex::scoped_lock manager_lock(m_mutex);
00326 VocabularyMap::const_iterator i = m_vocab_map.find(vocab_id);
00327 if (i == m_vocab_map.end())
00328 throw VocabularyNotFoundException(vocab_id);
00329 return i->second->getName();
00330 }
00331
00338 inline const std::string& getComment(const std::string& vocab_id) const {
00339 boost::mutex::scoped_lock manager_lock(m_mutex);
00340 VocabularyMap::const_iterator i = m_vocab_map.find(vocab_id);
00341 if (i == m_vocab_map.end())
00342 throw VocabularyNotFoundException(vocab_id);
00343 return i->second->getComment();
00344 }
00345
00347 inline bool hasVocabulary(const std::string& vocab_id) const {
00348 boost::mutex::scoped_lock manager_lock(m_mutex);
00349 return (m_vocab_map.find(vocab_id) != m_vocab_map.end());
00350 }
00351
00353 inline bool hasTerm(const std::string& term_id) const {
00354 boost::mutex::scoped_lock manager_lock(m_mutex);
00355 return (m_vocabulary.findTerm(term_id) != Vocabulary::UNDEFINED_TERM_REF);
00356 }
00357
00359 inline VocabularyPtr getVocabulary(void) const {
00360 boost::mutex::scoped_lock manager_lock(m_mutex);
00361 return VocabularyPtr(new Vocabulary(m_vocabulary));
00362 }
00363
00365 inline std::string getVocabularyPath(void) const { return m_vocab_path; }
00366
00368 std::string getPermissionType(void) const { return VOCABULARIES_PERMISSION_TYPE; }
00369
00370 private:
00371
00380 template <typename Function>
00381 inline void updateVocabulary(const std::string& vocab_id, Function f) {
00382 boost::mutex::scoped_lock manager_lock(m_mutex);
00383 VocabularyMap::iterator i = m_vocab_map.find(vocab_id);
00384 if (i == m_vocab_map.end())
00385 throw VocabularyNotFoundException(vocab_id);
00386 f(i->second);
00387 manager_lock.unlock();
00388 boost::mutex::scoped_lock signal_lock(m_signal_mutex);
00389 m_signal_vocabulary_updated();
00390 }
00391
00392
00394 typedef boost::shared_ptr<VocabularyConfig> VocabularyConfigPtr;
00395
00397 typedef PION_HASH_MAP<std::string, VocabularyConfigPtr, PION_HASH_STRING > VocabularyMap;
00398
00399
00401 static const std::string DEFAULT_CONFIG_FILE;
00402
00404 static const std::string DEFAULT_VOCABULARY_PATH;
00405
00407 static const std::string VOCABULARY_PATH_ELEMENT_NAME;
00408
00410 static const std::string VOCABULARY_CONFIG_ELEMENT_NAME;
00411
00413 static const std::string VOCABULARIES_PERMISSION_TYPE;
00414
00416 std::string m_vocab_path;
00417
00419 VocabularyMap m_vocab_map;
00420
00422 Vocabulary m_vocabulary;
00423
00425 mutable boost::signal0<void> m_signal_vocabulary_updated;
00426
00428 mutable boost::mutex m_signal_mutex;
00429
00431 mutable boost::mutex m_mutex;
00432 };
00433
00434
00435 }
00436 }
00437
00438 #endif