00001 #include "nationalcfg.h"
00002
00003 #include <opie2/odebug.h>
00004
00005 #include <qfile.h>
00006
00007 static QString _key_desc="description";
00008 static QString _key_doc="nationaldays";
00009 static QString _key_list="entries";
00010 static QString _key_entry="entry";
00011 static QString _key_calc="calculation";
00012
00013 static QString _content_type="type";
00014 static QString _content_float="floating";
00015 static QString _content_fix="fix";
00016
00017 static QString _content_name="name";
00018 static QString _content_value="value";
00019
00020 static QString _content_date="date";
00021 static QString _content_weekd="weekday";
00022 static QString _content_offset="offset";
00023 static QString _content_dayofmonth="dayofmonth";
00024 static QString _content_datedep="datedep";
00025 static QString _content_month="month";
00026
00027 NHcfg::NHcfg()
00028 :QXmlDefaultHandler(),err(""),_path("")
00029 {
00030 }
00031
00032 NHcfg::~NHcfg()
00033 {
00034 }
00035
00036 bool NHcfg::load(const QString&aPath)
00037 {
00038 _path=aPath;
00039 stage = 0;
00040 QFile *f=new QFile(_path);
00041 if (!f) {
00042 oerr << "Could not open file" << oendl;
00043 return false;
00044 }
00045 QXmlInputSource is(*f);
00046 QXmlSimpleReader reader;
00047 reader.setContentHandler(this);
00048 reader.setErrorHandler(this);
00049
00050 currentFixList.clear();
00051 currentFloatList.clear();
00052 counter = 0;
00053 level = 0;
00054
00055 err = "";
00056 bool ret = reader.parse(is);
00057 if (err.length()>0)
00058 odebug << "Errors: " << err << oendl;
00059 return ret;
00060 }
00061
00062 const tentrylist&NHcfg::fixDates()const
00063 {
00064 return currentFixList;
00065 }
00066
00067 const tentrylist&NHcfg::floatingDates()const
00068 {
00069 return currentFloatList;
00070 }
00071
00072 bool NHcfg::warning(const QXmlParseException& e)
00073 {
00074 QString tmp;
00075
00076 tmp.sprintf("%d: warning: %s\n", e.lineNumber(),
00077 (const char*) e.message().utf8());
00078
00079 err += tmp;
00080
00081 return true;
00082 }
00083
00084 bool NHcfg::error(const QXmlParseException& e)
00085 {
00086 QString tmp;
00087
00088 tmp.sprintf("%d: error: %s\n", e.lineNumber(),
00089 (const char*) e.message().utf8());
00090
00091 err += tmp;
00092
00093 return true;
00094 }
00095
00096 bool NHcfg::fatalError(const QXmlParseException& e)
00097 {
00098 QString tmp;
00099
00100 tmp.sprintf("%d: fatal error: %s\n", e.lineNumber(),
00101 (const char*) e.message().utf8());
00102
00103 err += tmp;
00104
00105 return false;
00106 }
00107
00108 bool NHcfg::startElement(const QString&, const QString&,const QString& name, const QXmlAttributes& attr)
00109 {
00110 bool ret = false;
00111 if (name==_key_doc) {
00112 stage = 1;
00113 return true;
00114 }
00115 if (stage == 0) {
00116 err = "This is not a national holiday config file";
00117 return false;
00118 }
00119 if (name==_key_desc) {
00120 stage = 2;
00121 ret = setName(attr);
00122 return ret;
00123 }
00124 if (stage<2) {return false;}
00125 if (name==_key_list) {stage=3;return true;}
00126
00127 if (stage<3) {return false;}
00128
00129 if (name==_key_entry) {
00130 ++level;
00131 ++counter;
00132 m_currentEntry = NHentry();
00133
00134 }
00135 if (name==_key_calc) {
00136 ++level;
00137
00138 return true;
00139 }
00140 if (level == 1) {
00141 return parsevalue(name,attr);
00142 } else if (level >= 2) {
00143 return parseCalc(name,attr);
00144 }
00145 }
00146
00147 bool NHcfg::setName(const QXmlAttributes&attr)
00148 {
00149 int nindx = attr.index("value");
00150 if (nindx==-1) {
00151 return false;
00152 }
00153 _contentname = attr.value(nindx);
00154 return true;
00155 }
00156
00157 bool NHcfg::parsevalue(const QString&name,const QXmlAttributes&attr)
00158 {
00159 if (name != _key_entry && name != _key_calc) {err = QString("Not a valid entry (%1)").arg(name); return false;}
00160
00161 int nindex = attr.index(_content_name);
00162 int dindex = attr.index(_content_date);
00163 int tindex = attr.index(_content_type);
00164
00165 if (nindex == -1) {
00166 err = QString("Listentry %1 is invalid (name missing)").arg(counter);
00167 return false;
00168 }
00169 m_currentEntry.setName(attr.value(nindex));
00170
00171 if (tindex != -1 && attr.value(tindex)==_content_float) {
00172 m_currentEntry.setType(NHentry::floating);
00173 return true;
00174 }
00175
00176 if (dindex == -1) {
00177 err = QString("Listentry %1 is invalid ").arg(counter);return false;
00178 }
00179
00180 QString txt = attr.value(nindex);
00181 QString dstring = attr.value(dindex);
00182 QStringList e = QStringList::split("-",dstring);
00183 if (e.count()!=2){err=QString("Datestring %1 is invalid (entry %2)").arg(dstring).arg(counter);return false;}
00184 QDate d(0,e[0].toInt(),e[1].toInt());
00185 m_currentEntry.setDate(d);
00186 return true;
00187 }
00188
00189 bool NHcfg::parseCalc(const QString&name,const QXmlAttributes&attr)
00190 {
00191 ++level;
00192 int vindex = attr.index(_content_value);
00193 if (vindex == -1) {
00194 err = QString("Value for element %1 on entry %2 is missing").arg(name).arg(counter);
00195 return false;
00196 }
00197 int what_c =0;
00198 QString what = name.lower();
00199 QString value;
00200 if (what == _content_date) {
00201 what_c = 1;
00202 } else if (what == _content_weekd) {
00203 what_c = 2;
00204 } else if (what == _content_offset) {
00205 what_c = 3;
00206 } else if (what == _content_dayofmonth) {
00207 what_c = 4;
00208 } else if (what == _content_datedep) {
00209 what_c = 5;
00210 } else if (what == _content_month) {
00211 what_c = 6;
00212 }
00213 if (what_c == 0) {
00214 err = QString("Unknown element %1 on entry %2").arg(name).arg(counter);
00215 return false;
00216 }
00217 value = attr.value(vindex).lower();
00218 QStringList e;
00219 QDate d;
00220 bool dotformat = false;
00221 switch (what_c) {
00222 case 1:
00223 if (value != "easter") {
00224 e = QStringList::split("-",value);
00225 if (e.count()!=2) {
00226 e = QStringList::split(".",value);
00227 dotformat = true;
00228 }
00229 if (e.count()!=2){err=QString("Datestring %1 is invalid (entry %2)").arg(value).arg(counter);return false;}
00230 if (!dotformat) {
00231 d=QDate(0,e[0].toInt(),e[1].toInt());
00232 } else {
00233 d=QDate(0,e[1].toInt(),e[0].toInt());
00234 }
00235 } else {
00236 d=QDate(9999,1,1);
00237 }
00238 m_currentEntry.setDate(d);
00239 break;
00240 case 2:
00241 m_currentEntry.setWeekday(value);
00242 break;
00243 case 3:
00244 m_currentEntry.setOffet(value.toInt());
00245 break;
00246 case 4:
00247 m_currentEntry.setDayofmonth(value);
00248 break;
00249 case 5:
00250 m_currentEntry.setDaydep(value);
00251 break;
00252 case 6:
00253 m_currentEntry.setMonth(value);
00254 break;
00255 }
00256 return true;
00257 }
00258
00259 bool NHcfg::endElement(const QString&, const QString&,const QString& name)
00260 {
00261
00262 if (name==_key_entry) {
00263 if (m_currentEntry.type()==NHentry::fix) {
00264 currentFixList.append(m_currentEntry);
00265 } else {
00266 currentFloatList.append(m_currentEntry);
00267
00268 }
00269 } else if (name==_key_calc) {
00270
00271 }
00272 if (stage>=3) {
00273 --level;
00274 }
00275
00276 return true;
00277 }
00278
00279 const QString&NHcfg::errorString()const
00280 {
00281 return err;
00282 }
00283
00284 NHentry::NHentry()
00285 :m_Type(fix)
00286 {
00287 m_Offset=0;
00288 }
00289
00290 NHentry::~NHentry()
00291 {}
00292
00293 void NHentry::setName(const QString&aName)
00294 {
00295 m_Name = aName;
00296 }
00297
00298 const QString&NHentry::name()const
00299 {
00300 return m_Name;
00301 }
00302
00303 void NHentry::setType(NHentry::entry_type aType)
00304 {
00305 m_Type = aType;
00306 }
00307
00308 NHentry::entry_type NHentry::type()const
00309 {
00310 return m_Type;
00311 }
00312
00313 void NHentry::setDate(const QDate&aDate)
00314 {
00315 m_Date = aDate;
00316 }
00317
00318 const QDate&NHentry::date()const
00319 {
00320 return m_Date;
00321 }
00322
00323 void NHentry::setWeekday(const QString&aDay)
00324 {
00325 m_Weekday = aDay;
00326 }
00327
00328 const QString&NHentry::weekday()const
00329 {
00330 return m_Weekday;
00331 }
00332
00333 void NHentry::setDayofmonth(const QString&aDay)
00334 {
00335 m_Dayofmonth = aDay;
00336 }
00337
00338 const QString&NHentry::dayofmonth()const
00339 {
00340 return m_Dayofmonth;
00341 }
00342
00343 void NHentry::setDaydep(const QString&dep)
00344 {
00345 m_Depth = dep;
00346 }
00347
00348 const QString&NHentry::daydep()const
00349 {
00350 return m_Depth;
00351 }
00352
00353 void NHentry::setMonth(const QString&month)
00354 {
00355 m_Month = month;
00356 }
00357
00358 const QString&NHentry::month()const
00359 {
00360 return m_Month;
00361 }
00362
00363 void NHentry::setOffet(int aOffset)
00364 {
00365 m_Offset = aOffset;
00366 }
00367
00368 const int NHentry::offset()const
00369 {
00370 return m_Offset;
00371 }