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.common.QName;
29 import org.opendaylight.yangtools.yang.common.Revision;
30 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
36 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
38 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
40 import java.util.Deque;
42 import static java.lang.String.format;
43 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.DF_ERR;
44 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
45 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.PROP_NODE_ERR;
46 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.getResolvedNamespace;
47 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.resolveBaseTypeFrom;
48 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision;
49 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE;
50 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE;
51 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
52 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
53 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
54 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE;
55 import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findDataChildSchemaByQName;
56 import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findSchemaForChild;
57 import static org.opendaylight.yangtools.yang.data.util.ParserStreamUtils.findSchemaNodeByNameAndNamespace;
60 * Representation of MDSAL based serializer helper, which adds properties
61 * node to the properties tree based on its types.
63 public class MdsalSerializerHelper extends SerializerHelper<SchemaNode, SchemaContext> {
66 * Current properties node.
68 private PropertiesNode propNode;
71 * Current schema node.
73 private SchemaNode curSchemaNode;
77 * Creates MDSAL serializer helper with root schema node, schema context
80 * @param n schema node of the URI's last node
81 * @param c schema context
82 * @param u URI of the request
84 public MdsalSerializerHelper(SchemaNode n, SchemaContext c,
87 Namespace ns = new Namespace(n.getQName().getLocalName(),
88 n.getQName().getNamespace(),
89 getRevision(n.getQName().getRevision()));
90 propNode = new RootNode<>(n.getQName().getLocalName(), ns,
92 curSchemaNode = getSchemaNode();
96 protected SchemaNode getSchemaNode() {
101 protected SchemaContext getSchemaCtx() {
106 protected SchemaNode getCurSchema() {
107 return curSchemaNode;
111 protected void addNode(String name, String nameSpace, String value,
112 String valNameSpace, NodeType type)
113 throws SvcLogicException {
116 ns = getResolvedNamespace(null, nameSpace,
117 getSchemaCtx(), propNode);
119 ns = getResolvedNamespace(nameSpace, null,
120 getSchemaCtx(), propNode);
122 if (isChildPresent(name, ns)) {
123 addNodeToProperty(name, ns, value, valNameSpace, type);
125 throw new SvcLogicException(format(
126 "Unable to add the node %s", name));
131 protected void exitNode() throws SvcLogicException {
132 propNode = propNode.parent();
133 if (propNode != null) {
134 NodeType type = propNode.nodeType();
135 if (type == MULTI_INSTANCE_HOLDER_NODE ||
136 type == MULTI_INSTANCE_LEAF_HOLDER_NODE) {
137 propNode = propNode.parent();
140 if (propNode == null || propNode.appInfo() == null
141 || !(propNode.appInfo() instanceof SchemaNode)) {
142 throw new SvcLogicException(PROP_NODE_ERR);
144 curSchemaNode = (SchemaNode) propNode.appInfo();
148 protected PropertiesNode getPropertiesNode() {
153 * Adds the node to property node based on the type of the schema node,
154 * which is decided based on the name and namespace of the input
157 * @param name name of the node
158 * @param ns namespace of the node
159 * @param value value of the node if its a leaf/leaf-list
160 * @param valNamespace namespace of the value
161 * @param type type of the node
162 * @throws SvcLogicException when adding child fails
164 private void addNodeToProperty(String name, Namespace ns, String value,
165 String valNamespace, NodeType type)
166 throws SvcLogicException {
169 validateNodeType(type);
171 if (curSchemaNode instanceof LeafSchemaNode) {
172 valueNs = getValueNs(curSchemaNode, valNamespace, type);
173 propNode = propNode.addChild(name, ns,
174 SINGLE_INSTANCE_LEAF_NODE,
175 value, valueNs, curSchemaNode);
176 } else if (curSchemaNode instanceof LeafListSchemaNode) {
177 valueNs = getValueNs(curSchemaNode, valNamespace, type);
178 propNode = propNode.addChild(null, name, ns,
179 MULTI_INSTANCE_LEAF_NODE, value,
180 valueNs, curSchemaNode);
181 } else if (curSchemaNode instanceof ListSchemaNode) {
182 propNode = propNode.addChild(null, name, ns, MULTI_INSTANCE_NODE,
185 propNode = propNode.addChild(name, ns, SINGLE_INSTANCE_NODE,
191 * Returns the namespace of the value namespace in case of identity ref.
193 * @param schemaNode schema node
194 * @param valNs value name space
195 * @param nodeType node type
196 * @return namespace of value namespace
197 * @throws SvcLogicException when namespace resolution fails for identityref
199 private Namespace getValueNs(SchemaNode schemaNode, String valNs,
200 NodeType nodeType) throws SvcLogicException {
204 if (schemaNode instanceof LeafSchemaNode) {
205 type = ((LeafSchemaNode) schemaNode).getType();
207 type = ((LeafListSchemaNode) schemaNode).getType();
209 TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
210 if (baseType instanceof IdentityrefTypeDefinition) {
211 if (nodeType == null) {
212 ns = getResolvedNamespace(null, valNs, getSchemaCtx(),
215 ns = getResolvedNamespace(valNs, null, getSchemaCtx(),
224 * Validates that the node type from the data format matches with that of
225 * the corresponding schema node.
227 * @param type node type from the abstract data format
228 * @throws SvcLogicException when the node type is wrong
230 private void validateNodeType(NodeType type) throws SvcLogicException {
233 case SINGLE_INSTANCE_LEAF_NODE:
234 verify = curSchemaNode instanceof LeafSchemaNode;
237 case MULTI_INSTANCE_LEAF_NODE:
238 verify = curSchemaNode instanceof LeafListSchemaNode;
241 case MULTI_INSTANCE_NODE:
242 verify = curSchemaNode instanceof ListSchemaNode;
245 case SINGLE_INSTANCE_NODE:
246 verify = (!(curSchemaNode instanceof LeafSchemaNode) &&
247 !(curSchemaNode instanceof LeafListSchemaNode) &&
248 !(curSchemaNode instanceof ListSchemaNode));
252 throw new SvcLogicException(format(NODE_TYPE_ERR,
256 throw new SvcLogicException(format(DF_ERR, curSchemaNode
257 .getQName().getLocalName(), type.toString()));
262 * Returns true if the child schema is present with the name and
263 * namespace inside the current schema node, if present updates the
264 * current schema node; false otherwise.
266 * @param name name of the child schema node
267 * @param namespace namespace of the child schema node
268 * @return returns true if the child schema is available; false otherwise
270 private boolean isChildPresent(String name, Namespace namespace) {
271 QName qname = QName.create(namespace.moduleNs(),
272 Revision.of(namespace.revision()), name);
273 SchemaNode childNode = null;
274 if (curSchemaNode instanceof DataSchemaNode) {
275 Deque<DataSchemaNode> dataSchema = findSchemaNodeByNameAndNamespace(
276 (DataSchemaNode) curSchemaNode, name, namespace.moduleNs());
277 if (dataSchema != null && !dataSchema.isEmpty()) {
278 childNode = dataSchema.pop();
281 if (!dataSchema.isEmpty()) {
282 childNode = findSchemaForChild(((ChoiceSchemaNode) childNode),
287 childNode = findDataChildSchemaByQName(curSchemaNode, qname);
290 if (childNode != null) {
291 curSchemaNode = childNode;