Commit bf9718e4 authored by ics's avatar ics

Merge Branch V3.1 into master

parent d6953a69
......@@ -9,6 +9,6 @@ Makefile.in
mod
obj
.project
.settings
share
/build/
.settings/
* Corrected bug: crash occurred when pausing a controller that had no pause command.
* Add virtual inheritance for base classes *Properties in Count (TimeCountProperties, KineticCountProperties...). That implied to add init function and empty constructor in some classes.
* Replaced protocol buffers array encoding with Xavier training's project to speed up the transfers.
* Implemented the logging of properties when set from the client. PropertyRefresher refactored: PropertyContainer is a new base class.
......
......@@ -18,7 +18,7 @@ AC_DEFUN([AC_NEXUS],
for nexus_path_tmp in $nexus_possible_path ; do
# test include
CXXFLAGS="$CXXFLAGS -I$nexus_path_tmp/include"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <napi.h>]],[[]])],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <nexus/napi.h>]],[[]])],
[NEXUS_CFLAGS="-I$nexus_path_tmp/include"
NEXUS_LIBS="-L$nexus_path_tmp/lib"
nexus_found=yes]
......@@ -37,7 +37,7 @@ AC_DEFUN([AC_NEXUS],
# search for library
LIBS="$LIBS $NEXUS_LIBS -lNeXus"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <napi.h>]],
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <nexus/napi.h>]],
[[]])],
[ nexus_found=yes],
[ nexus_found=no])
......
......@@ -18,24 +18,26 @@
#include "common/base/ServerProperties.h"
#include "ics/Module/ModuleManager.h"
#include "ics/DataProvider/Property/XMLFileCollector.h"
#include "ics/DataProvider/Property/PropertyInfos.h"
#include <iostream>
#include <cstdlib>
#include <sstream>
#include "common/connection/HttpConnection.h"
using namespace std;
using namespace common;
int main(int argc, char* argv[]) {
ServerProperties::initInstance(".");
ServerProperties::initInstance("");
XMLFileCollector::initInstance();
ModuleManager::initInstance();
try {
ModuleManager::getInstance()->loadModulesFromSequence(ServerProperties::getInstance()->getNomadHomePath() + "/mod");
} catch (const Exception & e) {
cout << "unable to find modules path" << endl;
cout << "Unable to find the modules path." << endl;
}
// select the module to test
......@@ -45,19 +47,19 @@ int main(int argc, char* argv[]) {
if (argc > 1) {
moduleName = argv[1];
} else {
cout << "enter a module name:";
cout << "Enter a module name:";
getline(cin, moduleName);
}
cout << "testing " << moduleName << endl;
cout << "Testing " << moduleName << endl;
// test existence of module
bool success = ModuleManager::getInstance()->testModule(moduleName);
if (success) {
cout << "success" << endl;
cout << "Success." << endl;
} else {
cout << "failure" << endl;
cout << "Failure." << endl;
}
ModuleManager::resetInstance();
......
......@@ -18,7 +18,7 @@
#include "LMFit.h"
#include <cminpack.h>
#include <cminpack-1/cminpack.h>
#include <math.h>
#include <sstream>
......
......@@ -338,7 +338,7 @@ void MultiGaussPeakFinder::findPeaks(const Array<double, 1>& y, const Array<doub
ostream& operator<<(ostream &os, const MultiGaussPeakFinder& fit) {
os << string(false);
os << fit.string(false);
return os;
}
......
......@@ -31,6 +31,7 @@
#include <fstream>
#include <blitz/array.h>
#include <math.h>
#include <string>
#include "RoughPeakFinder.h"
#include "Peak.h"
......
......@@ -17,7 +17,7 @@
*/
#include "PolynomialPeakFinder.h"
#include <cminpack.h>
#include <cminpack-1/cminpack.h>
BZ_USING_NAMESPACE(blitz)
......
......@@ -63,7 +63,7 @@ std::vector<std::string> FileUtilities::getFilesWithExtension(const std::string&
}
} else {
throw NoSuchDirectoryException("cannot read \"" + pathName + "\"");
throw NoSuchDirectoryException("cannot read " + pathName);
}
return fileNames;
......@@ -104,7 +104,7 @@ std::vector<fs::path> FileUtilities::getFilePathsWithExtension(const std::string
}
} else {
throw NoSuchDirectoryException("cannot read \"" + pathName + "\"");
throw NoSuchDirectoryException("cannot read " + pathName);
}
return filePaths;
......@@ -132,7 +132,7 @@ std::string FileUtilities::getFileName(fs::path& path1, const std::string& name,
if (fs::is_directory(file) == true) {
if (defaultname.empty()) {
throw NotRegularFile("cannot read \"" + file.string() + "\"");
throw NotRegularFile("cannot read " + file.string());
}
file /= defaultname;
}
......@@ -142,7 +142,7 @@ std::string FileUtilities::getFileName(fs::path& path1, const std::string& name,
}
if (fs::is_regular_file(file) == false) {
throw NotRegularFile("cannot read \"" + file.string() + "\"");
throw NotRegularFile("cannot read " + file.string());
}
return file.string();
......@@ -159,7 +159,7 @@ std::string FileUtilities::getDirectoryName(fs::path& path1, const std::string&
}
if (fs::is_directory(path3) == false) {
throw NoSuchDirectoryException("cannot read \"" + path3.string() + "\"");
throw NoSuchDirectoryException("cannot read " + path3.string());
}
return path3.string();
......
......@@ -55,6 +55,8 @@ message Message {
GetFamilyImageKeys = 23;
GetControllerIconKeys = 24;
UserLog = 25;
}
required Type type = 1;
......@@ -96,3 +98,9 @@ message WriteResourceRequest {
required string fileName = 2;
required string content = 3;
}
message UserLogRequest {
required string userName = 1;
required string message = 2;
}
......@@ -24,6 +24,8 @@
#include <core/dataaccess/DataAccess.h>
#include <core/transportlayer/dataprovider/ServantAccessor.h>
#include <core/transportlayer/dataprovider/PropertyAccessor.h>
#include <dataprovider/transportlayer/dataprovider/ServantAccessorDirectImpl.h>
#include <dataprovider/transportlayer/dataprovider/PropertyAccessorDirectImpl.h>
#include <boost/lexical_cast.hpp>
#include <math.h>
#include <string>
......@@ -126,12 +128,18 @@ void BooleanExpression::init() {
bool BooleanExpression::evaluate() {
// get the property values
for (map<string, BaseValueWrapper*>::iterator p = _values.begin(); p != _values.end(); ++p) {
p->second->getValue();
}
try {
// get the property values
for (map<string, BaseValueWrapper*>::iterator p = _values.begin(); p != _values.end(); ++p) {
p->second->getValue();
}
return (_parser->Eval() != 0.0);
return (_parser->Eval() != 0.0);
} catch (...) {
cerr << "Error while evaluating the expression, check the expression '" << _expression << "'" << endl;
return false;
}
}
void BooleanExpression::setVariableValue(const std::string& variableName, double value) {
......@@ -262,13 +270,23 @@ double * BooleanExpression::addValue(const char * valueName, void * pUserData) {
message += servantName + "' does not exist";
throw ParserError(message);
} catch (dataprovider::ServantAccessorDirectImpl::NoSuchServantException const & e) {
string message("servant with name '");
message += servantName + "' does not exist";
throw ParserError(message);
} catch (PropertyAccessor::NoSuchPropertyException const & e) {
string message("servant with name '");
message += servantName + "' has no property '" + propertyName + "'";
throw ParserError(message);
} catch (Exception const & e) {
throw e;
} catch (dataprovider::PropertyAccessorDirectImpl::NoSuchPropertyException const & e) {
string message("servant with name '");
message += servantName + "' has no property '" + propertyName + "'";
throw ParserError(message);
} catch (...) {
throw ParserError("unknown error");
}
}
}
......
INCLUDES = -I$(top_srcdir)/src -I/usr/java/default/include -I/usr/java/default/include/linux -I/usr/lib/jvm/default-java/include
INCLUDES = -I$(top_srcdir)/src -I/usr/java/default/include -I/usr/java/default/include/linux -I/usr/lib/jvm/jdk10.0.1/include -I/usr/lib/jvm/jdk10.0.1/include/linux
SRC_PATH = $(top_srcdir)/src/core/clientcalculator
FILE_PATH = $(SRC_PATH)/fr/ill/ics/bridge
JAVAC = javac
JAVAC_OPTIONS =
JAVAH = javah
JAVAH_OPTIONS = -classpath $(SRC_PATH) -o $(SRC_PATH)/ClientCalculator.h
lib_LTLIBRARIES = libclientcalculator.la
libclientcalculator_la_SOURCES = \
ClientCalculator.cpp
fr_ill_ics_bridge_ClientCalculator.cpp
libclientcalculator_la_CPPFLAGS = \
$(NOMAD_CXXFLAGS)
......@@ -25,12 +22,9 @@ libclientcalculator_la_LIBADD = \
$(CMINPACK_LIB)
ClientCalculator.cpp: ClientCalculator.h
fr_ill_ics_bridge_ClientCalculator.cpp: fr_ill_ics_bridge_ClientCalculator.h
# problem with the $(FILE_PATH)/ClientCalculator.class target, due to path that is not .
ClientCalculator.h: $(FILE_PATH)/ClientCalculator.class
$(JAVAH) $(JAVAH_OPTIONS) fr.ill.ics.bridge.ClientCalculator
$(FILE_PATH)/ClientCalculator.class: $(FILE_PATH)/ClientCalculator.java
$(JAVAC) $(JAVAC_OPTIONS) $(FILE_PATH)/ClientCalculator.java
fr_ill_ics_bridge_ClientCalculator.h:
$(JAVAC) -h $(SRC_PATH) $(FILE_PATH)/ClientCalculator.java
\ No newline at end of file
......@@ -16,7 +16,7 @@
* limitations under the Licence.
*/
#include "ClientCalculator.h"
#include "fr_ill_ics_bridge_ClientCalculator.h"
#include "common/analysislibrary/MultiGaussPeakFinder.h"
#include "common/analysislibrary/ExponentialFit.h"
#include "common/analysislibrary/SimpleGaussFinder.h"
......@@ -186,4 +186,4 @@ JNIEXPORT jdoubleArray JNICALL Java_fr_ill_ics_bridge_ClientCalculator_simpleGau
return resultsArray;
}
\ No newline at end of file
}
......@@ -359,7 +359,7 @@ std::string AtomicCommandBox::toXMLString(const std::string& space) const {
unsigned long controllerID = DataAccess::getInstance()->getServantIDFromCommandID(getExecutionDatabaseID(), _commandID);
string controllerName = DataAccess::getInstance()->getServantName(getExecutionDatabaseID(), controllerID);
return space + "<atomic controller=\"" + controllerName + "\" id=\"" + to<string>(getID()) + "\" logId=\"" + to<string>(logID()) + "\" commandId=\"" + to<string>(_commandID) + "\" isSettings=\"" + to<string>(_isSettings) + "\"/>";
return space + "<atomic controller=\"" + controllerName + "\" id=\"" + to<string>(getID()) + "\" logId=\"" + to<string>(logID()) + "\" commandId=\"" + to<string>(_commandID) + "\" isSettings=\"" + to<string>(_isSettings) + "\" settingsFile=\"" + to<string>(_settingsFileName) + "\"/>";
}
std::string AtomicCommandBox::toString(const std::string& space) const {
......
......@@ -188,12 +188,13 @@ public:
*/
virtual ConditionElement * toConditionElement() = 0;
void notify();
protected:
void setState(common::ConditionState state);
bool actualValue() const;
bool oldValue() const;
bool isFirst() const;
void notify();
void resetAndCheck();
boost::recursive_mutex _mutex;
......
......@@ -542,7 +542,7 @@ std::string ConditionManager::toString() {
void ConditionManager::writeConditionManagerFile() {
// write the file
ofstream conditionFile(_conditionManagerConfigFileName.c_str(), ios::out);
std::ofstream conditionFile(_conditionManagerConfigFileName.c_str(), ios::out);
conditionFile << toXMLString() << endl;
conditionFile.close();
......
......@@ -119,13 +119,17 @@ void Sender::pauseCommand(unsigned long databaseID, unsigned long commandID) {
unsigned long pauseCommandID = DataAccess::getInstance()->getSisterCommandID(databaseID, commandID, "pause");
// starting the associated stop command
newCommand(databaseID, pauseCommandID, false);
if (pauseCommandID != 0) {
newCommand(databaseID, pauseCommandID, false);
} else {
cout << "cannot pause command <" << commandID << ">" << endl;
}
} else {
Scheduler::getInstance()->requestPauseCommand(databaseID, commandID, requestID);
}
} catch (Exception & e) {
err << "cannot pause command : " << e.printStack() << eol;
err << "cannot pause command <" << commandID << "> : " << e.printStack() << eol;
}
}
......@@ -140,13 +144,17 @@ void Sender::restartCommand(unsigned long databaseID, unsigned long commandID) {
unsigned long restartCommandID = DataAccess::getInstance()->getSisterCommandID(databaseID, commandID, "continue");
// starting the associated stop command
newCommand(databaseID, restartCommandID, false);
if (restartCommandID != 0) {
newCommand(databaseID, restartCommandID, false);
} else {
cout << "cannot restart command <" << commandID << ">" << endl;
}
} else {
Scheduler::getInstance()->requestRestartCommand(databaseID, commandID, requestID);
}
} catch (Exception & e) {
err << "cannot restart command : " << e.printStack() << eol;
err << "cannot restart command <" << commandID << "> : " << e.printStack() << eol;
}
}
......
......@@ -23,7 +23,6 @@
#include <core/conditions/ConditionManager.h>
using namespace std;
using namespace boost;
using namespace cameo;
namespace core {
......@@ -40,7 +39,7 @@ void ConditionManagerResponder::init() {
m_responder = application::Responder::create("condition_manager");
// Start the thread.
m_thread.reset(new thread(bind(&ConditionManagerResponder::loop, this)));
m_thread.reset(new boost::thread(boost::bind(&ConditionManagerResponder::loop, this)));
cout << "Initialised ConditionManagerResponder" << endl;
}
......
......@@ -28,6 +28,8 @@
#include <ics/InstrumentManager/HardwareManager.h>
#include <ics/InstrumentManager/InstrumentManager.h>
#include <ics/Module/ModuleManager.h>
#include <core/log/LogHandler.h>
#include <core/log/SimpleLog.h>
using namespace std;
using namespace boost;
......@@ -91,6 +93,7 @@ void ServantManagerResponder::initProcessFunctions() {
m_processFunctions[servantmanager::Message::GetServantCommandsState] = &ServantManagerResponder::processGetServantCommandsState;
m_processFunctions[servantmanager::Message::GetFamilyImageKeys] = &ServantManagerResponder::processGetFamilyImageKeys;
m_processFunctions[servantmanager::Message::GetControllerIconKeys] = &ServantManagerResponder::processGetControllerIconKeys;
m_processFunctions[servantmanager::Message::UserLog] = &ServantManagerResponder::processUserLog;
}
void ServantManagerResponder::processGetWholeConfiguration(const std::string & message, std::string & response) {
......@@ -483,6 +486,27 @@ void ServantManagerResponder::processGetControllerIconKeys(const std::string & m
responseMessage.SerializeToString(&response);
}
void ServantManagerResponder::processUserLog(const std::string & message, std::string & response) {
servantmanager::UserLogRequest messageRequest;
messageRequest.ParseFromString(message);
common::BooleanResponse responseMessage;
// Log the message.
string logMessage = "";
if (!messageRequest.username().empty()) {
logMessage += messageRequest.username() + " : ";
}
logMessage += messageRequest.message();
LogHandler::getInstance()->write(SimpleLog(common::LOG_INFO, logMessage));
responseMessage.set_value(true);
// Serialize the response.
responseMessage.SerializeToString(&response);
}
void ServantManagerResponder::loop() {
......
......@@ -93,6 +93,8 @@ private:
void processGetFamilyImageKeys(const std::string & message, std::string & response);
void processGetControllerIconKeys(const std::string & message, std::string & response);
void processUserLog(const std::string & message, std::string & response);
dataprovider::ServantAccessorDirectImpl* m_servantAccessor;
std::auto_ptr<boost::thread> m_thread;
......
......@@ -1351,6 +1351,9 @@ private:
std::map<PropertyInfoKey, PropertyInfoItem, PropertyInfoComparator> _setpointPropertyInfoMap;
std::map<PropertyInfoKey, PropertyInfoItem, PropertyInfoComparator> _noSetpointPropertyInfoMap;
template<typename>
friend struct DatabaseGetter;
};
}
......
......@@ -199,26 +199,82 @@ void Database::setIcsArraySize(unsigned long propertyID, long size) {
}
}
/**
* Template class to manage special case:
* A client can request a string value whereas the real type is not string.
* In that case, we return the converted string value.
*/
template<typename ValueType>
ValueType Database::getValue(unsigned long propertyID) {
struct DatabaseGetter {
try {
unsigned long propertyKeyID = getPropertyKeyID(propertyID);
static ValueType get(Database & db, unsigned long propertyID) {
ScopedLock lock(_lockManager->lockPropertyForReading(propertyKeyID, common::eol));
try {
unsigned long propertyKeyID = db.getPropertyKeyID(propertyID);
BaseProperty * property = getPropertyFromKeyID(propertyKeyID);
ElementaryProperty<ValueType> * typedProperty = dynamic_cast<ElementaryProperty<ValueType> *>(property);
ScopedLock lock(db._lockManager->lockPropertyForReading(propertyKeyID, common::eol));
if (typedProperty == 0) {
throw BadPropertyTypeException(propertyID, common::TypeToString<ValueType>::convert(), property->getType());
BaseProperty * property = db.getPropertyFromKeyID(propertyKeyID);
ElementaryProperty<ValueType> * typedProperty = dynamic_cast<ElementaryProperty<ValueType> *>(property);
if (typedProperty == 0) {
throw Database::BadPropertyTypeException(propertyID, common::TypeToString<ValueType>::convert(), property->getType());
}
return typedProperty->getValue();
} catch (common::Exception const & e) {
throw;
}
}
};
return typedProperty->getValue();
/**
* Specialisation of the DatabaseGetter<> class for std::string.
*/
template<>
struct DatabaseGetter<std::string> {
} catch (common::Exception const & e) {
throw;
typedef std::string ValueType;
static ValueType get(Database & db, unsigned long propertyID) {
try {
unsigned long propertyKeyID = db.getPropertyKeyID(propertyID);
ScopedLock lock(db._lockManager->lockPropertyForReading(propertyKeyID, common::eol));
BaseProperty * property = db.getPropertyFromKeyID(propertyKeyID);
// Special case for
if (property->getType() != common::TypeToString<common::String>::convert()) {
DataProperty * dataProperty = dynamic_cast<DataProperty *>(property);
if (dataProperty == 0) {
throw Database::BadPropertyTypeException(propertyID, common::TypeToString<ValueType>::convert(), property->getType());
}
bool overflow;
return dataProperty->getStringValue(overflow);
}
ElementaryProperty<ValueType> * typedProperty = dynamic_cast<ElementaryProperty<ValueType> *>(property);
if (typedProperty == 0) {
throw Database::BadPropertyTypeException(propertyID, common::TypeToString<ValueType>::convert(), property->getType());
}
return typedProperty->getValue();
} catch (common::Exception const & e) {
throw;
}
}
};
template<typename ValueType>
ValueType Database::getValue(unsigned long propertyID) {
return DatabaseGetter<ValueType>::get(*this, propertyID);
}
template<typename ValueType>
......
......@@ -26,13 +26,11 @@
#include <xercesc/dom/DOMNodeList.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMWriter.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/dom/DOMWriterFilter.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/dom/DOMNode.hpp>
......
......@@ -26,6 +26,7 @@
#include <boost/property_tree/exceptions.hpp>
using namespace boost;
using namespace std;
namespace fs = boost::filesystem;
namespace pt = boost::property_tree;
......
......@@ -81,6 +81,9 @@ const std::string FluentdLogWriter::COLON = ":";
const std::string FluentdLogWriter::COMMA = ",";
const std::string FluentdLogWriter::QUOTATION_MARK = "\"";
const std::string FluentdLogWriter::MAINTENANCE_FAMILY = "Maintenance";
const std::string FluentdLogWriter::INTERNAL_USE_PROPOSAL_ID = "0";
using namespace common;
FluentdLogWriter::LogException::LogException(const std::string& message) :
......@@ -200,9 +203,7 @@ void FluentdLogWriter::write(Log* log) {
// only show messages in case it was activated
if (m_showMessages) {
stringstream os;
write_json(os, m_message, true);
cout << "Fluentd log message: " << os.str() << endl << endl;
cout << "Fluentd log message: " << s.GetString() << endl << endl;
}
std::string instrumentCode = Database::getInstance()->getValue<std::string>(m_propertyIdOfInstrumentCode);
......@@ -373,7 +374,17 @@ void FluentdLogWriter::addMessageEnding(Log* log) {
if (servantID != 0) {
std::string controllerType = getType(servantID);
m_message.put(ICON, getControllerIconKey(controllerType));
string family = getFamilyName(servantID);
if (family == MAINTENANCE_FAMILY) {
_isMaintenanceLog = true;
// All log messages concerning maintenance must be attached to "internal use"
m_message.put(PROPOSAL_ID, INTERNAL_USE_PROPOSAL_ID);
} else {
_isMaintenanceLog = false;
}
m_message.put(FAMILY, getFamilyName(servantID));
m_message.put(IMAGE, dynamic_cast<ControllerLog*>(log)->getImageName());
} else {
......@@ -715,7 +726,13 @@ void FluentdLogWriter::addMessageEndingUsingRapidJson(Log* log, rapidjson::Prett
writer.String(createLevelString(log->getLevel()).c_str());
writer.Key(PROPOSAL_ID.c_str());
writer.String(Database::getInstance()->getValue<std::string>(m_propertyIdOfProposalId).c_str());
if (_isMaintenanceLog) {
// All log messages concerning maintenance must be attached to "internal use"
writer.String(INTERNAL_USE_PROPOSAL_ID.c_str());
} else {
writer.String(Database::getInstance()->getValue<std::string>(m_propertyIdOfProposalId).c_str());
}
string instrumentId = Database::getInstance()->getValue<std::string>(m_propertyIdOfInstrumentId);
......
......@@ -123,6 +123,8 @@ private:
unsigned long m_propertyIdOfSampleName;
bool m_initDone;
bool _isMaintenanceLog;
std::map<unsigned long, std::string> m_parentID;
boost::property_tree::ptree m_message;
......@@ -169,6 +171,8 @@ private:
const static std::string COMMA;
const static std::string QUOTATION_MARK;
const static std::string MAINTENANCE_FAMILY;
const static std::string INTERNAL_USE_PROPOSAL_ID;
};
}
......
......@@ -348,7 +348,7 @@ std::string XMLLogWriter::formatCommandZoneContent(AtomicElement* element, const
string ctype = getServantType(Database::getInstance()->getServantID(element->getCommandID()));
if (element->isSettings()) {
return indent + "<settings id=\"" + element->getLogID() + "\" name=\"" + cname + "\"/>\n";
return indent + "<settings id=\"" + element->getLogID() + "\" name=\"" + cname + "\" settingsFile=\"" + element->getSettingsFileName() + "\"/>\n";
} else {
return indent + "<atomic id=\"" + element->getLogID() + "\" ctype=\"" + ctype + "\" cname=\"" + cname + "\"/>\n";
}
......
......@@ -62,6 +62,8 @@ const std::string CommandZoneParser::LOG_ID_ATTRIBUTE = "logId";
const std::string CommandZoneParser::COMMAND_ID_ATTRIBUTE = "commandId";
const std::string CommandZoneParser::CONTROLLER_ID_ATTRIBUTE = "controllerId";
const std::string CommandZoneParser::IS_SETTINGS_ATTRIBUTE = "isSettings";
const std::string CommandZoneParser::SETTINGS_FILE_NAME_ATTRIBUTE = "settingsFile";
const std::string CommandZoneParser::VARIABLE_NAME_ATTRIBUTE = "variableName";
const std::string CommandZoneParser::TYPE_ATTRIBUTE = "type";
......@@ -91,7 +93,7 @@ void CommandZoneParser::startElement(const std::string& uri, const std::string&
_currentElementStack.push_back(_root);
} else if (qName == ATOMIC_TAG) {
CommandZoneElement* element = new AtomicElement(to<unsigned long>(getAttribute(ID_ATTRIBUTE)), getAttribute(LOG_ID_ATTRIBUTE), to<unsigned long>(getAttribute(COMMAND_ID_ATTRIBUTE)), getAttribute(IS_SETTINGS_ATTRIBUTE) == "true");
CommandZoneElement* element = new AtomicElement(to<unsigned long>(getAttribute(ID_ATTRIBUTE)), getAttribute(LOG_ID_ATTRIBUTE), to<unsigned long>(getAttribute(COMMAND_ID_ATTRIBUTE)), getAttribute(IS_SETTINGS_ATTRIBUTE) == "true", getAttribute(SETTINGS_FILE_NAME_ATTRIBUTE));
_currentElementStack.back()->addChild(element);
_currentElementStack.push_back(element);