Align JSON DataNode for Get and Post/Put API in CPS
[cps.git] / cps-service / src / main / java / org / onap / cps / utils / DataMapUtils.java
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Pantheon.tech
4  *  Modifications (C) 2021 Nordix Foundation
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.utils;
22
23 import static java.util.stream.Collectors.groupingBy;
24 import static java.util.stream.Collectors.mapping;
25 import static java.util.stream.Collectors.toUnmodifiableList;
26 import static java.util.stream.Collectors.toUnmodifiableMap;
27
28 import com.google.common.collect.ImmutableMap;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Map;
32 import lombok.AccessLevel;
33 import lombok.NoArgsConstructor;
34 import org.onap.cps.spi.model.DataNode;
35
36 @NoArgsConstructor(access = AccessLevel.PRIVATE)
37 public class DataMapUtils {
38
39     /**
40      * Converts DataNode structure into a map including the root node identifier for a JSON response.
41      *
42      * @param dataNode data node object
43      * @return a map representing same data with the root node identifier
44      */
45     public static Map<String, Object> toDataMapWithIdentifier(final DataNode dataNode) {
46         return ImmutableMap.<String, Object>builder()
47             .put(getNodeIdentifier(dataNode.getXpath()), toDataMap(dataNode))
48             .build();
49     }
50
51     /**
52      * Converts DataNode structure into a map for a JSON response.
53      *
54      * @param dataNode data node object
55      * @return a map representing same data
56      */
57     public static Map<String, Object> toDataMap(final DataNode dataNode) {
58         return ImmutableMap.<String, Object>builder()
59             .putAll(dataNode.getLeaves())
60             .putAll(listElementsAsMap(dataNode.getChildDataNodes()))
61             .putAll(containerElementsAsMap(dataNode.getChildDataNodes()))
62             .build();
63     }
64
65     private static Map<String, Object> listElementsAsMap(final Collection<DataNode> dataNodes) {
66         if (dataNodes.isEmpty()) {
67             return Collections.emptyMap();
68         }
69         return ImmutableMap.<String, Object>builder()
70             .putAll(
71                 dataNodes.stream()
72                     .filter(dataNode -> isListElement(dataNode.getXpath()))
73                     .collect(groupingBy(
74                         dataNode -> getNodeIdentifier(dataNode.getXpath()),
75                         mapping(DataMapUtils::toDataMap, toUnmodifiableList())
76                     ))
77             ).build();
78     }
79
80     private static Map<String, Object> containerElementsAsMap(final Collection<DataNode> dataNodes) {
81         if (dataNodes.isEmpty()) {
82             return Collections.emptyMap();
83         }
84         return dataNodes.stream()
85             .filter(dataNode -> isContainerNode(dataNode.getXpath()))
86             .collect(
87                 toUnmodifiableMap(
88                     dataNode -> getNodeIdentifier(dataNode.getXpath()),
89                     DataMapUtils::toDataMap
90                 ));
91     }
92
93     private static String getNodeIdentifier(final String xpath) {
94         final int fromIndex = xpath.lastIndexOf("/") + 1;
95         final int toIndex = xpath.indexOf("[", fromIndex);
96         return toIndex > 0 ? xpath.substring(fromIndex, toIndex) : xpath.substring(fromIndex);
97     }
98
99     private static boolean isContainerNode(final String xpath) {
100         return !isListElement(xpath);
101     }
102
103     private static boolean isListElement(final String xpath) {
104         return xpath.endsWith("]");
105     }
106 }