2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.onap.cps.api.impl;
22 import com.google.common.collect.ImmutableList;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
29 import java.util.Optional;
32 import org.opendaylight.yangtools.yang.common.QName;
33 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.Module;
37 * Class to store a Yang Fragment (container or list element).
39 public class Fragment {
42 private final String xpath;
45 private final Map<String, Object> attributes = new HashMap<>();
48 private final Module module;
51 private final Fragment parentFragment;
54 private final Set<Fragment> childFragments = new HashSet<>(0);
56 private final QName[] qnames;
58 private Optional<Set<String>> optionalLeafListNames = Optional.empty();
61 * Create a root Fragment.
63 * @param module the Yang module that encompasses this fragment
64 * @param qnames the list of qualified names that points the schema node for this fragment
65 * @param xpath the xpath of root fragment
67 public static Fragment createRootFragment(final Module module, final QName[] qnames, final String xpath) {
68 return new Fragment(null, module, qnames, xpath);
72 * Create a Child Fragment under a given Parent Fragment.
74 * @param parentFragment the parent (can be null for 'root' objects)
75 * @param module the Yang module that encompasses this fragment
76 * @param qnames array of qualified names that points the schema node for this fragment
77 * @param xpath the xpath for this fragment
79 private Fragment(final Fragment parentFragment, final Module module, final QName[] qnames, final String xpath) {
80 this.parentFragment = parentFragment;
87 * Create a Child Fragment where the current Fragment is the parent.
89 * @param childQname The Qualified name for the child (relative to the parent)
90 * @param childXPath The child xpath (relative to the parrent)
91 * @return the child fragment
93 public Fragment createChildFragment(final QName childQname, final String childXPath) {
94 final QName[] qnamesForChild = Arrays.copyOf(qnames, qnames.length + 1);
95 qnamesForChild[qnamesForChild.length - 1] = childQname;
96 final Fragment childFragment = new Fragment(this, module, qnamesForChild, getXpath() + childXPath);
97 childFragments.add(childFragment);
102 * Define a leaf list by providing its name.
103 * The list is not instantiated until the first value is provided
105 * @param name the name of the leaf list
107 public void addLeafListName(final String name) {
108 if (optionalLeafListNames.isEmpty()) {
109 optionalLeafListNames = Optional.of(new HashSet<>());
111 optionalLeafListNames.get().add(name);
115 * Add a leaf or leaf list value.
116 * For Leaf lists it is essential to first define the attribute is a leaf list by using addLeafListName method
118 * @param name the name of the leaf (or leaf list)
119 * @param value the value of the leaf (or element of leaf list)
121 public void addLeafValue(final String name, final Object value) {
122 if (optionalLeafListNames.isPresent() && optionalLeafListNames.get().contains(name)) {
123 addLeafListValue(name, value);
125 attributes.put(name, value);
129 private void addLeafListValue(final String name, final Object value) {
130 if (attributes.containsKey(name)) {
131 final ImmutableList<Object> oldList = (ImmutableList<Object>) attributes.get(name);
132 final List<Object> newList = new ArrayList<>(oldList);
134 attributes.put(name, ImmutableList.copyOf(newList));
136 attributes.put(name, ImmutableList.of(value));
141 * Get the SchemaNodeIdentifier for this fragment.
143 * @return the SchemaNodeIdentifier
145 public String getSchemaNodeIdentifier() {
146 final StringBuilder stringBuilder = new StringBuilder();
147 for (final QName qname : qnames) {
148 stringBuilder.append(qname.getLocalName());
149 stringBuilder.append('/');
151 return stringBuilder.toString();
155 * Get the Optional SchemaNode (model) for this data fragment.
157 * @return the Optional SchemaNode
159 public Optional<DataSchemaNode> getSchemaNode() {
160 return module.findDataTreeChild(qnames);