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
16 #define JSON_IMPL
17 #include "json_output.h"
18
19 #include <base/containers/vector.h>
20 #include <base/util/uid_util.h>
21 #include <core/json/json.h>
22
23 #include <meta/base/namespace.h>
24 #include <meta/base/plugin.h>
25 #include <meta/base/ref_uri.h>
26 #include <meta/ext/minimal_object.h>
27
28 META_BEGIN_NAMESPACE()
29
30 namespace Serialization {
31
32 META_REGISTER_CLASS(Visitor, "2838202a-b362-4715-96ed-59f19334b3ac", ObjectCategoryBits::NO_CATEGORY)
33
34 struct Visitor : IntroduceInterfaces<MinimalObject, ISerNodeVisitor> {
META_IMPLEMENT_OBJECT_TYPE_INTERFACESerialization::Visitor35 META_IMPLEMENT_OBJECT_TYPE_INTERFACE(ClassId::Visitor)
36
37 json_value GetValue()
38 {
39 return BASE_NS::move(node_);
40 }
41
42 private:
VisitSerialization::Visitor43 void Visit(const IRootNode&) override
44 {
45 CORE_LOG_E("Second root node, ignoring...");
46 }
VisitSerialization::Visitor47 void Visit(const INilNode&) override
48 {
49 node_ = json_value::null {};
50 }
VisitSerialization::Visitor51 void Visit(const IObjectNode& n) override
52 {
53 json_value::object object;
54 if (n.GetObjectId().IsValid() && n.GetMembers()) {
55 Visitor v;
56 n.GetMembers()->Apply(v);
57 auto value = v.GetValue();
58 if (value.is_object()) {
59 object.emplace_back("$classId", json_value::string(n.GetObjectId().ToString()));
60 if (!n.GetObjectClassName().empty()) {
61 object.emplace_back("$className", json_value::string(n.GetObjectClassName()));
62 }
63 if (!n.GetObjectName().empty()) {
64 object.emplace_back("$name", json_value::string(n.GetObjectName()));
65 }
66 if (n.GetInstanceId().IsValid()) {
67 object.emplace_back("$instanceId", json_value::string(n.GetInstanceId().ToString()));
68 }
69 json_value::object obj = value.object_;
70 object.insert(object.end(), obj.begin(), obj.end());
71 }
72 }
73 node_ = BASE_NS::move(object);
74 }
VisitSerialization::Visitor75 void Visit(const IArrayNode& n) override
76 {
77 auto members = n.GetMembers();
78 json_value::array array;
79 array.reserve(members.size());
80 for (auto&& m : members) {
81 Visitor v;
82 m->Apply(v);
83 array.emplace_back(v.GetValue());
84 }
85 node_ = BASE_NS::move(array);
86 }
VisitSerialization::Visitor87 void Visit(const IMapNode& n) override
88 {
89 auto members = n.GetMembers();
90 json_value::object object;
91 for (auto&& m : members) {
92 Visitor v;
93 m.node->Apply(v);
94 object.emplace_back(BASE_NS::move(m.name), v.GetValue());
95 }
96 node_ = BASE_NS::move(object);
97 }
VisitSerialization::Visitor98 void Visit(const IBuiltinValueNode<bool>& n) override
99 {
100 node_ = json_value { n.GetValue() };
101 }
VisitSerialization::Visitor102 void Visit(const IBuiltinValueNode<double>& n) override
103 {
104 node_ = json_value { n.GetValue() };
105 }
VisitSerialization::Visitor106 void Visit(const IBuiltinValueNode<int64_t>& n) override
107 {
108 node_ = json_value { n.GetValue() };
109 }
VisitSerialization::Visitor110 void Visit(const IBuiltinValueNode<uint64_t>& n) override
111 {
112 node_ = json_value { n.GetValue() };
113 }
VisitSerialization::Visitor114 void Visit(const IBuiltinValueNode<BASE_NS::string>& n) override
115 {
116 node_ = json_value { n.GetValue() };
117 }
VisitSerialization::Visitor118 void Visit(const IBuiltinValueNode<RefUri>& n) override
119 {
120 json_value::object object;
121 object.emplace_back("$ref", n.GetValue().ToString());
122 node_ = BASE_NS::move(object);
123 }
VisitSerialization::Visitor124 void Visit(const ISerNode&) override
125 {
126 CORE_LOG_E("Unknown node type");
127 }
128
129 private:
130 json_value node_;
131 };
132
MetadataObject(const IRootNode & root)133 json_value MetadataObject(const IRootNode& root)
134 {
135 json_value::object object;
136 object.emplace_back("meta-version", json_value::string(META_VERSION.ToString()));
137 for (auto&& v : root.GetMetadata()) {
138 object.emplace_back(BASE_NS::string(v.key), json_value::string(v.data));
139 }
140 return object;
141 }
142
Process(const ISerNode::Ptr & tree)143 BASE_NS::string JsonOutput::Process(const ISerNode::Ptr& tree)
144 {
145 CORE_NS::json::standalone_value res;
146
147 if (auto root = interface_cast<IRootNode>(tree)) {
148 if (root->GetObject()) {
149 json_value::object object;
150 object.emplace_back("$meta", MetadataObject(*root));
151
152 Visitor v;
153 root->GetObject()->Apply(v);
154 auto node = v.GetValue();
155 if (node.is_object()) {
156 object.emplace_back("$root", BASE_NS::move(node));
157 res = BASE_NS::move(object);
158 } else {
159 CORE_LOG_E("failed to output root node object");
160 }
161 } else {
162 CORE_LOG_E("root node did not contain object");
163 }
164 }
165 return CORE_NS::json::to_string(res);
166 }
167
168 } // namespace Serialization
169
170 META_END_NAMESPACE()
171