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;