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