1
+ import kotlinx.serialization.ExperimentalSerializationApi
2
+ import kotlinx.serialization.KSerializer
3
+ import kotlinx.serialization.Serializable
4
+ import kotlinx.serialization.descriptors.PrimitiveKind
5
+ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
6
+ import kotlinx.serialization.encodeToString
7
+ import kotlinx.serialization.encoding.Decoder
8
+ import kotlinx.serialization.encoding.Encoder
9
+ import kotlinx.serialization.json.Json
10
+ import nl.adaptivity.xmlutil.serialization.XML
11
+ import java.io.File
12
+ import java.io.FileWriter
13
+ import java.io.PrintWriter
14
+ import java.util.*
15
+
16
+ /*
17
+ Al proceso de convertir la informacion en un cierto formato se le conoce como serializacion
18
+ esto nos permite convertir alguna estructura de kotlin en un formato de salida (json, xml, etc).
19
+
20
+ para sealizar kotlin utiliza una libreria auxilar llamada kotlinx.serialization.
21
+ este tambien nos provee de un modulo para poder serializar xml.
22
+
23
+ Serializar: proceso de convertir un objeto de kotlin a un formato de salida json o xml
24
+
25
+ Desializar: proceso de convertir un formato json o xml a un objeto de kotlin
26
+
27
+ para mas informacion visita:
28
+ https://kotlinlang.org/docs/serialization.html
29
+ https://github.com/rharter/kotlinx-serialization-xml
30
+
31
+ */
32
+
33
+
34
+
35
+ @OptIn(ExperimentalSerializationApi ::class )
36
+ fun jsonFile (){
37
+ val src= " src/main/resources/blackriper.json"
38
+ // crear clase para serializar y deserealizar
39
+ @Serializable
40
+ data class User (val name : String , val age : Int , val birdday : String ,val programingLenguages : List <String >)
41
+
42
+ // escribir file json
43
+ PrintWriter (FileWriter (src)).use {
44
+ val prettyJson = Json {
45
+ prettyPrint = true
46
+ prettyPrintIndent = " "
47
+ }
48
+ val user= User (" Rodolfo" , 29 , " 20/05/1994" , listOf (" kotlin" ," go" ," python" ))
49
+ it.write(prettyJson.encodeToString(user))
50
+ }
51
+
52
+ // leer fichero json
53
+ File (src).readText().let {
54
+ val user = Json .decodeFromString<User >(it)
55
+ println (user)
56
+ }
57
+
58
+ // borrar fichero
59
+ File (src).delete()
60
+
61
+ }
62
+
63
+ fun xmlFile () {
64
+ val src= " src/main/resources/blackriper.xml"
65
+ // crear data class
66
+ @Serializable
67
+ data class User (val name : String , val age : Int , val birdday : String ,val programingLenguages : List <String >)
68
+ // crear fichero xml
69
+ PrintWriter (FileWriter (src)).use {
70
+ val user= User (" Rodolfo" , 29 , " 20/05/1994" , listOf (" kotlin" ," go" ," swift" ))
71
+ it.write(XML .encodeToString(user))
72
+ }
73
+
74
+ // leer fichero xml
75
+ File (src).readText().let {
76
+ val user = XML .decodeFromString<User >(it)
77
+ println (user)
78
+ }
79
+
80
+ // borrar fichero
81
+ File (src).delete()
82
+
83
+ }
84
+
85
+ // reto extra con json y xml
86
+
87
+ // crear custom serializer para UUID
88
+ object UUIDSerializer : KSerializer<UUID> {
89
+ override val descriptor = PrimitiveSerialDescriptor (" UUID" , PrimitiveKind .STRING )
90
+
91
+ override fun deserialize (decoder : Decoder ): UUID {
92
+ return UUID .fromString(decoder.decodeString())
93
+ }
94
+
95
+ override fun serialize (encoder : Encoder , value : UUID ) {
96
+ encoder.encodeString(value.toString())
97
+ }
98
+ }
99
+
100
+
101
+ @Serializable
102
+ data class Product (
103
+ @Serializable(with = UUIDSerializer ::class )
104
+ val sku : UUID ,
105
+ var name : String ,
106
+ var cant : Int ,
107
+ var price : Double )
108
+
109
+ @Serializable
110
+ data class StoreProducts (val products : List <Product >)
111
+
112
+ enum class FileType {
113
+ JSON ,
114
+ XML
115
+ }
116
+
117
+ interface Store {
118
+ fun addProduct (product : Product )
119
+ fun removeProduct (name : String )
120
+ fun updateProduct (sku : UUID , product : Product )
121
+ fun showAllProducts ()
122
+ fun searchProductByName (name : String ):Product
123
+ fun calculateTotalSold ()
124
+ fun deleteFile ()
125
+ }
126
+
127
+ class SoldSore (private val fileName : String ,private val type : FileType ):Store{
128
+ private val products= mutableListOf<Product >()
129
+ private val fileProduct= File (" src/main/resources/$fileName " )
130
+ private val src= " src/main/resources/$fileName "
131
+
132
+ init {
133
+ if (fileProduct.exists()){
134
+ when (type){
135
+ FileType .JSON -> fileProduct.readText().let {
136
+ val productsFile = Json .decodeFromString<StoreProducts >(it)
137
+ productsFile.products.forEach { product ->
138
+ products.add(product)
139
+ }
140
+ }
141
+ FileType .XML -> fileProduct.readText().let {
142
+ val productsFile = XML .decodeFromString<StoreProducts >(it)
143
+ productsFile.products.forEach { product ->
144
+ products.add(product)
145
+ }
146
+ }
147
+ }
148
+
149
+ }
150
+ }
151
+
152
+ override fun addProduct (product : Product ) {
153
+ products.add(product)
154
+ saveFile()
155
+ }
156
+
157
+ override fun removeProduct (name : String ) {
158
+ val product= products.first { it.name== name }
159
+ val result= products.removeIf{it.sku== product.sku}
160
+ if (result) {
161
+ println (" Product deleted successfully" )
162
+ saveFile()
163
+ } else {
164
+ println (" Failed to delete the product" )
165
+ }
166
+ }
167
+
168
+ override fun updateProduct (sku : UUID , product : Product ) {
169
+ products.first { it.sku == sku }.apply {
170
+ this .name = product.name
171
+ this .cant = product.cant
172
+ this .price = product.price
173
+ }
174
+ saveFile()
175
+ }
176
+
177
+ override fun showAllProducts () {
178
+ val header= """
179
+ -----------------------
180
+ sku name cant price
181
+ -----------------------
182
+ """ .trimIndent()
183
+ println (header)
184
+ when (type){
185
+ FileType .JSON -> {
186
+ File (src).readText().let {
187
+ val products = Json .decodeFromString<StoreProducts >(it)
188
+ for (product in products.products) {
189
+ println (" ${product.sku} ${product.name} ${product.cant} ${product.price} " )
190
+ }
191
+ }
192
+ }
193
+ FileType .XML -> {
194
+ File (src).readText().let {
195
+ val products = XML .decodeFromString<StoreProducts >(it)
196
+ for (product in products.products) {
197
+ println (" ${product.sku} ${product.name} ${product.cant} ${product.price} " )
198
+ }
199
+ }
200
+ }
201
+ }
202
+
203
+
204
+ }
205
+
206
+ override fun searchProductByName (name : String ): Product =
207
+ products.first { it.name== name }
208
+
209
+ override fun calculateTotalSold () {
210
+ val header= """
211
+ ------------------------------------------------------------
212
+ sku name cant price Subtotal
213
+ -------------------------------------------------------------
214
+ """ .trimIndent()
215
+ println (header)
216
+ products.forEach {
217
+ println (" ${it.sku} ${it.name} ${it.cant} ${it.price} ${" %.2f" .format(it.cant* it.price)} " )
218
+ }
219
+ val total= products.sumOf { it.cant* it.price }
220
+ println (" Total sold: $total " )
221
+ }
222
+
223
+ override fun deleteFile () {
224
+ val result= File (src).delete()
225
+ if (result) {
226
+ println (" File deleted successfully" )
227
+ }else {
228
+ println (" Failed to delete the file" )
229
+ }
230
+ }
231
+
232
+ @OptIn(ExperimentalSerializationApi ::class )
233
+ private fun saveFile (){
234
+ when (type){
235
+ FileType .JSON -> {
236
+ PrintWriter (FileWriter (fileProduct)).use {
237
+ val prettyJson = Json {
238
+ prettyPrint = true
239
+ prettyPrintIndent = " "
240
+ }
241
+ val store= StoreProducts (products)
242
+ it.write(prettyJson.encodeToString(store))
243
+ }
244
+ }
245
+ FileType .XML -> {
246
+ PrintWriter (FileWriter (fileProduct)).use {
247
+ val store= StoreProducts (products)
248
+ it.write(XML .encodeToString(store))
249
+ }
250
+ }
251
+ }
252
+ }
253
+
254
+ }
255
+
256
+ fun oxxoStore () {
257
+ // modificar si se quiere usar json o xml
258
+ val oxxo = SoldSore (" products.xml" , FileType .XML )
259
+
260
+ do {
261
+ println (" 1. Add product" )
262
+ println (" 2. Remove product" )
263
+ println (" 3. Update product" )
264
+ println (" 4. Show all products" )
265
+ println (" 5. Search product by name" )
266
+ println (" 6. Calculate total sold" )
267
+ println (" 7. Exit" )
268
+ println (" Choose an option:" )
269
+ val option = readLine()!! .toInt()
270
+ when (option) {
271
+ 1 -> {
272
+ println (" Enter name:" )
273
+ val name = readLine()!! .lowercase()
274
+ println (" Enter cant:" )
275
+ val cant = readLine()!! .toInt()
276
+ println (" Enter price:" )
277
+ val price = readLine()!! .toDouble()
278
+ val sku = UUID .randomUUID()
279
+ val product = Product (sku, name, cant, price)
280
+ oxxo.addProduct(product)
281
+ }
282
+
283
+ 2 -> {
284
+ println (" Enter name:" )
285
+ val name = readLine()!! .lowercase()
286
+ oxxo.removeProduct(name)
287
+ }
288
+
289
+ 3 -> {
290
+ println (" Enter name product:" )
291
+ val oldname = readLine()!! .lowercase()
292
+ val prod = oxxo.searchProductByName(oldname)
293
+ println (" update name (${prod.name} ):" )
294
+ val name = if (readLine().isNullOrEmpty()) prod.name else readLine()!! .lowercase()
295
+ println (" update cat (${prod.cant} ):" )
296
+ val cant = if (readLine().isNullOrEmpty()) prod.cant else readLine()!! .toInt()
297
+ println (" update price (${prod.price} ):" )
298
+ val price = if (readLine().isNullOrEmpty()) prod.price else readLine()!! .toDouble()
299
+ val product = Product (prod.sku, name, cant, price)
300
+ oxxo.updateProduct(prod.sku, product)
301
+ }
302
+
303
+ 4 -> oxxo.showAllProducts()
304
+
305
+ 5 -> {
306
+ println (" Enter name:" )
307
+ val name = readLine()!! .lowercase()
308
+ val product = oxxo.searchProductByName(name)
309
+ println (" sku: ${product.sku} name: ${product.name} cant: ${product.cant} price: ${product.price} " )
310
+ }
311
+
312
+ 6 -> oxxo.calculateTotalSold()
313
+
314
+ }
315
+ } while (option != 7 )
316
+
317
+ oxxo.deleteFile()
318
+ }
319
+
320
+
321
+ fun main () {
322
+ // jsonFile()
323
+ // xmlFile()
324
+ oxxoStore()
325
+ }
0 commit comments