Fix checkstyle violations for "final" keyword
[cps.git] / cps-service / src / main / java / org / onap / cps / api / impl / Fragment.java
1 /*
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
8  *
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.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.cps.api.impl;
21
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;
28 import java.util.Map;
29 import java.util.Optional;
30 import java.util.Set;
31 import lombok.Getter;
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;
35
36 /**
37  * Class to store a Yang Fragment (container or list element).
38  */
39 public class Fragment {
40
41     @Getter
42     private final String xpath;
43
44     @Getter
45     private final Map<String, Object> attributes = new HashMap<>();
46
47     @Getter
48     private final Module module;
49
50     @Getter
51     private final Fragment parentFragment;
52
53     @Getter
54     private final Set<Fragment> childFragments = new HashSet<>(0);
55
56     private final QName[] qnames;
57
58     private Optional<Set<String>> optionalLeafListNames = Optional.empty();
59
60     /**
61      * Create a root Fragment.
62      *
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
66      */
67     public static Fragment createRootFragment(final Module module, final QName[] qnames, final String xpath) {
68         return new Fragment(null, module, qnames, xpath);
69     }
70
71     /**
72      * Create a Child Fragment under a given Parent Fragment.
73      *
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
78      */
79     private Fragment(final Fragment parentFragment, final Module module, final QName[] qnames, final String xpath) {
80         this.parentFragment = parentFragment;
81         this.module = module;
82         this.qnames = qnames;
83         this.xpath = xpath;
84     }
85
86     /**
87      * Create a Child Fragment where the current Fragment is the parent.
88      *
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
92      */
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);
98         return childFragment;
99     }
100
101     /**
102      * Define a leaf list by providing its name.
103      * The list is not instantiated until the first value is provided
104      *
105      * @param name the name of the leaf list
106      */
107     public void addLeafListName(final String name) {
108         if (optionalLeafListNames.isEmpty()) {
109             optionalLeafListNames = Optional.of(new HashSet<>());
110         }
111         optionalLeafListNames.get().add(name);
112     }
113
114     /**
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
117      *
118      * @param name  the name of the leaf (or leaf list)
119      * @param value the value of the leaf (or element of leaf list)
120      */
121     public void addLeafValue(final String name, final Object value) {
122         if (optionalLeafListNames.isPresent() && optionalLeafListNames.get().contains(name)) {
123             addLeafListValue(name, value);
124         } else {
125             attributes.put(name, value);
126         }
127     }
128
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);
133             newList.add(value);
134             attributes.put(name, ImmutableList.copyOf(newList));
135         } else {
136             attributes.put(name, ImmutableList.of(value));
137         }
138     }
139
140     /**
141      * Get the SchemaNodeIdentifier for this fragment.
142      *
143      * @return the SchemaNodeIdentifier
144      */
145     public String getSchemaNodeIdentifier() {
146         final StringBuilder stringBuilder = new StringBuilder();
147         for (final QName qname : qnames) {
148             stringBuilder.append(qname.getLocalName());
149             stringBuilder.append('/');
150         }
151         return stringBuilder.toString();
152     }
153
154     /**
155      * Get the Optional SchemaNode (model) for this data fragment.
156      *
157      * @return the Optional SchemaNode
158      */
159     public Optional<DataSchemaNode> getSchemaNode() {
160         return module.findDataTreeChild(qnames);
161     }
162 }