]> Creatis software - crea.git/blob - lib/creaDevManagerLib/modelCDMProject.cpp
Feature #1711
[crea.git] / lib / creaDevManagerLib / modelCDMProject.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  * modelCDMProject.cpp
30  *
31  *  Created on: 13/11/2012
32  *      Author: Daniel Felipe Gonzalez Obando
33  */
34
35 #include "modelCDMProject.h"
36
37 #include <iostream>
38 #include <sstream>
39 #include <vector>
40 #include <algorithm>
41 #include <fstream>
42 #include <ctime>
43
44 #include "CDMUtilities.h"
45 #include "creaWx.h"
46 #include "wx/dir.h"
47
48 modelCDMProject::modelCDMProject()
49 {
50   std::cout << "in constructor1" << std::endl;
51   this->appli = NULL;
52   this->lib = NULL;
53   this->CMakeLists = NULL;
54 }
55
56 modelCDMProject::modelCDMProject(
57     const std::string& path,
58     const std::string& name,
59     const std::string& buildPath
60 )
61 {
62   this->path = CDMUtilities::fixPath(path);
63   //open makelists file
64   std::string pathFixed(CDMUtilities::fixPath(path));
65
66   std::string pathMakeLists = pathFixed + CDMUtilities::SLASH + "CMakeLists.txt";
67
68   std::ifstream confFile;
69   confFile.open((pathMakeLists).c_str());
70
71   std::string word;
72   while(confFile.is_open() && !confFile.eof())
73     {
74       //std::cout << "leyendo " << word << std::endl;
75       //get project name
76       std::getline(confFile,word,'(');
77       std::vector<std::string> wordBits;
78       CDMUtilities::splitter::split(wordBits,word," (\n",CDMUtilities::splitter::no_empties);
79
80       if(wordBits[wordBits.size()-1] == "PROJECT")
81         {
82           std::getline(confFile,word,')');
83           std::vector<std::string> nameBits;
84           CDMUtilities::splitter::split(nameBits, word, " ", CDMUtilities::splitter::no_empties);
85
86           this->name = this->nameProject = "";
87           for (int i = 0; i < nameBits.size(); i++)
88             {
89               if(i != 0)
90                 this->name += " ";
91               this->name += nameBits[i];
92             }
93           this->nameProject = this->name;
94
95         }
96
97
98       if(wordBits[wordBits.size()-1] == "SET")
99         {
100           //get project version
101           std::getline(confFile,word,')');
102           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
103           if(wordBits[0] == "PROJECT_MAJOR_VERSION")
104             {
105               version = wordBits[1];
106             }
107           if(wordBits[0] == "PROJECT_MINOR_VERSION")
108             {
109               version += "." + wordBits[1];
110             }
111           if(wordBits[0] == "PROJECT_BUILD_VERSION")
112             {
113               version += "." + wordBits[1];
114             }
115
116           //get project versionDate
117           if(wordBits[0] == "PROJECT_VERSION_DATE")
118             {
119               std::vector<std::string> versionBits;
120               CDMUtilities::splitter::split(versionBits, wordBits[1], "\"", CDMUtilities::splitter::no_empties);
121               versionDate = versionBits[0];
122             }
123           //get project buildPath
124
125           if (buildPath != "")
126             {
127               this->buildPath = buildPath;
128             }
129           else
130             {
131               this->buildPath = this->path + "Bin";
132             }
133         }
134     }
135   confFile.close();
136
137   this->type = wxDIR_DIRS;
138   this->level = 0;
139
140   this->children.clear();
141   this->appli = NULL;
142   this->lib = NULL;
143   this->packages.clear();
144
145
146   //check all folders
147   wxDir dir(crea::std2wx((pathFixed).c_str()));
148   if (dir.IsOpened())
149     {
150       wxString fileName;
151       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
152       while (cont)
153         {
154           std::string stdfileName = crea::wx2std(fileName);
155
156           //if appli, create appli
157           if(stdfileName == "appli")
158             {
159               this->appli = new modelCDMAppli(pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
160               this->children.push_back(this->appli);
161             }
162           //if lib, create lib
163           else if(stdfileName == "lib")
164             {
165               this->lib = new modelCDMLib(pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
166               this->children.push_back(this->lib);
167             }
168           //if package , create package
169           else if(stdfileName.size() > 9 && stdfileName.substr(0,5) == "bbtk_" && stdfileName.substr(stdfileName.size()-4,4) == "_PKG")
170             {
171               modelCDMPackage* package = new modelCDMPackage(pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
172               this->packages.push_back(package);
173               this->children.push_back(package);
174             }
175           //if is an unknown folder, create folder
176           else
177             {
178               this->children.push_back(new modelCDMFolder(pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
179             }
180
181           cont = dir.GetNext(&fileName);
182         }
183
184       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
185       while (cont)
186         {
187           std::string stdfileName = crea::wx2std(fileName);
188
189           //if CMakeLists, create CMakeLists
190           if(stdfileName == "CMakeLists.txt")
191             {
192               this->CMakeLists = new modelCDMCMakeListsFile(pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
193               this->children.push_back(this->CMakeLists);
194             }
195           else
196             {
197               this->children.push_back(new modelCDMFile(pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
198             }
199           //if is an unknown file, create file
200           cont = dir.GetNext(&fileName);
201         }
202     }
203
204   this->SortChildren();
205
206 }
207
208 modelCDMProject::~modelCDMProject()
209 {
210 }
211
212 const std::string& modelCDMProject::GetNameProject() const
213 {
214   return this->nameProject;
215 }
216
217 const std::string& modelCDMProject::GetVersion() const
218 {
219   return this->version;
220 }
221
222 const std::string& modelCDMProject::GetVersionDate() const
223 {
224   return this->versionDate;
225 }
226
227 const std::string& modelCDMProject::GetBuildPath() const
228 {
229   return this->buildPath;
230 }
231
232 const std::vector<modelCDMPackage*>& modelCDMProject::GetPackages() const
233 {
234   return this->packages;
235 }
236
237 modelCDMAppli* modelCDMProject::GetAppli() const
238 {
239   return this->appli;
240 }
241
242 modelCDMLib* modelCDMProject::GetLib() const
243 {
244   return this->lib;
245 }
246
247 bool modelCDMProject::SetVersion(const std::string& version, std::string*& result)
248 {
249
250   std::vector<std::string> vers;
251   CDMUtilities::splitter::split(vers, version, " .", CDMUtilities::splitter::no_empties);
252
253   time_t now = time(0);
254   tm* ltm = localtime(&now);
255
256   std::stringstream date;
257   date << ltm->tm_mday << "/" << 1 + ltm->tm_mon << "/" << 1900 + ltm->tm_year;
258
259   //set name of library in CMakeLists inside copied folder
260   std::string line;
261   std::ifstream in((this->path + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
262   if( !in.is_open())
263     {
264       result = new std::string("CMakeLists.txt file failed to open.");
265       return false;
266     }
267   std::ofstream out((this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
268   if( !out.is_open())
269     {
270       result = new std::string("CMakeLists.txt.tmp file failed to open.");
271       return false;
272     }
273   while (getline(in, line))
274     {
275       if(line.find("SET(PROJECT_MAJOR_VERSION") != std::string::npos)
276         line = "SET(PROJECT_MAJOR_VERSION " + vers[0] + ")";
277       else if(line.find("SET(PROJECT_MINOR_VERSION") != std::string::npos)
278         line = "SET(PROJECT_MINOR_VERSION " + vers[1] + ")";
279       else if(line.find("SET(PROJECT_BUILD_VERSION") != std::string::npos)
280         line = "SET(PROJECT_BUILD_VERSION " + vers[2] + ")";
281       else if(line.find("SET(PROJECT_VERSION_DATE") != std::string::npos)
282               line = "SET(PROJECT_VERSION_DATE \"" + date.str() + "\")";
283       out << line << std::endl;
284     }
285   in.close();
286   out.close();
287   //delete old file and rename new file
288   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
289   if(system(renameCommand.c_str()))
290     {
291       result = new std::string("An error occurred while running '" + renameCommand + "'.");
292       return false;
293     }
294
295   this->version = vers[0] + "." + vers[1] + "." + vers[2];
296   this->versionDate = date.str();
297   return true;
298 }
299
300 bool modelCDMProject::SetBuildPath(const std::string& path, std::string*& result)
301 {
302   if(path == "")
303     {
304       result = new std::string("The path cannot be empty");
305       return false;
306     }
307   if(path == this->path)
308     {
309       result = new std::string("The path cannot be same as the project sources");
310       return false;
311     }
312   this->buildPath = path;
313   return true;
314 }
315
316 modelCDMIProjectTreeNode* modelCDMProject::CreatePackage(
317     const std::string& name,
318     std::string*& result,
319     const std::string& authors,
320     const std::string& authorsEmail,
321     const std::string& description,
322     const std::string& version
323 )
324 {
325   //fixing input parameters
326   std::vector<std::string> words;
327
328   CDMUtilities::splitter::split(words,name," ",CDMUtilities::splitter::no_empties);
329   std::string nameFixed = "";
330   for (int i = 0; i < words.size(); i++)
331     {
332       nameFixed += words[i];
333     }
334
335   words.clear();
336   CDMUtilities::splitter::split(words,authors," ",CDMUtilities::splitter::no_empties);
337   std::string authorFixed;
338   for (int i = 0; i < words.size(); i++)
339     {
340       authorFixed += words[i];
341     }
342
343   words.clear();
344   std::string descriptionFixed;
345   CDMUtilities::splitter::split(words,authorsEmail," ",CDMUtilities::splitter::no_empties);
346   for (int i = 0; i < words.size(); i++)
347     {
348       descriptionFixed += words[i];
349     }
350   words.clear();
351   CDMUtilities::splitter::split(words,description," ",CDMUtilities::splitter::no_empties);
352   for (int i = 0; i < words.size(); i++)
353     {
354       descriptionFixed += "_" + words[i];
355     }
356
357   //call project to create package : use bbCreatePackage <path> <name> [author] [description]
358   std::string creationCommand = "bbCreatePackage \"" + this->path + "\" \"" + nameFixed + "\" \"" + authorFixed + "\" \"" + descriptionFixed + "\"";
359   //TODO: bbCreatePackage script always returning 0. It should return 1 or greater if any error
360   if(system(creationCommand.c_str()))
361     {
362       result = new std::string("An error occurred while running '" + creationCommand + "'.");
363       return NULL;
364     }
365
366   //add library to model
367   modelCDMPackage* package = new modelCDMPackage(this->path + CDMUtilities::SLASH + "bbtk_" + nameFixed + "_PKG", "bbtk_" + nameFixed + "_PKG", this->level + 1);
368   this->packages.push_back(package);
369   this->children.push_back(package);
370
371   //TODO: set package version
372
373   this->SortChildren();
374
375   result = new std::string(this->path + CDMUtilities::SLASH + name);
376   return package;
377 }
378
379 modelCDMIProjectTreeNode* modelCDMProject::CreateLibrary(
380     const std::string& name,
381     std::string*& result,
382     const std::string& path
383 )
384 {
385   if(this->lib != NULL)
386     {
387       return this->lib->CreateLibrary(name, result);
388     }
389   result = new std::string("there is no lib folder in this project.");
390   return NULL;
391 }
392
393 modelCDMIProjectTreeNode* modelCDMProject::CreateApplication(
394     const std::string& name,
395     std::string*& result,
396     const std::string& path
397 )
398 {
399   if(this->appli != NULL)
400     {
401       return this->appli->CreateApplication(name, result);
402     }
403   result = new std::string("there is no appli folder in this project.");
404   return NULL;
405 }
406
407 modelCDMIProjectTreeNode* modelCDMProject::CreateBlackBox(
408     const std::string& name,
409     const std::string& package,
410     const std::string& authors,
411     const std::string& authorsEmail,
412     const std::string& categories,
413     const std::string& description
414 )
415 {
416   //TODO: implement method
417   return NULL;
418 }
419
420 bool modelCDMProject::OpenCMakeListsFile(std::string*& result)
421 {
422   if (!CDMUtilities::openTextEditor(this->CMakeLists->GetPath()))
423     return true;
424   else
425     {
426       result = new std::string("Couldn't open CMakeLists file.");
427       return false;
428     }
429 }
430
431 const bool modelCDMProject::Refresh(std::string*& result)
432 {
433   std::cout << "refreshing project" << std::endl;
434   //open makelists file
435   std::string pathMakeLists = this->path + CDMUtilities::SLASH + "CMakeLists.txt";
436
437   std::ifstream confFile;
438   confFile.open((pathMakeLists).c_str());
439
440   std::string word;
441   while(confFile.is_open() && !confFile.eof())
442     {
443       //std::cout << "leyendo " << word << std::endl;
444       //get project name
445       std::getline(confFile,word,'(');
446       std::vector<std::string> wordBits;
447       CDMUtilities::splitter::split(wordBits,word," (\n",CDMUtilities::splitter::no_empties);
448
449       if(wordBits[wordBits.size()-1] == "PROJECT")
450         {
451           std::getline(confFile,word,')');
452           std::vector<std::string> nameBits;
453           CDMUtilities::splitter::split(nameBits, word, " ", CDMUtilities::splitter::no_empties);
454
455           this->name = this->nameProject = "";
456           for (int i = 0; i < nameBits.size(); i++)
457             {
458               if(i != 0)
459                 this->name += " ";
460               this->name += nameBits[i];
461             }
462           this->nameProject = this->name;
463
464         }
465
466
467       if(wordBits[wordBits.size()-1] == "SET")
468         {
469           //get project version
470           std::getline(confFile,word,')');
471           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
472           if(wordBits[0] == "PROJECT_MAJOR_VERSION")
473             {
474               version = wordBits[1];
475             }
476           if(wordBits[0] == "PROJECT_MINOR_VERSION")
477             {
478               version += "." + wordBits[1];
479             }
480           if(wordBits[0] == "PROJECT_BUILD_VERSION")
481             {
482               version += "." + wordBits[1];
483             }
484
485           //get project versionDate
486           if(wordBits[0] == "PROJECT_VERSION_DATE")
487             {
488               std::vector<std::string> versionBits;
489               CDMUtilities::splitter::split(versionBits, wordBits[1], "\"", CDMUtilities::splitter::no_empties);
490               versionDate = versionBits[0];
491             }
492         }
493     }
494   confFile.close();
495
496   this->type = wxDIR_DIRS;
497   this->level = 0;
498
499   std::vector<bool> checked(this->children.size(), false);
500   std::vector<bool> checkedPackages(this->packages.size(), false);
501
502   //check all folders
503   wxDir dir(crea::std2wx((this->path).c_str()));
504   if (dir.IsOpened())
505     {
506       wxString fileName;
507       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
508       while (cont)
509         {
510           std::string stdfileName = crea::wx2std(fileName);
511
512           //if appli, create appli
513           if(stdfileName == "appli")
514             {
515               if (this->appli == NULL)
516                 {
517                   this->appli = new modelCDMAppli(this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
518                   this->children.push_back(this->appli);
519                 }
520               else
521                 {
522                   int pos = std::find(this->children.begin(), this->children.end(), this->appli) - this->children.begin();
523                   checked[pos] = true;
524                   if(!this->appli->Refresh(result))
525                     return false;
526                 }
527             }
528           //if lib, create lib
529           else if(stdfileName == "lib")
530             {
531               if (this->lib == NULL)
532                 {
533                   this->lib = new modelCDMLib(this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
534                   this->children.push_back(this->lib);
535                 }
536               else
537                 {
538                   int pos = std::find(this->children.begin(), this->children.end(), this->lib) - this->children.begin();
539                   checked[pos] = true;
540                   if(!this->lib->Refresh(result))
541                     return false;
542                 }
543
544             }
545           //if package , create package
546           else if(stdfileName.size() > 9 && stdfileName.substr(0,5) == "bbtk_" && stdfileName.substr(stdfileName.size()-4,4) == "_PKG")
547             {
548               std::string packageName = stdfileName.substr(5, stdfileName.size()-9);
549               bool found = false;
550               for (int i = 0;!found && i < this->packages.size(); i++)
551                 {
552                   if (this->packages[i]->GetName() == packageName)
553                     {
554                       found = true;
555                       int pos = std::find(this->children.begin(), this->children.end(), this->packages[i]) - this->children.begin();
556                       checked[pos] = true;
557                       checkedPackages[i] = true;
558                       if(!this->packages[i]->Refresh(result))
559                         return false;
560                     }
561                 }
562               if(!found)
563                 {
564                   modelCDMPackage* package = new modelCDMPackage(this->path + CDMUtilities::SLASH + stdfileName, stdfileName,this->level + 1);
565                   this->packages.push_back(package);
566                   this->children.push_back(package);
567                 }
568
569             }
570           //if is an unknown folder, create folder
571           else
572             {
573               bool found = false;
574               for (int i = 0; !found && i < this->children.size(); i++)
575                 {
576                   if (this->children[i]->GetName() == stdfileName)
577                     {
578                       found = true;
579                       checked[i] = true;
580                       if(!this->children[i]->Refresh(result))
581                         return false;
582                     }
583                 }
584
585               if(!found)
586                 {
587                   modelCDMFolder* folder = new modelCDMFolder(this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
588                   this->children.push_back(folder);
589                 }
590             }
591
592           cont = dir.GetNext(&fileName);
593         }
594
595       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
596       while (cont)
597         {
598           std::string stdfileName = crea::wx2std(fileName);
599
600           //if CMakeLists, create CMakeLists
601           if(stdfileName == "CMakeLists.txt")
602             {
603               if (this->CMakeLists == NULL)
604                 {
605                   this->CMakeLists = new modelCDMCMakeListsFile(this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
606                   this->children.push_back(this->CMakeLists);
607                 }
608               else
609                 {
610                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
611                   checked[pos] = true;
612                   if(!this->CMakeLists->Refresh(result))
613                     return false;
614                 }
615             }
616           //if is an unknown file, create file
617           else
618             {
619               bool found = false;
620               for (int i = 0; i <!found && this->children.size(); i++)
621                 {
622                   if (this->children[i]->GetName() == stdfileName)
623                     {
624                       found = true;
625                       checked[i] = true;
626                       if(!this->children[i]->Refresh(result))
627                         return false;
628                     }
629                 }
630
631               if(!found)
632                 {
633                   modelCDMFile* file = new modelCDMFile(this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
634                   this->children.push_back(file);
635                 }
636             }
637
638           cont = dir.GetNext(&fileName);
639         }
640     }
641
642   for (int i = 0; i < checkedPackages.size(); i++)
643     {
644       if(!checkedPackages[i])
645         {
646           this->packages.erase(this->packages.begin()+i);
647           checkedPackages.erase(checkedPackages.begin()+i);
648           i--;
649         }
650     }
651   for (int i = 0; i < checked.size(); i++)
652     {
653       if(!checked[i])
654         {
655           delete this->children[i];
656           this->children.erase(this->children.begin()+i);
657           checked.erase(checked.begin()+i);
658           i--;
659         }
660     }
661   this->SortChildren();
662   return true;
663 }
664
665 bool modelCDMProject::ConfigureBuild(std::string*& result)
666 {
667   //TODO: implement method
668   return true;
669 }
670
671 bool modelCDMProject::Build(std::string*& result)
672 {
673   //TODO: implement method
674   return true;
675 }
676
677 bool modelCDMProject::Connect(std::string*& result)
678 {
679   //TODO: implement method
680   return true;
681 }