1010 ******************************************************************************/
1111package com.redhat.devtools.intellij.kubernetes.editor
1212
13+ import com.fasterxml.jackson.databind.ObjectMapper
14+ import com.fasterxml.jackson.databind.node.ArrayNode
1315import com.intellij.json.JsonFileType
1416import com.intellij.openapi.fileTypes.FileType
1517import com.redhat.devtools.intellij.kubernetes.model.util.ResourceException
1618import com.redhat.devtools.intellij.kubernetes.model.util.createResource
1719import io.fabric8.kubernetes.api.model.GenericKubernetesResource
1820import io.fabric8.kubernetes.api.model.HasMetadata
21+ import io.fabric8.kubernetes.api.model.KubernetesListBuilder
1922import io.fabric8.kubernetes.client.utils.Serialization
2023import org.jetbrains.yaml.YAMLFileType
2124
2225object EditorResourceSerialization {
2326
2427 const val RESOURCE_SEPARATOR_YAML = " \n ---"
25- private const val RESOURCE_SEPARATOR_JSON = " ,\n "
2628
2729 /* *
2830 * Returns a list of [HasMetadata] for a given yaml or json string.
@@ -41,60 +43,99 @@ object EditorResourceSerialization {
4143 * @see JsonFileType.INSTANCE
4244 */
4345 fun deserialize (jsonYaml : String? , fileType : FileType ? , currentNamespace : String? ): List <HasMetadata > {
44- return if (jsonYaml == null
45- || ! isSupported(fileType)) {
46- emptyList()
47- } else {
48- val resources = jsonYaml
49- .split(RESOURCE_SEPARATOR_YAML )
50- .filter { jsonYaml -> jsonYaml.isNotBlank() }
51- if (resources.size > 1
52- && YAMLFileType .YML != fileType) {
53- throw ResourceException (
54- " ${fileType?.name ? : " File type" } is not supported for multi-resource documents. Only ${YAMLFileType .YML .name} is." )
46+ return try {
47+ when {
48+ jsonYaml == null ->
49+ emptyList()
50+
51+ YAMLFileType .YML == fileType ->
52+ yaml2Resources(jsonYaml, currentNamespace)
53+
54+ JsonFileType .INSTANCE == fileType ->
55+ json2Resources(jsonYaml, currentNamespace)
56+
57+ else ->
58+ emptyList()
5559 }
56- try {
57- resources
58- .map { jsonYaml ->
59- setMissingNamespace(currentNamespace, createResource<GenericKubernetesResource >(jsonYaml))
60+ } catch (e: RuntimeException ) {
61+ throw ResourceException (" Invalid kubernetes yaml/json" , e.cause ? : e)
62+ }
63+ }
64+
65+ private fun yaml2Resources (yaml : String , currentNamespace : String? ): List <HasMetadata > {
66+ val resources = yaml
67+ .split(RESOURCE_SEPARATOR_YAML )
68+ .filter { yaml ->
69+ yaml.isNotBlank()
70+ }
71+ return resources
72+ .map { yaml ->
73+ setMissingNamespace(currentNamespace, createResource<GenericKubernetesResource >(yaml))
74+ }
75+ .toList()
76+ }
77+
78+ private fun json2Resources (json : String? , currentNamespace : String? ): List <HasMetadata > {
79+ val mapper = ObjectMapper ()
80+ val rootNode = mapper.readTree(json)
81+ return when {
82+ rootNode.isArray ->
83+ (rootNode as ArrayNode )
84+ .mapNotNull { node ->
85+ setMissingNamespace(currentNamespace, mapper.treeToValue(node, GenericKubernetesResource ::class .java))
6086 }
6187 .toList()
62- } catch (e: RuntimeException ) {
63- throw ResourceException (" Invalid kubernetes yaml/json" , e.cause ? : e)
64- }
88+ rootNode.isObject ->
89+ listOf (
90+ setMissingNamespace(currentNamespace,
91+ mapper.treeToValue(rootNode, GenericKubernetesResource ::class .java)
92+ )
93+ )
94+ else ->
95+ emptyList()
6596 }
6697 }
6798
6899 private fun setMissingNamespace (namespace : String? , resource : HasMetadata ): HasMetadata {
69- if (resource.metadata.namespace.isNullOrEmpty()
100+ if (resource.metadata != null
101+ && resource.metadata.namespace.isNullOrEmpty()
70102 && namespace != null ) {
71103 resource.metadata.namespace = namespace
72104 }
73105 return resource
74106 }
75107
76108 fun serialize (resources : List <HasMetadata >, fileType : FileType ? ): String? {
77- if (fileType == null ) {
78- return null
79- }
80- if (resources.size >= 2
81- && fileType != YAMLFileType .YML ) {
82- throw UnsupportedOperationException (
83- " ${fileType.name} is not supported for multi-resource documents. Only ${YAMLFileType .YML .name} is." )
109+ return try {
110+ when {
111+ fileType == null ->
112+ null
113+
114+ YAMLFileType .YML == fileType ->
115+ resources2yaml(resources)
116+
117+ JsonFileType .INSTANCE == fileType ->
118+ resources2json(resources)
119+
120+ else ->
121+ " "
122+ }
123+ } catch (e: RuntimeException ) {
124+ throw ResourceException (" Invalid kubernetes yaml/json" , e.cause ? : e)
84125 }
85- return resources
86- .mapNotNull { resource -> serialize(resource, fileType) }
87- .joinToString(" \n " )
126+ }
88127
128+ private fun resources2yaml (resources : List <HasMetadata >): String {
129+ return resources.joinToString(" \n " ) { resource ->
130+ Serialization .asYaml(resource).trim()
131+ }
89132 }
90133
91- private fun serialize (resource : HasMetadata , fileType : FileType ): String? {
92- return when (fileType) {
93- YAMLFileType .YML ->
94- Serialization .asYaml(resource).trim()
95- JsonFileType .INSTANCE ->
96- Serialization .asJson(resource).trim()
97- else -> null
134+ private fun resources2json (resources : List <HasMetadata >): String {
135+ return if (resources.size == 1 ) {
136+ Serialization .asJson(resources.first()).trim()
137+ } else {
138+ Serialization .asJson(resources).trim()
98139 }
99140 }
100141
0 commit comments