aboutsummaryrefslogtreecommitdiffstats
path: root/src/factory
diff options
context:
space:
mode:
Diffstat (limited to 'src/factory')
-rw-r--r--src/factory/RBAAbstractMakerTable.cpp38
-rw-r--r--src/factory/RBAAbstractMakerTable.hpp60
-rw-r--r--src/factory/RBAJsonElement.cpp271
-rw-r--r--src/factory/RBAJsonElement.hpp148
-rw-r--r--src/factory/RBAJsonParser.cpp48
-rw-r--r--src/factory/RBAJsonParserImpl.cpp315
-rw-r--r--src/factory/RBAJsonParserImpl.hpp70
-rw-r--r--src/factory/RBAModelFactory.cpp201
-rw-r--r--src/factory/RBAModelFactory.hpp101
9 files changed, 1252 insertions, 0 deletions
diff --git a/src/factory/RBAAbstractMakerTable.cpp b/src/factory/RBAAbstractMakerTable.cpp
new file mode 100644
index 0000000..b8340a7
--- /dev/null
+++ b/src/factory/RBAAbstractMakerTable.cpp
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAAbstractMakerTable.cpp
+/// @brief Maker table abstraction class definition
+
+#include "RBAAbstractMakerTable.hpp"
+
+namespace rba
+{
+
+const std::list<std::string>&
+RBAAbstractMakerTable::getTags() const
+{
+ return tags_;
+}
+
+void
+RBAAbstractMakerTable::addTag(const std::string& tag)
+{
+ tags_.push_back(tag);
+}
+
+}
+
diff --git a/src/factory/RBAAbstractMakerTable.hpp b/src/factory/RBAAbstractMakerTable.hpp
new file mode 100644
index 0000000..81b0c09
--- /dev/null
+++ b/src/factory/RBAAbstractMakerTable.hpp
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAAbstractMakerTable.hpp
+/// @brief Maker table abstraction class header
+
+#ifndef RBAABSTRACTMAKERTABLE_HPP
+#define RBAABSTRACTMAKERTABLE_HPP
+
+#include <memory>
+#include "RBAModelElementMaker.hpp"
+
+namespace rba
+{
+
+class DLL_EXPORT RBAAbstractMakerTable
+{
+public:
+ RBAAbstractMakerTable()=default;
+ RBAAbstractMakerTable(const RBAAbstractMakerTable&)=delete;
+ RBAAbstractMakerTable(const RBAAbstractMakerTable&&)=delete;
+ RBAAbstractMakerTable& operator=(const RBAAbstractMakerTable&)=delete;
+ RBAAbstractMakerTable& operator=(const RBAAbstractMakerTable&&)=delete;
+ virtual ~RBAAbstractMakerTable()=default;
+
+public:
+ virtual std::list<std::unique_ptr<RBAModelElementMaker>> getMakers() const=0;
+ virtual const std::list<std::string>& getTags() const;
+
+protected:
+ void addTag(const std::string& tag);
+
+private:
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+ std::list<std::string> tags_;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+};
+
+}
+
+#endif
diff --git a/src/factory/RBAJsonElement.cpp b/src/factory/RBAJsonElement.cpp
new file mode 100644
index 0000000..9b8f639
--- /dev/null
+++ b/src/factory/RBAJsonElement.cpp
@@ -0,0 +1,271 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAJsonElement.cpp
+/// @brief JSON element class defintion file
+
+#include "RBAJsonElement.hpp"
+
+#include "RBAArbitrationPolicy.hpp"
+#include "RBAContentLoserType.hpp"
+#ifdef RBA_USE_LOG
+#include "RBAExpressionType.hpp"
+#endif
+
+namespace rba
+{
+
+// RBAJsonElement clas
+
+std::string RBAJsonElement::emptyStr_;
+
+const std::string&
+RBAJsonElement::getString() const
+{
+ // This function is never called
+ // because the function of the derived class is called
+ return emptyStr_;
+}
+
+std::int32_t
+RBAJsonElement::getInt() const
+{
+ // This function is never called
+ // because the function of the derived class is called
+ return -99;
+}
+
+RBAArbitrationPolicy
+RBAJsonElement::getArbitrationPolicy() const
+{
+ // This function is never called
+ // because the function of the derived class is called
+ return RBAArbitrationPolicy::DEFAULT;
+}
+
+RBAContentLoserType
+RBAJsonElement::getLoserType() const
+{
+ // This function is never called
+ // because the function of the derived class is called
+ return RBAContentLoserType::NEVER_GIVEUP;
+}
+
+#ifdef RBA_USE_LOG
+RBAExpressionType
+RBAJsonElement::getExpressionType() const
+{
+ // This function is never called
+ // because the function of the derived class is called
+ return RBAExpressionType::VALUE;
+}
+#endif
+
+void
+RBAJsonElement::setName(const std::string& name)
+{
+ name_ = name;
+}
+
+const std::string&
+RBAJsonElement::getName() const
+{
+ return name_;
+}
+
+void
+RBAJsonElement::addChild(std::unique_ptr<RBAJsonElement> child)
+{
+ children_.push_back(move(child));
+}
+
+const std::vector<std::unique_ptr<RBAJsonElement>>&
+RBAJsonElement::getChildren() const
+{
+ return children_;
+}
+
+RBAJsonElement*
+RBAJsonElement::getChild() const
+{
+ return children_.front().get();
+}
+
+const RBAJsonElement*
+RBAJsonElement::findChildren(const std::string& name) const
+{
+ RBAJsonElement* res{nullptr};
+ for(const auto& elem : children_) {
+ if(elem->getName() == name) {
+ res = elem.get();
+ break;
+ }
+ }
+
+ return res;
+}
+
+const std::string&
+RBAJsonElement::getClassName() const
+{
+ const RBAJsonElement* const elem {findChildren("class")};
+ if(elem != nullptr) {
+ return elem->getString();
+ }
+
+ return emptyStr_;
+}
+
+// RBAJsonElementElement class
+
+RBAJsonElementElement::RBAJsonElementElement(const std::string& name)
+ : RBAJsonElement{}
+{
+ setName(name);
+}
+
+// RBAJsonElementString class
+
+RBAJsonElementString::RBAJsonElementString(const std::string& name)
+ : RBAJsonElement{}
+{
+ setName(name);
+}
+
+RBAArbitrationPolicy
+RBAJsonElementString::getArbitrationPolicy() const
+{
+ if(str_ == "FIRST_COME_FIRST") {
+ return RBAArbitrationPolicy::FIRST_COME_FIRST;
+ }
+ else if(str_ == "LAST_COME_FIRST") {
+ return RBAArbitrationPolicy::LAST_COME_FIRST;
+ }
+ else if(str_ == "PRIORITY_FIRST_COME_FIRST") {
+ return RBAArbitrationPolicy::PRIORITY_FIRST_COME_FIRST;
+ }
+ else if(str_ == "PRIORITY_LAST_COME_FIRST") {
+ return RBAArbitrationPolicy::PRIORITY_LAST_COME_FIRST;
+ }
+ else {
+ return RBAArbitrationPolicy::DEFAULT;
+ }
+}
+
+RBAContentLoserType
+RBAJsonElementString::getLoserType() const
+{
+ if(str_ == "GOOD_LOSER") {
+ return RBAContentLoserType::GOOD_LOSER;
+ }
+ else if(str_ == "DO_NOT_GIVEUP_UNTIL_WIN") {
+ return RBAContentLoserType::DO_NOT_GIVEUP_UNTIL_WIN;
+ }
+ else {
+ return RBAContentLoserType::NEVER_GIVEUP;
+ }
+}
+
+#ifdef RBA_USE_LOG
+RBAExpressionType
+RBAJsonElementString::getExpressionType() const
+{
+ if(str_ == "VALUE") {
+ return RBAExpressionType::VALUE;
+ }
+ else if(str_ == "BOOLEAN") {
+ return RBAExpressionType::BOOLEAN;
+ }
+ else if(str_ == "AREA") {
+ return RBAExpressionType::AREA;
+ }
+ else if(str_ == "CONTENT") {
+ return RBAExpressionType::CONTENT;
+ }
+ else if(str_ == "SOUND") {
+ return RBAExpressionType::SOUND;
+ }
+ else if(str_ == "SET_OF_SOUND") {
+ return RBAExpressionType::SET_OF_SOUND;
+ }
+ else if(str_ == "SET_OF_AREA") {
+ return RBAExpressionType::SET_OF_AREA;
+ }
+ else if(str_ == "SET_OF_CONTENT") {
+ return RBAExpressionType::SET_OF_CONTENT;
+ }
+ else if(str_ == "SET_OF_ZONE") {
+ return RBAExpressionType::SET_OF_ZONE;
+ }
+ else if(str_ == "SCENE") {
+ return RBAExpressionType::SCENE;
+ }
+ else if(str_ == "ZONE") {
+ return RBAExpressionType::ZONE;
+ }
+ else if(str_ == "ACTION") {
+ return RBAExpressionType::ACTION;
+ }
+ else if(str_ == "SET_OF_ACTION") {
+ return RBAExpressionType::SET_OF_ACTION;
+ }
+ else {
+ return RBAExpressionType::EXTENSION;
+ }
+}
+#endif
+
+const std::string&
+RBAJsonElementString::getString() const
+{
+ return str_;
+}
+
+void
+RBAJsonElementString::setString(const std::string& str)
+{
+ str_ = str;
+}
+
+// RBAJsonElementInt class
+
+RBAJsonElementInt::RBAJsonElementInt(const std::string& name)
+ : RBAJsonElement{}
+{
+ setName(name);
+}
+
+std::int32_t
+RBAJsonElementInt::getInt() const
+{
+ return val_;
+}
+
+void
+RBAJsonElementInt::setInt(const std::int32_t val)
+{
+ val_ = val;
+}
+
+// RBAJsonElementArray class
+
+RBAJsonElementArray::RBAJsonElementArray(const std::string& name)
+ : RBAJsonElement{}
+{
+ setName(name);
+}
+
+}
diff --git a/src/factory/RBAJsonElement.hpp b/src/factory/RBAJsonElement.hpp
new file mode 100644
index 0000000..a5fcc8e
--- /dev/null
+++ b/src/factory/RBAJsonElement.hpp
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAJsonElement.hpp
+/// @brief JSON element class header file
+
+#ifndef RBAJSONELEMENT_HPP
+#define RBAJSONELEMENT_HPP
+
+#include <cstdint>
+#include <vector>
+#include <memory>
+#include <string>
+#include "RBADllExport.hpp"
+
+namespace rba
+{
+
+enum class RBAArbitrationPolicy : std::uint8_t;
+enum class RBAContentLoserType : std::uint8_t;
+#ifdef RBA_USE_LOG
+enum class RBAExpressionType : std::uint8_t;
+#endif
+
+/// @brief JSONエ Element class
+class DLL_EXPORT RBAJsonElement
+{
+public:
+ RBAJsonElement()=default;
+ RBAJsonElement(const RBAJsonElement&)=delete;
+ RBAJsonElement(const RBAJsonElement&&)=delete;
+ RBAJsonElement& operator=(const RBAJsonElement&)=delete;
+ RBAJsonElement& operator=(const RBAJsonElement&&)=delete;
+ virtual ~RBAJsonElement()=default;
+
+public:
+ virtual const std::string& getString() const;
+ virtual std::int32_t getInt() const;
+ virtual RBAArbitrationPolicy getArbitrationPolicy() const;
+ virtual RBAContentLoserType getLoserType() const;
+#ifdef RBA_USE_LOG
+ virtual RBAExpressionType getExpressionType() const;
+#endif
+
+ void setName(const std::string& name);
+ const std::string& getName() const;
+ void addChild(std::unique_ptr<RBAJsonElement> child);
+ const std::vector<std::unique_ptr<RBAJsonElement>>& getChildren() const;
+ RBAJsonElement* getChild() const;
+ const RBAJsonElement* findChildren(const std::string& name) const;
+ const std::string& getClassName() const;
+
+private:
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+ std::string name_ {""};
+ std::vector<std::unique_ptr<RBAJsonElement>> children_;
+ static std::string emptyStr_;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+};
+
+class RBAJsonElementElement : public RBAJsonElement
+{
+public:
+ explicit RBAJsonElementElement(const std::string& name);
+ RBAJsonElementElement(const RBAJsonElementElement&)=delete;
+ RBAJsonElementElement(const RBAJsonElementElement&&)=delete;
+ RBAJsonElementElement& operator=(const RBAJsonElementElement&)=delete;
+ RBAJsonElementElement& operator=(const RBAJsonElementElement&&)=delete;
+ virtual ~RBAJsonElementElement()=default;
+};
+
+class RBAJsonElementString : public RBAJsonElement
+{
+public:
+ explicit RBAJsonElementString(const std::string& name);
+ RBAJsonElementString(const RBAJsonElementString&)=delete;
+ RBAJsonElementString(const RBAJsonElementString&&)=delete;
+ RBAJsonElementString& operator=(const RBAJsonElementString&)=delete;
+ RBAJsonElementString& operator=(const RBAJsonElementString&&)=delete;
+ virtual ~RBAJsonElementString()=default;
+
+public:
+ RBAArbitrationPolicy getArbitrationPolicy() const override;
+ RBAContentLoserType getLoserType() const override;
+#ifdef RBA_USE_LOG
+ RBAExpressionType getExpressionType() const override;
+#endif
+
+ const std::string& getString() const override;
+ void setString(const std::string& str);
+
+private:
+ std::string str_ {""};
+
+};
+
+class RBAJsonElementInt : public RBAJsonElement
+{
+public:
+ explicit RBAJsonElementInt(const std::string& name);
+ RBAJsonElementInt(const RBAJsonElementInt&)=delete;
+ RBAJsonElementInt(const RBAJsonElementInt&&)=delete;
+ RBAJsonElementInt& operator=(const RBAJsonElementInt&)=delete;
+ RBAJsonElementInt& operator=(const RBAJsonElementInt&&)=delete;
+ virtual ~RBAJsonElementInt()=default;
+
+public:
+ std::int32_t getInt() const override;
+ void setInt(const std::int32_t val);
+
+private:
+ std::int32_t val_ {0};
+
+};
+
+class RBAJsonElementArray : public RBAJsonElement
+{
+public:
+ explicit RBAJsonElementArray(const std::string& name);
+ RBAJsonElementArray(const RBAJsonElementArray&)=delete;
+ RBAJsonElementArray(const RBAJsonElementArray&&)=delete;
+ RBAJsonElementArray& operator=(const RBAJsonElementArray&)=delete;
+ RBAJsonElementArray& operator=(const RBAJsonElementArray&&)=delete;
+ virtual ~RBAJsonElementArray()=default;
+};
+
+}
+
+#endif
diff --git a/src/factory/RBAJsonParser.cpp b/src/factory/RBAJsonParser.cpp
new file mode 100644
index 0000000..e0846a5
--- /dev/null
+++ b/src/factory/RBAJsonParser.cpp
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAJsonParser.cpp
+/// @brief JSON Parser class deginition file
+
+#include "RBAJsonParser.hpp"
+#include "RBAJsonParserImpl.hpp"
+#include "RBAExpression.hpp"
+#include "RBAModelFactory.hpp"
+
+namespace rba
+{
+
+RBAJsonParser::RBAJsonParser()
+ : impl_{std::make_unique<RBAJsonParser::Impl>()}
+{
+};
+
+RBAJsonParser::RBAJsonParser(RBAModelFactory* factory)
+ : impl_{std::make_unique<RBAJsonParser::Impl>(factory)}
+{
+};
+
+RBAJsonParser::~RBAJsonParser() noexcept
+{
+};
+
+RBAModel*
+RBAJsonParser::parse(const std::string& filename)
+{
+ return impl_->parse(filename);
+}
+
+}
diff --git a/src/factory/RBAJsonParserImpl.cpp b/src/factory/RBAJsonParserImpl.cpp
new file mode 100644
index 0000000..db65367
--- /dev/null
+++ b/src/factory/RBAJsonParserImpl.cpp
@@ -0,0 +1,315 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAJsonParserImpl.cpp
+/// @brief JSON Parser implment class defintion file
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+#include "RBAJsonParserImpl.hpp"
+
+#include "RBACommonMakerTable.hpp"
+#include "RBAConstraintMap.hpp"
+#include "RBAJsonElement.hpp"
+#include "RBAModelImpl.hpp"
+#include "RBASoundMakerTable.hpp"
+#include "RBAViewMakerTable.hpp"
+
+namespace rba
+{
+
+RBAJsonParser::Impl::
+Impl(RBAModelFactory* const factory)
+ : orgFactory_{factory},
+ factory_{nullptr}
+{
+}
+
+RBAModel*
+RBAJsonParser::Impl::
+parse(const std::string& filename)
+{
+ const std::unique_ptr<RBAJsonElement> root {readJsonFile(filename)};
+ if(root == nullptr) {
+ return nullptr;
+ }
+
+ const std::lock_guard<std::mutex> lock{mutex_};
+
+ if(orgFactory_ != nullptr) {
+ factory_ = orgFactory_;
+ }
+ else {
+ uniqueFactory_ = std::make_unique<RBAModelFactory>();
+ factory_ = uniqueFactory_.get();
+ }
+ resetFactory();
+
+ // get registered tag element
+ for(const auto& tag : factory_->getTags()) {
+ const RBAJsonElement* const jsonElems {root->findChildren(tag)};
+ if(jsonElems != nullptr) {
+ for(const auto& elem : jsonElems->getChildren()) {
+ // Generate Model element
+ const RBAModelElement* const modelElem {factory_->createElement(tag, elem.get())};
+ if(modelElem == nullptr) {
+ factory_->deleteModel();
+ return nullptr;
+ }
+ }
+ }
+ }
+
+ // Error if there is an exception in Factory
+ if(factory_->isException()) {
+ factory_->deleteModel();
+ return nullptr;
+ }
+
+ // Create map between Area and Costraint
+ createConstraintMap(root->findChildren("area_constraint_map"),
+ RBAConstraintMap::CONTENT_ALLOCATE_CONSTRAINTS);
+ createConstraintMap(root->findChildren("area_hidden_true_check_constraint_map"),
+ RBAConstraintMap::HIDDEN_TRUE_CHECK_CONSTRAINTS);
+ createConstraintMap(root->findChildren("area_hidden_false_check_constraint_map"),
+ RBAConstraintMap::HIDDEN_FALSE_CHECK_CONSTRAINTS);
+
+ // Create map between Zone and Costraint
+ createConstraintMap(root->findChildren("zone_constraint_map"),
+ RBAConstraintMap::CONTENT_ALLOCATE_CONSTRAINTS);
+ createConstraintMap(root->findChildren("zone_mute_true_check_constraint_map"),
+ RBAConstraintMap::HIDDEN_TRUE_CHECK_CONSTRAINTS);
+ createConstraintMap(root->findChildren("zone_mute_false_check_constraint_map"),
+ RBAConstraintMap::HIDDEN_FALSE_CHECK_CONSTRAINTS);
+ createConstraintMap(root->findChildren("zone_attenuate_true_check_constraint_map"),
+ RBAConstraintMap::ATTENUATE_TRUE_CHECK_CONSTRAINTS);
+ createConstraintMap(root->findChildren("zone_attenuate_false_check_constraint_map"),
+ RBAConstraintMap::ATTENUATE_FALSE_CHECK_CONSTRAINTS);
+
+ // Create Allocatable Maps that affect
+// createAllocatablesMap(root->findChildren("content_allocatables_map"));
+// createAllocatablesMap(root->findChildren("scene_allocatables_map"));
+// createAllocatablesMap(root->findChildren("statemachine_allocatables_map"));
+
+ // Error if there is no contents
+ if((factory_->getModel()->getViewContents().size() == 0U) &&
+ (factory_->getModel()->getSoundContents().size() == 0U)) {
+ std::cerr << filename << ": ViewContent or SoundContent not found"
+ << &std::endl;
+ factory_->deleteModel();
+ return nullptr;
+ }
+
+ return factory_->getModel();
+}
+
+void
+RBAJsonParser::Impl::createConstraintMap(const RBAJsonElement* const constraints,
+ const RBAConstraintMap& kind)
+{
+ if (constraints != nullptr) {
+ for (const auto& constraint : constraints->getChildren()) {
+ const RBAJsonElement* const elem {constraint->getChildren().front().get()};
+ const std::string& allocatableName {elem->getName()};
+ for (auto& e : elem->getChildren()) {
+ factory_->setAllocatableConstraint(allocatableName, e->getName(), kind);
+ }
+ }
+ }
+}
+
+void
+RBAJsonParser::Impl::createAllocatablesMap(const RBAJsonElement* const allocMap)
+{
+ if (allocMap != nullptr) {
+ RBAModelImpl* const model {dynamic_cast<RBAModelImpl*>(factory_->getModel())};
+ for (auto& elem : allocMap->getChildren()) {
+ // Get the object which influence
+ const auto owner = elem->getChild();
+ const auto ownerObj = model->findModelElementImpl(owner->getName());
+
+ for (auto& alloc : owner->getChildren()) {
+ // Get the object which is affected
+ const auto allocObj = model->findAllocatable(alloc->getName());
+
+ // Add to map
+ model->addAffectedAllocsMap(ownerObj, const_cast<RBAAllocatable*>(allocObj));
+ }
+ }
+ }
+}
+
+std::unique_ptr<RBAJsonElement>
+RBAJsonParser::Impl::readJsonFile(const std::string& filename)
+{
+ std::ifstream ifs{filename};
+ if(ifs.fail()) {
+ std::cerr << filename << ": No such file or directory" << &std::endl;
+ return nullptr;
+ }
+
+ std::ostringstream oss;
+ std::string line;
+ while(!ifs.eof()) {
+ ifs >> line;
+ oss << line;
+ }
+
+ return readJsonString(oss.str());
+}
+
+std::unique_ptr<RBAJsonElement>
+RBAJsonParser::Impl::readJsonString(const std::string& jsonstring)
+{
+ std::vector<RBAJsonElement*> queue;
+ RBAJsonElement* current{nullptr};
+ std::unique_ptr<RBAJsonElement> topElement{nullptr};
+ Status status{Status::START};
+ const std::size_t jsonSize{jsonstring.size()};
+ std::size_t tokenPos{0U};
+ std::size_t tokenSize{0U};
+ std::size_t strPos{0U};
+ std::size_t strSize{0U};
+
+ while (tokenPos < jsonSize) {
+ auto firstChar = jsonstring[tokenPos];
+ if(firstChar == '\"') {
+ // String
+ tokenSize = jsonstring.find('\"', tokenPos + 1U) - tokenPos + 1U;
+ switch(status) {
+ case Status::START:
+ strPos = tokenPos + 1U;
+ strSize = tokenSize - 2U;
+ break;
+ case Status::VALUE:
+ auto elem = std::make_unique<RBAJsonElementString>(jsonstring.substr(strPos, strSize));
+ elem->setString(jsonstring.substr(tokenPos + 1U, tokenSize - 2U));
+ current->addChild(std::move(elem));
+ strSize = 0U;
+ status = Status::START;
+ break;
+ }
+ }
+ else if(firstChar == ':') {
+ // Value mode
+ tokenSize = 1U;
+ status = Status::VALUE;
+ }
+ else if(firstChar == ',') {
+ tokenSize = 1U;
+ if(strSize > 0U) {
+ current->addChild(std::make_unique<RBAJsonElementString>(jsonstring.substr(strPos, strSize)));
+ strSize = 0U;
+ status = Status::START;
+ }
+ }
+ else if(firstChar == '{') {
+ // Start Element
+ tokenSize = 1U;
+ if(status == Status::START) {
+ if(current != nullptr) {
+ auto elem = std::make_unique<RBAJsonElementElement>(jsonstring.substr(strPos, strSize));
+ auto elemPtr = elem.get();
+ current->addChild(std::move(elem));
+ current = elemPtr;
+ queue.push_back(current);
+ strSize = 0U;
+ }
+ } else {
+ // status is Status::VALUE
+ auto elem = std::make_unique<RBAJsonElementElement>(jsonstring.substr(strPos, strSize));
+ auto elemPtr = elem.get();
+ if(current != nullptr) {
+ current->addChild(std::move(elem));
+ } else {
+ topElement = std::move(elem);
+ }
+ current = elemPtr;
+ queue.push_back(current);
+ strSize = 0U;
+ status = Status::START;
+ }
+ }
+ else if(firstChar == '}') {
+ // End Element
+ tokenSize = 1U;
+ if (!queue.empty()) {
+ queue.pop_back();
+ }
+ current = queue.empty() ? nullptr : queue.back();
+ }
+ else if(firstChar == '[') {
+ // Satrt array
+ tokenSize = 1U;
+ auto elem = std::make_unique<RBAJsonElementArray>(jsonstring.substr(strPos, strSize));
+ auto elemPtr = elem.get();
+ current->addChild(std::move(elem));
+ current = elemPtr;
+ queue.push_back(current);
+ strSize = 0U;
+ status = Status::START;
+ }
+ else if(firstChar == ']') {
+ // End array
+ tokenSize = 1U;
+ if(strSize > 0U) {
+ current->addChild(std::make_unique<RBAJsonElementString>(jsonstring.substr(strPos, strSize)));
+ strSize = 0U;
+ status = Status::START;
+ }
+ queue.pop_back();
+ current = queue.empty() ? nullptr : queue.back();
+ }
+ else if((firstChar == '-') || isdigit(firstChar)) {
+ // Numerical value
+ tokenSize = jsonstring.find_first_of(",}]", tokenPos + 1U) - tokenPos;
+ auto elem = std::make_unique<RBAJsonElementInt>(jsonstring.substr(strPos, strSize));
+ elem->setInt(std::stoi(jsonstring.substr(tokenPos, tokenSize)));
+ current->addChild(std::move(elem));
+ strSize = 0U;
+ status = Status::START;
+ }
+ else if((static_cast<std::int32_t>(firstChar) <= 0x20)) {
+ // skip
+ tokenSize = 1U;
+ }
+ else {
+ tokenSize = 1U;
+ std::cerr << "[ERROR] '" << jsonstring.substr(tokenPos, tokenSize)
+ << "' :Unknown token" << &std::endl;
+ }
+ tokenPos += tokenSize;
+ }
+
+ return topElement;
+}
+
+void
+RBAJsonParser::Impl::resetFactory()
+{
+ // Set if Maker is not registered
+ if(!factory_->hasMaker()) {
+ // Models such as area and zone should be registered first.
+ factory_->addMakerTable(RBAViewMakerTable());
+ factory_->addMakerTable(RBASoundMakerTable());
+ factory_->addMakerTable(RBACommonMakerTable());
+ }
+
+ factory_->resetException();
+}
+
+}
diff --git a/src/factory/RBAJsonParserImpl.hpp b/src/factory/RBAJsonParserImpl.hpp
new file mode 100644
index 0000000..533f894
--- /dev/null
+++ b/src/factory/RBAJsonParserImpl.hpp
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAJsonParserImpl.hpp
+/// @brief JSON Parser implementation class header file
+
+#ifndef RBAJSONPARSERIMPL_HPP
+#define RBAJSONPARSERIMPL_HPP
+
+#include <mutex>
+#include "RBAJsonParser.hpp"
+#include "RBAModelFactory.hpp"
+
+namespace rba
+{
+
+class RBAJsonElement;
+enum class RBAConstraintMap : std::uint8_t;
+
+/// @brief JSON Parser implementation class
+class RBAJsonParser::Impl
+{
+public:
+ Impl(RBAModelFactory* const factory=nullptr);
+ Impl(const Impl&)=delete;
+ Impl(const Impl&&)=delete;
+ Impl& operator=(const Impl&)=delete;
+ Impl& operator=(const Impl&&)=delete;
+ virtual ~Impl()=default;
+
+public:
+ RBAModel* parse(const std::string& filename);
+
+private:
+ virtual void resetFactory();
+
+private:
+ void createConstraintMap(const RBAJsonElement* const constraints,
+ const RBAConstraintMap& kind);
+ void createAllocatablesMap(const RBAJsonElement* const allocMap);
+ std::unique_ptr<RBAJsonElement> readJsonFile(const std::string& filename);
+ std::unique_ptr<RBAJsonElement> readJsonString(const std::string& jsonstring);
+
+private:
+ enum class Status : std::uint8_t {
+ START,
+ VALUE,
+ };
+ RBAModelFactory* orgFactory_;
+ RBAModelFactory* factory_;
+ std::unique_ptr<RBAModelFactory> uniqueFactory_;
+ std::mutex mutex_;
+};
+
+}
+
+#endif
diff --git a/src/factory/RBAModelFactory.cpp b/src/factory/RBAModelFactory.cpp
new file mode 100644
index 0000000..28c42e0
--- /dev/null
+++ b/src/factory/RBAModelFactory.cpp
@@ -0,0 +1,201 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// @file RBAModelFactory.cpp
+/// @brief Model Factory class definition file
+
+#include <algorithm>
+#include "RBAModelFactory.hpp"
+#include "RBAModelImpl.hpp"
+#include "RBAJsonElement.hpp"
+#include "RBAAbstractMakerTable.hpp"
+#include "RBAConstraintImpl.hpp"
+
+namespace rba
+{
+
+RBAModelFactory::RBAModelFactory(RBAModelImpl* const model)
+ : model_{nullptr},
+ exception_{false}
+{
+ if(model != nullptr) {
+ model_ = model;
+ }
+ else {
+ // @Deviation (A18-5-2)
+ // [Contents that deviate from the rules]
+ // Operators new and delete shall not be called explicitly.
+ // [Explain that it is okay to deviate from the rules]
+ // model_ is not owned by RBAModelFacotry.
+ // Therefore, it is not managed by the smart pointer.
+ // There is no problem because it is managed by
+ // the user side of RBAModelFactory.
+ model_ = new RBAModelImpl();
+ }
+}
+
+RBAModelFactory::~RBAModelFactory() noexcept
+{
+}
+
+RBAModel* const
+RBAModelFactory::getModel() const
+{
+ return model_;
+}
+
+void
+RBAModelFactory::deleteModel()
+{
+ // @Deviation (A18-5-2)
+ // [Contents that deviate from the rules]
+ // Operators new and delete shall not be called explicitly.
+ // [Explain that it is okay to deviate from the rules]
+ // Since it is managed by the user side of RBAModelFactory,
+ // there is no problem even if it is deleted from the outside.
+ delete model_;
+ model_ = nullptr;
+}
+
+void
+RBAModelFactory::addMakerTable(const RBAAbstractMakerTable& makerTable)
+{
+ for(auto& maker : makerTable.getMakers()) {
+ maker->setFactory(this);
+ const std::string label {maker->getLabel()};
+ nameToMaker_[label] = maker.get();
+ makers_.push_back(std::move(maker));
+ }
+ for(auto& tag : makerTable.getTags()) {
+ if (std::find(tags_.begin(), tags_.end(), tag) == tags_.end()) {
+ tags_.push_back(tag);
+ }
+ }
+}
+
+void
+RBAModelFactory::addMaker(const std::string label,
+ std::unique_ptr<RBAModelElementMaker> maker)
+{
+ maker->setFactory(this);
+ nameToMaker_[label] = maker.get();
+ makers_.push_back(std::move(maker));
+}
+
+bool
+RBAModelFactory::hasMaker() const
+{
+ return !nameToMaker_.empty();
+}
+
+const std::list<std::string>&
+RBAModelFactory::getTags() const
+{
+ return tags_;
+}
+
+RBAModelElement*
+RBAModelFactory::createElement(const std::string& className,
+ const RBAJsonElement* const jsonElement,
+ RBAModelElement* const owner)
+{
+ auto it = nameToMaker_.find(className);
+ if(it == nameToMaker_.end()) {
+ const RBAJsonElement* const classElement {jsonElement->findChildren("class")};
+ if(classElement != nullptr) {
+ it = nameToMaker_.find(classElement->getString());
+ if(it == nameToMaker_.end()) {
+ return nullptr;
+ }
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ return it->second->create(jsonElement, model_, owner);
+}
+
+void
+RBAModelFactory::setAllocatableConstraint(const std::string& allocatableName,
+ const std::string& constraintName,
+ const RBAConstraintMap& kind)
+{
+ // Get allocatable
+ RBAAllocatable* const allocatable
+ {const_cast<RBAAllocatable*>(model_->findAllocatable(allocatableName))};
+ // Get constraint
+ RBAConstraintImpl* const constraint {model_->findConstraintImpl(constraintName)};
+ if ((allocatable != nullptr) && (constraint != nullptr)) {
+ allocatable->addConstraint(constraint, kind);
+ }
+}
+
+// Variable can be defined with the same name in different scopes,
+// but here we are registering the Variable defined in the scope
+// that is being created
+void
+RBAModelFactory::pushVariable(const RBAVariable* const var)
+{
+ currentVariables_.push_back(var);
+}
+
+// Variables can be defined with the same name in different scopes,
+// but when you leave the scope with a definition, Variable is deleted.
+void
+RBAModelFactory::popVariable()
+{
+ if(!currentVariables_.empty()) {
+ currentVariables_.pop_back();
+ }
+}
+
+const RBAVariable*
+RBAModelFactory::getVariable(const std::string& varName)
+{
+ const auto itr =
+ std::find_if(currentVariables_.rbegin(), currentVariables_.rend(),
+ [&varName](const RBAVariable* element) -> bool {
+ return element->getElementName() == varName;
+ });
+
+ if (itr != currentVariables_.rend())
+ {
+ return *itr;
+ }
+
+ return nullptr;
+}
+
+void
+RBAModelFactory::resetException()
+{
+ exception_ = false;
+}
+
+void
+RBAModelFactory::setException()
+{
+ exception_ = true;
+}
+
+bool
+RBAModelFactory::isException() const
+{
+ return exception_;
+}
+
+}
diff --git a/src/factory/RBAModelFactory.hpp b/src/factory/RBAModelFactory.hpp
new file mode 100644
index 0000000..9250f92
--- /dev/null
+++ b/src/factory/RBAModelFactory.hpp
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2019 DENSO CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/// @file RBAModelFactory.hpp
+/// @brief Model Factory class header file
+
+#ifndef RBAMODELFACTORY_HPP
+#define RBAMODELFACTORY_HPP
+
+#include <string>
+#include <list>
+#include <memory>
+#include <unordered_map>
+#include "RBADllExport.hpp"
+
+namespace rba
+{
+
+class RBAModel;
+class RBAModelImpl;
+class RBAJsonElement;
+class RBAModelElement;
+class RBAVariable;
+class RBAAbstractMakerTable;
+class RBAModelElementMaker;
+enum class RBAConstraintMap : std::uint8_t;
+
+/// @brief Model Factory class
+class DLL_EXPORT RBAModelFactory
+{
+public:
+ RBAModelFactory(RBAModelImpl* const model=nullptr);
+ RBAModelFactory(const RBAModelFactory&)=delete;
+ RBAModelFactory(const RBAModelFactory&&)=delete;
+ RBAModelFactory& operator=(const RBAModelFactory&)=delete;
+ RBAModelFactory& operator=(const RBAModelFactory&&)=delete;
+ virtual ~RBAModelFactory() noexcept;
+
+ public:
+ RBAModel* const getModel() const;
+ void deleteModel();
+ void addMakerTable(const RBAAbstractMakerTable& makerTable);
+ void addMaker(const std::string label,
+ std::unique_ptr<RBAModelElementMaker> maker);
+ bool hasMaker() const;
+ const std::list<std::string>& getTags() const;
+
+ RBAModelElement* createElement(const std::string& className,
+ const RBAJsonElement* const jsonElement,
+ RBAModelElement* const owner=nullptr);
+
+ void setAllocatableConstraint(const std::string& allocatableName,
+ const std::string& constraintName,
+ const RBAConstraintMap& kind);
+
+ void pushVariable(const RBAVariable* const var);
+ void popVariable();
+ const RBAVariable* getVariable(const std::string& varName);
+
+ void resetException();
+ void setException();
+ bool isException() const;
+
+private:
+ RBAModelImpl* model_;
+ bool exception_;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+ std::unordered_map<std::string, RBAModelElementMaker*> nameToMaker_;
+ // unique_ptr list for storing
+ std::list<std::unique_ptr<RBAModelElementMaker>> makers_;
+ // current variable for working
+ std::list<const RBAVariable*> currentVariables_;
+ // JSON element tag list, set from the registered MakerTable
+ std::list<std::string> tags_;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+};
+
+}
+
+#endif