c1ab4fc6eaede7824456a808e066566fa5873ce2
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.ccsdk.apps.controllerblueprints.core.utils
18
19 import kotlinx.coroutines.async
20 import kotlinx.coroutines.runBlocking
21 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
22 import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
23 import org.apache.commons.io.IOUtils
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
25 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
26 import java.io.*
27 import java.nio.charset.Charset
28 import java.util.zip.ZipFile
29
30 class BluePrintArchiveUtils {
31
32     companion object {
33
34         fun getFileContent(fileName: String): String = runBlocking {
35             async {
36                 try {
37                     File(fileName).readText(Charsets.UTF_8)
38                 } catch (e: Exception) {
39                     throw BluePrintException("couldn't find file($fileName)")
40                 }
41             }.await()
42         }
43
44         fun compress(source: String, destination: String, absolute: Boolean): Boolean {
45             val rootDir = File(source)
46             val saveFile = File(destination)
47             return compress(rootDir, saveFile, absolute)
48         }
49
50         /**
51          * Create a new Zip from a root directory
52          *
53          * @param directory the base directory
54          * @param filename the output filename
55          * @param absolute store absolute filepath (from directory) or only filename
56          * @return True if OK
57          */
58         fun compress(source: File, destination: File, absolute: Boolean): Boolean {
59             // recursive call
60             val zaos: ZipArchiveOutputStream
61             try {
62                 zaos = ZipArchiveOutputStream(FileOutputStream(destination))
63             } catch (e: FileNotFoundException) {
64                 return false
65             }
66
67             try {
68                 recurseFiles(source, source, zaos, absolute)
69             } catch (e2: IOException) {
70                 try {
71                     zaos.close()
72                 } catch (e: IOException) {
73                     // ignore
74                 }
75
76                 return false
77             }
78
79             try {
80                 zaos.finish()
81             } catch (e1: IOException) {
82                 // ignore
83             }
84
85             try {
86                 zaos.flush()
87             } catch (e: IOException) {
88                 // ignore
89             }
90
91             try {
92                 zaos.close()
93             } catch (e: IOException) {
94                 // ignore
95             }
96
97             return true
98         }
99
100         /**
101          * Recursive traversal to add files
102          *
103          * @param root
104          * @param file
105          * @param zaos
106          * @param absolute
107          * @throws IOException
108          */
109         @Throws(IOException::class)
110         private fun recurseFiles(root: File, file: File, zaos: ZipArchiveOutputStream,
111                                  absolute: Boolean) {
112             if (file.isDirectory) {
113                 // recursive call
114                 val files = file.listFiles()
115                 for (file2 in files!!) {
116                     recurseFiles(root, file2, zaos, absolute)
117                 }
118             } else if (!file.name.endsWith(".zip") && !file.name.endsWith(".ZIP")) {
119                 var filename: String? = null
120                 if (absolute) {
121                     filename = file.absolutePath.substring(root.absolutePath.length)
122                 } else {
123                     filename = file.name
124                 }
125                 val zae = ZipArchiveEntry(filename)
126                 zae.setSize(file.length())
127                 zaos.putArchiveEntry(zae)
128                 val fis = FileInputStream(file)
129                 IOUtils.copy(fis, zaos)
130                 zaos.closeArchiveEntry()
131             }
132         }
133
134
135         fun deCompress(zipFile: File, targetPath: String): File {
136             val zip = ZipFile(zipFile, Charset.defaultCharset())
137             val enumeration = zip.entries()
138             while (enumeration.hasMoreElements()) {
139                 val entry = enumeration.nextElement()
140                 val destFilePath = File(targetPath, entry.name)
141                 destFilePath.parentFile.mkdirs()
142                 if (entry.isDirectory)
143                     continue
144                 val bufferedIs = BufferedInputStream(zip.getInputStream(entry))
145                 bufferedIs.use {
146                     destFilePath.outputStream().buffered(1024).use { bos ->
147                         bufferedIs.copyTo(bos)
148                     }
149                 }
150             }
151
152             val destinationDir = File(targetPath)
153             check(destinationDir.isDirectory && destinationDir.exists()) {
154                 throw BluePrintProcessorException("failed to decompress blueprint(${zipFile.absolutePath}) to ($targetPath) ")
155             }
156             return destinationDir
157         }
158     }
159
160 }