/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 "metadata.h"
#include
#include
META_BEGIN_NAMESPACE()
namespace Internal {
IMetadata::Ptr Metadata::CloneMetadata() const
{
return BASE_NS::shared_ptr(new Metadata(static_cast(*this)));
}
Metadata::Metadata()
: propertyContainer_(new MetadataPropertyContainer),
properties_(interface_pointer_cast(propertyContainer_))
{}
// make deep copy of everything
Metadata::Metadata(const IMetadata& data)
: propertyContainer_(new MetadataPropertyContainer),
properties_(interface_pointer_cast(propertyContainer_))
{
for (auto&& v : data.GetAllProperties()) {
if (auto prop = DuplicatePropertyType(GetObjectRegistry(), v)) {
prop->SetValue(v->GetValue());
properties_->Add(prop);
}
}
for (auto&& v : data.GetAllEvents()) {
if (auto i = interface_cast(v)) {
AddEvent(interface_pointer_cast(i->GetClone()));
}
}
for (auto&& v : data.GetAllFunctions()) {
if (auto i = interface_cast(v)) {
AddFunction(interface_pointer_cast(i->GetClone()));
}
}
}
IContainer::Ptr Metadata::GetPropertyContainer()
{
return properties_;
}
IContainer::ConstPtr Metadata::GetPropertyContainer() const
{
return properties_;
}
void Metadata::AddProperty(const IProperty::Ptr& p)
{
CORE_ASSERT_MSG(p, "Trying to add null property");
if (p) {
if (auto other = properties_->FindAny(IContainer::FindOptions { p->GetName(), TraversalType::NO_HIERARCHY })) {
if (interface_pointer_cast(other) == p) {
CORE_LOG_W("Property already in metadata: %s", p->GetName().c_str());
} else {
CORE_LOG_E("Property with same name already exists in metadata: %s", p->GetName().c_str());
}
} else {
properties_->Add(p);
}
}
}
void Metadata::RemoveProperty(const IProperty::Ptr& p)
{
if (properties_->Remove(p)) {
if (auto pp = interface_pointer_cast(p)) {
pp->SetOwner(nullptr);
}
}
}
template
static void AddImpl(Container& cont, const Type& p)
{
for (auto& pp : cont) {
if (p == pp) {
return;
}
}
cont.push_back(p);
}
template
static void RemoveImpl(Container& cont, const Type& p)
{
for (auto it = cont.begin(); it != cont.end(); ++it) {
if (*it == p) {
cont.erase(it);
return;
}
}
}
void Metadata::AddFunction(const IFunction::Ptr& p)
{
AddImpl(functionMetadata_, p);
}
void Metadata::RemoveFunction(const IFunction::Ptr& p)
{
RemoveImpl(functionMetadata_, p);
}
void Metadata::AddEvent(const IEvent::Ptr& p)
{
AddImpl(eventMetadata_, p);
}
void Metadata::RemoveEvent(const IEvent::Ptr& p)
{
RemoveImpl(eventMetadata_, p);
}
void Metadata::SetProperties(const BASE_NS::vector& vec)
{
properties_->RemoveAll();
for (auto&& p : vec) {
properties_->Add(p);
}
}
void Metadata::Merge(const IMetadata::Ptr& data)
{
if (auto cont = data->GetPropertyContainer()) {
auto vec = cont->GetAll();
for (auto&& v : vec) {
AddProperty(v);
}
for (auto&& v : data->GetAllEvents()) {
AddEvent(v);
}
for (auto&& v : data->GetAllFunctions()) {
AddFunction(v);
}
}
}
template
static NewContainer GetAllImpl(const Container& cont)
{
NewContainer res;
res.reserve(cont.size());
for (const auto& v : cont) {
res.push_back(v);
}
return res;
}
BASE_NS::vector Metadata::GetAllProperties()
{
return properties_->GetAll();
}
BASE_NS::vector Metadata::GetAllProperties() const
{
return GetAllImpl>(properties_->GetAll());
}
BASE_NS::vector Metadata::GetAllFunctions()
{
return functionMetadata_;
}
BASE_NS::vector Metadata::GetAllFunctions() const
{
return GetAllImpl>(functionMetadata_);
}
BASE_NS::vector Metadata::GetAllEvents()
{
return eventMetadata_;
}
BASE_NS::vector Metadata::GetAllEvents() const
{
return GetAllImpl>(eventMetadata_);
}
IProperty::Ptr Metadata::GetPropertyByName(BASE_NS::string_view name)
{
return properties_->FindByName(name);
}
IProperty::ConstPtr Metadata::GetPropertyByName(BASE_NS::string_view name) const
{
return properties_->FindByName(name);
}
template
static Ret GetByName(Container&& cont, BASE_NS::string_view name)
{
for (auto&& t : cont) {
if (t->GetName() == name) {
return t;
}
}
return nullptr;
}
IFunction::Ptr Metadata::GetFunctionByName(BASE_NS::string_view name)
{
return GetByName(functionMetadata_, name);
}
IFunction::ConstPtr Metadata::GetFunctionByName(BASE_NS::string_view name) const
{
return GetByName(functionMetadata_, name);
}
IEvent::Ptr Metadata::GetEventByName(BASE_NS::string_view name)
{
return GetByName(eventMetadata_, name);
}
IEvent::ConstPtr Metadata::GetEventByName(BASE_NS::string_view name) const
{
return GetByName(eventMetadata_, name);
}
MetadataPropertyContainer::MetadataPropertyContainer()
{
impl_.SetImplementingIContainer(nullptr, this);
SetRequiredInterfaces({ IProperty::UID });
}
BASE_NS::vector MetadataPropertyContainer::GetAll() const
{
return impl_.GetAll();
}
IObject::Ptr MetadataPropertyContainer::GetAt(SizeType index) const
{
return impl_.GetAt(index);
}
IContainer::SizeType MetadataPropertyContainer::GetSize() const
{
return impl_.GetSize();
}
BASE_NS::vector MetadataPropertyContainer::FindAll(const FindOptions& options) const
{
return impl_.FindAll(options);
}
IObject::Ptr MetadataPropertyContainer::FindAny(const FindOptions& options) const
{
return impl_.FindAny(options);
}
IObject::Ptr MetadataPropertyContainer::FindByName(BASE_NS::string_view name) const
{
return impl_.FindByName(name);
}
bool MetadataPropertyContainer::Add(const IObject::Ptr& object)
{
return impl_.Add(object);
}
bool MetadataPropertyContainer::Insert(SizeType index, const IObject::Ptr& object)
{
return impl_.Insert(index, object);
}
bool MetadataPropertyContainer::Remove(SizeType index)
{
return impl_.Remove(index);
}
bool MetadataPropertyContainer::Remove(const IObject::Ptr& child)
{
return impl_.Remove(child);
}
bool MetadataPropertyContainer::Move(SizeType fromIndex, SizeType toIndex)
{
return impl_.Move(fromIndex, toIndex);
}
bool MetadataPropertyContainer::Move(const IObject::Ptr& child, SizeType toIndex)
{
return impl_.Move(child, toIndex);
}
bool MetadataPropertyContainer::Replace(const IObject::Ptr& child, const IObject::Ptr& replaceWith, bool addAlways)
{
return impl_.Replace(child, replaceWith, addAlways);
}
void MetadataPropertyContainer::RemoveAll()
{
return impl_.RemoveAll();
}
bool MetadataPropertyContainer::SetRequiredInterfaces(const BASE_NS::vector& interfaces)
{
return false;
}
BASE_NS::vector MetadataPropertyContainer::GetRequiredInterfaces() const
{
return impl_.GetRequiredInterfaces();
}
bool MetadataPropertyContainer::IsAncestorOf(const IObject::ConstPtr& object) const
{
return impl_.IsAncestorOf(object);
}
BASE_NS::shared_ptr MetadataPropertyContainer::EventOnAdded() const
{
return onAdded_;
}
BASE_NS::shared_ptr MetadataPropertyContainer::EventOnRemoved() const
{
return onRemoved_;
}
BASE_NS::shared_ptr MetadataPropertyContainer::EventOnMoved() const
{
return onMoved_;
}
BASE_NS::shared_ptr MetadataPropertyContainer::EventOnAdding() const
{
return onAdding_;
}
BASE_NS::shared_ptr MetadataPropertyContainer::EventOnRemoving() const
{
return onRemoving_;
}
IterationResult MetadataPropertyContainer::Iterate(const IterationParameters& params)
{
return impl_.Iterate(params);
}
IterationResult MetadataPropertyContainer::Iterate(const IterationParameters& params) const
{
return impl_.Iterate(params);
}
} // namespace Internal
META_END_NAMESPACE()