1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "metadata.h"
16 
17 #include <meta/api/iteration.h>
18 #include <meta/api/util.h>
19 
20 META_BEGIN_NAMESPACE()
21 namespace Internal {
22 
CloneMetadata() const23 IMetadata::Ptr Metadata::CloneMetadata() const
24 {
25     return BASE_NS::shared_ptr<IMetadata>(new Metadata(static_cast<const IMetadata&>(*this)));
26 }
27 
Metadata()28 Metadata::Metadata()
29     : propertyContainer_(new MetadataPropertyContainer),
30       properties_(interface_pointer_cast<IContainer>(propertyContainer_))
31 {}
32 
33 // make deep copy of everything
Metadata(const IMetadata & data)34 Metadata::Metadata(const IMetadata& data)
35     : propertyContainer_(new MetadataPropertyContainer),
36       properties_(interface_pointer_cast<IContainer>(propertyContainer_))
37 {
38     for (auto&& v : data.GetAllProperties()) {
39         if (auto prop = DuplicatePropertyType(GetObjectRegistry(), v)) {
40             prop->SetValue(v->GetValue());
41             properties_->Add(prop);
42         }
43     }
44     for (auto&& v : data.GetAllEvents()) {
45         if (auto i = interface_cast<ICloneable>(v)) {
46             AddEvent(interface_pointer_cast<IEvent>(i->GetClone()));
47         }
48     }
49     for (auto&& v : data.GetAllFunctions()) {
50         if (auto i = interface_cast<ICloneable>(v)) {
51             AddFunction(interface_pointer_cast<IFunction>(i->GetClone()));
52         }
53     }
54 }
55 
GetPropertyContainer()56 IContainer::Ptr Metadata::GetPropertyContainer()
57 {
58     return properties_;
59 }
60 
GetPropertyContainer() const61 IContainer::ConstPtr Metadata::GetPropertyContainer() const
62 {
63     return properties_;
64 }
65 
AddProperty(const IProperty::Ptr & p)66 void Metadata::AddProperty(const IProperty::Ptr& p)
67 {
68     CORE_ASSERT_MSG(p, "Trying to add null property");
69     if (p) {
70         if (auto other = properties_->FindAny(IContainer::FindOptions { p->GetName(), TraversalType::NO_HIERARCHY })) {
71             if (interface_pointer_cast<IProperty>(other) == p) {
72                 CORE_LOG_W("Property already in metadata: %s", p->GetName().c_str());
73             } else {
74                 CORE_LOG_E("Property with same name already exists in metadata: %s", p->GetName().c_str());
75             }
76         } else {
77             properties_->Add(p);
78         }
79     }
80 }
81 
RemoveProperty(const IProperty::Ptr & p)82 void Metadata::RemoveProperty(const IProperty::Ptr& p)
83 {
84     if (properties_->Remove(p)) {
85         if (auto pp = interface_pointer_cast<IPropertyInternal>(p)) {
86             pp->SetOwner(nullptr);
87         }
88     }
89 }
90 
91 template<typename Container, typename Type>
AddImpl(Container & cont,const Type & p)92 static void AddImpl(Container& cont, const Type& p)
93 {
94     for (auto& pp : cont) {
95         if (p == pp) {
96             return;
97         }
98     }
99     cont.push_back(p);
100 }
101 
102 template<typename Container, typename Type>
RemoveImpl(Container & cont,const Type & p)103 static void RemoveImpl(Container& cont, const Type& p)
104 {
105     for (auto it = cont.begin(); it != cont.end(); ++it) {
106         if (*it == p) {
107             cont.erase(it);
108             return;
109         }
110     }
111 }
112 
AddFunction(const IFunction::Ptr & p)113 void Metadata::AddFunction(const IFunction::Ptr& p)
114 {
115     AddImpl(functionMetadata_, p);
116 }
117 
RemoveFunction(const IFunction::Ptr & p)118 void Metadata::RemoveFunction(const IFunction::Ptr& p)
119 {
120     RemoveImpl(functionMetadata_, p);
121 }
AddEvent(const IEvent::Ptr & p)122 void Metadata::AddEvent(const IEvent::Ptr& p)
123 {
124     AddImpl(eventMetadata_, p);
125 }
RemoveEvent(const IEvent::Ptr & p)126 void Metadata::RemoveEvent(const IEvent::Ptr& p)
127 {
128     RemoveImpl(eventMetadata_, p);
129 }
130 
SetProperties(const BASE_NS::vector<IProperty::Ptr> & vec)131 void Metadata::SetProperties(const BASE_NS::vector<IProperty::Ptr>& vec)
132 {
133     properties_->RemoveAll();
134     for (auto&& p : vec) {
135         properties_->Add(p);
136     }
137 }
138 
Merge(const IMetadata::Ptr & data)139 void Metadata::Merge(const IMetadata::Ptr& data)
140 {
141     if (auto cont = data->GetPropertyContainer()) {
142         auto vec = cont->GetAll<IProperty>();
143         for (auto&& v : vec) {
144             AddProperty(v);
145         }
146         for (auto&& v : data->GetAllEvents()) {
147             AddEvent(v);
148         }
149         for (auto&& v : data->GetAllFunctions()) {
150             AddFunction(v);
151         }
152     }
153 }
154 
155 template<typename NewContainer, typename Container>
GetAllImpl(const Container & cont)156 static NewContainer GetAllImpl(const Container& cont)
157 {
158     NewContainer res;
159     res.reserve(cont.size());
160     for (const auto& v : cont) {
161         res.push_back(v);
162     }
163     return res;
164 }
165 
GetAllProperties()166 BASE_NS::vector<IProperty::Ptr> Metadata::GetAllProperties()
167 {
168     return properties_->GetAll<IProperty>();
169 }
GetAllProperties() const170 BASE_NS::vector<IProperty::ConstPtr> Metadata::GetAllProperties() const
171 {
172     return GetAllImpl<BASE_NS::vector<IProperty::ConstPtr>>(properties_->GetAll<IProperty>());
173 }
174 
GetAllFunctions()175 BASE_NS::vector<IFunction::Ptr> Metadata::GetAllFunctions()
176 {
177     return functionMetadata_;
178 }
179 
GetAllFunctions() const180 BASE_NS::vector<IFunction::ConstPtr> Metadata::GetAllFunctions() const
181 {
182     return GetAllImpl<BASE_NS::vector<IFunction::ConstPtr>>(functionMetadata_);
183 }
184 
GetAllEvents()185 BASE_NS::vector<IEvent::Ptr> Metadata::GetAllEvents()
186 {
187     return eventMetadata_;
188 }
GetAllEvents() const189 BASE_NS::vector<IEvent::ConstPtr> Metadata::GetAllEvents() const
190 {
191     return GetAllImpl<BASE_NS::vector<IEvent::ConstPtr>>(eventMetadata_);
192 }
193 
GetPropertyByName(BASE_NS::string_view name)194 IProperty::Ptr Metadata::GetPropertyByName(BASE_NS::string_view name)
195 {
196     return properties_->FindByName<IProperty>(name);
197 }
GetPropertyByName(BASE_NS::string_view name) const198 IProperty::ConstPtr Metadata::GetPropertyByName(BASE_NS::string_view name) const
199 {
200     return properties_->FindByName<IProperty>(name);
201 }
202 
203 template<typename Ret, typename Container>
GetByName(Container && cont,BASE_NS::string_view name)204 static Ret GetByName(Container&& cont, BASE_NS::string_view name)
205 {
206     for (auto&& t : cont) {
207         if (t->GetName() == name) {
208             return t;
209         }
210     }
211     return nullptr;
212 }
213 
GetFunctionByName(BASE_NS::string_view name)214 IFunction::Ptr Metadata::GetFunctionByName(BASE_NS::string_view name)
215 {
216     return GetByName<IFunction::Ptr>(functionMetadata_, name);
217 }
GetFunctionByName(BASE_NS::string_view name) const218 IFunction::ConstPtr Metadata::GetFunctionByName(BASE_NS::string_view name) const
219 {
220     return GetByName<IFunction::ConstPtr>(functionMetadata_, name);
221 }
GetEventByName(BASE_NS::string_view name)222 IEvent::Ptr Metadata::GetEventByName(BASE_NS::string_view name)
223 {
224     return GetByName<IEvent::Ptr>(eventMetadata_, name);
225 }
GetEventByName(BASE_NS::string_view name) const226 IEvent::ConstPtr Metadata::GetEventByName(BASE_NS::string_view name) const
227 {
228     return GetByName<IEvent::ConstPtr>(eventMetadata_, name);
229 }
230 
MetadataPropertyContainer()231 MetadataPropertyContainer::MetadataPropertyContainer()
232 {
233     impl_.SetImplementingIContainer(nullptr, this);
234     SetRequiredInterfaces({ IProperty::UID });
235 }
236 
GetAll() const237 BASE_NS::vector<IObject::Ptr> MetadataPropertyContainer::GetAll() const
238 {
239     return impl_.GetAll();
240 }
GetAt(SizeType index) const241 IObject::Ptr MetadataPropertyContainer::GetAt(SizeType index) const
242 {
243     return impl_.GetAt(index);
244 }
GetSize() const245 IContainer::SizeType MetadataPropertyContainer::GetSize() const
246 {
247     return impl_.GetSize();
248 }
FindAll(const FindOptions & options) const249 BASE_NS::vector<IObject::Ptr> MetadataPropertyContainer::FindAll(const FindOptions& options) const
250 {
251     return impl_.FindAll(options);
252 }
FindAny(const FindOptions & options) const253 IObject::Ptr MetadataPropertyContainer::FindAny(const FindOptions& options) const
254 {
255     return impl_.FindAny(options);
256 }
FindByName(BASE_NS::string_view name) const257 IObject::Ptr MetadataPropertyContainer::FindByName(BASE_NS::string_view name) const
258 {
259     return impl_.FindByName(name);
260 }
Add(const IObject::Ptr & object)261 bool MetadataPropertyContainer::Add(const IObject::Ptr& object)
262 {
263     return impl_.Add(object);
264 }
Insert(SizeType index,const IObject::Ptr & object)265 bool MetadataPropertyContainer::Insert(SizeType index, const IObject::Ptr& object)
266 {
267     return impl_.Insert(index, object);
268 }
Remove(SizeType index)269 bool MetadataPropertyContainer::Remove(SizeType index)
270 {
271     return impl_.Remove(index);
272 }
Remove(const IObject::Ptr & child)273 bool MetadataPropertyContainer::Remove(const IObject::Ptr& child)
274 {
275     return impl_.Remove(child);
276 }
Move(SizeType fromIndex,SizeType toIndex)277 bool MetadataPropertyContainer::Move(SizeType fromIndex, SizeType toIndex)
278 {
279     return impl_.Move(fromIndex, toIndex);
280 }
Move(const IObject::Ptr & child,SizeType toIndex)281 bool MetadataPropertyContainer::Move(const IObject::Ptr& child, SizeType toIndex)
282 {
283     return impl_.Move(child, toIndex);
284 }
Replace(const IObject::Ptr & child,const IObject::Ptr & replaceWith,bool addAlways)285 bool MetadataPropertyContainer::Replace(const IObject::Ptr& child, const IObject::Ptr& replaceWith, bool addAlways)
286 {
287     return impl_.Replace(child, replaceWith, addAlways);
288 }
RemoveAll()289 void MetadataPropertyContainer::RemoveAll()
290 {
291     return impl_.RemoveAll();
292 }
SetRequiredInterfaces(const BASE_NS::vector<TypeId> & interfaces)293 bool MetadataPropertyContainer::SetRequiredInterfaces(const BASE_NS::vector<TypeId>& interfaces)
294 {
295     return false;
296 }
GetRequiredInterfaces() const297 BASE_NS::vector<TypeId> MetadataPropertyContainer::GetRequiredInterfaces() const
298 {
299     return impl_.GetRequiredInterfaces();
300 }
IsAncestorOf(const IObject::ConstPtr & object) const301 bool MetadataPropertyContainer::IsAncestorOf(const IObject::ConstPtr& object) const
302 {
303     return impl_.IsAncestorOf(object);
304 }
EventOnAdded() const305 BASE_NS::shared_ptr<IEvent> MetadataPropertyContainer::EventOnAdded() const
306 {
307     return onAdded_;
308 }
EventOnRemoved() const309 BASE_NS::shared_ptr<IEvent> MetadataPropertyContainer::EventOnRemoved() const
310 {
311     return onRemoved_;
312 }
EventOnMoved() const313 BASE_NS::shared_ptr<IEvent> MetadataPropertyContainer::EventOnMoved() const
314 {
315     return onMoved_;
316 }
EventOnAdding() const317 BASE_NS::shared_ptr<IEvent> MetadataPropertyContainer::EventOnAdding() const
318 {
319     return onAdding_;
320 }
EventOnRemoving() const321 BASE_NS::shared_ptr<IEvent> MetadataPropertyContainer::EventOnRemoving() const
322 {
323     return onRemoving_;
324 }
Iterate(const IterationParameters & params)325 IterationResult MetadataPropertyContainer::Iterate(const IterationParameters& params)
326 {
327     return impl_.Iterate(params);
328 }
Iterate(const IterationParameters & params) const329 IterationResult MetadataPropertyContainer::Iterate(const IterationParameters& params) const
330 {
331     return impl_.Iterate(params);
332 }
333 
334 } // namespace Internal
335 
336 META_END_NAMESPACE()
337