GroupCloner.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #include "GroupCloner.h"
25 
26 #include <filesystem>
27 #include <IceUtil/UUID.h>
28 #include <QDir>
29 #include <QDirIterator>
30 #include <QFileInfo>
32 #include <filesystem>
33 
34 using namespace armarx;
35 using namespace armarx::statechartmodel;
36 
37 GroupCloner::GroupCloner(const std::weak_ptr<StateTreeModel>& treeModel, const ArmarXPackageToolInterfacePtr& packageTool) :
38  treeModel(treeModel),
39  packageTool(packageTool)
40 {
41 }
42 
43 
44 QVector<StatechartGroupPtr> GroupCloner::getGroupDependencies(const StatechartGroupPtr& group, bool includeSelf)
45 {
46  QVector<statechartmodel::StatePtr> states = group->getAllStates(false);
47 
48  auto result = GetGroupsFromStates(treeModel.lock(), states);
49 
50  if (!includeSelf)
51  {
52  auto it = std::remove_if(result.begin(), result.end(), [&](const StatechartGroupPtr & g)
53  {
54  return g->getGroupPath() == group->getGroupPath();
55  });
56  result.erase(it, result.end());
57  }
58 
59  return result;
60 }
61 
62 QVector<StatechartGroupPtr> GroupCloner::getMappedGroups(const StatechartGroupMapping& mapping)
63 {
64  QVector<StatechartGroupPtr> result;
65 
66  for (const auto& groupMapping : mapping.groupMappings)
67  {
68  auto group = treeModel.lock()->getGroupByName(groupMapping.groupName);
69 
70  if (!group)
71  {
72  ARMARX_WARNING_S << "Group " << groupMapping.groupName << " was not loaded";
73  }
74  else
75  {
76  result.push_back(group);
77  }
78  }
79 
80  return result;
81 }
82 
83 std::optional<StatechartGroupMapping> GroupCloner::cloneGroupsTo(const QVector<QPair<StatechartGroupPtr, QString>>& groupsNames, const QString& packageDir, const StatechartGroupMapping& mapping, bool createNewUUIDs)
84 {
85  StatechartGroupMapping newMapping = mapping;
86  ARMARX_INFO_S << "Groups that will be cloned: ";
87 
88  for (const auto& gEntry : groupsNames)
89  {
90  const auto& g = gEntry.first;
91  ARMARX_INFO_S << " " << g->getName() << " -> " << gEntry.second;
92 
93  bool groupMapped = std::find_if(mapping.groupMappings.cbegin(), mapping.groupMappings.cend(), [&](const StatechartGroupMapping::GroupMapping & gm)
94  {
95  return gm.groupName == g->getName();
96  }) != mapping.groupMappings.cend();
97 
98  if (groupMapped)
99  {
100  ARMARX_WARNING_S << "Mapping file seems to be inconsistent with folder structure";
101  return std::optional<StatechartGroupMapping>();
102  }
103 
104  QVector<statechartmodel::StatePtr> states = g->getAllStates();
105 
106  StatechartGroupMapping::GroupMapping groupMapping {g->getName(), gEntry.second, g->getPackageName(), {}};
107 
108  for (const statechartmodel::StatePtr& state : states)
109  {
110  bool stateMapped = std::find_if(groupMapping.stateMappings.cbegin(), groupMapping.stateMappings.cend(), [&](const StatechartGroupMapping::StateMapping & sm)
111  {
112  return sm.stateName == state->getStateName();
113  }) != groupMapping.stateMappings.cend();
114 
115  if (!stateMapped)
116  {
117  QString targetUUID = state->getUUID();
118 
119  if (createNewUUIDs)
120  {
121  targetUUID = QString::fromUtf8(IceUtil::generateUUID().c_str());
122  }
123 
124  groupMapping.stateMappings.insert({state->getStateName(), state->getUUID(), targetUUID});
125  }
126  }
127 
128  newMapping.groupMappings.insert(groupMapping);
129  }
130 
131  QVector<StatechartGroupPtr> groups;
132  std::transform(groupsNames.begin(), groupsNames.end(), std::back_inserter(groups),
133  [](const QPair<StatechartGroupPtr, QString>& p)
134  {
135  return p.first;
136  });
137 
138  for (const StatechartGroupPtr& g : groups)
139  {
140  if (!g->existsCMakeLists())
141  {
142  ARMARX_WARNING_S << g->getName() << " at " << g->getGroupPath() << " contains no CMakeLists.txt - is it an installed package? Installed packages cannot be cloned since they do not contain the CMakelists file and CPP files";
143  return std::optional<StatechartGroupMapping>();
144  }
145  }
146 
147  registerGroups(groups, newMapping, packageDir);
148 
149  for (const auto& g : groups)
150  {
151  if (!cloneGroupTo(g, packageDir, newMapping))
152  {
153  ARMARX_WARNING_S << "Cloning group '" << g->getName() << "' failed, aborting...";
154  return std::optional<StatechartGroupMapping>();
155  }
156  }
157 
158  ARMARX_INFO_S << "Cloning done";
159 
160  return std::optional<StatechartGroupMapping>(newMapping);
161 }
162 
163 void GroupCloner::registerGroups(const QVector<StatechartGroupPtr>& groups, const StatechartGroupMapping& mapping, const QString& packageDir)
164 {
165  const QString packageName = QFileInfo(packageDir).fileName();
166 
167  for (const StatechartGroupPtr& g : groups)
168  {
169  if (auto groupName = mapping.queryMappedGroupName(g->getName()))
170  {
171  QString tempStateName = *groupName + "TempState";
172  packageTool->addStatechart(groupName->toUtf8().data(), tempStateName.toUtf8().data(), packageDir.toUtf8().data());
173  RemoveDir(
174  packageDir + QDir::separator() +
175  "source" + QDir::separator() +
176  packageName + QDir::separator() +
177  "statecharts" + QDir::separator() +
178  *groupName);
179  }
180  }
181 }
182 
183 bool GroupCloner::cloneGroupTo(const StatechartGroupPtr& group, const QString& packageFolder, const StatechartGroupMapping& mapping)
184 {
185  QFileInfo packageInfo(packageFolder);
186  ARMARX_CHECK_EXPRESSION(packageInfo.isDir() && packageInfo.exists());
187 
188  auto newGroupNameOpt = mapping.queryMappedGroupName(group->getName());
189  ARMARX_CHECK_EXPRESSION(newGroupNameOpt);
190  QString newGroupName = *newGroupNameOpt;
191 
192  const QString oldPackageName = group->getPackageName();
193  const QString newPackageName = QFileInfo(packageFolder).fileName();
194  const QString packageStatechartsDir =
195  packageFolder + QDir::separator() + "source" + QDir::separator() + newPackageName + QDir::separator() + "statecharts";
196  QString newGroupPath = packageStatechartsDir + QDir::separator() + newGroupName;
197 
198  ARMARX_INFO_S << "Cloning '" << group->getGroupPath() << "' to '" << newGroupPath << "'";
199 
200  if (QDir(newGroupPath).exists())
201  {
202  ARMARX_WARNING_S << newGroupPath << " already exists, but should not exist. Skipping...";
203  return false;
204  }
205  else if (!QDir(newGroupPath).mkpath("."))
206  {
207  ARMARX_ERROR_S << "Could not create directory: " << newGroupPath;
208  return false;
209  }
210 
211  QMap<QString, QString> renameCandidateMap;
212  renameCandidateMap.insert(group->getName() + ".scgxml", newGroupName + ".scgxml");
213  renameCandidateMap.insert(group->getName() + "RemoteStateOfferer.h", newGroupName + "RemoteStateOfferer.h");
214  renameCandidateMap.insert(group->getName() + "RemoteStateOfferer.cpp", newGroupName + "RemoteStateOfferer.cpp");
215  renameCandidateMap.insert(group->getName() + "StatechartContext.h", newGroupName + "StatechartContext.h");
216  renameCandidateMap.insert(group->getName() + "StatechartContext.cpp", newGroupName + "StatechartContext.cpp");
217 
218  QMap<QString, bool> expectedFileSeenMap;
219  expectedFileSeenMap.insert("CMakeLists.txt", false);
220  expectedFileSeenMap.insert(group->getName() + ".scgxml", false);
221  expectedFileSeenMap.insert(group->getName() + "RemoteStateOfferer.h", false);
222  expectedFileSeenMap.insert(group->getName() + "RemoteStateOfferer.cpp", false);
223 
224  // the context files don't have to exist; the contents are normally generated as part of the generated files
225  QVector<QString> optionalExpectedFiles;
226  optionalExpectedFiles.push_back(group->getName() + "StatechartContext.generated.h");
227  optionalExpectedFiles.push_back(group->getName() + "StatechartContext.h");
228  optionalExpectedFiles.push_back(group->getName() + "StatechartContext.cpp");
229 
230  QVector<QString> doNotCopy;
231  doNotCopy.push_back(group->getName() + "StatechartContext.generated.h");
232 
233  QVector<StateTreeNodePtr> allNodes = group->getAllNodes();
234 
235  for (const StateTreeNodePtr& n : allNodes)
236  {
237  if (!n->isState())
238  {
239  continue;
240  }
241 
242  const QString xml = QString::fromUtf8(n->getBoostXmlFilePath(StateTreeNode::Path::RelativeToGroup).c_str());
243  const QString cpp = QString::fromUtf8(n->getBoostCppFilePath(StateTreeNode::Path::RelativeToGroup).c_str());
244  const QString h = QString::fromUtf8(n->getBoostHFilePath(StateTreeNode::Path::RelativeToGroup).c_str());
245  const QString gen = QString::fromUtf8(n->getBoostGeneratedHFilePath(StateTreeNode::Path::RelativeToGroup).c_str());
246 
247  expectedFileSeenMap.insert(xml, false);
248 
249  if (n->checkCppExists())
250  {
251  expectedFileSeenMap.insert(cpp, false);
252  expectedFileSeenMap.insert(h, false);
253  optionalExpectedFiles.push_back(gen);
254  }
255 
256  doNotCopy.push_back(gen);
257  }
258 
259  QVector<QPair<QRegExp, QString>> codeFileReplaceList;
260  codeFileReplaceList.push_back({QRegExp(oldPackageName + "_" + group->getName()), newPackageName + "_" + newGroupName});
261  codeFileReplaceList.push_back({QRegExp(oldPackageName + "::" + group->getName()), newPackageName + "::" + newGroupName});
262  codeFileReplaceList.push_back({QRegExp("namespace[\\n\\s]*" + group->getName()), "namespace " + newGroupName});
263  codeFileReplaceList.push_back({QRegExp("namespace[\\n\\s]*armarx::" + group->getName()), "namespace armarx::" + newGroupName});
264  codeFileReplaceList.push_back({QRegExp(group->getName() + "StatechartContext"), newGroupName + "StatechartContext"});
265  codeFileReplaceList.push_back({QRegExp(group->getName() + "RemoteStateOfferer"), newGroupName + "RemoteStateOfferer"});
266  codeFileReplaceList.push_back({QRegExp(oldPackageName + "/statecharts/" + group->getName()), newPackageName + "/statecharts/" + newGroupName});
267 
268  QVector<QPair<QRegExp, QString>> cmakeListsReplaceList;
269  cmakeListsReplaceList.push_back({QRegExp("armarx_component_set_name\\(\"" + group->getName() + "\"\\)"),
270  "armarx_component_set_name(\"" + newGroupName + "\")"
271  });
272  cmakeListsReplaceList.push_back({QRegExp(group->getName() + "\\.scgxml"), newGroupName + ".scgxml"});
273  cmakeListsReplaceList.push_back({QRegExp(group->getName() + "StatechartContext"), newGroupName + "StatechartContext"});
274  cmakeListsReplaceList.push_back({QRegExp(group->getName() + "RemoteStateOfferer"), newGroupName + "RemoteStateOfferer"});
275 
276  auto xmlProcessor = [&](const std::string&, const std::string & attribName, const std::string & attribValue) -> std::string
277  {
278  QString value = QString::fromUtf8(attribValue.c_str());
279 
280  if (attribName == "refuuid" || attribName == "uuid")
281  {
282  QString value = QString::fromUtf8(attribValue.c_str());
283 
284  if (auto qresult = mapping.queryMappedUuid(value))
285  {
286  return qresult->toUtf8().data();
287  }
288  else
289  {
290  ARMARX_WARNING_S << "No mapping was generated for uuid " << value;
291  }
292  }
293  else if (attribName == "proxyName")
294  {
295  value = value.replace("RemoteStateOfferer", "");
296 
297  if (auto qresult = mapping.queryMappedGroupName(value))
298  {
299  return std::string(qresult->toUtf8().data()) + "RemoteStateOfferer";
300  }
301  else
302  {
303  ARMARX_WARNING_S << "No mapping was generated for group " << value;
304  }
305  }
306 
307  return attribValue;
308  };
309 
310  auto scgxmlProcessor = [&](const std::string&, const std::string & attribName, const std::string & attribValue) -> std::string
311  {
312  QString value = QString::fromUtf8(attribValue.c_str());
313 
314  if (attribName == "package" && oldPackageName == value)
315  {
316  return newPackageName.toUtf8().data();
317  }
318  else if (attribName == "name")
319  {
320  if (auto newGroupName = mapping.queryMappedGroupName(value))
321  {
322  return newGroupName->toUtf8().data();
323  }
324  }
325 
326  return attribValue;
327  };
328 
329  QDirIterator it(group->getGroupPath(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
330 
331  while (it.hasNext())
332  {
333  const auto f = QFileInfo(it.next());
334  QString relativePath = QDir(group->getGroupPath()).relativeFilePath(f.absoluteFilePath());
335  QString srcFilePath = group->getGroupPath() + QDir::separator() + relativePath;
336  QString tgtFilePath = newGroupPath + QDir::separator() + (renameCandidateMap.contains(relativePath) ? renameCandidateMap[relativePath] : relativePath);
337 
338  if (f.isDir())
339  {
340  if (!QDir(tgtFilePath).mkpath("."))
341  {
342  ARMARX_WARNING_S << "Could not create directory at path: " << tgtFilePath;
343  return false;
344  }
345 
346  ARMARX_VERBOSE_S << "Created directory '" << tgtFilePath << "'";
347  continue;
348  }
349 
350  if (doNotCopy.contains(relativePath))
351  {
352  ARMARX_VERBOSE_S << "Skipping file '" << relativePath << "'";
353  continue;
354  }
355 
356  ARMARX_DEBUG_S << "Cloning file '" << srcFilePath << "' -> '" << tgtFilePath << "'";
357 
358  if (expectedFileSeenMap.contains(relativePath))
359  {
360  expectedFileSeenMap[relativePath] = true;
361  }
362  else if (!optionalExpectedFiles.contains(relativePath))
363  {
364  ARMARX_WARNING_S << "Unexpected file '" << relativePath << "', processing anyway... - expected files" << expectedFileSeenMap.toStdMap();
365  }
366 
367  if (f.suffix() == "xml" || f.suffix() == "scgxml")
368  {
369  ARMARX_VERBOSE_S << "Processing xml file: " << relativePath;
370  auto readerPtr = RapidXmlReader::FromFile(srcFilePath.toUtf8().data());
371  RapidXmlReaderNode rootNode = readerPtr->getRoot();
372  RapidXmlWriter writer;
373  auto writerNode = writer.createRootNode(rootNode.name());
374 
375  if (f.suffix() == "xml")
376  {
377  ProcessXMLFile(rootNode, writerNode, xmlProcessor);
378  }
379  else
380  {
381  ProcessXMLFile(rootNode, writerNode, scgxmlProcessor);
382  }
383 
384  writer.saveToFile(tgtFilePath.toUtf8().data(), true);
385  }
386  else if (f.suffix() == "cpp" || f.suffix() == "h")
387  {
388  ARMARX_VERBOSE_S << "Processing code file: " << relativePath;
389  RegexReplaceFile(srcFilePath, tgtFilePath, codeFileReplaceList);
390  }
391  else if (f.fileName() == "CMakeLists.txt")
392  {
393  ARMARX_VERBOSE_S << "Processing CMakeLists file: " << relativePath;
394  RegexReplaceFile(srcFilePath, tgtFilePath, cmakeListsReplaceList);
395  }
396  else
397  {
398  ARMARX_VERBOSE_S << "Copying file: " << relativePath;
399  QFile::copy(srcFilePath, tgtFilePath);
400  }
401  }
402 
403  for (const auto& f : expectedFileSeenMap.toStdMap())
404  {
405  if (!f.second)
406  {
407  ARMARX_WARNING_S << "Expected file '" << f.first << "' was not found while cloning";
408  }
409  }
410 
411  ARMARX_INFO_S << "Cloned group " << group->getName();
412  return true;
413 }
414 
415 QVector<StatechartGroupPtr> GroupCloner::GetGroupsFromStates(const StateTreeModelPtr& treeModel, const QVector<statechartmodel::StatePtr>& states)
416 {
417  QVector<StatechartGroupPtr> result;
418 
419  for (const auto& state : states)
420  {
421  auto stateGroup = treeModel->getNodeByState(state)->getGroup();
422  ARMARX_CHECK_EXPRESSION(stateGroup);
423  bool alreadyExists = std::find_if(result.constBegin(), result.constEnd(), [&](const StatechartGroupPtr & depGroup)
424  {
425  return stateGroup->getDefinitionFilePath() == depGroup->getDefinitionFilePath();
426  }) != result.constEnd();
427 
428  if (!alreadyExists)
429  {
430  result.push_back(stateGroup);
431  }
432  }
433 
434  return result;
435 }
436 
437 bool GroupCloner::CopyRecursively(const QString& srcPath, const QString& tgtParentDirPath)
438 {
439  QFileInfo srcInfo(srcPath);
440  QFileInfo tgtInfo(tgtParentDirPath);
441 
442  if (srcInfo.fileName() == tgtInfo.fileName())
443  {
444  auto newDir = QDir(tgtParentDirPath);
445  newDir.cdUp();
446  return CopyRecursively(srcPath, newDir.path());
447  }
448 
449  if (!tgtInfo.isDir() && tgtInfo.exists())
450  {
451  ARMARX_WARNING_S << "Destination '" << tgtParentDirPath << "' has to be a folder" << flush;
452  return false;
453  }
454 
455  if (srcInfo.isDir())
456  {
457  const QString newTgtDirPath = tgtParentDirPath + QDir::separator() + srcInfo.fileName();
458  const auto newDir = QDir(newTgtDirPath);
459 
460  if (newDir.exists())
461  {
462  ARMARX_IMPORTANT_S << "Target dir already exists: " << newTgtDirPath;
463  return false;
464  }
465 
466  if (!newDir.mkpath("."))
467  {
468  ARMARX_IMPORTANT_S << "Failed creating dir: " << newTgtDirPath;
469  return false;
470  }
471 
472  QDir sourceDir(srcPath);
473  QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
474 
475  for (const QString& fileName : fileNames)
476  {
477  const QString newSrcFilePath = srcPath + QDir::separator() + fileName;
478 
479  if (!CopyRecursively(newSrcFilePath, newTgtDirPath))
480  {
481  return false;
482  }
483  }
484  }
485  else
486  {
487  const QString newTgtFilePath = tgtParentDirPath + QDir::separator() + srcInfo.fileName();
488 
489  if (!QFile::copy(srcPath, newTgtFilePath))
490  {
491  ARMARX_IMPORTANT_S << "Could not copy file: " << srcPath << " -> " << newTgtFilePath;
492  return false;
493  }
494  }
495 
496  return true;
497 }
498 
499 void GroupCloner::RegexReplaceFile(const QString& srcFilePath, const QString& tgtFilePath, const QVector<QPair<QRegExp, QString>>& replaceList)
500 {
501  QString fileContent = GuiStatechartGroupXmlReader::ReadFileContents(srcFilePath);
502 
503  for (const auto& replace : replaceList)
504  {
505  fileContent = fileContent.replace(replace.first, replace.second);
506  }
507 
508  GroupXmlWriter::WriteFileContents(tgtFilePath, fileContent);
509 }
510 
511 bool GroupCloner::RemoveDir(const QString& dirName)
512 {
513  bool result = true;
514  QDir dir(dirName);
515 
516  if (dir.exists(dirName))
517  {
518  for (QFileInfo info : dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst))
519  {
520  if (info.isDir())
521  {
522  result = RemoveDir(info.absoluteFilePath());
523  }
524  else
525  {
526  result = QFile::remove(info.absoluteFilePath());
527  }
528 
529  if (!result)
530  {
531  return result;
532  }
533  }
534 
535  result = dir.rmdir(dirName);
536  }
537 
538  return result;
539 }
armarx::RapidXmlReader::FromFile
static RapidXmlReaderPtr FromFile(const std::string &path)
Definition: RapidXmlReader.h:497
armarx::StateTreeModelPtr
std::shared_ptr< StateTreeModel > StateTreeModelPtr
Definition: StateTreeModel.h:44
ARMARX_IMPORTANT_S
#define ARMARX_IMPORTANT_S
Definition: Logging.h:203
armarx::RapidXmlWriter
Definition: RapidXmlWriter.h:99
XmlReader.h
armarx::GuiStatechartGroupXmlReader::ReadFileContents
static QString ReadFileContents(QString path)
Definition: GroupXmlReader.cpp:109
armarx::GroupCloner::getMappedGroups
QVector< StatechartGroupPtr > getMappedGroups(const StatechartGroupMapping &mapping)
Definition: GroupCloner.cpp:62
armarx::ArmarXPackageToolInterfacePtr
std::shared_ptr< ArmarXPackageToolInterface > ArmarXPackageToolInterfacePtr
Definition: ArmarXPackageToolInterface.h:55
armarx::StateTreeNodePtr
std::shared_ptr< StateTreeNode > StateTreeNodePtr
Definition: StatechartGroupDefs.h:31
cpp
IceStorm Admin cpp
Definition: CMakeLists.txt:87
armarx::StatechartGroupMapping::StateMapping
Definition: StatechartGroupMapping.h:36
armarx::StatechartGroupMapping::queryMappedUuid
std::optional< QString > queryMappedUuid(const QString &sourceUuid) const
Definition: StatechartGroupMapping.cpp:101
armarx::GroupCloner::GetGroupsFromStates
static QVector< StatechartGroupPtr > GetGroupsFromStates(const StateTreeModelPtr &treeModel, const QVector< statechartmodel::StatePtr > &states)
Definition: GroupCloner.cpp:415
armarx::GroupCloner::ProcessXMLFile
static void ProcessXMLFile(RapidXmlReaderNode source, RapidXmlWriterNode target, const Function &processorFunction)
Definition: GroupCloner.h:64
armarx::StateTreeNode::Path::RelativeToGroup
@ RelativeToGroup
armarx::GroupCloner::RegexReplaceFile
static void RegexReplaceFile(const QString &srcFilePath, const QString &tgtFilePath, const QVector< QPair< QRegExp, QString >> &replaceList)
Definition: GroupCloner.cpp:499
armarx::StatechartGroupMapping
Definition: StatechartGroupMapping.h:34
armarx::RapidXmlReaderNode::name
std::string name() const
Definition: RapidXmlReader.h:349
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::GroupXmlWriter::WriteFileContents
static void WriteFileContents(QString path, QString contents)
Definition: GroupXmlWriter.cpp:90
ARMARX_DEBUG_S
#define ARMARX_DEBUG_S
Definition: Logging.h:198
armarx::GroupCloner::GroupCloner
GroupCloner(const std::weak_ptr< StateTreeModel > &treeModel, const ArmarXPackageToolInterfacePtr &packageTool)
Definition: GroupCloner.cpp:37
copy
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this and transmit the and to prepare derivative works of the and to permit third parties to whom the Software is furnished to do all subject to the including the above license this restriction and the following must be included in all copies of the in whole or in and all derivative works of the unless such copies or derivative works are solely in the form of machine executable object code generated by a source language processor THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF FITNESS FOR A PARTICULAR TITLE AND NON INFRINGEMENT IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN TORT OR ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE The MIT Marcin Kalicinski Permission is hereby free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to copy
Definition: license.txt:39
armarx::GroupCloner::getGroupDependencies
QVector< StatechartGroupPtr > getGroupDependencies(const StatechartGroupPtr &group, bool includeSelf=false)
Definition: GroupCloner.cpp:44
armarx::GroupCloner::RemoveDir
static bool RemoveDir(const QString &dirName)
Definition: GroupCloner.cpp:511
armarx::GroupCloner::cloneGroupsTo
std::optional< StatechartGroupMapping > cloneGroupsTo(const QVector< QPair< StatechartGroupPtr, QString >> &groupsNames, const QString &packageDir, const StatechartGroupMapping &mapping=StatechartGroupMapping(), bool createNewUUIDs=true)
Definition: GroupCloner.cpp:83
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:209
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
armarx::statechartmodel
Definition: XmlWriter.h:36
armarx::StatechartGroupMapping::GroupMapping
Definition: StatechartGroupMapping.h:48
armarx::StatechartGroupMapping::groupMappings
std::set< GroupMapping > groupMappings
Definition: StatechartGroupMapping.h:60
armarx::RapidXmlReaderNode
Definition: RapidXmlReader.h:68
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::StatechartGroupPtr
std::shared_ptr< StatechartGroup > StatechartGroupPtr
Definition: StatechartGroupDefs.h:34
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::RapidXmlWriter::saveToFile
void saveToFile(const std::string &path, bool indent)
Definition: RapidXmlWriter.h:126
GroupCloner.h
armarx::transform
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition: algorithm.h:315
armarx::RapidXmlWriter::createRootNode
RapidXmlWriterNode createRootNode(const std::string &name)
Definition: RapidXmlWriter.h:113
armarx::statechartmodel::StatePtr
std::shared_ptr< State > StatePtr
Definition: State.h:46
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:200
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
armarx::StatechartGroupMapping::queryMappedGroupName
std::optional< QString > queryMappedGroupName(const QString &sourceGroupName) const
Definition: StatechartGroupMapping.cpp:88
armarx::StatechartGroupMapping::GroupMapping::stateMappings
std::set< StateMapping > stateMappings
Definition: StatechartGroupMapping.h:53
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28