2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2019 Bell Canada.
4 * Modifications Copyright © 2019 Nordix Foundation.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package org.onap.ccsdk.cds.controllerblueprints.core.utils
21 import com.google.common.base.Predicates
22 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
23 import org.slf4j.LoggerFactory
25 import java.nio.charset.*
26 import java.nio.file.*
27 import java.nio.file.attribute.*
28 import java.util.function.*
29 import java.util.zip.*
31 class BluePrintArchiveUtils {
34 private val log = LoggerFactory.getLogger(BluePrintArchiveUtils::class.java)
37 * Create a new Zip from a root directory
39 * @param source the base directory
40 * @param destination the output filename
43 fun compress(source: File, destination: File): Boolean {
45 if(!destination.parentFile.exists()) {
46 destination.parentFile.mkdirs()
48 destination.createNewFile()
49 val ignoreZipFiles = Predicate<Path> { path -> !path.endsWith(".zip") && !path.endsWith(".ZIP") }
50 FileOutputStream(destination).use { out ->
51 compressFolder(source.toPath(), out, pathFilter = ignoreZipFiles)
53 } catch (e: Exception) {
54 log.error("Fail to compress folder($source) to path(${destination.path})", e)
61 * In-memory compress an entire folder.
63 fun compressToBytes(baseDir: Path, compressionLevel: Int = Deflater.NO_COMPRESSION): ByteArray {
64 return compressFolder(baseDir, ByteArrayOutputStream(), compressionLevel = compressionLevel)
69 * Compress an entire folder.
71 * @param baseDir path of base folder to be packaged.
72 * @param output the output stream
73 * @param pathFilter filter to ignore files based on its path.
74 * @param compressionLevel the wanted compression level.
75 * @param fixedModificationTime to force every entry to have this modification time.
76 * Useful for reproducible operations, like tests, for example.
78 private fun <T> compressFolder(baseDir: Path, output: T,
79 pathFilter: Predicate<Path> = Predicates.alwaysTrue(),
80 compressionLevel: Int = Deflater.DEFAULT_COMPRESSION,
81 fixedModificationTime: Long? = null): T
82 where T : OutputStream {
83 ZipOutputStream(output)
84 .apply { setLevel(compressionLevel) }
86 Files.walkFileTree(baseDir, object : SimpleFileVisitor<Path>() {
87 @Throws(IOException::class)
88 override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
89 if (pathFilter.test(file)) {
90 val zipEntry = ZipEntry(baseDir.relativize(file).toString())
91 fixedModificationTime?.let {
95 zos.putNextEntry(zipEntry)
99 return FileVisitResult.CONTINUE
102 @Throws(IOException::class)
103 override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
104 val zipEntry = ZipEntry(baseDir.relativize(dir).toString() + "/")
105 fixedModificationTime?.let {
108 zos.putNextEntry(zipEntry)
110 return FileVisitResult.CONTINUE
117 fun deCompress(zipFile: File, targetPath: String): File {
118 val zip = ZipFile(zipFile, Charset.defaultCharset())
119 val enumeration = zip.entries()
120 while (enumeration.hasMoreElements()) {
121 val entry = enumeration.nextElement()
122 val destFilePath = File(targetPath, entry.name)
123 destFilePath.parentFile.mkdirs()
125 if (entry.isDirectory)
128 val bufferedIs = BufferedInputStream(zip.getInputStream(entry))
130 destFilePath.outputStream().buffered(1024).use { bos ->
131 bufferedIs.copyTo(bos)
136 val destinationDir = File(targetPath)
137 check(destinationDir.isDirectory && destinationDir.exists()) {
138 throw BluePrintProcessorException("failed to decompress blueprint(${zipFile.absolutePath}) to ($targetPath) ")
141 return destinationDir