ab5175dea18b0f3ebf456ec45af0ab6b965db3b9
[ccsdk/apps.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 java.io.*
28 import java.nio.charset.Charset
29 import java.util.zip.ZipFile
30
31 class BluePrintArchiveUtils {
32
33     companion object {
34
35         fun getFileContent(fileName: String): String = runBlocking {
36             async {
37                 try {
38                     File(fileName).readText(Charsets.UTF_8)
39                 } catch (e: Exception) {
40                     throw BluePrintException("couldn't find file($fileName)")
41                 }
42             }.await()
43         }
44
45         fun compress(source: String, destination: String, absolute: Boolean): Boolean {
46             val rootDir = File(source)
47             val saveFile = File(destination)
48             return compress(rootDir, saveFile, absolute)
49         }
50
51         /**
52          * Create a new Zip from a root directory
53          *
54          * @param directory the base directory
55          * @param filename the output filename
56          * @param absolute store absolute filepath (from directory) or only filename
57          * @return True if OK
58          */
59         fun compress(source: File, destination: File, absolute: Boolean): Boolean {
60             // recursive call
61             val zaos: ZipArchiveOutputStream
62             try {
63                 zaos = ZipArchiveOutputStream(FileOutputStream(destination))
64             } catch (e: FileNotFoundException) {
65                 return false
66             }
67
68             try {
69                 recurseFiles(source, source, zaos, absolute)
70             } catch (e2: IOException) {
71                 try {
72                     zaos.close()
73                 } catch (e: IOException) {
74                     // ignore
75                 }
76
77                 return false
78             }
79
80             try {
81                 zaos.finish()
82             } catch (e1: IOException) {
83                 // ignore
84             }
85
86             try {
87                 zaos.flush()
88             } catch (e: IOException) {
89                 // ignore
90             }
91
92             try {
93                 zaos.close()
94             } catch (e: IOException) {
95                 // ignore
96             }
97
98             return true
99         }
100
101         /**
102          * Recursive traversal to add files
103          *
104          * @param root
105          * @param file
106          * @param zaos
107          * @param absolute
108          * @throws IOException
109          */
110         @Throws(IOException::class)
111         private fun recurseFiles(root: File, file: File, zaos: ZipArchiveOutputStream,
112                                  absolute: Boolean) {
113             if (file.isDirectory) {
114                 // recursive call
115                 val files = file.listFiles()
116                 for (file2 in files!!) {
117                     recurseFiles(root, file2, zaos, absolute)
118                 }
119             } else if (!file.name.endsWith(".zip") && !file.name.endsWith(".ZIP")) {
120                 var filename: String? = null
121                 if (absolute) {
122                     filename = file.absolutePath.substring(root.absolutePath.length)
123                 } else {
124                     filename = file.name
125                 }
126                 val zae = ZipArchiveEntry(filename)
127                 zae.setSize(file.length())
128                 zaos.putArchiveEntry(zae)
129                 val fis = FileInputStream(file)
130                 IOUtils.copy(fis, zaos)
131                 zaos.closeArchiveEntry()
132             }
133         }
134
135
136         fun deCompress(zipFile: File, targetPath: String): File {
137             val zip = ZipFile(zipFile, Charset.defaultCharset())
138             val enumeration = zip.entries()
139             while (enumeration.hasMoreElements()) {
140                 val entry = enumeration.nextElement()
141                 val destFilePath = File(targetPath, entry.name)
142                 destFilePath.parentFile.mkdirs()
143
144                 if (entry.isDirectory)
145                     continue
146
147                 val bufferedIs = BufferedInputStream(zip.getInputStream(entry))
148                 bufferedIs.use {
149                     destFilePath.outputStream().buffered(1024).use { bos ->
150                         bufferedIs.copyTo(bos)
151                     }
152                 }
153             }
154
155             val destinationDir = File(targetPath)
156             check(destinationDir.isDirectory && destinationDir.exists()) {
157                 throw BluePrintProcessorException("failed to decompress blueprint(${zipFile.absolutePath}) to ($targetPath) ")
158             }
159
160             return destinationDir
161         }
162
163         /**
164          * Get the first item in directory
165          *
166          * @param zipFile
167          * @return string
168          */
169         fun getFirstItemInDirectory(dir: File): String {
170             return dir.walk().map { it.name }.elementAt(1)
171         }
172     }
173
174 }