fe7929e859c9f793fb67f52a7ee34b8e43900582
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2019 Bell Canada.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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
18 package org.onap.ccsdk.apps.controllerblueprints.core.utils
19
20 import kotlinx.coroutines.async
21 import kotlinx.coroutines.runBlocking
22 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
23 import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
24 import org.apache.commons.io.IOUtils
25 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
26 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
27 import org.slf4j.LoggerFactory
28 import java.io.BufferedInputStream
29 import java.io.File
30 import java.io.FileInputStream
31 import java.io.IOException
32 import java.nio.charset.Charset
33 import java.util.zip.ZipFile
34
35 class BluePrintArchiveUtils {
36
37     companion object {
38         private val log = LoggerFactory.getLogger(BluePrintArchiveUtils::class.java)
39
40         fun getFileContent(fileName: String): String = runBlocking {
41             async {
42                 try {
43                     File(fileName).readText(Charsets.UTF_8)
44                 } catch (e: Exception) {
45                     throw BluePrintException("couldn't find file($fileName)")
46                 }
47             }.await()
48         }
49
50         fun compress(source: String, destination: String, absolute: Boolean): Boolean {
51             val rootDir = File(source)
52             val saveFile = File(destination)
53             return compress(rootDir, saveFile, absolute)
54         }
55
56         /**
57          * Create a new Zip from a root directory
58          *
59          * @param source the base directory
60          * @param destination the output filename
61          * @param absolute store absolute filepath (from directory) or only filename
62          * @return True if OK
63          */
64         fun compress(source: File, destination: File, absolute: Boolean): Boolean {
65             try {
66                 ZipArchiveOutputStream(destination).use {
67                     recurseFiles(source, source, it, absolute)
68                 }
69             } catch (e: Exception) {
70                 log.error("Fail to compress folder(:$source) to path(${destination.path}", e)
71                 return false
72             }
73             return true
74         }
75
76         /**
77          * Recursive traversal to add files
78          *
79          * @param root
80          * @param file
81          * @param zaos
82          * @param absolute
83          * @throws IOException
84          */
85         @Throws(IOException::class)
86         private fun recurseFiles(root: File, file: File, zaos: ZipArchiveOutputStream,
87                                  absolute: Boolean) {
88             if (file.isDirectory) {
89                 // recursive call
90                 val files = file.listFiles()
91                 for (fileChild in files!!) {
92                     recurseFiles(root, fileChild, zaos, absolute)
93                 }
94             } else if (!file.name.endsWith(".zip") && !file.name.endsWith(".ZIP")) {
95                 val filename = if (absolute) {
96                     file.absolutePath.substring(root.absolutePath.length)
97                 } else {
98                     file.name
99                 }
100                 val zae = ZipArchiveEntry(filename)
101                 zae.size = file.length()
102                 zaos.putArchiveEntry(zae)
103                 FileInputStream(file).use { IOUtils.copy(it, zaos) }
104                 zaos.closeArchiveEntry()
105             }
106         }
107
108
109         fun deCompress(zipFile: File, targetPath: String): File {
110             val zip = ZipFile(zipFile, Charset.defaultCharset())
111             val enumeration = zip.entries()
112             while (enumeration.hasMoreElements()) {
113                 val entry = enumeration.nextElement()
114                 val destFilePath = File(targetPath, entry.name)
115                 destFilePath.parentFile.mkdirs()
116
117                 if (entry.isDirectory)
118                     continue
119
120                 val bufferedIs = BufferedInputStream(zip.getInputStream(entry))
121                 bufferedIs.use {
122                     destFilePath.outputStream().buffered(1024).use { bos ->
123                         bufferedIs.copyTo(bos)
124                     }
125                 }
126             }
127
128             val destinationDir = File(targetPath)
129             check(destinationDir.isDirectory && destinationDir.exists()) {
130                 throw BluePrintProcessorException("failed to decompress blueprint(${zipFile.absolutePath}) to ($targetPath) ")
131             }
132
133             return destinationDir
134         }
135
136         /**
137          * Get the first item in directory
138          *
139          * @param zipFile
140          * @return string
141          */
142         fun getFirstItemInDirectory(dir: File): String {
143             return dir.walk().map { it.name }.elementAt(1)
144         }
145     }
146
147 }