presage  0.8.7
predictorRegistry.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************
00003  *  Presage, an extensible predictive text entry system
00004  *  ---------------------------------------------------
00005  *
00006  *  Copyright (C) 2008  Matteo Vescovi <matteo.vescovi@yahoo.co.uk>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License along
00019     with this program; if not, write to the Free Software Foundation, Inc.,
00020     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00021                                                                              *
00022                                                                 **********(*)*/
00023 
00024 
00025 #include "predictorRegistry.h"
00026 
00027 // REVISIT: including predictors here because Plump is temporarily
00028 // disabled. Predictor lifetime management is currently disabled.
00029 //
00030 // IMPORTANT: remove following includes when moving back to dynamically
00031 // loaded predictors.
00032 //
00033 #ifdef USE_SQLITE
00034 # include "predictors/smoothedNgramPredictor.h"
00035 #endif
00036 #include "predictors/ARPAPredictor.h"
00037 #include "predictors/abbreviationExpansionPredictor.h"
00038 #include "predictors/dummyPredictor.h"
00039 #include "predictors/dictionaryPredictor.h"
00040 #include "predictors/recencyPredictor.h"
00041 #include "predictors/dejavuPredictor.h"
00042 
00043 const char* PredictorRegistry::LOGGER  = "Presage.PredictorRegistry.LOGGER";
00044 const char* PredictorRegistry::PREDICTORS = "Presage.PredictorRegistry.PREDICTORS";
00045 
00046 PredictorRegistry::PredictorRegistry(Configuration* configuration)
00047     : config(configuration),
00048       contextTracker(0),
00049       logger("PredictorRegistry", std::cerr),
00050       dispatcher(this)
00051 {
00052     // build notification dispatch map
00053     dispatcher.map (config->find (LOGGER), & PredictorRegistry::setLogger);
00054     dispatcher.map (config->find (PREDICTORS), & PredictorRegistry::setPredictors);
00055 }
00056 
00057 
00058 PredictorRegistry::~PredictorRegistry()
00059 {
00060     removePredictors();
00061 }
00062 
00063 void PredictorRegistry::setLogger (const std::string& value)
00064 {
00065     logger << setlevel (value);
00066     logger << INFO << "LOGGER: " << value << endl;
00067 }
00068 
00069 
00070 void PredictorRegistry::setContextTracker(ContextTracker* ct) {
00071     if (contextTracker != ct) {
00072         contextTracker = ct;
00073         removePredictors ();
00074         setPredictors (predictors_list);
00075     }
00076 }
00077 
00078 void PredictorRegistry::setPredictors(const std::string& predictorList)
00079 {
00080     predictors_list = predictorList;
00081     logger << INFO << "PREDICTORS: " << predictors_list << endl;
00082 
00083     if (contextTracker) {
00084         // predictors need tracker, only initialize them if available
00085 
00086         removePredictors();
00087 
00088         std::stringstream ss(predictors_list);
00089         std::string predictor;
00090         while (ss >> predictor) {
00091             logger << INFO << "Initializing predictive predictor: " << predictor << endl;
00092             addPredictor(predictor);
00093         }
00094     }
00095 }
00096 
00097 void PredictorRegistry::addPredictor(const std::string& predictorName)
00098 {
00099     Predictor* predictor = 0;
00100     try {
00101         // TODO: this will have to do for now, until a proper predictor
00102         // framework (i.e. plump) is integrated into presage. Until
00103         // then, all known predictors have to be listed here and explicitly
00104         // created based on their name.
00105         //
00106         if (predictorName == "AbbreviationExpansionPredictor") {
00107             predictor = new AbbreviationExpansionPredictor(config, contextTracker);
00108         } else if (predictorName == "DummyPredictor") {
00109             predictor = new DummyPredictor(config, contextTracker);
00110         } else if (predictorName == "DictionaryPredictor" ) {
00111             predictor = new DictionaryPredictor(config, contextTracker);
00112 #ifdef USE_SQLITE
00113         } else if (predictorName == "SmoothedNgramPredictor") {
00114             predictor = new SmoothedNgramPredictor(config, contextTracker);
00115 #endif
00116         } else if (predictorName == "RecencyPredictor") {
00117             predictor = new RecencyPredictor(config, contextTracker);
00118         } else if (predictorName == "DejavuPredictor") {
00119             predictor = new DejavuPredictor(config, contextTracker);
00120         } else if (predictorName == "ARPAPredictor") {
00121               predictor = new ARPAPredictor(config,contextTracker);
00122         }
00123     } catch (PresageException ex) {
00124         logger << ERROR << "Predictor " + predictorName + " failed to initialize." << endl;
00125     }
00126 
00127     if (predictor != 0) {
00128         predictors.push_back (predictor);
00129         logger << INFO << "Activated predictive predictor: " << predictorName << endl;
00130     } else {
00131         // TODO: raise exception
00132         logger << FATAL << "Unable to initialize predictor: " << predictorName << endl;
00133         throw PredictorRegistryException(PRESAGE_INIT_PREDICTOR_ERROR, "Unable to initialize predictor: " + predictorName);
00134     }
00135 }
00136 
00137 void PredictorRegistry::removePredictors()
00138 {
00139     for (size_t i = 0; i < predictors.size(); i++) {
00140         logger << DEBUG << "Removing predictor: " << predictors[i]->getName() << endl;
00141         delete predictors[i];
00142     }
00143     predictors.clear();
00144 }
00145 
00146 PredictorRegistry::Iterator PredictorRegistry::iterator()
00147 {
00148     return Iterator(predictors);
00149 }
00150 
00151 
00153 // Iterator
00154 PredictorRegistry::Iterator::Iterator(std::vector<Predictor*>& cont)
00155     : iter_end(cont.end()),
00156       iter_curr(cont.begin())
00157 {}
00158 
00159 PredictorRegistry::Iterator::~Iterator()
00160 {}
00161 
00162 bool PredictorRegistry::Iterator::hasNext() const
00163 {
00164     bool result = (iter_end != iter_curr);
00165 
00166     return result;
00167 }
00168 
00169 Predictor* PredictorRegistry::Iterator::next()
00170 {
00171     Predictor* result = *iter_curr;
00172     iter_curr++;
00173     return result;
00174 }
00175 
00176 void PredictorRegistry::update (const Observable* variable)
00177 {
00178     logger << DEBUG << "About to invoke dispatcher: " << variable->get_name () << " - " << variable->get_value() << endl;
00179 
00180     dispatcher.dispatch (variable);
00181 }