Re-factored the basic idea of the application: Engine is the main class that ownsWind...
[qtmeetings] / src / Domain / Configuration / Configuration.cpp
1 #include "Configuration.h"
2 #include "ConnectionSettings.h"
3 #include "StartupSettings.h"
4 #include "DisplaySettings.h"
5 #include "Room.h"
6 #include <QDomDocument>
7 #include <QDomElement>
8 #include <QDomNode>
9 #include <QFile>
10 #include <QCryptographicHash>
11
12 #include <QtDebug>
13
14 Configuration * Configuration::sInstance = 0;
15 QString Configuration::sConfigurationPath = "/etc/QtMeetings.conf";
16
17 Configuration::Configuration() :
18                 iConnectionSettings( 0 ),
19                 iStartupSettings( 0 ),
20                 iDisplaySettings( 0 )
21 {
22 }
23
24 Configuration::~Configuration()
25 {
26         delete iConnectionSettings;
27         delete iStartupSettings;
28         delete iDisplaySettings;
29         while ( !iRooms.isEmpty() )
30         {
31                 delete iRooms.takeFirst();
32         }
33 }
34
35 Configuration* Configuration::instance()
36 {
37         if ( sInstance == 0 )
38         {
39                 sInstance = readFromXML( sConfigurationPath );
40         if( !sInstance )
41         {
42             qDebug() << "FATAL: Configuration cannot be read from:" << Configuration::sConfigurationPath;
43         }
44     }
45         return sInstance;
46 }
47
48 ConnectionSettings* Configuration::connectionSettings()
49 {
50         return iConnectionSettings;
51 }
52
53 StartupSettings * Configuration::startupSettings()
54 {
55         return iStartupSettings;
56 }
57
58 DisplaySettings * Configuration::displaySettings()
59 {
60         return iDisplaySettings;
61 }
62
63 Room* Configuration::defaultRoom()
64 {
65         // default room is stored as the first element of the list
66         return ( iRooms.count() == 0 ) ? 0 : iRooms.at( 0 );
67 }
68
69 QString Configuration::languageCode()
70 {
71         return iLanguageCode;
72 }
73
74 QList<Room*> Configuration::rooms()
75 {
76         return iRooms;
77 }
78
79 QByteArray Configuration::adminPassword()
80 {
81         return iAdminPassword;
82 }
83
84 void Configuration::save()
85 {
86         QDomDocument doc;
87         QFile file( sConfigurationPath );
88
89         if ( !file.open( QIODevice::ReadWrite ) )
90         {
91                 return;
92         }
93
94         if ( !doc.setContent( &file ) )
95         {
96                 file.close();
97                 return;
98         }
99
100         QDomElement root = doc.documentElement();
101         // Save all attributes to document
102
103         saveAdminPassword( root );
104
105         for ( QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling() )
106         {
107                 QDomElement e = node.toElement();
108                 QString tagName = e.tagName().toLower();
109
110                 if ( tagName == QString( "connection" ) )
111                 {
112                         saveConnectionSettings( node );
113                 }
114                 else if ( tagName == QString( "rooms" ) )
115                 {
116                         saveRooms( node );
117                 }
118                 else if ( tagName == QString( "language" ) )
119                 {
120                         saveLanguageCode( node );
121                 }
122                 else if ( tagName == QString( "startup" ) )
123                 {
124                         saveStartupSettings( node );
125                 }
126                 else if ( tagName == QString( "display" ) )
127                 {
128                         saveDisplaySettings( node );
129                 }
130         }
131
132         //! Empty the file from previous content and write again with new one
133         file.resize( 0 );
134         file.write( doc.toByteArray( 4 ) );     //! 4 as intent
135
136         file.close();
137
138 }
139
140 void Configuration::saveConnectionSettings( const QDomNode &aXML )
141 {
142         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
143         {
144                 QDomElement e = node.toElement();
145                 QString tagName = e.tagName().toLower();
146
147                 if ( tagName == QString( "serverurl" ) )
148                 {
149                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->serverUrl().toString() );
150                         e.replaceChild( t, e.firstChild() );
151                 }
152                 else if ( tagName == QString( "username" ) )
153                 {
154                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->username() );
155                         e.replaceChild( t, e.firstChild() );
156                 }
157                 else if ( tagName == QString( "password" ) )
158                 {
159                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->password() );
160                         e.replaceChild( t, e.firstChild() );
161                 }
162                 else if ( tagName == QString( "refreshinterval" ) )
163                 {
164                         QString s = QString( "%1" ).arg( iConnectionSettings->refreshInterval() );
165                         QDomText t = node.ownerDocument().createTextNode( s );
166                         e.replaceChild( t, e.firstChild() );
167                 }
168         }
169 }
170
171 void Configuration::saveRooms( const QDomNode &aXML )
172 {
173         //! List of rooms must be cleared and rewritten again
174         QDomDocument doc = aXML.ownerDocument();
175         QDomNode root = aXML; 
176
177         // Remove child nodes...
178         int count = root.childNodes().count();
179         QDomNode node = root.firstChild();
180         QDomNode next;
181         for (int i=0; i<count; i++)
182         {
183                 qDebug() << "remove " << node.toElement().text();
184                 next = node.nextSibling();
185                 node = root.removeChild(node);
186                 node = next;
187         }
188
189         QList<Room*>::iterator i;
190         for ( i = iRooms.begin(); i != iRooms.end(); ++i )
191         {
192                 QDomElement tag = doc.createElement( "room" );
193                 node.appendChild( tag );
194
195                 // First room in the list is a dafault room
196                 if ( i == iRooms.begin() )
197                 {
198                         tag.setAttribute( "default", "true" );
199                 }
200
201                 QDomElement ename = doc.createElement( "name" );
202                 QDomText tname = node.ownerDocument().createTextNode(( *i )->name() );
203                 ename.appendChild( tname );
204                 tag.appendChild( ename );
205
206                 QDomElement eaddress = doc.createElement( "address" );
207                 QDomText taddress = node.ownerDocument().createTextNode(( *i )->address() );
208                 eaddress.appendChild( taddress );
209                 tag.appendChild( eaddress );
210         }
211 }
212
213 void Configuration::saveLanguageCode( const QDomNode &aXML )
214 {
215         QDomElement e = aXML.toElement();
216         e.setAttribute( "code", languageCode() );
217 }
218
219 void Configuration::saveStartupSettings( const QDomNode &aXML )
220 {
221         QDomElement e = aXML.toElement();
222
223         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
224         {
225                 e = node.toElement();
226                 QString tagName = e.tagName().toLower();
227
228                 if ( tagName == QString( "powersaving" ) )
229                 {
230                         ( iStartupSettings->isPowersavingEnabled() ?
231                           e.setAttribute( "enabled", "true" ) :
232                           e.setAttribute( "enabled", "false" ) );
233
234                         e.setAttribute( "on", iStartupSettings->turnOnAt().toString( "hh:mm" ) );
235                         e.setAttribute( "off", iStartupSettings->turnOffAt().toString( "hh:mm" ) );
236                 }
237         }
238 }
239
240 void Configuration::saveDisplaySettings( const QDomNode &aXML )
241 {
242         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
243         {
244                 QDomElement e = node.toElement();
245                 QString tagName = e.tagName().toLower();
246
247                 if ( tagName == QString( "schedule" ) )
248                 {
249                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
250                         {
251                                 QDomElement scheduleElem = scheduleNode.toElement();
252                                 tagName = scheduleElem.tagName().toLower();
253
254                                 if ( tagName == QString( "week" ) )
255                                 {
256                                         scheduleElem.setAttribute( "days", iDisplaySettings->daysInSchedule() );
257                                 }
258                                 else if ( tagName == QString( "day" ) )
259                                 {
260                                         scheduleElem.setAttribute( "startsat", iDisplaySettings->dayStartsAt().toString( "hh:mm" ) );
261                                         scheduleElem.setAttribute( "endsat", iDisplaySettings->dayEndsAt().toString( "hh:mm" ) );
262                                 }
263                         }       // end of for
264                 }       // end of schedule
265                 else if ( tagName == QString( "dateformat" ) )
266                 {
267                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->dateFormat() );
268                         e.replaceChild( t, e.firstChild() );
269                 }
270                 else if ( tagName == QString( "timeformat" ) )
271                 {
272                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->timeFormat() );
273                         e.replaceChild( t, e.firstChild() );
274                 }
275                 else if ( tagName == QString( "screensaver" ) )
276                 {
277                         QString s = QString( "%1" ).arg( iDisplaySettings->screensaver() );
278                         QDomText t = node.ownerDocument().createTextNode( s );
279                         e.replaceChild( t, e.firstChild() );
280                 }
281         }
282 }
283
284 void Configuration::saveAdminPassword( const QDomNode &aXML )
285 {
286         QDomElement e = aXML.toElement();
287         e.setAttribute( "password", QString( adminPassword() ) );
288 }
289
290
291 Configuration* Configuration::readFromXML( const QString &aPath )
292 {
293         QDomDocument doc;
294         QFile file( aPath );
295
296         if ( !file.open( QIODevice::ReadOnly ) )
297         {
298                 return 0;
299         }
300         if ( !doc.setContent( &file ) )
301         {
302                 file.close();
303                 return 0;
304         }
305         file.close();
306
307         QDomElement root = doc.documentElement();
308         // check if the file is the one we need
309         if ( root.tagName().toLower() != QString( "configuration" ) )
310         {
311                 return 0;
312         }
313
314         Configuration* conf = new Configuration();
315
316         conf->iAdminPassword = Configuration::readAdminPassword( root );
317
318         for ( QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling() )
319         {
320                 QDomElement e = node.toElement();
321                 QString tagName = e.tagName().toLower();
322
323                 if ( tagName == QString( "connection" ) )
324                 {
325                         conf->iConnectionSettings = Configuration::readConnectionSettings( node );
326                 }
327                 else if ( tagName == QString( "rooms" ) )
328                 {
329                         conf->iRooms = Configuration::readRooms( node );
330                 }
331                 else if ( tagName == QString( "language" ) )
332                 {
333                         conf->iLanguageCode = Configuration::readLanguageCode( node );
334                 }
335                 else if ( tagName == QString( "startup" ) )
336                 {
337                         conf->iStartupSettings = Configuration::readStartupSettings( node );
338                 }
339                 else if ( tagName == QString( "display" ) )
340                 {
341                         conf->iDisplaySettings = Configuration::readDisplaySettings( node );
342                 }
343         }
344
345         return conf;
346 }
347
348 ConnectionSettings* Configuration::readConnectionSettings( const QDomNode &aXML )
349 {
350         QString server, username, password;
351         unsigned int interval = Configuration::sDefaultInterval;
352
353         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
354         {
355                 QDomElement e = node.toElement();
356                 QString tagName = e.tagName().toLower();
357
358                 if ( tagName == QString( "serverurl" ) )
359                 {
360                         server = e.text();
361                 }
362                 else if ( tagName == QString( "username" ) )
363                 {
364                         username = e.text();
365                 }
366                 else if ( tagName == QString( "password" ) )
367                 {
368                         password = e.text();
369                 }
370                 else if ( tagName == QString( "refreshinterval" ) )
371                 {
372                         bool success = false;
373                         unsigned int intervalTMP = e.text().toUInt( &success );
374                         if ( success )
375                         {
376                                 interval = intervalTMP;
377                         }
378                 }
379         }
380
381         return new ConnectionSettings( server, username, password, interval );
382 }
383
384 QList<Room*> Configuration::readRooms( const QDomNode &aXML )
385 {
386         QList<Room*> rooms;
387
388         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
389         {
390                 QDomElement e = node.toElement();
391                 QString tagName = e.tagName().toLower();
392
393                 if ( tagName == QString( "room" ) )
394                 {
395                         QString name, address;
396
397                         for ( QDomNode roomNode = node.firstChild(); !roomNode.isNull(); roomNode = roomNode.nextSibling() )
398                         {
399                                 QDomElement roomElem = roomNode.toElement();
400                                 tagName = roomElem.tagName().toLower();
401                                 if ( tagName == QString( "name" ) )
402                                 {
403                                         name = roomElem.text();
404                                 }
405                                 else if ( tagName == QString( "address" ) )
406                                 {
407                                         address = roomElem.text();
408                                 }
409                         }
410                         Room* room = new Room( name, address );
411                         QString defaultAttr = e.attribute( "default" ).toLower();
412                         if ( defaultAttr == QString( "true" ) )
413                         {
414                                 rooms.insert( 0, room );
415                         }
416                         else
417                         {
418                                 rooms.append( room );
419                         }
420                 }
421         }
422
423         return rooms;
424 }
425
426 QString Configuration::readLanguageCode( const QDomNode &aXML )
427 {
428         QDomElement e = aXML.toElement();
429         QString tagName = e.tagName().toLower();
430
431         if ( e.hasAttribute( "code" ) )
432         {
433                 return e.attribute( "code" );
434         }
435         else
436         {
437                 // default language is English
438                 return "EN";
439         }
440 }
441
442 StartupSettings * Configuration::readStartupSettings( const QDomNode &aXML )
443 {
444         QDomElement e = aXML.toElement();
445
446         bool isPowersavingEnabled = false;
447         QTime turnOnAt, turnOffAt;
448
449         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
450         {
451                 e = node.toElement();
452                 QString tagName = e.tagName().toLower();
453
454                 if ( tagName == QString( "powersaving" ) )
455                 {
456                         if ( e.hasAttribute( "enabled" ) &&
457                                   e.attribute( "enabled" ) == QString( "true" ) )
458                         {
459                                 isPowersavingEnabled = true;
460                         }
461
462                         if ( e.hasAttribute( "on" ) )
463                         {
464                                 QString on = e.attribute( "on" );
465                                 turnOnAt = QTime::fromString( on, "hh:mm" );
466
467                         }
468
469                         if ( e.hasAttribute( "off" ) )
470                         {
471                                 QString off = e.attribute( "off" );
472                                 turnOffAt = QTime::fromString( off, "hh:mm" );
473                         }
474                 }
475         }
476
477         return new StartupSettings( isPowersavingEnabled, turnOnAt, turnOffAt );
478 }
479
480 DisplaySettings * Configuration::readDisplaySettings( const QDomNode &aXML )
481 {
482         DisplaySettings::DaysInSchedule daysInSchedule = DisplaySettings::WeekdaysInSchedule;
483         QTime dayStartsAt, dayEndsAt;
484         DisplaySettings::DateFormat dateformat = DisplaySettings::ShortDateFormat;
485         DisplaySettings::TimeFormat timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
486         int screensaver = 1;    //! Default value for screensaver wait time
487
488         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
489         {
490                 QDomElement e = node.toElement();
491                 QString tagName = e.tagName().toLower();
492
493                 if ( tagName == QString( "schedule" ) )
494                 {
495                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
496                         {
497                                 QDomElement scheduleElem = scheduleNode.toElement();
498                                 tagName = scheduleElem.tagName().toLower();
499
500                                 if ( tagName == QString( "week" ) )
501                                 {
502                                         if ( scheduleElem.hasAttribute( "days" ) )
503                                         {
504                                                 // default value is 5, only other supported possibility is 7
505                                                 bool success = false;
506                                                 unsigned int days = scheduleElem.attribute( "days" ).toUInt( &success );
507                                                 daysInSchedule = ( success && days == 7 ) ? DisplaySettings::WholeWeekInSchedule : DisplaySettings::WeekdaysInSchedule;
508                                         }
509
510                                 }
511                                 else if ( tagName == QString( "day" ) )
512                                 {
513                                         if ( scheduleElem.hasAttribute( "startsat" ) )
514                                         {
515                                                 QString time = scheduleElem.attribute( "startsat" );
516                                                 dayStartsAt = QTime::fromString( time, "hh:mm" );
517                                         }
518                                         if ( scheduleElem.hasAttribute( "endsat" ) )
519                                         {
520                                                 QString time = scheduleElem.attribute( "endsat" );
521                                                 dayEndsAt = QTime::fromString( time, "hh:mm" );
522                                         }
523
524                                 }
525                         }       // end of for
526                 }       // end of schedule
527                 else if ( tagName == QString( "dateformat" ) )
528                 {
529                         //! Not able to display long format anyway at the moment
530                         /*
531                         if ( e.text() == QObject::tr( "dddd d MMMM yyyy" ) )
532                                 dateformat = DisplaySettings::LongDateFormat;
533                         else
534                                 dateformat = DisplaySettings::ShortDateFormat;
535                         */
536                         dateformat = DisplaySettings::ShortDateFormat;
537                 }
538                 else if ( tagName == QString( "timeformat" ) )
539                 {
540                         //! Not able to display "TwelveHoursTimeFormat" anyway at the moment
541                         /*
542                         if ( e.text() == QObject::tr( "hh:mm ap" ) )
543                                 timeformat = DisplaySettings::TwelveHoursTimeFormat;
544                         else
545                                 timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
546                         */
547                         timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
548                 }
549                 else if ( tagName == QString( "screensaver" ) )
550                 {
551                         bool success = false;
552                         unsigned int screensaverTMP = e.text().toUInt( &success );
553                         if ( success )
554                         {
555                                 screensaver = screensaverTMP;
556                         }
557                 }
558         }
559
560         return new DisplaySettings( dateformat, timeformat, daysInSchedule, dayStartsAt, dayEndsAt, screensaver );
561 }
562
563 QByteArray Configuration::readAdminPassword( const QDomNode &aXML )
564 {
565         QDomElement e = aXML.toElement();
566         QString tagName = e.tagName().toLower();
567         if ( e.hasAttribute( "password" ) )
568         {
569                 QString pw = e.attribute( "password" );
570                 // Check if the password is default uncrypted "admin"
571                 if ( pw == QString( "admin" ) )
572                 {
573                         // uncrypted password needs to be encoded
574                         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
575                         hash->addData( pw.toUtf8() );
576                         pw = QString( hash->result() );
577                         delete hash;
578                 }
579                 return ( pw.toAscii() ).toHex();
580                 
581         }
582         else
583         {
584                 return 0;
585         }
586 }
587
588 void Configuration::setRooms( const QList<Room*> aRooms )
589 {
590         iRooms = aRooms;
591 }
592
593 QString Configuration::hashPassword( const QString aPassword )
594 {
595         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
596         hash->addData( aPassword.toUtf8() );
597         QByteArray password = hash->result();
598         delete hash;
599
600         return QString( password );
601 }