2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
23 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
24 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
25 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType;
26 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
27 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.RootNode;
28 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
33 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
35 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
37 import java.util.Deque;
39 import static java.lang.String.format;
40 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.DF_ERR;
41 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
42 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.PROP_NODE_ERR;
43 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.getResolvedNamespace;
44 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.resolveBaseTypeFrom;
45 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision;
46 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE;
47 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE;
48 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
49 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
50 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
51 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE;
52 import static org.opendaylight.yangtools.yang.data.util.ParserStreamUtils.findSchemaNodeByNameAndNamespace;
55 * Representation of MDSAL based serializer helper, which adds properties
56 * node to the properties tree based on its types.
58 public class MdsalSerializerHelper extends SerializerHelper<SchemaNode, SchemaContext> {
61 * Current properties node.
63 private PropertiesNode propNode;
66 * Current schema node.
68 private SchemaNode curSchemaNode;
72 * Creates MDSAL serializer helper with root schema node, schema context
75 * @param n schema node of the URI's last node
76 * @param c schema context
77 * @param u URI of the request
79 public MdsalSerializerHelper(SchemaNode n, SchemaContext c,
82 Namespace ns = new Namespace(n.getQName().getLocalName(),
83 n.getQName().getNamespace(),
84 getRevision(n.getQName().getRevision()));
85 propNode = new RootNode<>(n.getQName().getLocalName(), ns,
87 curSchemaNode = getSchemaNode();
91 protected SchemaNode getSchemaNode() {
96 protected SchemaContext getSchemaCtx() {
101 protected SchemaNode getCurSchema() {
102 return curSchemaNode;
106 protected void addNode(String name, String nameSpace, String value,
107 String valNameSpace, NodeType type)
108 throws SvcLogicException {
111 ns = getResolvedNamespace(null, curSchemaNode, getSchemaCtx(),
112 nameSpace, propNode);
114 ns = getResolvedNamespace(nameSpace, curSchemaNode, getSchemaCtx(),
115 nameSpace, propNode);
117 if (isChildPresent(name, ns)) {
118 addNodeToProperty(name, ns, value, valNameSpace, type);
123 protected void exitNode() throws SvcLogicException {
124 propNode = propNode.parent();
125 if (propNode != null) {
126 NodeType type = propNode.nodeType();
127 if (type == MULTI_INSTANCE_HOLDER_NODE ||
128 type == MULTI_INSTANCE_LEAF_HOLDER_NODE) {
129 propNode = propNode.parent();
132 if (propNode == null || propNode.appInfo() == null
133 || !(propNode.appInfo() instanceof SchemaNode)) {
134 throw new SvcLogicException(PROP_NODE_ERR);
136 curSchemaNode = (SchemaNode) propNode.appInfo();
140 protected PropertiesNode getPropertiesNode() {
145 * Adds the node to property node based on the type of the schema node,
146 * which is decided based on the name and namespace of the input
149 * @param name name of the node
150 * @param ns namespace of the node
151 * @param value value of the node if its a leaf/leaf-list
152 * @param valNamespace namespace of the value
153 * @param type type of the node
154 * @throws SvcLogicException when adding child fails
156 private void addNodeToProperty(String name, Namespace ns, String value,
157 String valNamespace, NodeType type)
158 throws SvcLogicException {
161 validateNodeType(type);
163 if (curSchemaNode instanceof LeafSchemaNode) {
164 valueNs = getValueNs(curSchemaNode, valNamespace, type);
165 propNode = propNode.addChild(name, ns,
166 SINGLE_INSTANCE_LEAF_NODE,
167 value, valueNs, curSchemaNode);
168 } else if (curSchemaNode instanceof LeafListSchemaNode) {
169 valueNs = getValueNs(curSchemaNode, valNamespace, type);
170 propNode = propNode.addChild(null, name, ns,
171 MULTI_INSTANCE_LEAF_NODE, value,
172 valueNs, curSchemaNode);
173 } else if (curSchemaNode instanceof ListSchemaNode) {
174 propNode = propNode.addChild(null, name, ns, MULTI_INSTANCE_NODE,
177 propNode = propNode.addChild(name, ns, SINGLE_INSTANCE_NODE,
183 * Returns the namespace of the value namespace in case of identity ref.
185 * @param schemaNode schema node
186 * @param valNs value name space
187 * @param nodeType node type
188 * @return namespace of value namespace
189 * @throws SvcLogicException when namespace resolution fails for identityref
191 private Namespace getValueNs(SchemaNode schemaNode, String valNs,
192 NodeType nodeType) throws SvcLogicException {
195 TypeDefinition type = ((LeafSchemaNode) schemaNode).getType();
196 TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
197 if (baseType instanceof IdentityrefTypeDefinition) {
198 if (nodeType == null) {
199 ns = getResolvedNamespace(null,schemaNode, getSchemaCtx(),
202 ns = getResolvedNamespace(valNs, schemaNode, getSchemaCtx(),
211 * Validates that the node type from the data format matches with that of
212 * the corresponding schema node.
214 * @param type node type from the abstract data format
215 * @throws SvcLogicException when the node type is wrong
217 private void validateNodeType(NodeType type) throws SvcLogicException {
220 case SINGLE_INSTANCE_LEAF_NODE:
221 verify = curSchemaNode instanceof LeafSchemaNode;
224 case MULTI_INSTANCE_LEAF_NODE:
225 verify = curSchemaNode instanceof LeafListSchemaNode;
228 case MULTI_INSTANCE_NODE:
229 verify = curSchemaNode instanceof ListSchemaNode;
232 case SINGLE_INSTANCE_NODE:
233 verify = (!(curSchemaNode instanceof LeafSchemaNode) &&
234 !(curSchemaNode instanceof LeafListSchemaNode) &&
235 !(curSchemaNode instanceof ListSchemaNode));
239 throw new SvcLogicException(format(NODE_TYPE_ERR,
243 throw new SvcLogicException(format(DF_ERR, curSchemaNode
244 .getQName().getLocalName(), type.toString()));
249 * Returns true if the child schema is present with the name and
250 * namespace inside the current schema node, if present updates the
251 * current schema node; false otherwise.
253 * @param name name of the child schema node
254 * @param namespace namespace of the child schema node
255 * @return returns true if the child schema is available; false otherwise
257 private boolean isChildPresent(String name, Namespace namespace) {
258 Deque<DataSchemaNode> dataSchema = findSchemaNodeByNameAndNamespace(
259 (DataSchemaNode) curSchemaNode, name, namespace.moduleNs());
260 if (dataSchema != null) {
261 DataSchemaNode node = dataSchema.pop();
263 curSchemaNode = node;