XMLStateComponent.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 ArmarX::
19 * @author Mirko Waechter ( mirko.waechter at kit dot edu)
20 * @date 2014
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24 
25 #include "XMLStateComponent.h"
26 
27 #include <random>
28 
29 #include <Ice/Properties.h>
30 #include <IceUtil/UUID.h>
31 
32 #include <SimoxUtility/algorithm/string/string_tools.h>
33 
39 
40 #include "../StatechartEventDistributor.h"
41 #include "GroupXmlReader.h"
42 #include "XMLRemoteStateOfferer.h"
43 
44 namespace armarx
45 {
46 
48  {
49  uuid = IceUtil::generateUUID();
50  }
51 
52  void
54  {
55  std::string groupFilepathString =
56  PropertyUser::getProperty<std::string>("XMLStatechartGroupDefinitionFile").getValue();
57  std::string profileName =
58  PropertyUser::getProperty<std::string>("XMLStatechartProfile").getValue();
59 
60  //std::string profileDefinitionFilepath = PropertyUser::getProperty<std::string>("XMLStatechartProfile").getValue();
62  Application::getInstance()->getArmarXPackageNames());
63  selectedProfile = profiles->getProfileByName(profileName);
64 
65  if (!selectedProfile)
66  {
67  throw LocalException("Could not find profile '" + profileName + "'");
68  }
69 
70  ARMARX_IMPORTANT << "Using profile " << selectedProfile->getFullName();
71 
72 
73  Ice::StringSeq includePaths;
75  packages.push_back(Application::GetProjectName());
76 
77  for (const std::string& projectName : packages)
78  {
79  if (projectName.empty())
80  {
81  continue;
82  }
83 
84  CMakePackageFinder project(projectName);
85  auto pathsString = project.getIncludePaths();
86  Ice::StringSeq projectIncludePaths = simox::alg::split(pathsString, ";,");
87  includePaths.insert(
88  includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
89  }
90 
92 
93  ArmarXDataPath::getAbsolutePath(groupFilepathString, groupFilepathString, includePaths);
94  reader->readXml(std::filesystem::path(groupFilepathString));
95 
96  auto extraProperties = reader->getConfigurationFileContent();
97  if (!extraProperties.empty())
98  {
99  auto props = Ice::createProperties();
100  std::filesystem::path temp =
101  std::filesystem::temp_directory_path() / std::to_string(std::random_device{}());
102  temp += ".cfg";
103  std::ofstream file(temp.string().c_str());
104  file << extraProperties;
105  file.close();
106  props->load(temp.string());
107  std::filesystem::remove(temp);
108  for (auto& prop : props->getPropertiesForPrefix(""))
109  {
110  tryAddProperty(prop.first, prop.second);
111  }
112  }
113  CMakePackageFinder pack(reader->getPackageName());
114 
115  if (pack.packageFound())
116  {
117  std::string libPath = "lib" + reader->getGroupName() + ".so";
118 
119  std::string libPaths = pack.getLibraryPaths();
120  std::vector<std::string> libpathList = simox::alg::split(libPaths, ";");
121 
122  std::string libPathNextGen =
123  "lib" + reader->getPackageName() + "_" + reader->getGroupName() + ".so";
124 
125  if (ArmarXDataPath::getAbsolutePath(libPath, libPath, libpathList, false))
126  {
127  loadLib(libPath);
130  }
132  libPathNextGen, libPathNextGen, libpathList, false))
133  {
134  loadLib(libPathNextGen);
137  }
138  else
139  {
140  ARMARX_ERROR << "Could not find state user code lib file `" << libPath << "` or `"
141  << libPathNextGen << "`";
142  }
143  }
144 
145  offererName = reader->getGroupName() + STATEOFFERERSUFFIX;
147  reader);
148  if (!offerer)
149  {
150  ARMARX_WARNING << "Could not find XMLRemoteStateOfferer with name " << offererName
151  << "\nAvailable classes are:\n"
153  offerer = new XMLRemoteStateOfferer<>(reader);
154  }
155 
156  if (PropertyUser::getProperty<std::string>("XMLRemoteStateOffererName").isSet())
157  {
158  offererName =
159  PropertyUser::getProperty<std::string>("XMLRemoteStateOffererName").getValue();
160  }
161  }
162 
163  void
165  {
166  ComponentPtr obj = ComponentPtr::dynamicCast(offerer);
167  obj->forceComponentCreatedByComponentCreateFunc();
168  StatechartContextPtr::dynamicCast(offerer)->setReportingTopic(
169  getProperty<std::string>("StateReportingTopic").getValue());
170  obj->initializeProperties(offererName, getIceProperties(), getConfigDomain());
171  if (getProperty<bool>("EnableProfiling").getValue() &&
172  !obj->getProperty<bool>("EnableProfiling").isSet())
173  {
174  obj->enableProfiler(true);
175  }
176 
177  bool usePrx = false;
178  iceObjName = selectedProfile->getStatechartGroupPrefix() + obj->getName();
179  if (getArmarXManager()->getIceManager()->isObjectReachable(iceObjName))
180  {
181  ARMARX_INFO << "Using already running proxy: " << iceObjName;
182  usePrx = true;
183  }
184  else
185  {
186  getArmarXManager()->addObject(obj, false, iceObjName);
187  }
188 
189  for (auto state :
190  Split(getProperty<std::string>("StatesToEnter").getValue(), ",", true, true))
191  {
192  simox::alg::trim(state);
193  if (state == "")
194  {
195  continue;
196  }
197  createAndEnterInstance(state, usePrx);
198  }
199  }
200 
201  std::string
203  {
204  return "XMLStateComponent";
205  }
206 
209  {
211  }
212 
213  bool
214  XMLStateComponent::loadLib(std::string libPath)
215  {
216  if (!ArmarXDataPath::getAbsolutePath(libPath, libPath))
217  {
218  ARMARX_ERROR << "Could not find state user code lib file: " << libPath;
219  return false;
220  }
221 
222  if (libraries.find(libPath) != libraries.end())
223  {
224  return true;
225  }
226 
227  try
228  {
230  ARMARX_VERBOSE << "Loading lib: " << libPath;
231  lib->load(libPath);
232  libraries[libPath] = lib;
233  }
235  {
236  ARMARX_ERROR << "Library loading failed: " << e.what();
237  return false;
238  }
239 
240  return true;
241  }
242 
243  void
244  XMLStateComponent::createAndEnterInstance(const std::string& stateClassName,
245  bool useExisitingPrx)
246  {
247  if (useExisitingPrx)
248  {
249  RemoteStateOffererInterfacePrx off =
250  getArmarXManager()->getIceManager()->getProxy<RemoteStateOffererInterfacePrx>(
251  iceObjName);
252  auto stateId =
253  off->createRemoteStateInstance(stateClassName, nullptr, "TopLevel", stateClassName);
254  off->callRemoteState(stateId, StringVariantContainerBaseMap());
255  stateIDStartedUsingExisitingPrx = stateId;
256  }
257  else
258  {
259  StatechartContextPtr context = StatechartContextPtr::dynamicCast(offerer);
260  context->getObjectScheduler()->waitForObjectState(eManagedIceObjectStarted);
261  RemoteStateOffererIceBasePtr off = RemoteStateOffererIceBasePtr::dynamicCast(offerer);
262  auto stateId =
263  off->createRemoteStateInstance(stateClassName, nullptr, "TopLevel", stateClassName);
264  off->callRemoteState(stateId, StringVariantContainerBaseMap());
265  }
266  }
267 
268  void
270  {
271  if (getArmarXManager()->getIceManager()->isObjectReachable(iceObjName))
272  {
273  RemoteStateOffererInterfacePrx off =
274  getArmarXManager()->getIceManager()->getProxy<RemoteStateOffererInterfacePrx>(
275  iceObjName);
276  if (stateIDStartedUsingExisitingPrx != -1 &&
277  off->getAvailableStateInstances().count(stateIDStartedUsingExisitingPrx) != 0)
278  {
279  ARMARX_DEBUG << "Exiting state with id: " << stateIDStartedUsingExisitingPrx
280  << " which has been started using already running proxy.";
281  off->breakActiveSubstateRemotely(stateIDStartedUsingExisitingPrx, nullptr);
282  off->breakRemoteState(stateIDStartedUsingExisitingPrx, nullptr);
283  off->removeInstance(stateIDStartedUsingExisitingPrx);
284  }
285  }
286  }
287 } // namespace armarx
armarx::XMLStateComponent::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: XMLStateComponent.cpp:164
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:366
armarx::Application::GetProjectName
static const std::string & GetProjectName()
Definition: Application.cpp:879
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
armarx::CMakePackageFinder::packageFound
bool packageFound() const
Returns whether or not this package was found with cmake.
Definition: CMakePackageFinder.cpp:511
armarx::DynamicLibraryPtr
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr
Definition: DynamicLibrary.h:124
ArmarXManager.h
armarx::XMLStateComponent::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: XMLStateComponent.cpp:53
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:36
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:360
armarx::AbstractFactoryMethod< XMLStateOffererFactoryBase, StatechartGroupXmlReaderPtr, XMLStateOffererFactoryBasePtr >::fromName
static SharedPointerType fromName(const std::string &name, StatechartGroupXmlReaderPtr params)
Function which can be used to retrieve an object specified by string name.
Definition: AbstractFactoryMethod.h:82
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:52
armarx::XMLStateComponent::offererName
std::string offererName
Definition: XMLStateComponent.h:152
armarx::CMakePackageFinder::getLibraryPaths
std::string getLibraryPaths() const
Returns the library paths seperated by semi-colons.
Definition: CMakePackageFinder.h:134
GroupXmlReader.h
armarx::XMLStateComponent::libraries
std::map< std::string, DynamicLibraryPtr > libraries
Definition: XMLStateComponent.h:150
armarx::PropertyUser::tryAddProperty
bool tryAddProperty(const std::string &propertyName, const std::string &value)
Definition: PropertyUser.cpp:203
project
std::string project
Definition: VisualizationRobot.cpp:85
armarx::exceptions::local::DynamicLibraryException
This exception is thrown if an invalid value was specified for a property.
Definition: DynamicLibraryException.h:38
IceInternal::Handle
Definition: forward_declarations.h:8
armarx::XMLStateComponent::offerer
XMLStateOffererFactoryBasePtr offerer
Definition: XMLStateComponent.h:154
armarx::StatechartGroupXmlReaderPtr
std::shared_ptr< StatechartGroupXmlReader > StatechartGroupXmlReaderPtr
Definition: GroupXmlReader.h:94
armarx::XMLStateComponentProperties
Definition: XMLStateComponent.h:41
armarx::XMLStateComponent::createAndEnterInstance
void createAndEnterInstance(const std::string &stateClassName, bool useExisitingPrx=false)
Definition: XMLStateComponent.cpp:244
armarx::XMLStateComponent::XMLStateComponent
XMLStateComponent()
Definition: XMLStateComponent.cpp:47
Ice::createProperties
Ice::PropertiesPtr createProperties()
armarx::XMLRemoteStateOfferer
Definition: XMLRemoteStateOfferer.h:51
STATEOFFERERSUFFIX
#define STATEOFFERERSUFFIX
Definition: XMLStateComponent.h:33
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::XMLStateComponent::uuid
std::string uuid
Definition: XMLStateComponent.h:151
StatechartProfiles.h
armarx::XMLStateComponent::onDisconnectComponent
void onDisconnectComponent() override
Hook for subclass.
Definition: XMLStateComponent.cpp:269
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::Application::getInstance
static ApplicationPtr getInstance()
Retrieve shared pointer to the application object.
Definition: Application.cpp:315
armarx::Component::getConfigDomain
std::string getConfigDomain()
Retrieve config domain for this component as set in constructor.
Definition: Component.cpp:65
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
armarx::StatechartGroupXmlReader
Definition: GroupXmlReader.h:37
XMLStateComponent.h
armarx::XMLStateComponent::profiles
StatechartProfilesPtr profiles
Definition: XMLStateComponent.h:155
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
CMakePackageFinder.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
IceUtil::Handle
Definition: forward_declarations.h:30
armarx::AbstractFactoryMethod< XMLStateOffererFactoryBase, StatechartGroupXmlReaderPtr, XMLStateOffererFactoryBasePtr >::getAvailableClasses
static std::vector< std::string > getAvailableClasses()
getAvailableClasses retrieves a list of all registered classes as their string-representation.
Definition: AbstractFactoryMethod.h:105
armarx::ArmarXDataPath::getAbsolutePath
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
Definition: ArmarXDataPath.cpp:109
armarx::PropertyUser::getIceProperties
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
Definition: PropertyUser.cpp:221
armarx::StatechartProfiles::ReadProfileFiles
static StatechartProfilesPtr ReadProfileFiles(const std::vector< std::string > &packages)
Definition: StatechartProfiles.cpp:47
armarx::DynamicLibrary
The DynamicLibrary class provides a mechanism to load libraries at runtime.
Definition: DynamicLibrary.h:49
armarx::XMLStateComponent::iceObjName
std::string iceObjName
Definition: XMLStateComponent.h:153
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
XMLRemoteStateOfferer.h
ArmarXDataPath.h
armarx::ManagedIceObject::getCommunicator
Ice::CommunicatorPtr getCommunicator() const
Definition: ManagedIceObject.cpp:451
armarx::XMLStateComponent::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: XMLStateComponent.cpp:208
armarx::XMLStateComponent::getDefaultName
std::string getDefaultName() const override
Retrieve default name of component.
Definition: XMLStateComponent.cpp:202
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::Application::GetProjectDependencies
static const Ice::StringSeq & GetProjectDependencies()
Definition: Application.cpp:885
armarx::XMLStateComponent::loadLib
bool loadLib(std::string libPath)
Definition: XMLStateComponent.cpp:214
armarx::ArmarXManager::RegisterKnownObjectFactoriesWithIce
static void RegisterKnownObjectFactoriesWithIce(const Ice::CommunicatorPtr &ic)
Registers all object factories that are known with Ice.
Definition: ArmarXManager.cpp:1287
armarx::XMLStateComponent::selectedProfile
StatechartProfilePtr selectedProfile
Definition: XMLStateComponent.h:156
Application.h
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:38