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