26 #include "../../StatechartViewerPlugin/model/stateinstance/RegularState.h"
27 #include "../../StatechartViewerPlugin/model/DynamicRemoteStateClass.h"
39 iceCommunicator(iceCommunicator),
44 QByteArray utf8Xml = xmlString.toUtf8();
57 QString version = readAttribute(stateNode,
"version");
59 if (version !=
"1.0" && version !=
"1.1" && version !=
"1.2")
61 throw XmlReaderException(
"Only statechart XML definition version 1.0 - 1.2 are supported right now!");
74 loadedState->setStateName(readAttribute(stateNode,
"name"));
75 loadedState->setSize(QSizeF(readAttribute(stateNode,
"width").
toFloat(), readAttribute(stateNode,
"height").
toFloat()));
76 loadedState->setDescription(readDescription(stateNode));
84 while ((curNode = inputParameterNI.
getNext()))
86 parameterList.unite(readParameterList(curNode));
89 loadedState->setInputParameters(parameterList);
91 parameterList.clear();
95 while ((curNode = localParameterNI.
getNext()))
97 parameterList.unite(readParameterList(curNode));
100 loadedState->setLocalParameters(parameterList);
102 parameterList.clear();
104 XmlNodeIterator outputParameterNI(stateNode,
"OutputParameters",
false);
106 while ((curNode = outputParameterNI.
getNext()))
108 parameterList.unite(readParameterList(curNode));
111 loadedState->setOutputParameters(parameterList);
116 while ((curNode = substatesNI.
getNext()))
118 substateList.unite(readSubstateList(curNode));
121 loadedState->replaceSubstates(substateList);
126 while ((curNode = eventNI.
getNext()))
128 eventList.append(readEventList(curNode));
131 loadedState->setOutgoingEvents(eventList);
137 readStartState(startStateNode);
143 while ((curNode = transitionNI.
getNext()))
145 transitionList.append(readTransitionList(curNode));
148 loadedState->replaceTransitions(transitionList);
156 return descriptionNode ? QString::fromUtf8(descriptionNode->value()) :
"";
166 while ((curNode = eventNI.getNext()))
169 event->name = readAttribute(curNode,
"name");
170 event->description = readDescription(curNode);
172 for (EventList::const_iterator i = eventList.begin(); i != eventList.end(); ++i)
174 if ((*i)->name == event->name)
180 eventList.append(event);
193 while ((curNode = parameterNI.getNext()))
196 stateParameter->type = readAttribute(curNode,
"type");
198 stateParameter->description = readDescription(curNode);
201 stateParameter->setDefaultValueJson(readAttribute(curNode,
"default",
false));
203 if (!stateParameter->getDefaultValueJson().isEmpty())
205 std::function<bool(std::string, std::string)> loadVar;
206 loadVar = [&](std::string curType, std::string prevType)
208 if (curType == prevType)
216 jsonObject->fromString(stateParameter->getDefaultValueJson().toUtf8().data());
219 {VariantContainerBasePtr::dynamicCast(jsonObject->deserializeIceObject()), stateParameter->getDefaultValueJson()};
222 catch (Ice::NoValueFactoryException& e)
224 ARMARX_INFO_S <<
"Variant missing - trying to load variant " << e.type <<
" now";
225 info->loadLibraryOfVariant(e.type);
227 return loadVar(e.type, curType);
236 catch (exceptions::user::UnknownTypeException& e)
238 ARMARX_WARNING_S <<
"Could not deserialize JSONString for type " << stateParameter->type;
240 catch (
const armarx::JSONException& e)
242 throw XmlReaderException(
"Could not parse JSON: " + stateParameter->getDefaultValueJson().toStdString());
251 while ((defaultValueCurNode = defaultValueNI.getNext()))
253 QString profileName = readAttribute(defaultValueCurNode,
"profile",
false);
255 if (profileName.size() == 0)
260 QString valueJson = readAttribute(defaultValueCurNode,
"value",
true);
261 VariantContainerBasePtr valueVariant;
262 std::function<bool(std::string, std::string)> loadVar;
263 loadVar = [&](std::string curType, std::string prevType)
265 if (curType == prevType)
273 jsonObject->fromString(valueJson.toUtf8().data());
275 valueVariant = VariantContainerBasePtr::dynamicCast(jsonObject->deserializeIceObject());
277 catch (Ice::NoValueFactoryException& e)
279 ARMARX_INFO_S <<
"Variant missing - trying to load variant " << e.type <<
" now";
280 info->loadLibraryOfVariant(e.type);
282 return loadVar(e.type, curType);
291 catch (exceptions::user::UnknownTypeException& e)
293 ARMARX_WARNING_S <<
"Could not deserialize JSONString for type " << stateParameter->type;
295 catch (
const armarx::JSONException& e)
300 stateParameter->profileDefaultValues[profileName] = QPair<VariantContainerBasePtr, QString>(valueVariant, valueJson);
303 QString optionalStr = readAttribute(curNode,
"optional");
305 if (optionalStr ==
"yes")
307 stateParameter->optional =
true;
309 else if (optionalStr ==
"no")
311 stateParameter->optional =
false;
315 throw XmlReaderException(
"\"optional\" attribute must have value \"yes\" or \"no\"!");
318 QString parameterName = readAttribute(curNode,
"name");
320 if (stateParameterMap.contains(parameterName))
325 stateParameterMap[parameterName] = stateParameter;
328 return stateParameterMap;
336 XmlNodeIterator parameterMappingNI(parameterMappingListNode,
"ParameterMapping",
false);
338 while ((curNode = parameterMappingNI.getNext()))
341 parameterMapping->sourceKey = readAttribute(curNode,
"from");
342 parameterMapping->destinationKey = readAttribute(curNode,
"to");
344 QString mappingSourceString = readAttribute(curNode,
"sourceType");
347 if (parameterMapping->source == eMappingSourcesCount)
349 throw XmlReaderException(
"Unknown value for sourceType: \"" + mappingSourceString.toStdString() +
"\"");
357 while ((defaultValueCurNode = defaultValueNI.getNext()))
359 QString profileName = readAttribute(defaultValueCurNode,
"profile",
false);
361 if (profileName.size() == 0)
366 QString valueJson = readAttribute(defaultValueCurNode,
"value",
true);
367 parameterMapping->profileValues[profileName] = valueJson;
371 parameterMappingList.append(parameterMapping);
374 return parameterMappingList;
379 loadedState->setStartState(getSubstateByInstanceName(readAttribute(startStateNode,
"substateName")));
383 if (parameterMappingsNode)
385 loadedState->setStartStateInputMapping(readParameterMappingList(parameterMappingsNode));
389 SupportPoints points;
390 if (supportPointsNode)
393 XmlNodeIterator supportPointNI(supportPointsNode,
"SupportPoint",
false);
395 while ((supportPointNode = supportPointNI.getNext()))
397 QPointF supportPoint(readAttribute(supportPointNode,
"posX").
toFloat(), readAttribute(supportPointNode,
"posY").
toFloat());
399 supportPoints.append(supportPoint);
401 points.setControlPoints(supportPoints);
402 loadedState->setTransitionSupportPoints(transition, points);
416 if (!stateInstanceFactory)
418 throw XmlReaderException(
"Invalid substate type: \"" + std::string(curNode->name()) +
"\"");
423 QString stateInstanceName = stateInstance->getInstanceName();
425 if (stateInstanceMap.contains(stateInstanceName))
427 throw XmlReaderException(
"Duplicate substate name: " + stateInstanceName.toStdString());
430 stateInstanceMap[stateInstanceName] = stateInstance;
435 return stateInstanceMap;
445 while ((curNode = transitionNI.getNext()))
449 QString sourceStateName = readAttribute(curNode,
"from");
450 QString eventName = readAttribute(curNode,
"eventName");
452 if (!hasSubstateByInstanceName(sourceStateName))
454 ARMARX_WARNING_S <<
"Skipping broken transition in state '" << loadedState->getStateName().toStdString() <<
"'. SourceState '"
455 << sourceStateName <<
"' of event '" << eventName <<
"' could not be found in the list of substates. State UUID=" << loadedState->getUUID()
456 <<
".\nStatechart group information or state path are not available at this point. Sorry. Use grep.";
460 transition->sourceState = getSubstateByInstanceName(sourceStateName);
461 transition->destinationState = getSubstateByInstanceName(readAttribute(curNode,
"to",
false));
462 transition->eventName = eventName;
463 transition->transitionUserCode = readAttribute(curNode,
"transitionCodeEnabled",
false) ==
"1";
467 if (parameterMappingsNode)
469 transition->mappingToNextStatesInput = readParameterMappingList(parameterMappingsNode);
474 if (parameterMappingsNode)
476 transition->mappingToParentStatesLocal = readParameterMappingList(parameterMappingsNode);
481 if (parameterMappingsNode)
483 transition->mappingToParentStatesOutput = readParameterMappingList(parameterMappingsNode);
488 if (supportPointsNode)
491 XmlNodeIterator supportPointNI(supportPointsNode,
"SupportPoint",
false);
493 while ((supportPointNode = supportPointNI.getNext()))
495 QPointF supportPoint(readAttribute(supportPointNode,
"posX").
toFloat(), readAttribute(supportPointNode,
"posY").
toFloat());
497 supportPoints.append(supportPoint);
499 transition->supportPoints.setControlPoints(supportPoints);
502 transitionList.append(transition);
505 return transitionList;
508 bool XmlReader::hasSubstateByInstanceName(
const QString& name)
const
515 return loadedState->getSubstates().contains(name);
518 StateInstancePtr XmlReader::getSubstateByInstanceName(
const QString& name)
const
527 if (!substates.contains(name))
529 std::stringstream ss;
530 ss <<
"Available substates (";
531 ss << substates.size();
534 for (QString
s : substates.keys())
536 ss <<
s.toStdString() <<
"; ";
539 throw XmlReaderException(
"Referenced substate \"" + name.toStdString() +
"\" not found in State \"" + loadedState->getStateName().toStdString() +
"\"! " + ss.str());
542 return substates[name];
545 QString XmlReader::readAttribute(
rapidxml::xml_node<>* node,
const QString& attributeName,
bool required)
const
553 throw XmlReaderException(
"Attribute \"" + attributeName.toStdString() +
"\" for \"" + node->name() +
"\" node not found!");
561 return QString::fromUtf8(attribute->value());
565 parentNode(parentNode),
568 nodeNameUtf8(nodeName.
toUtf8()),
569 required(required) {}
573 if (currentChildNode)
582 currentChildNode = nextChildNode;
586 currentChildNode = parentNode->
first_node(nodeNameUtf8.data());
588 if (required && !currentChildNode)
590 throw XmlReaderException(
"Required node \"" + nodeName.toStdString() +
"\" not found!");
594 return currentChildNode;