Skip to content

Commit

Permalink
Merge pull request #190 from mtconnect/back_port_asset_parser_fixes_f…
Browse files Browse the repository at this point in the history
…rom_dev

Back-ported changes for asset handling with extended schema from 2.0.
  • Loading branch information
wsobel authored Nov 11, 2021
2 parents 6a42067 + 1d6524a commit 8c2afa6
Show file tree
Hide file tree
Showing 20 changed files with 553 additions and 263 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# The version number.
set(AGENT_VERSION_MAJOR 1)
set(AGENT_VERSION_MINOR 7)
set(AGENT_VERSION_MINOR 8)
set(AGENT_VERSION_PATCH 0)
set(AGENT_VERSION_BUILD 7)
set(AGENT_VERSION_BUILD 1)
#set(AGENT_VERSION_RC "RC9")

# This minimum version is to support Visual Studio 2017 and C++ feature checking and FetchContent
Expand Down
3 changes: 2 additions & 1 deletion agent_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ set(AGENT_SOURCES

"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity/entity.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity/qname.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity/entity.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity/qname.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity/requirement.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity/requirement.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/entity/factory.hpp"
Expand Down
8 changes: 7 additions & 1 deletion src/assets/cutting_tool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ namespace mtconnect
{Requirement("Measurement", ENTITY, measurement, 1, Requirement::Infinite)}));
measurements->registerMatchers();
measurements->registerFactory(regex(".+"), measurement);

static auto ext = make_shared<Factory>();
ext->registerFactory(regex(".+"), ext);
ext->setAny(true);

static auto item =
make_shared<Factory>(Requirements{{"indices", true},
Expand All @@ -72,6 +74,8 @@ namespace mtconnect
{"ProgramToolGroup", false},
{"Measurements", ENTITY_LIST, measurements, false}});
item->registerFactory(regex(".+"), ext);
item->setAny(true);

measurements->registerMatchers();
item->setOrder({"Description", "Locus", "ItemLife", "ProgramToolGroup", "Measurements"});

Expand All @@ -88,6 +92,8 @@ namespace mtconnect
Requirement("Measurements", ENTITY_LIST, measurements, false),
Requirement("CuttingItems", ENTITY_LIST, items, false)}));
lifeCycle->registerFactory(regex(".+"), ext);
lifeCycle->setAny(true);

measurements->registerMatchers();
lifeCycle->setOrder({"ReconditionCount", "ToolLife", "ProgramToolGroup", "ProgramToolNumber",
"ProcessSpindleSpeed", "ProcessFeedRate", "ConnectionCodeMachineSide",
Expand Down
55 changes: 55 additions & 0 deletions src/entity/entity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright Copyright 2009-2021, AMT – The Association For Manufacturing Technology (“AMT”)
// All rights reserved.
//
// 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.
//

#include <unordered_set>

#include "factory.hpp"

using namespace std;

namespace mtconnect {
namespace entity {
bool Entity::addToList(const std::string &name, FactoryPtr factory, EntityPtr entity,
ErrorList &errors)
{
if (!hasProperty(name))
{
entity::EntityList list {entity};
auto entities = factory->create(name, list, errors);
if (errors.empty())
setProperty(name, entities);
else
return false;
}
else
{
auto *entities = std::get_if<EntityPtr>(&getProperty_(name));
if (entities)
{
std::get<EntityList>((*entities)->getProperty_("LIST")).emplace_back(entity);
}
else
{
errors.emplace_back(new EntityError("Cannont find list for: " + name));
return false;
}
}

return true;
}
} // namespace entity
} // namespace mtconnect
50 changes: 31 additions & 19 deletions src/entity/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,25 @@

#pragma once

#include <unordered_map>

#include "observation/data_set.hpp"
#include "requirement.hpp"
#include "qname.hpp"
#include "requirement.hpp"

#include <unordered_map>

namespace mtconnect
{
namespace entity
{
struct PropertyKey : public std::string
namespace mtconnect {
namespace entity {
struct PropertyKey : public QName
{
using std::string::string;
PropertyKey(const PropertyKey &s) : std::string(s) {}
PropertyKey(const std::string &s) : std::string(s) {}
PropertyKey(const std::string &&s) : std::string(s) {}
PropertyKey(const char *s) : std::string(s) {}
using QName::QName;
PropertyKey(const PropertyKey &s) : QName(s) {}
PropertyKey(const std::string &s) : QName(s) {}
PropertyKey(const std::string &&s) : QName(s) {}
PropertyKey(const char *s) : QName(s) {}

void clearMark() const { const_cast<PropertyKey *>(this)->m_mark = false; }
void setMark() const { const_cast<PropertyKey *>(this)->m_mark = true; }
bool m_mark{false};
bool m_mark {false};
};

using Properties = std::map<PropertyKey, Value>;
Expand All @@ -55,20 +53,19 @@ namespace mtconnect
else
return std::nullopt;
}

class Entity : public std::enable_shared_from_this<Entity>
{
public:
using super = std::nullptr_t;

Entity() {}
Entity(const std::string &name, const Properties &props) : m_name(name), m_properties(props)
{
}
{}
Entity(const Entity &entity) = default;
virtual ~Entity() {}

EntityPtr getptr() { return shared_from_this(); }
EntityPtr getptr() const { return const_cast<Entity *>(this)->shared_from_this(); }

bool hasListWithAttribute() const
{
Expand All @@ -78,7 +75,7 @@ namespace mtconnect
const Properties &getProperties() const { return m_properties; }
const Value &getProperty(const std::string &n) const
{
static Value noValue{std::monostate()};
static Value noValue {std::monostate()};
auto it = m_properties.find(n);
if (it == m_properties.end())
return noValue;
Expand Down Expand Up @@ -129,6 +126,10 @@ namespace mtconnect

return std::nullopt;
}

bool addToList(const std::string &name, FactoryPtr factory, EntityPtr entity,
ErrorList &errors);

void setValue(const Value &v) { setProperty("VALUE", v); }
void erase(const std::string &name) { m_properties.erase(name); }

Expand Down Expand Up @@ -161,6 +162,17 @@ namespace mtconnect
auto erase(Properties::iterator &it) { return m_properties.erase(it); }

// Entity Factory
protected:
Value &getProperty_(const std::string &name)
{
static Value noValue {std::monostate()};
auto it = m_properties.find(name);
if (it == m_properties.end())
return noValue;
else
return it->second;
}

protected:
QName m_name;
Properties m_properties;
Expand Down
53 changes: 29 additions & 24 deletions src/entity/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@

using namespace std;

namespace mtconnect
{
namespace entity
{
namespace mtconnect {
namespace entity {
static dlib::logger g_logger("EntityFactory");

void Factory::_dupFactory(FactoryPtr &factory, FactoryMap &factories)
Expand All @@ -39,8 +37,8 @@ namespace mtconnect
else
{
auto ptr = make_shared<Factory>(*factory);
ptr->_deepCopy(factories);
factories.emplace(factory, ptr);
ptr->_deepCopy(factories);
factory = ptr;
}
}
Expand Down Expand Up @@ -108,7 +106,7 @@ namespace mtconnect

bool Factory::isSufficient(Properties &properties, ErrorList &errors) const
{
bool success{true};
bool success {true};
for (auto &p : properties)
p.first.clearMark();

Expand All @@ -127,14 +125,12 @@ namespace mtconnect
if (list.size() < m_minListSize)
{
errors.emplace_back(new PropertyError("The list must have at least " +
to_string(m_minListSize) +
" entries"));
to_string(m_minListSize) + " entries"));
success = false;

}
}
}

for (const auto &r : m_requirements)
{
Properties::const_iterator p;
Expand All @@ -147,7 +143,7 @@ namespace mtconnect
if (r.isRequired())
{
errors.emplace_back(new PropertyError(
"Property " + r.getName() + " is required and not provided", r.getName()));
"Property " + r.getName() + " is required and not provided", r.getName()));
success = false;
}
}
Expand Down Expand Up @@ -178,21 +174,30 @@ namespace mtconnect
}
}
}

std::list<string> extra;
for (auto &p : properties)
if (!p.first.m_mark)
extra.emplace_back(p.first);

// Check for additional properties
if (!m_isList && !extra.empty())
if (!m_any && !m_isList)
{
std::stringstream os;
os << "The following keys were present and not expected: ";
for (auto &k : extra)
os << k << ",";
errors.emplace_back(new PropertyError(os.str()));
success = false;
std::list<string> extra;
for (auto &p : properties)
{
// Check that all properties are expected and if they are not, allow
// xml attributes through if the namespace portion starts with xml.
if (!p.first.m_mark && (!p.first.hasNs() || p.first.getNs().find_first_of("xml") != 0))
{
extra.emplace_back(p.first);
}
}

// Check for additional properties
if (!extra.empty())
{
std::stringstream os;
os << "The following keys were present and not expected: ";
for (auto &k : extra)
os << k << ",";
errors.emplace_back(new PropertyError(os.str()));
success = false;
}
}

return success;
Expand Down
34 changes: 20 additions & 14 deletions src/entity/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,20 @@

#pragma once

#include "entity.hpp"
#include <unordered_map>

#include <map>
#include <set>
#include <unordered_map>

#include "entity.hpp"

namespace mtconnect
{
namespace entity
{
namespace mtconnect {
namespace entity {
using Requirements = std::list<Requirement>;

class Factory : public Matcher, public std::enable_shared_from_this<Factory>
{
public:
using Function =
std::function<std::shared_ptr<Entity>(const std::string &name, Properties &)>;
using Function = std::function<EntityPtr(const std::string &name, Properties &)>;
using Matcher = std::function<bool(const std::string &)>;
using MatchPair = std::pair<Matcher, FactoryPtr>;
using StringFactory = std::unordered_map<std::string, FactoryPtr>;
Expand Down Expand Up @@ -76,7 +73,13 @@ namespace mtconnect
bool isList() const { return m_isList; }
void setHasRaw(bool raw) { m_hasRaw = raw; }
bool hasRaw() const { return m_hasRaw; }
void setMinListSize(size_t size) { m_minListSize = size; m_isList = true; }
bool isAny() const { return m_any; }
void setAny(bool any) { m_any = any; }
void setMinListSize(size_t size)
{
m_minListSize = size;
m_isList = true;
}

bool isPropertySet(const std::string &name) const { return m_propertySets.count(name) > 0; }
bool isSimpleProperty(const std::string &name) const
Expand Down Expand Up @@ -197,7 +200,7 @@ namespace mtconnect
auto factory = factoryFor(name);
if (factory)
{
Properties p{{"LIST", a}};
Properties p {{"LIST", a}};
return factory->make(name, p, errors);
}
else
Expand Down Expand Up @@ -281,9 +284,12 @@ namespace mtconnect

StringFactory m_stringFactory;
MatchFactory m_matchFactory;
bool m_isList{false};
size_t m_minListSize{0};
bool m_hasRaw{false};

bool m_isList {false};
size_t m_minListSize {0};
bool m_hasRaw {false};
bool m_any {false};

std::set<std::string> m_propertySets;
std::set<std::string> m_simpleProperties;
};
Expand Down
Loading

0 comments on commit 8c2afa6

Please sign in to comment.