Documentation for OpenFLUID 2.2.0
WareSignatureSerializer.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 
33 /**
34  @file WareSignatureSerializer.hpp
35 
36  @author Jean-Christophe FABRE <jean-christophe.fabre@inrae.fr>
37  @author Armel THÖNI <armel.thoni@inrae.fr>
38  */
39 
40 
41 #ifndef __OPENFLUID_WARESDEV_WARESIGNATURESERIALIZER_HPP__
42 #define __OPENFLUID_WARESDEV_WARESIGNATURESERIALIZER_HPP__
43 
44 
45 #include <string>
46 #include <vector>
47 #include <fstream>
48 #include <utility>
49 
52 #include <openfluid/ware/TypeDefs.hpp>
59 #include <openfluid/config.hpp>
60 #include <openfluid/dllexport.hpp>
61 
62 
63 namespace openfluid { namespace waresdev {
64 
65 
67 {
68  if (Json.contains("simulator"))
69  {
71  }
72  else if (Json.contains("observer"))
73  {
75  }
76  else if (Json.contains("builderext"))
77  {
79  }
80 
82 }
83 
84 
85 // =====================================================================
86 // =====================================================================
87 
88 
89 inline openfluid::ware::WareType detectWareType(const std::string& Path)
90 {
91  std::ifstream InFile(Path,std::ifstream::in);
92 
93  try
94  {
95  auto Json = openfluid::thirdparty::json::parse(InFile);
96 
97  return detectWareTypeFromJson(Json);
98  }
99  catch (openfluid::thirdparty::json::exception& E)
100  {
101  openfluid::utils::log::error("Waresdev", E.what());
103  }
104 
106 }
107 
108 
109 // =====================================================================
110 // =====================================================================
111 
112 
113 inline std::pair<openfluid::ware::WareType,openfluid::ware::WareID_t> detectWareTypeAndID(const std::string& Path)
114 {
117 
118  std::ifstream InFile(Path,std::ifstream::in);
119 
120  try
121  {
122  auto Json = openfluid::thirdparty::json::parse(InFile);
123 
124  Type = detectWareTypeFromJson(Json);
125 
126  const std::string TmpID = Json.value("id","");
128  {
129  ID = TmpID;
130  }
131  }
132  catch (openfluid::thirdparty::json::exception& E)
133  {
134  openfluid::utils::log::error("Waresdev", E.what());
136  }
137 
138  return {Type,ID};
139 }
140 
141 
142 // =====================================================================
143 // =====================================================================
144 
145 
146 template<class SignatureType>
148 {
149  protected:
150 
151  const std::string m_LinkUID;
152 
153  // TODO review and refactor methods names, responsibilities and organization for better consistency
154 
155 
156  std::string toWareCPPBase(const SignatureType& Sign) const;
157 
158  std::string toWareCMakeBase(const SignatureType& Sign) const;
159 
161  m_LinkUID(openfluid::tools::generatePseudoUniqueIdentifier(24))
162  { }
163 
164 
165  public:
166 
168  { }
169 
170  virtual SignatureType fromJSON(const openfluid::thirdparty::json& Json) const = 0;
171 
172  virtual openfluid::thirdparty::json toJSON(const SignatureType& Sign) const = 0;
173 
174  virtual std::string toWareCPP(const SignatureType& Sign) const = 0;
175 
176  virtual std::string toWareCMake(const SignatureType& Sign) const = 0;
177 
178  static SignatureType fromJSONBase(const openfluid::thirdparty::json& Json);
179 
180  static openfluid::thirdparty::json toJSONBase(const SignatureType& Sign);
181 
182  SignatureType readFromJSONFile(const std::string& FilePath) const;
183 
184  void writeToJSONFile(const SignatureType& Sign, const std::string& FilePath) const;
185 
186  void writeToWareCPPFile(const SignatureType& Sign, const std::string& FilePath) const;
187 
188  void writeToParamsUICPPFile(const SignatureType& Sign, const std::string& FilePath) const;
189 
190  void writeToWareCMakeFile(const SignatureType& Sign, const std::string& FilePath) const;
191 
192  void writeToParamsUICMakeFile(const SignatureType& Sign, const std::string& FilePath) const;
193 
194  virtual void writeToBuildFiles(const SignatureType& Sign, const std::string& Path) const = 0;
195 };
196 
197 
198 // =====================================================================
199 // =====================================================================
200 
201 
202 template<class SignatureType>
204 {
205  SignatureType Sign;
206 
207  Sign.ID = Json.value("id","");
208  if (!openfluid::tools::isValidWareID(Sign.ID, true))
209  {
210  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Missing or invalid ware ID");
211  }
212 
213 
214  Sign.Name = Json.value("name","");
215  Sign.Description = Json.value("description","");
216  Sign.Version = Json.value("version","");
217  Sign.setStatusFromString(openfluid::tools::trim(Json.value("status","")));
218 
219  // authors
220  {
221  openfluid::thirdparty::json PeopleArr = Json.value("authors",openfluid::thirdparty::json::array());
222  if (PeopleArr.is_array())
223  {
224  for (const auto& P : PeopleArr)
225  {
226  if (P.is_object() && P.contains("name"))
227  {
228  Sign.Authors.push_back({P["name"],P.value("email","")});
229  }
230  }
231  }
232  }
233 
234  // contacts
235  {
236  openfluid::thirdparty::json PeopleArr = Json.value("contacts",openfluid::thirdparty::json::array());
237  if (PeopleArr.is_array())
238  {
239  for (const auto& P : PeopleArr)
240  {
241  if (P.is_object() && P.contains("name"))
242  {
243  Sign.Contacts.push_back({P["name"],P.value("email","")});
244  }
245  }
246  }
247  }
248 
249  //license
250  Sign.License = openfluid::tools::trim(Json.value("license",""));
251 
252  // links
253  {
254  openfluid::thirdparty::json::array_t LinksArr = Json.value("links",openfluid::thirdparty::json::array());
255  for (const auto& L : LinksArr)
256  {
257  if (L.is_object() && L.contains("url"))
258  {
259  Sign.Links.push_back({L.value("label",""),L["url"]});
260  }
261  }
262  }
263 
264  // tags
265  {
266  openfluid::thirdparty::json TagsArr = Json.value("tags",openfluid::thirdparty::json::array());
267  if (TagsArr.is_array())
268  {
269  for (const auto& T : TagsArr)
270  {
271  if (T.is_string())
272  {
273  Sign.Tags.push_back(T.get<std::string>());
274  }
275  }
276  }
277  }
278 
279  // issues
280  {
281  openfluid::thirdparty::json IssuesArr = Json.value("issues",openfluid::thirdparty::json::array());
282  if (IssuesArr.is_array())
283  {
284  for (const auto& I : IssuesArr)
285  {
286  if (I.is_object() && I.contains("id"))
287  {
288  try
289  {
291  Sign.Issues.insert(Issue,Issue.ID);
292  }
293  catch (std::exception& E)
294  {
295  throw E;
296  }
297  }
298  }
299  }
300  }
301 
302  // dependencies
303  {
304  openfluid::thirdparty::json DependenciesMap = Json.value("dependencies",openfluid::thirdparty::json::object());
305  if (DependenciesMap.is_object())
306  {
307  for (const auto& D : DependenciesMap.items())
308  {
309  Sign.Dependencies.insert({D.key(), D.value()});
310  }
311  }
312  }
313 
314  return Sign;
315 }
316 
317 
318 // =====================================================================
319 // =====================================================================
320 
321 
322 template<class SignatureType>
324 {
325  openfluid::thirdparty::json Json = openfluid::thirdparty::json::object();
326 
327  Json["id"] = Sign.ID;
328  Json["name"] = Sign.Name;
329  Json["description"] = Sign.Description;
330  Json["version"] = Sign.Version;
331  Json["status"] = Sign.getStatusAsString();
332 
333  // authors
334  {
335  auto PeopleArr = openfluid::thirdparty::json::array();
336  for (const auto& P : Sign.Authors)
337  {
338  auto PersonObj = openfluid::thirdparty::json::object();
339  PersonObj["name"] = P.first;
340  PersonObj["email"] = P.second;
341  PeopleArr.push_back(PersonObj);
342  }
343  Json["authors"] = PeopleArr;
344  }
345 
346  // contacts
347  {
348  auto PeopleArr = openfluid::thirdparty::json::array();
349  for (const auto& P : Sign.Contacts)
350  {
351  auto PersonObj = openfluid::thirdparty::json::object();
352  PersonObj["name"] = P.first;
353  PersonObj["email"] = P.second;
354  PeopleArr.push_back(PersonObj);
355  }
356  Json["contacts"] = PeopleArr;
357  }
358 
359  // license
360  Json["license"] = Sign.License;
361 
362  // tags
363  Json["tags"] = Sign.Tags;
364 
365  // links
366  {
367  auto LnkArr = openfluid::thirdparty::json::array();
368  for (const auto& L : Sign.Links)
369  {
370  auto LnkObj = openfluid::thirdparty::json::object();
371  LnkObj["label"] = L.first;
372  LnkObj["url"] = L.second;
373  LnkArr.push_back(LnkObj);
374  }
375  Json["links"] = LnkArr;
376  }
377 
378  // issues
379  {
380  auto IssArr = openfluid::thirdparty::json::array();
381  for (const auto& I : Sign.Issues.getAll())
382  {
383  auto IObj = I.second.toJSON(I.first);
384  IssArr.push_back(IObj);
385  }
386  Json["issues"] = IssArr;
387  }
388 
389  // dependencies
390  auto Deps = openfluid::thirdparty::json::object();
391  for (const auto& D : Sign.Dependencies)
392  {
393  Deps[D.first] = D.second;
394  }
395  Json["dependencies"] = Deps;
396 
397 
398  return Json;
399 }
400 
401 
402 // =====================================================================
403 // =====================================================================
404 
405 
406 template<class SignatureType>
407 std::string WareSignatureSerializer<SignatureType>::toWareCPPBase(const SignatureType& Sign) const
408 {
409  std::string CPP;
410 
411  CPP += CppWriter::getCPPAssignment("ID",Sign.ID,true);
412 
413  // build info
414  CPP += CppWriter::getCPPAssignment("BuildInfo.SDKVersion",openfluid::config::VERSION_FULL,true);
415  CPP += CppWriter::getCPPAssignment("BuildInfo.BuildType","(WAREBUILD_BUILD_TYPE)");
416  CPP += CppWriter::getCPPAssignment("BuildInfo.CompilerID","(WAREBUILD_COMPILER_ID)");
417  CPP += CppWriter::getCPPAssignment("BuildInfo.CompilerVersion","(WAREBUILD_COMPILER_VERSION)");
418  CPP += CppWriter::getCPPAssignment("BuildInfo.CompilationFlags","(WAREBUILD_COMPILATION_FLAGS)");
419 
420  CPP += CppWriter::getCPPAssignment("Name",openfluid::tools::escapeString(Sign.Name),true);
421  CPP += CppWriter::getCPPAssignment("Description",openfluid::tools::escapeString(Sign.Description),true);
422  CPP += CppWriter::getCPPAssignment("Version",Sign.Version,true);
423  CPP += CppWriter::getCPPAssignment("Status",
424  "openfluid::ware::"+openfluid::tools::toUpperCase(Sign.getStatusAsString()));
425 
426  // authors
427  std::vector<std::string> AuthorsStrVect;
428  for (const auto& A : Sign.Authors)
429  {
430  AuthorsStrVect.push_back(CppWriter::getCPPVectorString({A.first,A.second},true));
431  }
432  CPP += CppWriter::getCPPAssignment("Authors",CppWriter::getCPPVectorString(AuthorsStrVect));
433 
434  // contact
435  std::vector<std::string> ContactsStrVect;
436  for (const auto& C : Sign.Contacts)
437  {
438  ContactsStrVect.push_back(CppWriter::getCPPVectorString({C.first,C.second},true));
439  }
440  CPP += CppWriter::getCPPAssignment("Contacts",CppWriter::getCPPVectorString(ContactsStrVect));
441 
442  // license
443  CPP += CppWriter::getCPPAssignment("License",Sign.License,true);
444 
445  // tags
446  CPP += CppWriter::getCPPAssignment("Tags",CppWriter::getCPPVectorString(Sign.Tags,true));
447 
448  // links
449  std::vector<std::string> LinksStrVect;
450  for (const auto& L : Sign.Links)
451  {
452  LinksStrVect.push_back(CppWriter::getCPPVectorString({L.first,L.second},true));
453  }
454  CPP += CppWriter::getCPPAssignment("Links",CppWriter::getCPPVectorString(LinksStrVect));
455 
456  // issues
457  for (const auto& I : Sign.Issues())
458  {
459  std::vector<std::string> IssData;
460  IssData.push_back(std::to_string(I.first));
461  IssData.push_back(CppWriter::getQuotedString(openfluid::tools::escapeString(I.second.Title)));
462  IssData.push_back(CppWriter::getQuotedString(openfluid::tools::escapeString(I.second.Description)));
463  IssData.push_back(CppWriter::getCPPVectorString(I.second.Tags,true));
464  IssData.push_back(CppWriter::getQuotedString(I.second.Creator));
465  IssData.push_back(CppWriter::getCPPDateTimeString(I.second.CreatedAt));
466  IssData.push_back(CppWriter::getCPPDateTimeString(I.second.UpdatedAt));
467  if (I.second.IsOpen)
468  {
469  IssData.push_back("true");
470  }
471  else
472  {
473  IssData.push_back("false");
474  }
475 
476  CPP += CppWriter::getCPPMethod("Issues","insert",{CppWriter::getCPPVectorString(IssData),std::to_string(I.first)});
477  }
478 
479  return CPP;
480 }
481 
482 
483 // =====================================================================
484 // =====================================================================
485 
486 
487 template<class SignatureType>
488 std::string WareSignatureSerializer<SignatureType>::toWareCMakeBase(const SignatureType& Sign) const
489 {
490  std::string CMake;
491 
492  CMake += "SET(WARE_ID \""+Sign.ID+"\")\n";
493  CMake += "SET(WARE_LINKUID \""+m_LinkUID+"\")\n";
494 
495  return CMake;
496 }
497 
498 
499 // =====================================================================
500 // =====================================================================
501 
502 
503 template<class SignatureType>
504 SignatureType WareSignatureSerializer<SignatureType>::readFromJSONFile(const std::string& Path) const
505 {
506  std::ifstream InFile(Path,std::ifstream::in);
507 
508  try
509  {
510  auto FullJson = openfluid::thirdparty::json::parse(InFile);
511  auto Sign = fromJSON(FullJson);
512  return Sign;
513  }
514  catch (openfluid::thirdparty::json::exception& E)
515  {
516  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Error parsing file "+Path+
517  " ("+std::string(E.what())+")");
518  }
519 }
520 
521 
522 // =====================================================================
523 // =====================================================================
524 
525 
526 template<class SignatureType>
528  const std::string& FilePath) const
529 {
530  auto Json = toJSON(Sign);
531 
532  std::ofstream OutFile(FilePath,std::ofstream::out);
533  OutFile << Json.dump(2);
534 }
535 
536 
537 // =====================================================================
538 // =====================================================================
539 
540 
541 template<class SignatureType>
543  const std::string& FilePath) const
544 {
545  std::ofstream OutFile(FilePath,std::ofstream::out);
546 
547  OutFile << toWareCPP(Sign);
548  OutFile << "\n\n";
549  OutFile << CppWriter::getCPPLinkUIDProc(m_LinkUID);
550  OutFile << "\n\n";
551 }
552 
553 
554 // =====================================================================
555 // =====================================================================
556 
557 
558 template<class SignatureType>
560  const std::string& FilePath) const
561 {
562  std::ofstream OutFile(FilePath,std::ofstream::out);
563 
564  OutFile << CppWriter::getCPPHead("openfluid/builderext/BuilderExtensionSignature.hpp",
565  "openfluid::builderext::BuilderExtensionSignature");
566 
567  OutFile << CppWriter::getCPPAssignment("ID",Sign.ID+openfluid::config::WARESDEV_PARAMSUI_IDSUFFIX,true);
568  OutFile << CppWriter::getCPPAssignment("Role","openfluid::builderext::ExtensionRole::PARAMETERIZATION");
569  OutFile << CppWriter::getCPPAssignment("BuildInfo.SDKVersion",openfluid::config::VERSION_FULL,true);
570  OutFile << CppWriter::getCPPAssignment("BuildInfo.BuildType","(WAREBUILD_BUILD_TYPE)");
571  OutFile << CppWriter::getCPPAssignment("BuildInfo.CompilerID","(WAREBUILD_COMPILER_ID)");
572  OutFile << CppWriter::getCPPAssignment("BuildInfo.CompilerVersion","(WAREBUILD_COMPILER_VERSION)");
573  OutFile << CppWriter::getCPPAssignment("BuildInfo.CompilationFlags","(WAREBUILD_COMPILATION_FLAGS)");
574 
575  OutFile << CppWriter::getCPPTail();
576 
577  OutFile << "\n\n";
578  OutFile << CppWriter::getCPPLinkUIDProc(m_LinkUID);
579  OutFile << "\n\n";
580 }
581 
582 
583 // =====================================================================
584 // =====================================================================
585 
586 
587 template<class SignatureType>
589  const std::string& FilePath) const
590 {
591  std::ofstream OutFile(FilePath,std::ofstream::out);
592 
593  OutFile << toWareCMake(Sign);
594  OutFile << "\n\n";
595 }
596 
597 
598 // =====================================================================
599 // =====================================================================
600 
601 
602 template<class SignatureType>
604  const std::string& FilePath) const
605 {
606  std::ofstream OutFile(FilePath,std::ofstream::out);
607 
608  OutFile << CppWriter::getHead("#");
609  OutFile << "SET(WARE_ID \""+Sign.ID+openfluid::config::WARESDEV_PARAMSUI_IDSUFFIX+"\")\n";
610  OutFile << "SET(WARE_LINKUID \""+m_LinkUID+"\")\n";
611  OutFile << "SET(WARE_TYPE \"builderext\")\n";
612  OutFile << "SET(WARE_IS_BUILDEREXT TRUE)\n";
613  OutFile << "SET(WARE_IS_PARAMSUI TRUE)\n";
614  OutFile << "\n\n";
615 }
616 
617 
618 } } // namespaces
619 
620 
621 #endif /* __OPENFLUID_WARESDEV_WARESIGNATURESERIALIZER_HPP__ */
Definition: FrameworkException.hpp:51
Definition: WareIssues.hpp:60
unsigned int ID
Definition: WareIssues.hpp:63
static WareIssue fromJSON(const openfluid::thirdparty::json &IssueJson)
Definition: WareIssues.hpp:98
Definition: WareSignatureSerializer.hpp:148
WareSignatureSerializer()
Definition: WareSignatureSerializer.hpp:160
SignatureType readFromJSONFile(const std::string &FilePath) const
Definition: WareSignatureSerializer.hpp:504
virtual SignatureType fromJSON(const openfluid::thirdparty::json &Json) const =0
void writeToParamsUICPPFile(const SignatureType &Sign, const std::string &FilePath) const
Definition: WareSignatureSerializer.hpp:559
void writeToParamsUICMakeFile(const SignatureType &Sign, const std::string &FilePath) const
Definition: WareSignatureSerializer.hpp:603
std::string toWareCPPBase(const SignatureType &Sign) const
Definition: WareSignatureSerializer.hpp:407
virtual std::string toWareCPP(const SignatureType &Sign) const =0
void writeToWareCPPFile(const SignatureType &Sign, const std::string &FilePath) const
Definition: WareSignatureSerializer.hpp:542
virtual void writeToBuildFiles(const SignatureType &Sign, const std::string &Path) const =0
void writeToWareCMakeFile(const SignatureType &Sign, const std::string &FilePath) const
Definition: WareSignatureSerializer.hpp:588
static openfluid::thirdparty::json toJSONBase(const SignatureType &Sign)
Definition: WareSignatureSerializer.hpp:323
std::string toWareCMakeBase(const SignatureType &Sign) const
Definition: WareSignatureSerializer.hpp:488
void writeToJSONFile(const SignatureType &Sign, const std::string &FilePath) const
Definition: WareSignatureSerializer.hpp:527
const std::string m_LinkUID
Definition: WareSignatureSerializer.hpp:151
virtual openfluid::thirdparty::json toJSON(const SignatureType &Sign) const =0
static SignatureType fromJSONBase(const openfluid::thirdparty::json &Json)
Definition: WareSignatureSerializer.hpp:203
~WareSignatureSerializer()
Definition: WareSignatureSerializer.hpp:167
virtual std::string toWareCMake(const SignatureType &Sign) const =0
#define OPENFLUID_API
Definition: dllexport.hpp:86
nlohmann::ordered_json json
Definition: JSON.hpp:52
std::string OPENFLUID_API generatePseudoUniqueIdentifier(const unsigned int Length)
std::string OPENFLUID_API escapeString(const std::string &Str)
std::string OPENFLUID_API trim(const std::string &Str)
FilesystemPath Path
Definition: FilesystemPath.hpp:308
bool OPENFLUID_API isValidWareID(const openfluid::ware::WareID_t &ID, bool Template=false)
std::string OPENFLUID_API toUpperCase(const std::string &Str)
void OPENFLUID_API error(const std::string &Context, const std::string &Msg)
WareType
Definition: TypeDefs.hpp:61
std::string WareID_t
Definition: TypeDefs.hpp:49
openfluid::ware::WareType detectWareType(const std::string &Path)
Definition: WareSignatureSerializer.hpp:89
openfluid::ware::WareType detectWareTypeFromJson(const openfluid::thirdparty::json &Json)
Definition: WareSignatureSerializer.hpp:66
std::pair< openfluid::ware::WareType, openfluid::ware::WareID_t > detectWareTypeAndID(const std::string &Path)
Definition: WareSignatureSerializer.hpp:113
Definition: ApplicationException.hpp:47
static std::string getCPPTail()
Definition: WareCppWriterHelpers.hpp:249
static std::string getHead(const std::string CommentChar)
Definition: WareCppWriterHelpers.hpp:60
static std::string getCPPVectorString(const std::vector< std::string > &StrVect, bool AutoQuote=false)
Definition: WareCppWriterHelpers.hpp:123
static std::string getCPPDateTimeString(const openfluid::core::DateTime &DT)
Definition: WareCppWriterHelpers.hpp:104
static std::string getQuotedString(const std::string &Str)
Definition: WareCppWriterHelpers.hpp:94
static std::string getCPPHead(const std::string &WareIncludeStr, const std::string &WareTypeStr)
Definition: WareCppWriterHelpers.hpp:75
static std::string getCPPLinkUIDProc(const std::string LinkUID)
Definition: WareCppWriterHelpers.hpp:210
static std::string getCPPAssignment(const std::string &Member, const std::string &Value, bool AutoQuote=false)
Definition: WareCppWriterHelpers.hpp:165
static std::string getCPPMethod(const std::string &Member, const std::string &Method, const std::vector< std::string > &Args, const std::string &Access=".")
Definition: WareCppWriterHelpers.hpp:182