Merge "Update policy-apex-pdp for checkstyle 8.43"
[policy/apex-pdp.git] / plugins / plugins-context / plugins-context-schema / plugins-context-schema-avro / src / main / java / org / onap / policy / apex / plugins / context / schema / avro / AvroSchemaKeyTranslationUtilities.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2020-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  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.plugins.context.schema.avro;
23
24 import com.google.gson.GsonBuilder;
25 import com.google.gson.JsonArray;
26 import com.google.gson.JsonElement;
27 import com.google.gson.JsonObject;
28 import java.util.Map.Entry;
29
30 /**
31  * This static final class contains utility methods for Avro schemas.
32  *
33  * @author Liam Fallon (liam.fallon@ericsson.com)
34  */
35 public final class AvroSchemaKeyTranslationUtilities {
36     // Constants for key replacements
37     private static final String DOT_STRING = ".";
38     private static final String DOT_STRING_REPLACEMENT = "_DoT_";
39     private static final String DASH_STRING = "-";
40     private static final String DASH_STRING_REPLACEMENT = "_DasH_";
41     private static final String COLON_STRING = ":";
42     private static final String COLON_STRING_REPLACEMENT = "_ColoN_";
43
44     /**
45      * Default constructor to avoid subclassing.
46      */
47     private AvroSchemaKeyTranslationUtilities() {
48         // Private constructor to prevent subclassing
49     }
50
51     /**
52      * Translate characters in JSON keys to values that are legal in Avro. Avro names must start with [A-Za-z_] and
53      * subsequently contain only [A-Za-z0-9_]
54      *
55      * @param jsonString The JSON string to translate
56      * @param revert True if we want to revert the field names to their original values
57      * @return the translated JSON string
58      */
59     public static String translateIllegalKeys(final String jsonString, final boolean revert) {
60         if (jsonString == null) {
61             return jsonString;
62         }
63
64         // Create a JSON element for the incoming JSON string
65         final var jsonElement = new GsonBuilder().serializeNulls().create().fromJson(jsonString,
66                 JsonElement.class);
67
68         final var translatedJsonElement = translateIllegalKeys(jsonElement, revert);
69
70         return new GsonBuilder().serializeNulls().create().toJson(translatedJsonElement);
71     }
72
73     /**
74      * Translate characters in JSON keys to values that are legal in Avro. Avro names must start with [A-Za-z_] and
75      * subsequently contain only [A-Za-z0-9_]
76      *
77      * @param jsonElement The JSON element to translate
78      * @param revert True if we want to revert the field names to their original values
79      * @return the translated JSON element
80      */
81     public static JsonElement translateIllegalKeys(final JsonElement jsonElement, final boolean revert) {
82         // We only act on JSON objects and arrays
83         if (jsonElement.isJsonObject()) {
84             return translateIllegalKeys(jsonElement.getAsJsonObject(), revert);
85         } else if (jsonElement.isJsonArray()) {
86             return translateIllegalKeys(jsonElement.getAsJsonArray(), revert);
87         } else {
88             return jsonElement;
89         }
90     }
91
92     /**
93      * Translate characters in JSON keys to values that are legal in Avro. Avro names must start with [A-Za-z_] and
94      * subsequently contain only [A-Za-z0-9_]
95      *
96      * @param jsonObject The JSON object to translate
97      * @param revert True if we want to revert the field names to their original values
98      * @return the translated JSON element
99      */
100     public static JsonElement translateIllegalKeys(final JsonObject jsonObject, final boolean revert) {
101         final var newJsonObject = new JsonObject();
102
103         for (final Entry<String, JsonElement> jsonObjectEntry : jsonObject.entrySet()) {
104             newJsonObject.add(translateIllegalKey(jsonObjectEntry.getKey(), revert),
105                     translateIllegalKeys(jsonObjectEntry.getValue(), revert));
106         }
107
108         return newJsonObject;
109     }
110
111     /**
112      * Translate characters in JSON keys to values that are legal in Avro. Avro names must start with [A-Za-z_] and
113      * subsequently contain only [A-Za-z0-9_]
114      *
115      * @param jsonArray The JSON array to translate
116      * @param revert True if we want to revert the field names to their original values
117      * @return the translated JSON element
118      */
119     public static JsonElement translateIllegalKeys(final JsonArray jsonArray, final boolean revert) {
120         final var newJsonArray = new JsonArray();
121
122         for (var i = 0; i < jsonArray.size(); i++) {
123             newJsonArray.add(translateIllegalKeys(jsonArray.get(i), revert));
124         }
125
126         return newJsonArray;
127     }
128
129     /**
130      * Translate characters in a single JSON key to values that are legal in Avro. Avro names must start with [A-Za-z_]
131      * and subsequently contain only [A-Za-z0-9_]
132      *
133      * @param key The key to translate
134      * @param revert True if we want to revert the field names to their original values
135      * @return the translated key
136      */
137     private static String translateIllegalKey(final String key, final boolean revert) {
138         if (revert) {
139             return key.replace(DOT_STRING_REPLACEMENT, DOT_STRING)
140                     .replace(DASH_STRING_REPLACEMENT, DASH_STRING)
141                     .replace(COLON_STRING_REPLACEMENT, COLON_STRING);
142         } else {
143             return key.replace(DOT_STRING, DOT_STRING_REPLACEMENT)
144                     .replace(DASH_STRING, DASH_STRING_REPLACEMENT)
145                     .replace(COLON_STRING, COLON_STRING_REPLACEMENT);
146         }
147     }
148 }