00001 
00006 #include "Cache.h"
00007 
00008 #include "exceptions.h"
00009 
00010 #include "functions.h"
00011 
00012 #include <iostream>
00013 #include <string>
00014 #include <fstream>
00015 #include <sstream>
00016 
00017 Cache::Cache(const string& configurationDirectory) throw (Exception) {
00018 
00019         loadConfFile(configurationDirectory + "/config.cfg");
00020         loadUserConfFile(configurationDirectory + "/users.cfg");
00021 
00022         logger.setParameters(config);
00023         logger.logLoadConfig(configurationDirectory, config.logLevel);
00024 
00025         gc = new GarbageCollector(this, config.GCInterval);
00026 }
00027 
00028 Cache::~Cache() {
00029         for (map<string, User *>::iterator i = users.begin(); i != users.end(); ++i) {
00030                 cout << "Deleting " << i->first << endl;
00031                 delete i->second;
00032         }
00033 
00034         delete gc;
00035 
00036 }
00037 
00038 void Cache::reloadConfig(const string& configurationDirectory) {
00039         loadConfFile(configurationDirectory + "/config.cfg");
00040         gc->setInterval(config.GCInterval);
00041         logger.logLoadConfig(configurationDirectory, config.logLevel);
00042         logger.setParameters(config);
00043 }
00044 
00045 User * Cache::login(const string& name) {
00046         logger.logLogin(name);
00047         return users[name];
00048 }
00049 
00050 void Cache::loadConfFile(const string& confFilename) throw (Exception) {
00051 
00052         ifstream file(confFilename.c_str());
00053 
00054         if (!file) {
00055                 throw FileNotFound(confFilename);
00056         }
00057 
00058         Settings newConfig;
00059         bool assigned[7] = { 0, 0, 0, 0, 0, 0, 0 };
00060         int index;
00061 
00062         const int bufferSize = 128;
00063         char buffer[bufferSize];
00064 
00065         int line = 0;
00066 
00067         while (file.getline(buffer, bufferSize)) {
00068 
00069                 ++line;
00070 
00071                 string s = removeBlanks(string(buffer));
00072 
00073                 if (s.length() == 0) {
00074                         continue;
00075                 }
00076 
00077                 if (!s.compare(0, 9, "logLevel=")) {
00078 
00079                         index = 0;
00080                         newConfig.logLevel = extractValue(s, 9, confFilename, line);
00081 
00082                 } else if (!s.compare(0, 11, "numThreads=")) {
00083 
00084                         index = 1;
00085                         newConfig.numThreads = extractValue(s, 11, confFilename, line);
00086 
00087                 } else if (!s.compare(0, 11, "GCInterval=")) {
00088 
00089                         index = 2;
00090                         newConfig.GCInterval = extractValue(s, 11, confFilename, line);
00091 
00092                 } else if (!s.compare(0, 12, "maxCapacity=")) {
00093 
00094                         index = 3;
00095                         newConfig.maxCapacity = extractValue(s, 12, confFilename, line);
00096 
00097                 } else if (!s.compare(0, 12, "logInterval=")) {
00098 
00099                         index = 4;
00100                         newConfig.logInterval = extractValue(s, 12, confFilename, line);
00101 
00102                 } else if (!s.compare(0, 16, "logBufferLength=")) {
00103 
00104                         index = 5;
00105                         newConfig.logBufferLength = extractValue(s, 16, confFilename, line);
00106 
00107                 } else if (!s.compare(0, 13, "logDirectory=")) {
00108 
00109                         index = 6;
00110                         newConfig.logDirectory = s.substr(13);
00111 
00112                 } else {
00113                         throw ConfigParseException("Config parse error", confFilename, line);
00114                 }
00115 
00116                 if (assigned[index]) {
00117                         throw ConfigSemanticException("Double variable definition", confFilename, line);
00118                 }
00119                 assigned[index] = 1;
00120 
00121         }
00122 
00123         if (!file.eof() && file.fail()) {
00124                 throw IOException(confFilename);
00125         }
00126 
00127         cout << "Cache: \tconfiguration read from: " << confFilename << endl;
00128         config = newConfig;
00129 
00130 }
00131 
00132 void Cache::loadUserConfFile(const string& confFilename) throw (Exception) {
00133 
00134 #if 1
00135         string login = SINGLE_USER;
00136         User * user = new User(this, login, 0);
00137         users[login] = user;
00138         cout << "Cache: \tuser registered: " << login << endl;
00139 #else
00140         ifstream file(confFilename.c_str());
00141 
00142         if (!file) {
00143                 throw FileNotFound(confFilename);
00144         }
00145 
00146         const int bufferSize = 128;
00147         char buffer[bufferSize];
00148 
00149         int line = 0;
00150         bool lastReadQuota = 1;
00151         string login;
00152 
00153         while (file.getline(buffer, bufferSize)) {
00154 
00155                 ++line;
00156 
00157                 string s = removeBlanks(string(buffer));
00158 
00159                 if (s.length() == 0) {
00160                         continue;
00161                 }
00162 
00163                 if (lastReadQuota) {
00164 
00165                         if (s.find("=") != string::npos) {
00166                                 throw ConfigParseException("Illegal character in username: \"=\"", confFilename, line);
00167                         }
00168 
00169                         lastReadQuota = 0;
00170                         login = s;
00171 
00172                 } else {
00173 
00174                         lastReadQuota = 1;
00175 
00176                         if (!s.compare(0, 6, "quota=")) {
00177 
00178                                 int quota = extractValue(s, 6, confFilename, line);
00179 
00180                                 if (quota <= 0) {
00181                                         throw ConfigSemanticException("Quota seems to be too small", confFilename, line);
00182                                 }
00183 
00184                                 User * user = new User(this, login, quota);
00185                                 users[login] = user;
00186                                 cout << "Cache: \tuser registered: " << login << endl; 
00187 
00188                         } else {
00189                                 throw ConfigParseException("Config parse error", confFilename, line);
00190                         }
00191 
00192                 }
00193 
00194         }
00195 
00196         if (!file.eof() && file.fail()) {
00197                 throw IOException(confFilename);
00198         }
00199 
00200         if (!lastReadQuota) {
00201 
00202                 throw ConfigSemanticException("No user config specified", confFilename, line);
00203 
00204         }
00205 
00206         cout << "Cache: \tuser configuration read from: " << confFilename << endl;
00207 #endif
00208 
00209 }