18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci#include "functions.h"
168bf80f4bSopenharmony_ci
178bf80f4bSopenharmony_ci#include <meta/ext/serialization/serializer.h>
188bf80f4bSopenharmony_ci
198bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
208bf80f4bSopenharmony_ci
218bf80f4bSopenharmony_ciBASE_NS::string SettableFunction::GetName() const
228bf80f4bSopenharmony_ci{
238bf80f4bSopenharmony_ci    auto p = func_.lock();
248bf80f4bSopenharmony_ci    return p ? p->GetName() : BASE_NS::string();
258bf80f4bSopenharmony_ci}
268bf80f4bSopenharmony_ciIObject::ConstPtr SettableFunction::GetDestination() const
278bf80f4bSopenharmony_ci{
288bf80f4bSopenharmony_ci    auto p = func_.lock();
298bf80f4bSopenharmony_ci    return p ? p->GetDestination() : nullptr;
308bf80f4bSopenharmony_ci}
318bf80f4bSopenharmony_civoid SettableFunction::Invoke(const ICallContext::Ptr& context) const
328bf80f4bSopenharmony_ci{
338bf80f4bSopenharmony_ci    if (auto p = func_.lock()) {
348bf80f4bSopenharmony_ci        p->Invoke(context);
358bf80f4bSopenharmony_ci    }
368bf80f4bSopenharmony_ci}
378bf80f4bSopenharmony_ciICallContext::Ptr SettableFunction::CreateCallContext() const
388bf80f4bSopenharmony_ci{
398bf80f4bSopenharmony_ci    auto p = func_.lock();
408bf80f4bSopenharmony_ci    return p ? p->CreateCallContext() : nullptr;
418bf80f4bSopenharmony_ci}
428bf80f4bSopenharmony_cibool SettableFunction::SetTarget(const IObject::Ptr& obj, BASE_NS::string_view name)
438bf80f4bSopenharmony_ci{
448bf80f4bSopenharmony_ci    return ResolveFunction(obj, name);
458bf80f4bSopenharmony_ci}
468bf80f4bSopenharmony_cibool SettableFunction::ResolveFunction(const IObject::Ptr& obj, BASE_NS::string_view name)
478bf80f4bSopenharmony_ci{
488bf80f4bSopenharmony_ci    func_ = nullptr;
498bf80f4bSopenharmony_ci    if (auto metad = interface_cast<IMetadata>(obj)) {
508bf80f4bSopenharmony_ci        func_ = metad->GetFunctionByName(name);
518bf80f4bSopenharmony_ci    }
528bf80f4bSopenharmony_ci    return !func_.expired();
538bf80f4bSopenharmony_ci}
548bf80f4bSopenharmony_ciReturnError SettableFunction::Export(IExportContext& c) const
558bf80f4bSopenharmony_ci{
568bf80f4bSopenharmony_ci    if (auto func = func_.lock()) {
578bf80f4bSopenharmony_ci        if (auto dest = func->GetDestination()) {
588bf80f4bSopenharmony_ci            return Serializer(c) & NamedValue("Destination", dest) & NamedValue("Function", func->GetName());
598bf80f4bSopenharmony_ci        }
608bf80f4bSopenharmony_ci        CORE_LOG_E("No destination object with Function");
618bf80f4bSopenharmony_ci    }
628bf80f4bSopenharmony_ci    return GenericError::FAIL;
638bf80f4bSopenharmony_ci}
648bf80f4bSopenharmony_ciReturnError SettableFunction::Import(IImportContext& c)
658bf80f4bSopenharmony_ci{
668bf80f4bSopenharmony_ci    IObject::Ptr p;
678bf80f4bSopenharmony_ci    BASE_NS::string func;
688bf80f4bSopenharmony_ci    Serializer ser(c);
698bf80f4bSopenharmony_ci    if (ser & NamedValue("Destination", p) & NamedValue("Function", func)) {
708bf80f4bSopenharmony_ci        if (ResolveFunction(p, func)) {
718bf80f4bSopenharmony_ci            return GenericError::SUCCESS;
728bf80f4bSopenharmony_ci        }
738bf80f4bSopenharmony_ci    }
748bf80f4bSopenharmony_ci    return GenericError::FAIL;
758bf80f4bSopenharmony_ci}
768bf80f4bSopenharmony_ci
778bf80f4bSopenharmony_ciBASE_NS::string PropertyFunction::GetName() const
788bf80f4bSopenharmony_ci{
798bf80f4bSopenharmony_ci    auto p = prop_.lock();
808bf80f4bSopenharmony_ci    return p ? p->GetName() : BASE_NS::string();
818bf80f4bSopenharmony_ci}
828bf80f4bSopenharmony_ciIObject::ConstPtr PropertyFunction::GetDestination() const
838bf80f4bSopenharmony_ci{
848bf80f4bSopenharmony_ci    return interface_pointer_cast<IObject>(prop_.lock());
858bf80f4bSopenharmony_ci}
868bf80f4bSopenharmony_civoid PropertyFunction::Invoke(const ICallContext::Ptr& context) const
878bf80f4bSopenharmony_ci{
888bf80f4bSopenharmony_ci    if (auto p = prop_.lock()) {
898bf80f4bSopenharmony_ci        context->SetResult(p->GetValue());
908bf80f4bSopenharmony_ci    } else {
918bf80f4bSopenharmony_ci        CORE_LOG_W("Invoked property function without valid property");
928bf80f4bSopenharmony_ci    }
938bf80f4bSopenharmony_ci}
948bf80f4bSopenharmony_ciICallContext::Ptr PropertyFunction::CreateCallContext() const
958bf80f4bSopenharmony_ci{
968bf80f4bSopenharmony_ci    ICallContext::Ptr context;
978bf80f4bSopenharmony_ci    if (auto i = interface_pointer_cast<IPropertyInternalAny>(prop_)) {
988bf80f4bSopenharmony_ci        if (auto any = i->GetInternalAny()) {
998bf80f4bSopenharmony_ci            context = GetObjectRegistry().ConstructDefaultCallContext();
1008bf80f4bSopenharmony_ci            if (context) {
1018bf80f4bSopenharmony_ci                context->DefineResult(any->Clone(false));
1028bf80f4bSopenharmony_ci            }
1038bf80f4bSopenharmony_ci        }
1048bf80f4bSopenharmony_ci    }
1058bf80f4bSopenharmony_ci    return context;
1068bf80f4bSopenharmony_ci}
1078bf80f4bSopenharmony_cibool PropertyFunction::SetTarget(const IProperty::ConstPtr& prop)
1088bf80f4bSopenharmony_ci{
1098bf80f4bSopenharmony_ci    prop_ = prop;
1108bf80f4bSopenharmony_ci    return false;
1118bf80f4bSopenharmony_ci}
1128bf80f4bSopenharmony_ciReturnError PropertyFunction::Export(IExportContext& c) const
1138bf80f4bSopenharmony_ci{
1148bf80f4bSopenharmony_ci    return Serializer(c) & NamedValue("source", prop_);
1158bf80f4bSopenharmony_ci}
1168bf80f4bSopenharmony_ciReturnError PropertyFunction::Import(IImportContext& c)
1178bf80f4bSopenharmony_ci{
1188bf80f4bSopenharmony_ci    return Serializer(c) & NamedValue("source", uri_);
1198bf80f4bSopenharmony_ci}
1208bf80f4bSopenharmony_ciReturnError PropertyFunction::Finalize(IImportFunctions& funcs)
1218bf80f4bSopenharmony_ci{
1228bf80f4bSopenharmony_ci    if (uri_.IsValid() && uri_.ReferencesProperty()) {
1238bf80f4bSopenharmony_ci        auto objUri = uri_;
1248bf80f4bSopenharmony_ci        objUri.TakeLastNode();
1258bf80f4bSopenharmony_ci        if (auto obj = interface_pointer_cast<IMetadata>(funcs.ResolveRefUri(objUri))) {
1268bf80f4bSopenharmony_ci            if (auto prop = obj->GetPropertyByName(uri_.ReferencedName())) {
1278bf80f4bSopenharmony_ci                prop_ = prop;
1288bf80f4bSopenharmony_ci            }
1298bf80f4bSopenharmony_ci            return GenericError::SUCCESS;
1308bf80f4bSopenharmony_ci        }
1318bf80f4bSopenharmony_ci    }
1328bf80f4bSopenharmony_ci    return GenericError::FAIL;
1338bf80f4bSopenharmony_ci}
1348bf80f4bSopenharmony_ci
1358bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
136