2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2019 IBM.
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
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.
18 package org.onap.ccsdk.cds.controllerblueprints.core
20 import com.fasterxml.jackson.databind.JsonNode
21 import com.fasterxml.jackson.databind.node.ArrayNode
22 import com.fasterxml.jackson.databind.node.BooleanNode
23 import com.fasterxml.jackson.databind.node.DoubleNode
24 import com.fasterxml.jackson.databind.node.IntNode
25 import com.fasterxml.jackson.databind.node.MissingNode
26 import com.fasterxml.jackson.databind.node.NullNode
27 import com.fasterxml.jackson.databind.node.ObjectNode
28 import com.fasterxml.jackson.databind.node.TextNode
29 import org.apache.commons.lang3.ObjectUtils
30 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
31 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JsonParserUtils
32 import org.slf4j.LoggerFactory
33 import org.slf4j.helpers.MessageFormatter
35 import kotlin.reflect.KClass
40 * @author Brinda Santh
43 fun <T : Any> logger(clazz: T) = LoggerFactory.getLogger(clazz.javaClass)!!
45 fun <T : KClass<*>> logger(clazz: T) = LoggerFactory.getLogger(clazz.java)!!
47 fun <T : Any> T?.defaultToEmpty(): String {
48 return this?.toString() ?: ""
51 fun <T : Any> T?.defaultToUUID(): String {
52 return this?.toString() ?: UUID.randomUUID().toString()
55 fun <T : Any> T.bpClone(): T {
56 return ObjectUtils.clone(this)
59 fun String.isJson(): Boolean {
60 return ((this.trim().startsWith("{") && this.trim().endsWith("}")) ||
61 (this.trim().startsWith("[") && this.trim().endsWith("]")))
64 fun Any.asJsonString(intend: Boolean? = false): String {
65 return JacksonUtils.getJson(this, intend!!)
68 fun String.asJsonPrimitive(): TextNode {
72 inline fun <reified T : Any> String.jsonAsType(): T {
73 return JacksonUtils.readValue<T>(this.trim())
76 // If you know the string is json content, then use the function directly
77 fun String.jsonAsJsonType(): JsonNode {
78 return JacksonUtils.jsonNode(this.trim())
81 fun Boolean.asJsonPrimitive(): BooleanNode {
82 return BooleanNode.valueOf(this)
85 fun Int.asJsonPrimitive(): IntNode {
86 return IntNode.valueOf(this)
89 fun Double.asJsonPrimitive(): DoubleNode {
90 return DoubleNode.valueOf(this)
94 * Utility to convert Primitive object to Json Type Primitive.
96 fun <T : Any?> T.asJsonPrimitive(): JsonNode {
97 return if (this == null || this is MissingNode || this is NullNode) {
102 this.asJsonPrimitive()
104 this.asJsonPrimitive()
106 this.asJsonPrimitive()
108 this.asJsonPrimitive()
110 throw BluePrintException("$this type is not supported")
115 /** Based on Blueprint DataType Convert string value to JsonNode Type **/
116 fun String.asJsonType(bpDataType: String): JsonNode {
117 return when (bpDataType.toLowerCase()) {
118 BluePrintConstants.DATA_TYPE_STRING -> this.asJsonPrimitive()
119 BluePrintConstants.DATA_TYPE_BOOLEAN -> this.toBoolean().asJsonPrimitive()
120 BluePrintConstants.DATA_TYPE_INTEGER -> this.toInt().asJsonPrimitive()
121 BluePrintConstants.DATA_TYPE_FLOAT -> this.toFloat().asJsonPrimitive()
122 BluePrintConstants.DATA_TYPE_DOUBLE -> this.toDouble().asJsonPrimitive()
123 // For List, Map and Complex Types.
124 else -> this.jsonAsJsonType()
129 * Utility to convert Complex or Primitive object to Json Type.
131 fun <T : Any?> T.asJsonType(): JsonNode {
132 return if (this == null || this is MissingNode || this is NullNode) {
140 this.jsonAsJsonType()
145 BooleanNode.valueOf(this)
147 IntNode.valueOf(this.toInt())
149 DoubleNode.valueOf(this.toDouble())
151 JacksonUtils.jsonNodeFromObject(this)
156 fun Map<String, *>.asJsonNode(): JsonNode {
157 return JacksonUtils.jsonNodeFromObject(this)
160 fun Map<String, *>.asObjectNode(): ObjectNode {
161 return JacksonUtils.objectNodeFromObject(this)
164 fun format(message: String, vararg args: Any?): String {
165 if (args != null && args.isNotEmpty()) {
166 return MessageFormatter.arrayFormat(message, args).message
171 fun <T : Any> Map<String, *>.castOptionalValue(key: String, valueType: KClass<T>): T? {
172 return if (containsKey(key)) {
179 fun <T : Any> Map<String, *>.castValue(key: String, valueType: KClass<T>): T {
180 if (containsKey(key)) {
183 throw BluePrintException("couldn't find the key $key")
187 fun ArrayNode.asListOfString(): List<String> {
188 return JacksonUtils.getListFromJsonNode(this, String::class.java)
191 fun <T> JsonNode.asType(clazzType: Class<T>): T {
192 return JacksonUtils.readValue(this, clazzType)
193 ?: throw BluePrintException("couldn't convert JsonNode of type $clazzType")
196 fun JsonNode.asListOfString(): List<String> {
197 check(this is ArrayNode) { "JsonNode is not of type ArrayNode" }
198 return this.asListOfString()
201 fun <T : JsonNode> T?.returnNullIfMissing(): JsonNode? {
202 return if (this == null || this is NullNode || this is MissingNode) {
207 fun <T : JsonNode> T?.isNullOrMissing(): Boolean {
208 return this == null || this is NullNode || this is MissingNode
212 * Convert Json to map of json node, the root fields will be map keys
214 fun JsonNode.rootFieldsToMap(): MutableMap<String, JsonNode> {
215 if (this is ObjectNode) {
216 val propertyMap: MutableMap<String, JsonNode> = linkedMapOf()
217 this.fields().forEach {
218 propertyMap[it.key] = it.value
222 throw BluePrintException("json node should be Object Node Type")
226 fun JsonNode.removeNullNode() {
227 val it = this.iterator()
228 while (it.hasNext()) {
229 val child = it.next()
233 child.removeNullNode()
238 fun MutableMap<String, JsonNode>.putJsonElement(key: String, value: Any) {
239 val convertedValue = value.asJsonType()
240 this[key] = convertedValue
243 fun Map<String, JsonNode>.getAsString(key: String): String {
244 return this[key]?.asText() ?: throw BluePrintException("couldn't find value for key($key)")
247 fun Map<String, JsonNode>.getAsBoolean(key: String): Boolean {
248 return this[key]?.asBoolean() ?: throw BluePrintException("couldn't find value for key($key)")
251 fun Map<String, JsonNode>.getAsInt(key: String): Int {
252 return this[key]?.asInt() ?: throw BluePrintException("couldn't find value for key($key)")
255 fun Map<String, JsonNode>.getAsDouble(key: String): Double {
256 return this[key]?.asDouble() ?: throw BluePrintException("couldn't find value for key($key)")
259 fun Map<String, JsonNode>.getOptionalAsString(key: String): String? {
260 return if (this.containsKey(key)) this[key]!!.asText() else null
263 fun Map<String, JsonNode>.getOptionalAsBoolean(key: String): Boolean? {
264 return if (this.containsKey(key)) this[key]!!.asBoolean() else null
267 fun Map<String, JsonNode>.getOptionalAsInt(key: String): Int? {
268 return if (this.containsKey(key)) this[key]!!.asInt() else null
271 fun Map<String, JsonNode>.getOptionalAsDouble(key: String): Double? {
272 return if (this.containsKey(key)) this[key]!!.asDouble() else null
277 inline fun checkEquals(value1: String?, value2: String?, lazyMessage: () -> Any): Boolean {
278 if (value1.equals(value2, ignoreCase = true)) {
281 throw BluePrintException(lazyMessage().toString())
285 inline fun checkNotEmpty(value: String?, lazyMessage: () -> Any): String {
286 if (value == null || value.isEmpty()) {
287 val message = lazyMessage()
288 throw IllegalStateException(message.toString())
294 inline fun checkNotBlank(value: String?, lazyMessage: () -> Any): String {
295 if (value == null || value.isBlank()) {
296 val message = lazyMessage()
297 throw IllegalStateException(message.toString())
303 fun isNotEmpty(value: String?): Boolean {
304 return value != null && value.isNotEmpty()
307 fun isNotBlank(value: String?): Boolean {
308 return value != null && value.isNotBlank()
311 fun <T : String> T?.emptyTONull(): String? {
312 return if (this == null || this.isEmpty()) null else this
315 fun nullToEmpty(value: String?): String {
316 return if (isNotEmpty(value)) value!! else ""
319 inline fun <reified T : JsonNode> T.isComplexType(): Boolean {
320 return this is ObjectNode || this is ArrayNode
323 // Json Parsing Extensions
324 fun JsonNode.jsonPathParse(expression: String): JsonNode {
325 check(this.isComplexType()) { "$this is not complex or array node to apply expression" }
326 return JsonParserUtils.parse(this, expression)
329 // Json Path Extensions
330 fun JsonNode.jsonPaths(expression: String): List<String> {
331 check(this.isComplexType()) { "$this is not complex or array node to apply expression" }
332 return JsonParserUtils.paths(this, expression)