Salome HOME
Copyright update
[tools/install.git] / src / SALOME_XmlHandler.cxx
1 //  File      : SALOME_XmlHandler.cxx
2 //  Created   : Thu Dec 18 12:01:00 2002
3 //  Author    : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
4 //  Project   : SALOME
5 //  Module    : Installation Wizard
6 //  Copyright : 2002-2009 CEA
7
8 #include "globals.h"
9
10 #include "SALOME_XmlHandler.hxx"
11 #include "SALOME_ProductsView.hxx"
12 #include "SALOME_InstallWizard.hxx"
13
14 #include <qlineedit.h>
15 #include <qdir.h>
16 #include <qregexp.h>
17 #include <qstringlist.h>
18 #include <iostream.h>
19
20 // ================================================================
21 /*!
22  *  ::isBoolAttributeSet [ static ]
23  *  Returns true if the attribute stores boolean value and 
24  *  corresponds to True value
25  */
26 // ================================================================
27 static bool isBoolAttributeSet( const QString& attr ) {
28   return ( attr.lower() == "true" || 
29            attr.lower() == "yes"  ||
30            attr.lower() == "ok"   || 
31            ( !attr.stripWhiteSpace().isEmpty() && attr.toInt() != 0 ) );
32 }
33 // ================================================================
34 /*!
35  *  ::environmentVariable [ static ]
36  *  Seraches for the environment variable and returns it's
37  *  position on the given string
38  */
39 // ================================================================
40 QString environmentVariable( const QString& str, int& start, int& len ) {
41   QString varName = QString::null;
42   len = 0;
43
44   // Environment variable can be given in the form:
45   // - ${VARIABLE} or
46   // - $(VARIABLE) or 
47   // - $VARIABLE   or
48   // - %VARIABLE%
49   // The first symbol should be the letter.
50   QRegExp rx( "\\$\\{([a-zA-Z]+[a-zA-Z0-9_]*)\\}|\\$\\(([a-zA-Z]+[a-zA-Z0-9_]*)\\)|\\$([a-zA-Z]+[a-zA-Z0-9_]*)|\\%([a-zA-Z]+[a-zA-Z0-9_]*)\\%" );
51
52   int pos = rx.search( str, start );
53   if ( pos != -1 )
54   {
55     start = pos;
56     len = rx.matchedLength();
57     QStringList caps = rx.capturedTexts();
58     for ( uint i = 1; i <= caps.count() && varName.isEmpty(); i++ )
59       varName = *caps.at( i );
60   }
61   return varName;
62 }
63 // ================================================================
64 /*!
65  *  ::substituteVars [ static ]
66  *  Substitutes environment variables in the given string
67  *  by their values
68  */
69 // ================================================================
70 static QString substituteVars( const QString& str ) {
71   QString res = str;
72
73   int start( 0 ), len( 0 );
74   while ( true ) {
75     QString envName = environmentVariable( res, start, len );
76     if ( envName.isNull() )
77       break;
78
79     QString newStr = QString::null;
80     if ( ::getenv( envName ) )
81       newStr = QString( ::getenv( envName ) );
82
83     res.replace( start, len, newStr );
84   }
85
86   return res;
87 }
88
89 // ================================================================
90 /*!
91  *  StructureParser::StructureParser
92  *  Constructor
93  */
94 // ================================================================
95 StructureParser::StructureParser( SALOME_InstallWizard* wizard )
96      : myWizard( wizard ), 
97        myModules( 0 ), 
98        myPrereqs( 0 ), 
99        myTargetDir( 0 ), 
100        myTempDir( 0 )
101 {
102 }
103 // ================================================================
104 /*!
105  *  StructureParser::setProductsLists
106  *  Sets products list view
107  */
108 // ================================================================
109 void StructureParser::setProductsLists( ProductsView* mtree, ProductsView* ptree )
110 {
111   myModules = mtree;
112   myPrereqs = ptree;
113 }
114 // ================================================================
115 /*!
116  *  StructureParser::setTargetDir
117  *  Sets target directory widget
118  */
119 // ================================================================
120 void StructureParser::setTargetDir( QLineEdit* dir )
121 {
122   QString home = QDir::homeDirPath();
123   myTargetDir = dir;
124   if ( myTargetDir && !home.isEmpty() )
125     myTargetDir->setText( home + QDir::separator() + "salome" );
126 }
127 // ================================================================
128 /*!
129  *  StructureParser::setTempDir
130  *  Sets temp directory widget
131  */
132 // ================================================================
133 void StructureParser::setTempDir( QLineEdit* dir )
134 {
135   myTempDir = dir;
136   if ( myTempDir )
137     myTempDir->setText( "/tmp" );
138 }
139 // ================================================================
140 /*!
141  *  StructureParser::getConfigInfo
142  *  Parse 'config' part of the XML file
143  */
144 // ================================================================
145 void StructureParser::getConfigInfo(const QDomElement &theElem)
146 {
147   QString myVersion, myCaption, myCopyright, myLicense, myPlatforms;
148     if ( theElem.attribute( "version" ) ) {
149       myVersion = theElem.attribute( "version" ).stripWhiteSpace();
150       if ( myWizard && !myVersion.isEmpty() ) 
151         myWizard->setVersion( myVersion );
152     }
153     if ( theElem.attribute( "caption" ) ) {
154       myCaption = theElem.attribute( "caption" ).arg( myVersion ).stripWhiteSpace();
155       if ( myWizard && !myCaption.isEmpty() ) 
156         myWizard->setCaption( myCaption );
157     }
158     if ( theElem.attribute( "copyright" ) ) {
159       myCopyright = theElem.attribute( "copyright" ).stripWhiteSpace();
160       if ( myWizard && !myCopyright.isEmpty() ) 
161         myWizard->setCopyright( myCopyright );
162     }
163     if ( theElem.attribute( "license" ) ) {
164       myLicense = theElem.attribute( "license" ).stripWhiteSpace();
165       if ( myWizard && !myLicense.isEmpty() ) 
166         myWizard->setLicense( myLicense );
167     }
168     if ( theElem.attribute( "platforms" ) ) {
169 //       myPlatforms = theElem.attribute( "platforms" ).stripWhiteSpace();
170 //       if ( myWizard && !myPlatforms.isEmpty() ) 
171 //      myWizard->setPlatforms( myPlatforms );
172     }
173     if ( theElem.attribute( "targetdir" ) ) {
174       if ( myTargetDir )
175         myTargetDir->setText( substituteVars( theElem.attribute( "targetdir" ) ) );
176     }
177     if ( theElem.attribute( "tempdir" ) ) {
178       if ( myTempDir )
179         myTempDir->setText( substituteVars( theElem.attribute( "tempdir" ) ) );
180     }
181 }
182 // ================================================================
183 /*!
184  *  StructureParser::getButtonsInfo
185  *  Parse 'buttons' part of the XML file
186  */
187 // ================================================================
188 void StructureParser::getButtonsInfo(const QDomNode &theNode)
189 {
190   QString aLabel, aTootip, aScript;
191   for( QDomNode node = theNode.firstChild(); !node.isNull(); node = node.nextSibling() ) {
192     if ( !node.isElement() ) 
193       continue;
194     QDomElement elem = node.toElement();
195     if ( isBoolAttributeSet( elem.attribute( "disable" ) ) ) 
196       continue;
197     aLabel = ""; aTootip = ""; aScript = "";
198     if ( elem.attribute( "label" ) )
199       aLabel = elem.attribute( "label" ).stripWhiteSpace();
200     if ( elem.attribute( "tooltip" ) )
201       aTootip = elem.attribute( "tooltip" ).stripWhiteSpace();
202     if ( elem.attribute( "script" ) )
203       aScript = elem.attribute( "script" ).stripWhiteSpace();
204     if ( !aLabel.isEmpty() ) {
205       if ( node == theNode.firstChild() )
206         myWizard->addFinishButton( aLabel, aTootip, aScript, true );
207       else
208         myWizard->addFinishButton( aLabel, aTootip, aScript );
209     }
210   }
211 }
212 // ================================================================
213 /*!
214  *  StructureParser::getProductsInfo
215  *  Parse 'products' part of the XML file
216  */
217 // ================================================================
218 void StructureParser::getProductsInfo( const QDomNode &theNode )
219 {
220   MapDependencies mapDeps;
221   QCheckListItem* element;
222
223   QDomNode docNode = theNode.parentNode();
224   getDependenciesInfo( docNode, mapDeps );
225
226   for( QDomNode prodNode = theNode.firstChild(); !prodNode.isNull(); prodNode = prodNode.nextSibling() ) {
227     if ( !prodNode.isElement() ) 
228       continue;
229     for( QDomNode instNode = prodNode.firstChild(); !instNode.isNull(); instNode = instNode.nextSibling() ) {
230       if ( !instNode.isElement() ) 
231         continue;
232       QDomElement instElem = instNode.toElement();
233       if ( instElem.attribute( "os" ) != myWizard->getPlatform() && instElem.attribute( "os" ) != "all" ) 
234         continue;
235       if ( isBoolAttributeSet( instElem.attribute( "disable" ) ) )
236         break; // current product is skipped
237       QDomElement prodElem = prodNode.toElement();
238       
239       QStringList diskspace = QStringList::split( ",", instElem.attribute( "installdiskspace" ) );
240       long binreq = diskspace[ 0 ].toInt();
241       long srcreq = diskspace[ 1 ].toInt();
242       long cmplreq = diskspace[ 2 ].toInt();
243       
244       QString name = prodElem.attribute( "name" ).stripWhiteSpace();
245       QString type = prodElem.attribute( "type" ).stripWhiteSpace().lower();
246       BoolTristate woGuiMode = NotDefined;
247       bool pickUp = isBoolAttributeSet( instElem.attribute( "pickupenv" ) );
248       QString script = instElem.attribute( "script" );
249       QStringList typesList = QStringList::split( ",", type );
250       if ( typesList.find( "component" ) != typesList.end() ) {
251         QString woGuiAttr = instElem.attribute( "woguimode" );
252         if ( !woGuiAttr.isNull() )
253           woGuiMode = BoolTristate( isBoolAttributeSet( woGuiAttr ) );
254         element = myModules->addItem( name, 
255                                       "unknown", 
256                                       script );
257       }
258       else
259         element = myPrereqs->addItem( name,
260                                       "unknown", 
261                                       script );
262       QString descr = QString::null;
263       if ( prodElem.attribute( "description" ) != "" )
264         descr = prodElem.attribute( "description" ).stripWhiteSpace();
265       myWizard->setDependancies
266         ( element, 
267           Dependancies( name, 
268                         mapDeps[ name ],
269                         binreq, 
270                         srcreq, 
271                         cmplreq, 
272                         instElem.attribute( "temporarydiskspace" ).toInt(),
273                         instElem.attribute( "version" ),
274                         descr,
275                         type,
276                         pickUp, 
277                         woGuiMode ) );
278     } 
279   }
280 }
281 // ================================================================
282 /*!
283  *  StructureParser::getDependencies
284  *  Parse 'dependencies' part of the XML file
285  */
286 // ================================================================
287 void StructureParser::getDependenciesInfo( QDomNode &theNode, MapDependencies &theDepends )
288 {
289   QDomNode depsNode = theNode.namedItem( "dependencies" );
290   QStringList depsList = QStringList();
291   for( QDomNode prodNode = depsNode.firstChild(); !prodNode.isNull(); prodNode = prodNode.nextSibling() ) {
292     if ( !prodNode.isElement() ) 
293       continue;
294     QDomElement prodElem = prodNode.toElement();
295     QString prodName = prodElem.attribute( "name" ).stripWhiteSpace();
296     if ( theDepends.contains( prodName ) ) 
297       continue;
298     depsList.clear();
299     for ( QDomNode depNode = prodNode.firstChild(); !depNode.isNull(); depNode = depNode.nextSibling() ) {
300       if ( !depNode.isElement() ) 
301         continue;
302       QDomElement depElem = depNode.toElement();
303       QString depName = depElem.text();
304       if ( depName.isEmpty() )
305         continue;
306       if ( !depsList.contains( depName ) )
307         depsList.append( depName );
308     }
309     theDepends[ prodName ] = depsList;
310   }
311 }
312 // ================================================================
313 /*!
314  *  StructureParser::readXmlFile
315  *  Read XML configuration file for the current platform
316  */
317 // ================================================================
318 void StructureParser::readXmlFile(QString theFileName)
319 {
320   QDomDocument doc( "xml_doc" );
321   QFile file( theFileName );
322   if ( !file.open( IO_ReadOnly ) )
323     return;
324   if ( !doc.setContent( &file ) ) {
325     file.close();
326     return;
327   }
328   file.close();
329   
330   QDomElement docElem = doc.documentElement();
331
332   for( QDomNode node = docElem.firstChild(); !node.isNull(); node = node.nextSibling() ) {
333     QString nodeName = node.nodeName();
334     if ( nodeName == "config" && node.isElement() ) {
335       getConfigInfo( node.toElement() );
336     }
337     else if ( nodeName == "buttons" && node.hasChildNodes() && myModules && myWizard ) {
338       getButtonsInfo( node );
339     }
340     else if ( nodeName == "products" && node.hasChildNodes() && myModules && myWizard ) {
341       getProductsInfo( node );
342     }
343   }
344 }