platform/include/pion/platform/VocabularyManager.hpp

00001 // ------------------------------------------------------------------------
00002 // Pion is a development platform for building Reactors that process Events
00003 // ------------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Pion is free software: you can redistribute it and/or modify it under the
00007 // terms of the GNU Affero General Public License as published by the Free
00008 // Software Foundation, either version 3 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Pion is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Affero General Public License
00017 // along with Pion.  If not, see <http://www.gnu.org/licenses/>.
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 {        // begin namespace pion
00036 namespace platform {    // begin namespace platform (Pion Platform Library)
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 }   // end namespace platform
00436 }   // end namespace pion
00437 
00438 #endif

Generated on Wed Apr 13 16:38:34 2011 for pion-platform by  doxygen 1.4.7