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 <random>
26 
27 #include "XMLStateComponent.h"
28 #include "GroupXmlReader.h"
29 #include "XMLRemoteStateOfferer.h"
30 #include <IceUtil/UUID.h>
36 #include "../StatechartEventDistributor.h"
37 
38 #include <Ice/Properties.h>
39 
40 #include <SimoxUtility/algorithm/string/string_tools.h>
41 
42 namespace armarx
43 {
44 
46  {
47  uuid = IceUtil::generateUUID();
48  }
49 
51  {
52  std::string groupFilepathString = PropertyUser::getProperty<std::string>("XMLStatechartGroupDefinitionFile").getValue();
53  std::string profileName = PropertyUser::getProperty<std::string>("XMLStatechartProfile").getValue();
54 
55  //std::string profileDefinitionFilepath = PropertyUser::getProperty<std::string>("XMLStatechartProfile").getValue();
57  selectedProfile = profiles->getProfileByName(profileName);
58 
59  if (!selectedProfile)
60  {
61  throw LocalException("Could not find profile '" + profileName + "'");
62  }
63 
64  ARMARX_IMPORTANT << "Using profile " << selectedProfile->getFullName();
65 
66 
67 
68 
69  Ice::StringSeq includePaths;
71  packages.push_back(Application::GetProjectName());
72 
73  for (const std::string& projectName : packages)
74  {
75  if (projectName.empty())
76  {
77  continue;
78  }
79 
80  CMakePackageFinder project(projectName);
81  auto pathsString = project.getIncludePaths();
82  Ice::StringSeq projectIncludePaths = simox::alg::split(pathsString, ";,");
83  includePaths.insert(includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
84 
85  }
86 
88 
89  ArmarXDataPath::getAbsolutePath(groupFilepathString, groupFilepathString, includePaths);
90  reader->readXml(std::filesystem::path(groupFilepathString));
91 
92  auto extraProperties = reader->getConfigurationFileContent();
93  if (!extraProperties.empty())
94  {
95  auto props = Ice::createProperties();
96  std::filesystem::path temp = std::filesystem::temp_directory_path() / std::to_string(std::random_device{}());
97  temp += ".cfg";
98  std::ofstream file(temp.string().c_str());
99  file << extraProperties;
100  file.close();
101  props->load(temp.string());
102  std::filesystem::remove(temp);
103  for (auto& prop : props->getPropertiesForPrefix(""))
104  {
105  tryAddProperty(prop.first, prop.second);
106  }
107  }
108  CMakePackageFinder pack(reader->getPackageName());
109 
110  if (pack.packageFound())
111  {
112  std::string libPath = "lib" + reader->getGroupName() + ".so";
113 
114  std::string libPaths = pack.getLibraryPaths();
115  std::vector<std::string> libpathList = simox::alg::split(libPaths, ";");
116 
117  std::string libPathNextGen = "lib" + reader->getPackageName() + "_" + reader->getGroupName() + ".so";
118 
119  if (ArmarXDataPath::getAbsolutePath(libPath, libPath, libpathList, false))
120  {
121  loadLib(libPath);
123  }
124  else if (ArmarXDataPath::getAbsolutePath(libPathNextGen, libPathNextGen, libpathList, false))
125  {
126  loadLib(libPathNextGen);
128  }
129  else
130  {
131  ARMARX_ERROR << "Could not find state user code lib file `" << libPath << "` or `" << libPathNextGen << "`";
132  }
133  }
134 
135  offererName = reader->getGroupName() + STATEOFFERERSUFFIX;
136  offerer = XMLStateOffererFactoryBase::fromName(reader->getGroupName() + STATEOFFERERSUFFIX, reader);
137  if (!offerer)
138  {
139  ARMARX_WARNING << "Could not find XMLRemoteStateOfferer with name " << offererName << "\nAvailable classes are:\n" << XMLStateOffererFactoryBase::getAvailableClasses();
140  offerer = new XMLRemoteStateOfferer<>(reader);
141  }
142 
143  if (PropertyUser::getProperty<std::string>("XMLRemoteStateOffererName").isSet())
144  {
145  offererName = PropertyUser::getProperty<std::string>("XMLRemoteStateOffererName").getValue();
146  }
147  }
148 
150  {
151  ComponentPtr obj = ComponentPtr::dynamicCast(offerer);
152  obj->forceComponentCreatedByComponentCreateFunc();
153  StatechartContextPtr::dynamicCast(offerer)->setReportingTopic(getProperty<std::string>("StateReportingTopic").getValue());
154  obj->initializeProperties(offererName, getIceProperties(), getConfigDomain());
155  if (getProperty<bool>("EnableProfiling").getValue() && !obj->getProperty<bool>("EnableProfiling").isSet())
156  {
157  obj->enableProfiler(true);
158  }
159 
160  bool usePrx = false;
161  iceObjName = selectedProfile->getStatechartGroupPrefix() + obj->getName();
162  if (getArmarXManager()->getIceManager()->isObjectReachable(iceObjName))
163  {
164  ARMARX_INFO << "Using already running proxy: " << iceObjName;
165  usePrx = true;
166  }
167  else
168  {
169  getArmarXManager()->addObject(obj, false, iceObjName);
170  }
171 
172  for (auto state : Split(getProperty<std::string>("StatesToEnter").getValue(), ",", true, true))
173  {
174  simox::alg::trim(state);
175  if (state == "")
176  {
177  continue;
178  }
179  createAndEnterInstance(state, usePrx);
180  }
181  }
182 
184  {
185  return "XMLStateComponent";
186  }
187 
189  {
191  }
192 
193 
194  bool XMLStateComponent::loadLib(std::string libPath)
195  {
196  if (!ArmarXDataPath::getAbsolutePath(libPath, libPath))
197  {
198  ARMARX_ERROR << "Could not find state user code lib file: " << libPath;
199  return false;
200  }
201 
202  if (libraries.find(libPath) != libraries.end())
203  {
204  return true;
205  }
206 
207  try
208  {
210  ARMARX_VERBOSE << "Loading lib: " << libPath;
211  lib->load(libPath);
212  libraries[libPath] = lib;
213  }
215  {
216  ARMARX_ERROR << "Library loading failed: " << e.what();
217  return false;
218  }
219 
220  return true;
221  }
222 
223  void XMLStateComponent::createAndEnterInstance(const std::string& stateClassName, bool useExisitingPrx)
224  {
225  if (useExisitingPrx)
226  {
227  RemoteStateOffererInterfacePrx off = getArmarXManager()->getIceManager()->getProxy<RemoteStateOffererInterfacePrx>(iceObjName);
228  auto stateId = off->createRemoteStateInstance(stateClassName, nullptr, "TopLevel", stateClassName);
229  off->callRemoteState(stateId, StringVariantContainerBaseMap());
230  stateIDStartedUsingExisitingPrx = stateId;
231  }
232  else
233  {
234  StatechartContextPtr context = StatechartContextPtr::dynamicCast(offerer);
235  context->getObjectScheduler()->waitForObjectState(eManagedIceObjectStarted);
236  RemoteStateOffererIceBasePtr off = RemoteStateOffererIceBasePtr::dynamicCast(offerer);
237  auto stateId = off->createRemoteStateInstance(stateClassName, nullptr, "TopLevel", stateClassName);
238  off->callRemoteState(stateId, StringVariantContainerBaseMap());
239  }
240  }
241 
243  {
244  if (getArmarXManager()->getIceManager()->isObjectReachable(iceObjName))
245  {
246  RemoteStateOffererInterfacePrx off = getArmarXManager()->getIceManager()->getProxy<RemoteStateOffererInterfacePrx>(iceObjName);
247  if (stateIDStartedUsingExisitingPrx != -1 && off->getAvailableStateInstances().count(stateIDStartedUsingExisitingPrx) != 0)
248  {
249  ARMARX_DEBUG << "Exiting state with id: " << stateIDStartedUsingExisitingPrx << " which has been started using already running proxy.";
250  off->breakActiveSubstateRemotely(stateIDStartedUsingExisitingPrx, nullptr);
251  off->breakRemoteState(stateIDStartedUsingExisitingPrx, nullptr);
252  off->removeInstance(stateIDStartedUsingExisitingPrx);
253  }
254  }
255  }
256 }
armarx::XMLStateComponent::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: XMLStateComponent.cpp:149
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:353
armarx::Application::GetProjectName
static const std::string & GetProjectName()
Definition: Application.cpp:861
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::CMakePackageFinder::packageFound
bool packageFound() const
Returns whether or not this package was found with cmake.
Definition: CMakePackageFinder.cpp:485
armarx::DynamicLibraryPtr
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr
Definition: DynamicLibrary.h:123
ArmarXManager.h
armarx::XMLStateComponent::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: XMLStateComponent.cpp:50
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:35
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:348
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:76
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:53
armarx::XMLStateComponent::offererName
std::string offererName
Definition: XMLStateComponent.h:135
armarx::CMakePackageFinder::getLibraryPaths
std::string getLibraryPaths() const
Returns the library paths seperated by semi-colons.
Definition: CMakePackageFinder.h:128
GroupXmlReader.h
armarx::XMLStateComponent::libraries
std::map< std::string, DynamicLibraryPtr > libraries
Definition: XMLStateComponent.h:133
armarx::PropertyUser::tryAddProperty
bool tryAddProperty(const std::string &propertyName, const std::string &value)
Definition: PropertyUser.cpp:209
project
std::string project
Definition: VisualizationRobot.cpp:83
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:137
armarx::StatechartGroupXmlReaderPtr
std::shared_ptr< StatechartGroupXmlReader > StatechartGroupXmlReaderPtr
Definition: GroupXmlReader.h:89
armarx::XMLStateComponentProperties
Definition: XMLStateComponent.h:41
armarx::XMLStateComponent::createAndEnterInstance
void createAndEnterInstance(const std::string &stateClassName, bool useExisitingPrx=false)
Definition: XMLStateComponent.cpp:223
armarx::XMLStateComponent::XMLStateComponent
XMLStateComponent()
Definition: XMLStateComponent.cpp:45
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:177
armarx::XMLStateComponent::uuid
std::string uuid
Definition: XMLStateComponent.h:134
StatechartProfiles.h
armarx::XMLStateComponent::onDisconnectComponent
void onDisconnectComponent() override
Hook for subclass.
Definition: XMLStateComponent.cpp:242
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::Application::getInstance
static ApplicationPtr getInstance()
Retrieve shared pointer to the application object.
Definition: Application.cpp:289
armarx::Component::getConfigDomain
std::string getConfigDomain()
Retrieve config domain for this component as set in constructor.
Definition: Component.cpp:60
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::StatechartGroupXmlReader
Definition: GroupXmlReader.h:38
XMLStateComponent.h
armarx::XMLStateComponent::profiles
StatechartProfilesPtr profiles
Definition: XMLStateComponent.h:138
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
CMakePackageFinder.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
IceUtil::Handle< class PropertyDefinitionContainer >
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:99
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:111
armarx::PropertyUser::getIceProperties
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
Definition: PropertyUser.cpp:229
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:136
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
XMLRemoteStateOfferer.h
ArmarXDataPath.h
armarx::ManagedIceObject::getCommunicator
Ice::CommunicatorPtr getCommunicator() const
Definition: ManagedIceObject.cpp:431
armarx::XMLStateComponent::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: XMLStateComponent.cpp:188
armarx::XMLStateComponent::getDefaultName
std::string getDefaultName() const override
Retrieve default name of component.
Definition: XMLStateComponent.cpp:183
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::Application::GetProjectDependencies
static const Ice::StringSeq & GetProjectDependencies()
Definition: Application.cpp:868
armarx::XMLStateComponent::loadLib
bool loadLib(std::string libPath)
Definition: XMLStateComponent.cpp:194
armarx::ArmarXManager::RegisterKnownObjectFactoriesWithIce
static void RegisterKnownObjectFactoriesWithIce(const Ice::CommunicatorPtr &ic)
Registers all object factories that are known with Ice.
Definition: ArmarXManager.cpp:1204
armarx::XMLStateComponent::selectedProfile
StatechartProfilePtr selectedProfile
Definition: XMLStateComponent.h:139
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:36