2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
22 import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec;
23 import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO.IdentityValue;
24 import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO.Predicate;
25 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
26 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.Module;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 class InstanceIdentifierCodecImpl extends AbstractCodecImpl implements InstanceIdentifierCodec<IdentityValuesDTO> {
34 private static final Logger LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl.class);
36 InstanceIdentifierCodecImpl(final SchemaContextUtils schema) {
41 public IdentityValuesDTO serialize(final YangInstanceIdentifier data) {
42 IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO();
43 for (PathArgument pathArgument : data.getPathArguments()) {
44 IdentityValue identityValue = qNameToIdentityValue(pathArgument.getNodeType());
45 if (pathArgument instanceof NodeIdentifierWithPredicates && identityValue != null) {
46 List<Predicate> predicates = keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument)
48 identityValue.setPredicates(predicates);
49 } else if (pathArgument instanceof NodeWithValue && identityValue != null) {
50 List<Predicate> predicates = new ArrayList<>();
51 String value = String.valueOf(((NodeWithValue) pathArgument).getValue());
52 predicates.add(new Predicate(null, value));
53 identityValue.setPredicates(predicates);
55 identityValuesDTO.add(identityValue);
57 return identityValuesDTO;
61 public YangInstanceIdentifier deserialize(final IdentityValuesDTO data) {
62 List<PathArgument> result = new ArrayList<PathArgument>();
63 IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
64 Module module = getModuleByNamespace(valueWithNamespace.getNamespace());
66 LOG.info("Module by namespace '{}' of first node in instance-identiefier was not found.",
67 valueWithNamespace.getNamespace());
68 LOG.info("Instance-identifier will be translated as NULL for data - {}",
69 String.valueOf(valueWithNamespace.getValue()));
73 DataNodeContainer parentContainer = module;
74 List<IdentityValue> identities = data.getValuesWithNamespaces();
75 for (int i = 0; i < identities.size(); i++) {
76 IdentityValue identityValue = identities.get(i);
77 URI validNamespace = resolveValidNamespace(identityValue.getNamespace());
78 DataSchemaNode node = getSchema().findInstanceDataChildByNameAndNamespace(
79 parentContainer, identityValue.getValue(), validNamespace);
81 LOG.info("'{}' node was not found in {}", identityValue, parentContainer.getChildNodes());
82 LOG.info("Instance-identifier will be translated as NULL for data - {}",
83 String.valueOf(identityValue.getValue()));
86 QName qName = node.getQName();
87 PathArgument pathArgument = null;
88 if (identityValue.getPredicates().isEmpty()) {
89 pathArgument = new NodeIdentifier(qName);
91 if (node instanceof LeafListSchemaNode) { // predicate is value of leaf-list entry
92 Predicate leafListPredicate = identityValue.getPredicates().get(0);
93 if (!leafListPredicate.isLeafList()) {
94 LOG.info("Predicate's data is not type of leaf-list. It should be in format \".='value'\"");
95 LOG.info("Instance-identifier will be translated as NULL for data - {}",
96 String.valueOf(identityValue.getValue()));
99 pathArgument = new NodeWithValue(qName, leafListPredicate.getValue());
100 } else if (node instanceof ListSchemaNode) { // predicates are keys of list
101 DataNodeContainer listNode = (DataNodeContainer) node;
102 Map<QName, Object> predicatesMap = new HashMap<>();
103 for (Predicate predicate : identityValue.getPredicates()) {
104 validNamespace = resolveValidNamespace(predicate.getName().getNamespace());
105 DataSchemaNode listKey = getSchema()
106 .findInstanceDataChildByNameAndNamespace(listNode, predicate.getName().getValue(),
108 predicatesMap.put(listKey.getQName(), predicate.getValue());
110 pathArgument = new NodeIdentifierWithPredicates(qName, predicatesMap);
112 LOG.info("Node {} is not List or Leaf-list.", node);
113 LOG.info("Instance-identifier will be translated as NULL for data - {}",
114 String.valueOf(identityValue.getValue()));
118 result.add(pathArgument);
119 if (i < identities.size() - 1) { // last element in instance-identifier can be other than
121 if (node instanceof DataNodeContainer) {
122 parentContainer = (DataNodeContainer) node;
124 LOG.info("Node {} isn't instance of DataNodeContainer", node);
125 LOG.info("Instance-identifier will be translated as NULL for data - {}",
126 String.valueOf(identityValue.getValue()));
132 return result.isEmpty() ? null : YangInstanceIdentifier.create(result);
135 private static List<Predicate> keyValuesToPredicateList(final Map<QName, Object> keyValues) {
136 List<Predicate> result = new ArrayList<>();
137 for (QName qName : keyValues.keySet()) {
138 Object value = keyValues.get(qName);
139 result.add(new Predicate(qNameToIdentityValue(qName), String.valueOf(value)));
144 private static IdentityValue qNameToIdentityValue(final QName qName) {
146 // FIXME: the prefix here is completely arbitrary
147 return new IdentityValue(qName.getNamespace().toString(), qName.getLocalName(), qName.getPrefix());