Salome HOME
Fix regression in ParaView installation script: invalid path to the patch
[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-2014 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, myOptLibs;
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     if ( theElem.attribute( "optionallibs" ) ) {
182       myOptLibs = theElem.attribute( "optionallibs" ).stripWhiteSpace();
183       if ( myWizard && !myOptLibs.isEmpty() ) 
184         myWizard->setOptionalLibs( myOptLibs );
185     }
186 }
187 // ================================================================
188 /*!
189  *  StructureParser::getButtonsInfo
190  *  Parse 'buttons' part of the XML file
191  */
192 // ================================================================
193 void StructureParser::getButtonsInfo(const QDomNode &theNode)
194 {
195   QString aLabel, aTootip, aScript;
196   for( QDomNode node = theNode.firstChild(); !node.isNull(); node = node.nextSibling() ) {
197     if ( !node.isElement() ) 
198       continue;
199     QDomElement elem = node.toElement();
200     if ( isBoolAttributeSet( elem.attribute( "disable" ) ) ) 
201       continue;
202     aLabel = ""; aTootip = ""; aScript = "";
203     if ( elem.attribute( "label" ) )
204       aLabel = elem.attribute( "label" ).stripWhiteSpace();
205     if ( elem.attribute( "tooltip" ) )
206       aTootip = elem.attribute( "tooltip" ).stripWhiteSpace();
207     if ( elem.attribute( "script" ) )
208       aScript = elem.attribute( "script" ).stripWhiteSpace();
209     if ( !aLabel.isEmpty() ) {
210       if ( node == theNode.firstChild() )
211         myWizard->addFinishButton( aLabel, aTootip, aScript, true );
212       else
213         myWizard->addFinishButton( aLabel, aTootip, aScript );
214     }
215   }
216 }
217 // ================================================================
218 /*!
219  *  StructureParser::getProductsInfo
220  *  Parse 'products' part of the XML file
221  */
222 // ================================================================
223 void StructureParser::getProductsInfo( const QDomNode &theNode )
224 {
225   MapDependencies mapDeps;
226   QCheckListItem* element;
227
228   QDomNode docNode = theNode.parentNode();
229   getDependenciesInfo( docNode, mapDeps );
230
231   for( QDomNode prodNode = theNode.firstChild(); !prodNode.isNull(); prodNode = prodNode.nextSibling() ) {
232     if ( !prodNode.isElement() ) 
233       continue;
234     for( QDomNode instNode = prodNode.firstChild(); !instNode.isNull(); instNode = instNode.nextSibling() ) {
235       if ( !instNode.isElement() ) 
236         continue;
237       QDomElement instElem = instNode.toElement();
238       if ( instElem.attribute( "os" ) != myWizard->getPlatform() && instElem.attribute( "os" ) != "all" ) 
239         continue;
240       if ( isBoolAttributeSet( instElem.attribute( "disable" ) ) )
241         break; // current product is skipped
242       QDomElement prodElem = prodNode.toElement();
243       
244       QStringList diskspace = QStringList::split( ",", instElem.attribute( "installdiskspace" ) );
245       long binreq = diskspace[ 0 ].toInt();
246       long srcreq = diskspace[ 1 ].toInt();
247       long cmplreq = diskspace[ 2 ].toInt();
248       
249       QString name = prodElem.attribute( "name" ).stripWhiteSpace();
250       QString type = prodElem.attribute( "type" ).stripWhiteSpace().lower();
251       BoolTristate woGuiMode = NotDefined;
252       bool pickUp = isBoolAttributeSet( instElem.attribute( "pickupenv" ) );
253       QString script = instElem.attribute( "script" );
254       QStringList typesList = QStringList::split( ",", type );
255       if ( typesList.find( "component" ) != typesList.end() ) {
256         QString woGuiAttr = instElem.attribute( "woguimode" );
257         if ( !woGuiAttr.isNull() )
258           woGuiMode = BoolTristate( isBoolAttributeSet( woGuiAttr ) );
259         element = myModules->addItem( name, 
260                                       "unknown", 
261                                       script );
262       }
263       else
264         element = myPrereqs->addItem( name,
265                                       "unknown", 
266                                       script );
267       QString descr = QString::null;
268       if ( prodElem.attribute( "description" ) != "" )
269         descr = prodElem.attribute( "description" ).stripWhiteSpace();
270       myWizard->setDependancies
271         ( element, 
272           Dependancies( name, 
273                         mapDeps[ name ],
274                         binreq, 
275                         srcreq, 
276                         cmplreq, 
277                         instElem.attribute( "temporarydiskspace" ).toInt(),
278                         instElem.attribute( "version" ),
279                         descr,
280                         type,
281                         pickUp, 
282                         woGuiMode ) );
283     } 
284   }
285 }
286 // ================================================================
287 /*!
288  *  StructureParser::getDependencies
289  *  Parse 'dependencies' part of the XML file
290  */
291 // ================================================================
292 void StructureParser::getDependenciesInfo( QDomNode &theNode, MapDependencies &theDepends )
293 {
294   QDomNode depsNode = theNode.namedItem( "dependencies" );
295   QStringList depsList = QStringList();
296   for( QDomNode prodNode = depsNode.firstChild(); !prodNode.isNull(); prodNode = prodNode.nextSibling() ) {
297     if ( !prodNode.isElement() ) 
298       continue;
299     QDomElement prodElem = prodNode.toElement();
300     QString prodName = prodElem.attribute( "name" ).stripWhiteSpace();
301     if ( theDepends.contains( prodName ) ) 
302       continue;
303     depsList.clear();
304     for ( QDomNode depNode = prodNode.firstChild(); !depNode.isNull(); depNode = depNode.nextSibling() ) {
305       if ( !depNode.isElement() ) 
306         continue;
307       QDomElement depElem = depNode.toElement();
308       QString depName = depElem.text();
309       if ( depName.isEmpty() )
310         continue;
311       if ( !depsList.contains( depName ) )
312         depsList.append( depName );
313     }
314     theDepends[ prodName ] = depsList;
315   }
316 }
317 // ================================================================
318 /*!
319  *  StructureParser::readXmlFile
320  *  Read XML configuration file for the current platform
321  */
322 // ================================================================
323 void StructureParser::readXmlFile(QString theFileName)
324 {
325   QDomDocument doc( "xml_doc" );
326   QFile file( theFileName );
327   if ( !file.open( IO_ReadOnly ) )
328     return;
329   if ( !doc.setContent( &file ) ) {
330     file.close();
331     return;
332   }
333   file.close();
334   
335   QDomElement docElem = doc.documentElement();
336
337   for( QDomNode node = docElem.firstChild(); !node.isNull(); node = node.nextSibling() ) {
338     QString nodeName = node.nodeName();
339     if ( nodeName == "config" && node.isElement() ) {
340       getConfigInfo( node.toElement() );
341     }
342     else if ( nodeName == "buttons" && node.hasChildNodes() && myModules && myWizard ) {
343       getButtonsInfo( node );
344     }
345     else if ( nodeName == "products" && node.hasChildNodes() && myModules && myWizard ) {
346       getProductsInfo( node );
347     }
348   }
349 }