]> Creatis software - crea.git/blob - lib/creaDevManagerLib/modelCDMAppli.cpp
Feature #1711
[crea.git] / lib / creaDevManagerLib / modelCDMAppli.cpp
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 #                        pour la Sant�)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 #
10 #  This software is governed by the CeCILL-B license under French law and
11 #  abiding by the rules of distribution of free software. You can  use,
12 #  modify and/ or redistribute the software under the terms of the CeCILL-B
13 #  license as circulated by CEA, CNRS and INRIA at the following URL
14 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 #  or in the file LICENSE.txt.
16 #
17 #  As a counterpart to the access to the source code and  rights to copy,
18 #  modify and redistribute granted by the license, users are provided only
19 #  with a limited warranty  and the software's author,  the holder of the
20 #  economic rights,  and the successive licensors  have only  limited
21 #  liability.
22 #
23 #  The fact that you are presently reading this means that you have had
24 #  knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------
26  */
27
28 /*
29  * modelCDMAppli.cpp
30  *
31  *  Created on: Nov 23, 2012
32  *      Author: Daniel Felipe Gonzalez Obando
33  */
34
35 #include "modelCDMAppli.h"
36
37 #include <iostream>
38 #include <fstream>
39 #include <sstream>
40 #include <algorithm>
41
42 #include "CDMUtilities.h"
43 #include "creaWx.h"
44 #include "wx/dir.h"
45
46 modelCDMAppli::modelCDMAppli()
47 {
48 }
49
50 modelCDMAppli::modelCDMAppli(modelCDMIProjectTreeNode* parent, const std::string& path, const std::string& name, const int& level)
51 {
52   std::cout << "creating appli\n";
53   this->parent = parent;
54   this->type = wxDIR_DIRS;
55   this->name = name;
56   this->level = level;
57   this->path = path;
58
59
60
61   this->path = CDMUtilities::fixPath(path);
62   std::string pathFixed(CDMUtilities::fixPath(path));
63
64   this->applications.clear();
65   wxDir dir(crea::std2wx((pathFixed).c_str()));
66   if (dir.IsOpened())
67     {
68       wxString fileName;
69       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
70       while (cont)
71         {
72           std::string stdfileName = crea::wx2std(fileName);
73
74           if(stdfileName != "template_appli" && stdfileName != "template_wx_appli")
75             {
76               modelCDMApplication* application = new modelCDMApplication(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
77               this->applications.push_back(application);
78               this->children.push_back(application);
79             }
80           else
81             {
82               modelCDMFolder* folder = new modelCDMFolder(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
83               this->children.push_back(folder);
84             }
85
86           cont = dir.GetNext(&fileName);
87         }
88       //files
89       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
90       while (cont)
91         {
92           std::string stdfileName = crea::wx2std(fileName);
93
94           //if CMakeLists, create CMakeLists
95           if(stdfileName == "CMakeLists.txt")
96             {
97               this->CMakeLists = new modelCDMCMakeListsFile(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
98               this->children.push_back(this->CMakeLists);
99             }
100           //if is an unknown file, create file
101           else
102             {
103               this->children.push_back(new modelCDMFile(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
104             }
105
106           cont = dir.GetNext(&fileName);
107         }
108
109     }
110   this->SortChildren();
111   std::sort(this->applications.begin(), this->applications.end(), CompareNodeItem);
112 }
113
114 modelCDMAppli::~modelCDMAppli()
115 {
116 }
117
118 const std::vector<modelCDMApplication*>& modelCDMAppli::GetApplications() const
119 {
120   return this->applications;
121 }
122
123 modelCDMApplication* modelCDMAppli::CreateApplication(
124     const std::string& namein,
125     const int& type,
126     std::string*& result
127 )
128 {
129   std::vector<std::string> words;
130   CDMUtilities::splitter::split(words,namein," '/\\*\"%",CDMUtilities::splitter::no_empties);
131   std::string name;
132   for (int i = 0; i < (int)(words.size()); i++)
133     {
134       name += words[i];
135     }
136   if (name == "")
137     {
138       result = new std::string("The given name is not valid:  '/\\*\"% are forbidden.");
139       return NULL;
140     }
141
142   if (type == 0)
143     {
144       //copy template application folder with new name
145 #ifdef _WIN32
146       std::string copyCommand = "xcopy \"" + this->path + CDMUtilities::SLASH + "template_appli\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "\" /Y";
147 #else
148       std::string copyCommand = "cp -r \"" + this->path + CDMUtilities::SLASH + "template_appli\" \"" + this->path + CDMUtilities::SLASH + name + "\"";
149 #endif
150
151       if(system(copyCommand.c_str()))
152         {
153           result = new std::string("An error occurred while running '" + copyCommand + "'.");
154           return NULL;
155         }
156       //set name of library in CMakeLists inside copied folder
157       std::string line;
158       std::ifstream in((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
159       if( !in.is_open())
160         {
161           result = new std::string("CMakeLists.txt file failed to open.");
162           return NULL;
163         }
164       std::ofstream out((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
165       while (getline(in, line))
166         {
167           if(line == "SET ( EXE_NAME   MyExe  )")
168             line = "SET ( EXE_NAME   " + name + "  )";
169           out << line << std::endl;
170         }
171       in.close();
172       out.close();
173       //delete old file and rename new file
174 #ifdef _WIN32
175       std::string renameCommand = "move /Y \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt\"";
176 #else
177       std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt\"";
178 #endif
179
180       if(system(renameCommand.c_str()))
181         {
182           result = new std::string("An error occurred while running '" + renameCommand + "'.");
183           return NULL;
184         }
185
186       //add application to model
187       modelCDMApplication* application = new modelCDMApplication(this, this->path + CDMUtilities::SLASH + name, name, this->level + 1);
188       this->applications.push_back(application);
189       this->children.push_back(application);
190
191       this->SortChildren();
192
193       result = new std::string(this->path + CDMUtilities::SLASH + name);
194       return application;
195     }
196   else if(type == 1)
197     {
198       //copy template application folder with new name
199 #ifdef _WIN32
200       std::string copyCommand = "xcopy \"" + this->path + CDMUtilities::SLASH + "template_wx_appli\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "\" /Y";
201 #else
202       std::string copyCommand = "cp -r \"" + this->path + CDMUtilities::SLASH + "template_wx_appli\" \"" + this->path + CDMUtilities::SLASH + name + "\"";
203 #endif
204
205       if(system(copyCommand.c_str()))
206         {
207           result = new std::string("An error occurred while running '" + copyCommand + "'.");
208           return NULL;
209         }
210       //set name of library in CMakeLists inside copied folder
211       std::string line;
212       std::ifstream in((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
213       if( !in.is_open())
214         {
215           result = new std::string("CMakeLists.txt file failed to open.");
216           return NULL;
217         }
218       std::ofstream out((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
219       while (getline(in, line))
220         {
221           if(line == "SET ( EXE_NAME   MyExeWx  )")
222             line = "SET ( EXE_NAME   " + name + "  )";
223           out << line << std::endl;
224         }
225       in.close();
226       out.close();
227       //delete old file and rename new file
228 #ifdef _WIN32
229       std::string renameCommand = "move /Y \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt\"";
230 #else
231       std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt\"";
232 #endif
233
234       if(system(renameCommand.c_str()))
235         {
236           result = new std::string("An error occurred while running '" + renameCommand + "'.");
237           return NULL;
238         }
239
240       //add application to model
241       modelCDMApplication* application = new modelCDMApplication(this, this->path + CDMUtilities::SLASH + name, name, this->level + 1);
242       this->applications.push_back(application);
243       this->children.push_back(application);
244
245       this->SortChildren();
246
247       result = new std::string(this->path + CDMUtilities::SLASH + name);
248       return application;
249     }
250   else
251     {
252       std::string res = "Invalid application type: ";
253       res += type;
254       res += std::string(".\n0:Console application.\n1:GUI Application (wxWidgets).");
255       result = new std::string(res);
256
257       return NULL;
258     }
259 }
260
261 const bool modelCDMAppli::Refresh(std::string*& result)
262 {
263   std::cout << "refreshing appli" << std::endl;
264   this->type = wxDIR_DIRS;
265
266   std::vector<bool> checked(this->children.size(), false);
267   std::vector<bool> checkedApplications(this->applications.size(), false);
268
269   //check all folders
270   wxDir dir(crea::std2wx((this->path).c_str()));
271   if (dir.IsOpened())
272     {
273       wxString fileName;
274       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
275       while (cont)
276         {
277           std::string stdfileName = crea::wx2std(fileName);
278
279           if(stdfileName != "template_appli" && stdfileName != "template_wx_appli")
280             {
281               std::string applicationName = stdfileName;
282               //check if application already exist
283               bool found = false;
284               for (int i = 0; !found && i < (int)(this->applications.size()); i++)
285                 {
286                   if (this->applications[i]->GetName() == applicationName)
287                     {
288                       found = true;
289                       int pos = std::find(this->children.begin(), this->children.end(), this->applications[i]) - this->children.begin();
290                       checked[pos] = true;
291                       checkedApplications[i] = true;
292                       if(!this->applications[i]->Refresh(result))
293                         return false;
294                     }
295                 }
296               if(!found)
297                 {
298                   modelCDMApplication* application= new modelCDMApplication(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
299                   this->applications.push_back(application);
300                   this->children.push_back(application);
301                 }
302             }
303           else
304             {
305               //check if folder already exist
306               bool found = false;
307               for (int i = 0; !found && i < (int)(this->children.size()); i++)
308                 {
309                   if (this->children[i]->GetName() == stdfileName)
310                     {
311                       found = true;
312                       checked[i] = true;
313
314                       if(!this->children[i]->Refresh(result))
315                         return false;
316                     }
317                 }
318               if(!found)
319                 {
320                   modelCDMFolder* folder= new modelCDMFolder(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
321                   this->children.push_back(folder);
322                 }
323             }
324           cont = dir.GetNext(&fileName);
325         }
326
327       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
328       while (cont)
329         {
330           std::string stdfileName = crea::wx2std(fileName);
331
332           //if CMakeLists, create CMakeLists
333           if(stdfileName == "CMakeLists.txt")
334             {
335               if (this->CMakeLists == NULL)
336                 {
337                   this->CMakeLists = new modelCDMCMakeListsFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
338                   this->children.push_back(this->CMakeLists);
339                 }
340               else
341                 {
342                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
343                   checked[pos] = true;
344                   if(!this->CMakeLists->Refresh(result))
345                     return false;
346                 }
347             }
348           //if is an unknown file, create file
349           else
350             {
351               bool found = false;
352               for (int i = 0; !found && i < (int)(this->children.size()); i++)
353                 {
354                   if (this->children[i]->GetName() == stdfileName)
355                     {
356                       found = true;
357                       checked[i] = true;
358                       if(!this->children[i]->Refresh(result))
359                         return false;
360                     }
361                 }
362
363               if(!found)
364                 {
365                   modelCDMFile* file = new modelCDMFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
366                   this->children.push_back(file);
367                 }
368             }
369
370           cont = dir.GetNext(&fileName);
371         }
372     }
373
374   for (int i = 0; i < (int)(checkedApplications.size()); i++)
375     {
376       if(!checkedApplications[i])
377         {
378           this->applications.erase(this->applications.begin()+i);
379           checkedApplications.erase(checkedApplications.begin()+i);
380           i--;
381         }
382     }
383   for (int i = 0; i < (int)(checked.size()); i++)
384     {
385       if(!checked[i])
386         {
387           delete this->children[i];
388           this->children.erase(this->children.begin()+i);
389           checked.erase(checked.begin()+i);
390           i--;
391         }
392     }
393   this->SortChildren();
394   std::sort(this->applications.begin(), this->applications.end(), CompareNodeItem);
395   return true;
396 }
397
398 void modelCDMAppli::CheckStructure(std::map<std::string, bool>& properties)
399 {
400   //check cmake exist
401   if(this->CMakeLists != NULL)
402     {
403       //set properties parameters based on model
404       for (int i = 0; i < (int)(this->applications.size()); i++)
405         properties["appli add " + this->applications[i]->GetName()] = false;
406
407       //open cmakelists
408       std::ifstream confFile;
409       confFile.open((this->CMakeLists->GetPath()).c_str());
410
411       //take everything that is not commented
412       std::string fileContent;
413
414       std::string word;
415       std::vector<std::string> words;
416       while(confFile.is_open() && !confFile.eof())
417         {
418           std::getline(confFile,word, '\n');
419           if(word[0] != '#')
420             {
421               CDMUtilities::splitter::split(words, word, "#", CDMUtilities::splitter::empties_ok);
422               if (words.size() > 0)
423                 {
424                   word = words[0];
425                   CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::empties_ok);
426                   for (int i = 0; i < (int)(words.size()); i++)
427                     {
428                       if(words[i].substr(0,2) == "//")
429                         break;
430                       fileContent += words[i] + " ";
431                     }
432                 }
433             }
434         }
435
436       //check every instruction
437       std::stringstream ss(fileContent);
438       while(!ss.eof())
439         {
440           std::getline(ss,word, '(');
441
442           //check instruction name
443           CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
444
445           //add instructions
446           if (words.size() > 0 && words[words.size()-1] == "ADD_SUBDIRECTORY")
447             {
448               std::getline(ss,word, ')');
449               //std::cout << word << std::endl;
450               CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
451
452               if (words.size() > 0)
453                 {
454                   {
455                     properties["appli add " + words[0]] = true;
456                   }
457                 }
458             }
459         }
460
461     }
462
463   //check libraries' structure
464   for (int i = 0; i < (int)(this->applications.size()); i++)
465     {
466       properties["application " + this->applications[i]->GetName()] = true;
467       this->applications[i]->CheckStructure(properties);
468     }
469 }