]> Creatis software - crea.git/blob - lib/creaDevManagerLib/modelCDMLib.cpp
Feature #1711
[crea.git] / lib / creaDevManagerLib / modelCDMLib.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  * modelCDMLib.cpp
30  *
31  *  Created on: Nov 23, 2012
32  *      Author: Daniel Felipe Gonzalez Obando
33  */
34
35 #include "modelCDMLib.h"
36
37 #include <fstream>
38 #include <sstream>
39 #include <algorithm>
40
41 #include "CDMUtilities.h"
42 #include "creaWx.h"
43 #include "wx/dir.h"
44
45 modelCDMLib::modelCDMLib()
46 {
47 }
48
49 modelCDMLib::modelCDMLib(modelCDMIProjectTreeNode* parent, const std::string& path, const std::string& name, const int& level)
50 {
51   std::cout << "creating lib\n";
52   this->parent = parent;
53   this->type = wxDIR_DIRS;
54   this->name = name;
55   this->level = level;
56   this->path = path;
57
58
59
60   this->path = CDMUtilities::fixPath(path);
61   //open makelists file
62   std::string pathFixed(CDMUtilities::fixPath(path));
63
64   this->libraries.clear();
65   wxDir dir(crea::std2wx((pathFixed).c_str()));
66   if (dir.IsOpened())
67     {
68       wxString fileName;
69       //folders
70       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
71       while (cont)
72         {
73           std::string stdfileName = crea::wx2std(fileName);
74
75           if(stdfileName != "template_lib")
76             {
77               modelCDMLibrary* library = new modelCDMLibrary(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
78               this->libraries.push_back(library);
79               this->children.push_back(library);
80             }
81           else
82             {
83               modelCDMFolder* folder = new modelCDMFolder(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
84               this->children.push_back(folder);
85             }
86
87           cont = dir.GetNext(&fileName);
88         }
89       //files
90       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
91       while (cont)
92         {
93           std::string stdfileName = crea::wx2std(fileName);
94
95           //if CMakeLists, create CMakeLists
96           if(stdfileName == "CMakeLists.txt")
97             {
98               this->CMakeLists = new modelCDMCMakeListsFile(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
99               this->children.push_back(this->CMakeLists);
100             }
101           //if is an unknown file, create file
102           else
103             {
104               this->children.push_back(new modelCDMFile(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
105             }
106
107           cont = dir.GetNext(&fileName);
108         }
109     }
110   this->SortChildren();
111   std::sort(this->libraries.begin(), this->libraries.end(), CompareNodeItem);
112 }
113
114 modelCDMLib::~modelCDMLib()
115 {
116 }
117
118 const std::vector<modelCDMLibrary*>& modelCDMLib::GetLibraries() const
119 {
120   return this->libraries;
121 }
122
123 modelCDMLibrary* modelCDMLib::CreateLibrary(
124     const std::string& name,
125     std::string*& result
126 )
127 {
128   //copy template library folder with new name
129   std::string copyCommand = "cp -r \"" + this->path + CDMUtilities::SLASH + "template_lib\" \"" + this->path + CDMUtilities::SLASH + name + "\"";
130   if(system(copyCommand.c_str()))
131     {
132       result = new std::string("An error occurred while running '" + copyCommand + "'.");
133       return NULL;
134     }
135   //set name of library in CMakeLists inside copied folder
136   std::string line;
137   std::ifstream in((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
138   if( !in.is_open())
139     {
140       result = new std::string("CMakeLists.txt file failed to open.");
141       return NULL;
142     }
143   std::ofstream out((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
144   while (getline(in, line))
145     {
146       if(line == "SET ( LIBRARY_NAME   MyLib  )")
147         line = "SET ( LIBRARY_NAME   " + name + "  )";
148       out << line << std::endl;
149     }
150   in.close();
151   out.close();
152   //delete old file and rename new file
153   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt\"";
154   if(system(renameCommand.c_str()))
155     {
156       result = new std::string("An error occurred while running '" + renameCommand + "'.");
157       return NULL;
158     }
159
160   //add library to model
161   modelCDMLibrary* library = new modelCDMLibrary(this, this->path + CDMUtilities::SLASH + name, name, this->level + 1);
162   this->libraries.push_back(library);
163   this->children.push_back(library);
164
165   this->SortChildren();
166
167   result = new std::string(this->path + CDMUtilities::SLASH + name);
168   return library;
169 }
170
171 const bool modelCDMLib::Refresh(std::string*& result)
172 {
173   std::cout << "refreshing lib" << std::endl;
174   this->type = wxDIR_DIRS;
175
176
177
178   std::vector<bool> checked(this->children.size(), false);
179   std::vector<bool> checkedLibraries(this->libraries.size(), false);
180
181   //check all folders
182   wxDir dir(crea::std2wx((this->path).c_str()));
183   if (dir.IsOpened())
184     {
185       wxString fileName;
186       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
187       while (cont)
188         {
189           std::string stdfileName = crea::wx2std(fileName);
190
191           if(stdfileName != "template_lib")
192             {
193               std::string libraryName = stdfileName;
194               //check if library already exist
195               bool found = false;
196               for (int i = 0; !found && i < (int)(this->libraries.size()); i++)
197                 {
198                   if (this->libraries[i]->GetName() == libraryName)
199                     {
200                       found = true;
201                       int pos = std::find(this->children.begin(), this->children.end(), this->libraries[i]) - this->children.begin();
202                       checked[pos] = true;
203                       checkedLibraries[i] = true;
204                       if(!this->libraries[i]->Refresh(result))
205                         return false;
206                     }
207                 }
208               if(!found)
209                 {
210                   modelCDMLibrary* library = new modelCDMLibrary(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
211                   this->libraries.push_back(library);
212                   this->children.push_back(library);
213                 }
214             }
215           else
216             {
217               //check if folder already exist
218               bool found = false;
219               for (int i = 0; !found && i < (int)(this->children.size()); i++)
220                 {
221                   if (this->children[i]->GetName() == stdfileName)
222                     {
223                       found = true;
224                       checked[i] = true;
225                       if(!this->children[i]->Refresh(result))
226                         return false;
227                     }
228                 }
229               if(!found)
230                 {
231                   modelCDMFolder* folder= new modelCDMFolder(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
232                   this->children.push_back(folder);
233                 }
234             }
235           cont = dir.GetNext(&fileName);
236         }
237
238       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
239       while (cont)
240         {
241           std::string stdfileName = crea::wx2std(fileName);
242
243           //if CMakeLists, create CMakeLists
244           if(stdfileName == "CMakeLists.txt")
245             {
246               if (this->CMakeLists == NULL)
247                 {
248                   this->CMakeLists = new modelCDMCMakeListsFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
249                   this->children.push_back(this->CMakeLists);
250                 }
251               else
252                 {
253                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
254                   checked[pos] = true;
255                   if(!this->CMakeLists->Refresh(result))
256                     return false;
257                 }
258             }
259           //if is an unknown file, create file
260           else
261             {
262               bool found = false;
263               for (int i = 0; !found && i < (int)(this->children.size()); i++)
264                 {
265                   if (this->children[i]->GetName() == stdfileName)
266                     {
267                       found = true;
268                       checked[i] = true;
269                       if(!this->children[i]->Refresh(result))
270                         return false;
271                     }
272                 }
273
274               if(!found)
275                 {
276                   modelCDMFile* file = new modelCDMFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
277                   this->children.push_back(file);
278                 }
279             }
280
281           cont = dir.GetNext(&fileName);
282         }
283     }
284
285   for (int i = 0; i < (int)(checkedLibraries.size()); i++)
286     {
287       if(!checkedLibraries[i])
288         {
289           this->libraries.erase(this->libraries.begin()+i);
290           checkedLibraries.erase(checkedLibraries.begin()+i);
291           i--;
292         }
293     }
294   for (int i = 0; i < (int)(checked.size()); i++)
295     {
296       if(!checked[i])
297         {
298           delete this->children[i];
299           this->children.erase(this->children.begin()+i);
300           checked.erase(checked.begin()+i);
301           i--;
302         }
303     }
304   this->SortChildren();
305   std::sort(this->libraries.begin(), this->libraries.end(), CompareNodeItem);
306   return true;
307 }
308
309 void modelCDMLib::CheckStructure(std::map<std::string, bool>& properties)
310 {
311   //check cmake exist
312   if(this->CMakeLists != NULL)
313     {
314       //set properties parameters based on model
315       for (int i = 0; i < (int)(this->libraries.size()); i++)
316         properties["lib add " + libraries[i]->GetName()] = false;
317
318       //open cmakelists
319       std::ifstream confFile;
320       confFile.open((this->CMakeLists->GetPath()).c_str());
321
322       //take everything that is not commented
323       std::string fileContent;
324
325       std::string word;
326       std::vector<std::string> words;
327       while(confFile.is_open() && !confFile.eof())
328         {
329           std::getline(confFile,word, '\n');
330           if(word[0] != '#')
331             {
332               CDMUtilities::splitter::split(words, word, "#", CDMUtilities::splitter::empties_ok);
333               if (words.size() > 0)
334                 {
335                   word = words[0];
336                   CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::empties_ok);
337                   for (int i = 0; i < (int)(words.size()); i++)
338                     {
339                       if(words[i].substr(0,2) == "//")
340                         break;
341                       fileContent += words[i] + " ";
342                     }
343                 }
344             }
345         }
346
347       //check every instruction
348       std::stringstream ss(fileContent);
349       while(!ss.eof())
350         {
351           std::getline(ss,word, '(');
352
353           //check instruction name
354           CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
355
356           //add instructions
357           if (words.size() > 0 && words[words.size()-1] == "ADD_SUBDIRECTORY")
358             {
359               std::getline(ss,word, ')');
360               //std::cout << word << std::endl;
361               CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
362
363               if (words.size() > 0)
364                 {
365                   {
366                     properties["lib add " + words[0]] = true;
367                   }
368                 }
369             }
370         }
371
372     }
373
374   //check libraries' structure
375   for (int i = 0; i < (int)(this->libraries.size()); i++)
376     {
377       properties["library " + this->libraries[i]->GetName()] = true;
378       this->libraries[i]->CheckStructure(properties);
379     }
380 }