1 package org.openecomp.sdc.translator.utils;
3 import org.apache.commons.io.IOUtils;
4 import org.openecomp.sdc.common.errors.CoreException;
5 import org.openecomp.sdc.common.errors.ErrorCategory;
6 import org.openecomp.sdc.common.errors.ErrorCode;
7 import org.openecomp.sdc.datatypes.error.ErrorLevel;
8 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
9 import org.openecomp.sdc.logging.types.LoggerConstants;
10 import org.openecomp.sdc.logging.types.LoggerErrorCode;
11 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
12 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
14 import java.io.BufferedReader;
16 import java.io.FileInputStream;
17 import java.io.FileNotFoundException;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.InputStreamReader;
22 import java.net.URISyntaxException;
24 import java.util.Enumeration;
25 import java.util.HashMap;
27 import java.util.function.BiConsumer;
28 import java.util.function.Predicate;
29 import java.util.zip.ZipEntry;
30 import java.util.zip.ZipFile;
36 public class ResourceWalker {
38 public static Map<String, String> readResourcesFromDirectory(String resourceDirectoryToStart)
41 Map<String, String> filesContent = new HashMap<>();
42 traverse(resourceDirectoryToStart, (fileName, stream) -> {
43 BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
45 filesContent.put(fileName, IOUtils.toString(reader));
46 } catch (IOException exception) {
47 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_API,
48 LoggerTragetServiceName.READ_RESOURCE_FILE, ErrorLevel.ERROR.name(),
49 LoggerErrorCode.DATA_ERROR.getErrorCode(),
50 LoggerErrorDescription.RESOURCE_FILE_READ_ERROR
51 + " File name = " + fileName);
52 throw new CoreException((new ErrorCode.ErrorCodeBuilder())
53 .withMessage(LoggerErrorDescription.RESOURCE_FILE_READ_ERROR
54 + " File name = " + fileName)
55 .withId("Resource Read Error").withCategory(ErrorCategory.APPLICATION).build(),
62 private static void traverse(String start, BiConsumer<String, InputStream> handler) throws
65 URL url = ResourceWalker.class.getClassLoader().getResource(start);
67 throw new FileNotFoundException("Resource not found: " + start);
70 switch (url.getProtocol().toLowerCase()) {
73 traverseFile(new File(url.getPath()), handler);
77 String path = url.getPath();
78 int resourcePosition = path.lastIndexOf("!/" + start);
79 traverseArchive(path.substring(0, resourcePosition), start, handler);
82 throw new IllegalArgumentException("Unknown protocol");
86 private static void traverseArchive(String file, String resource, BiConsumer<String, InputStream>
88 throws URISyntaxException, IOException {
90 // There is what looks like a bug in Java:
91 // if "abc" is a directory in an archive,
92 // both "abc" and "abc/" will be found successfully.
93 // However, calling isDirectory() will return "true" for "abc/",
94 // but "false" for "abc".
95 try (ZipFile zip = new ZipFile(new URI(file).getPath())) {
97 Predicate<ZipEntry> predicate = buildPredicate(resource);
98 Enumeration<? extends ZipEntry> entries = zip.entries();
99 while (entries.hasMoreElements()) {
100 handleZipEntry(predicate, zip, entries.nextElement(), handler);
105 private static Predicate<ZipEntry> buildPredicate(String resource) {
107 if (resource.endsWith("/")) {
109 zipEntry.getName().startsWith(resource) && !zipEntry.isDirectory();
112 String name = zipEntry.getName();
113 return (name.equals(resource) || name.startsWith(resource + "/"))
114 && !zipEntry.isDirectory();
119 private static void handleZipEntry(Predicate<ZipEntry> predicate, ZipFile zip, ZipEntry zipEntry,
120 BiConsumer<String, InputStream> handler)
123 if (predicate.test(zipEntry)) {
125 try (InputStream input = zip.getInputStream(zipEntry)) {
126 handler.accept(zipEntry.getName(), input);
131 private static void traverseFile(File file, BiConsumer<String, InputStream> handler) throws
134 if (file.isDirectory()) {
135 for (File sub : file.listFiles()) {
136 traverseFile(sub, handler);
139 try (FileInputStream stream = new FileInputStream(file)) {
140 handler.accept(file.getName(), stream);