]> 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& buildPath
59 )
60 {
61   this->path = CDMUtilities::fixPath(path);
62   //open makelists file
63   std::string pathFixed(CDMUtilities::fixPath(path));
64
65   //TODO: set pathMakeLists for windows
66   std::string pathMakeLists = pathFixed + "/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 + "/appli", 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 + "/lib", 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 + "/" + 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 + "/" + 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 + "/" + stdfileName, this->level + 1);
193               this->children.push_back(this->CMakeLists);
194             }
195           else
196             {
197               this->children.push_back(new modelCDMFile(pathFixed + "/" + 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 << "/" << 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 + "/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 + "/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 + "/CMakeLists.txt.tmp " + this->path + "/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   //TODO: fix for windows
368   modelCDMPackage* package = new modelCDMPackage(this->path + "/bbtk_" + nameFixed + "_PKG", this->level + 1);
369   this->packages.push_back(package);
370   this->children.push_back(package);
371
372   //TODO: set package version
373
374   this->SortChildren();
375
376   result = new std::string(this->path + "/" + name);
377   return package;
378 }
379
380 modelCDMIProjectTreeNode* modelCDMProject::CreateLibrary(
381     const std::string& name,
382     std::string*& result,
383     const std::string& path
384 )
385 {
386   if(this->lib != NULL)
387     {
388       return this->lib->CreateLibrary(name, result);
389     }
390   result = new std::string("there is no lib folder in this project.");
391   return NULL;
392 }
393
394 modelCDMIProjectTreeNode* modelCDMProject::CreateApplication(
395     const std::string& name,
396     std::string*& result,
397     const std::string& path
398 )
399 {
400   if(this->appli != NULL)
401     {
402       return this->appli->CreateApplication(name, result);
403     }
404   result = new std::string("there is no appli folder in this project.");
405   return NULL;
406 }
407
408 modelCDMIProjectTreeNode* modelCDMProject::CreateBlackBox(
409     const std::string& name,
410     const std::string& package,
411     const std::string& authors,
412     const std::string& authorsEmail,
413     const std::string& categories,
414     const std::string& description
415 )
416 {
417   //TODO: implement method
418   return NULL;
419 }
420
421 bool modelCDMProject::OpenCMakeListsFile(std::string*& result)
422 {
423   if (!CDMUtilities::openTextEditor(this->CMakeLists->GetPath()))
424     return true;
425   else
426     {
427       result = new std::string("Couldn't open CMakeLists file.");
428       return false;
429     }
430 }
431
432 const bool modelCDMProject::Refresh(std::string*& result)
433 {
434   std::cout << "refreshing project" << std::endl;
435   //open makelists file
436   //TODO: set pathMakeLists for windows
437   std::string pathMakeLists = this->path + "/CMakeLists.txt";
438
439   std::ifstream confFile;
440   confFile.open((pathMakeLists).c_str());
441
442   std::string word;
443   while(confFile.is_open() && !confFile.eof())
444     {
445       //std::cout << "leyendo " << word << std::endl;
446       //get project name
447       std::getline(confFile,word,'(');
448       std::vector<std::string> wordBits;
449       CDMUtilities::splitter::split(wordBits,word," (\n",CDMUtilities::splitter::no_empties);
450
451       if(wordBits[wordBits.size()-1] == "PROJECT")
452         {
453           std::getline(confFile,word,')');
454           std::vector<std::string> nameBits;
455           CDMUtilities::splitter::split(nameBits, word, " ", CDMUtilities::splitter::no_empties);
456
457           this->name = this->nameProject = "";
458           for (int i = 0; i < nameBits.size(); i++)
459             {
460               if(i != 0)
461                 this->name += " ";
462               this->name += nameBits[i];
463             }
464           this->nameProject = this->name;
465
466         }
467
468
469       if(wordBits[wordBits.size()-1] == "SET")
470         {
471           //get project version
472           std::getline(confFile,word,')');
473           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
474           if(wordBits[0] == "PROJECT_MAJOR_VERSION")
475             {
476               version = wordBits[1];
477             }
478           if(wordBits[0] == "PROJECT_MINOR_VERSION")
479             {
480               version += "." + wordBits[1];
481             }
482           if(wordBits[0] == "PROJECT_BUILD_VERSION")
483             {
484               version += "." + wordBits[1];
485             }
486
487           //get project versionDate
488           if(wordBits[0] == "PROJECT_VERSION_DATE")
489             {
490               std::vector<std::string> versionBits;
491               CDMUtilities::splitter::split(versionBits, wordBits[1], "\"", CDMUtilities::splitter::no_empties);
492               versionDate = versionBits[0];
493             }
494         }
495     }
496   confFile.close();
497
498   this->type = wxDIR_DIRS;
499   this->level = 0;
500
501   std::vector<bool> checked(this->children.size(), false);
502   std::vector<bool> checkedPackages(this->packages.size(), false);
503
504   //check all folders
505   wxDir dir(crea::std2wx((this->path).c_str()));
506   if (dir.IsOpened())
507     {
508       wxString fileName;
509       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
510       while (cont)
511         {
512           std::string stdfileName = crea::wx2std(fileName);
513
514           //if appli, create appli
515           if(stdfileName == "appli")
516             {
517               if (this->appli == NULL)
518                 {
519                   this->appli = new modelCDMAppli(this->path + "/appli", this->level + 1);
520                   this->children.push_back(this->appli);
521                 }
522               else
523                 {
524                   int pos = std::find(this->children.begin(), this->children.end(), this->appli) - this->children.begin();
525                   checked[pos] = true;
526                   if(!this->appli->Refresh(result))
527                     return false;
528                 }
529             }
530           //if lib, create lib
531           else if(stdfileName == "lib")
532             {
533               if (this->lib == NULL)
534                 {
535                   this->lib = new modelCDMLib(this->path + "/lib", this->level + 1);
536                   this->children.push_back(this->lib);
537                 }
538               else
539                 {
540                   int pos = std::find(this->children.begin(), this->children.end(), this->lib) - this->children.begin();
541                   checked[pos] = true;
542                   if(!this->lib->Refresh(result))
543                     return false;
544                 }
545
546             }
547           //if package , create package
548           else if(stdfileName.size() > 9 && stdfileName.substr(0,5) == "bbtk_" && stdfileName.substr(stdfileName.size()-4,4) == "_PKG")
549             {
550               std::string packageName = stdfileName.substr(5, stdfileName.size()-9);
551               bool found = false;
552               for (int i = 0;!found && i < this->packages.size(); i++)
553                 {
554                   if (this->packages[i]->GetName() == packageName)
555                     {
556                       found = true;
557                       int pos = std::find(this->children.begin(), this->children.end(), this->packages[i]) - this->children.begin();
558                       checked[pos] = true;
559                       checkedPackages[i] = true;
560                       if(!this->packages[i]->Refresh(result))
561                         return false;
562                     }
563                 }
564               if(!found)
565                 {
566                   modelCDMPackage* package = new modelCDMPackage(this->path + "/" + stdfileName, this->level + 1);
567                   this->packages.push_back(package);
568                   this->children.push_back(package);
569                 }
570
571             }
572           //if is an unknown folder, create folder
573           else
574             {
575               bool found = false;
576               for (int i = 0; !found && i < this->children.size(); i++)
577                 {
578                   if (this->children[i]->GetName() == stdfileName)
579                     {
580                       found = true;
581                       checked[i] = true;
582                       if(!this->children[i]->Refresh(result))
583                         return false;
584                     }
585                 }
586
587               if(!found)
588                 {
589                   modelCDMFolder* folder = new modelCDMFolder(this->path + "/" + stdfileName, this->level + 1);
590                   this->children.push_back(folder);
591                 }
592             }
593
594           cont = dir.GetNext(&fileName);
595         }
596
597       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
598       while (cont)
599         {
600           std::string stdfileName = crea::wx2std(fileName);
601
602           //if CMakeLists, create CMakeLists
603           if(stdfileName == "CMakeLists.txt")
604             {
605               if (this->CMakeLists == NULL)
606                 {
607                   this->CMakeLists = new modelCDMCMakeListsFile(this->path + "/" + stdfileName, this->level + 1);
608                   this->children.push_back(this->CMakeLists);
609                 }
610               else
611                 {
612                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
613                   checked[pos] = true;
614                   if(!this->CMakeLists->Refresh(result))
615                     return false;
616                 }
617             }
618           //if is an unknown file, create file
619           else
620             {
621               bool found = false;
622               for (int i = 0; i <!found && this->children.size(); i++)
623                 {
624                   if (this->children[i]->GetName() == stdfileName)
625                     {
626                       found = true;
627                       checked[i] = true;
628                       if(!this->children[i]->Refresh(result))
629                         return false;
630                     }
631                 }
632
633               if(!found)
634                 {
635                   modelCDMFile* file = new modelCDMFile(this->path + "/" + stdfileName, this->level + 1);
636                   this->children.push_back(file);
637                 }
638             }
639
640           cont = dir.GetNext(&fileName);
641         }
642     }
643
644   for (int i = 0; i < checkedPackages.size(); i++)
645     {
646       if(!checkedPackages[i])
647         {
648           this->packages.erase(this->packages.begin()+i);
649           checkedPackages.erase(checkedPackages.begin()+i);
650           i--;
651         }
652     }
653   for (int i = 0; i < checked.size(); i++)
654     {
655       if(!checked[i])
656         {
657           delete this->children[i];
658           this->children.erase(this->children.begin()+i);
659           checked.erase(checked.begin()+i);
660           i--;
661         }
662     }
663   this->SortChildren();
664   return true;
665 }
666
667 bool modelCDMProject::ConfigureBuild(std::string*& result)
668 {
669   //TODO: implement method
670   return true;
671 }
672
673 bool modelCDMProject::Build(std::string*& result)
674 {
675   //TODO: implement method
676   return true;
677 }
678
679 bool modelCDMProject::Connect(std::string*& result)
680 {
681   //TODO: implement method
682   return true;
683 }