[SDC-29] Amdocs OnBoard 1707 initial commit.
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / utils / ResourceWalker.java
1 package org.openecomp.sdc.translator.utils;
2
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;
13
14 import java.io.BufferedReader;
15 import java.io.File;
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;
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.net.URL;
24 import java.util.Enumeration;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.function.BiConsumer;
28 import java.util.function.Predicate;
29 import java.util.zip.ZipEntry;
30 import java.util.zip.ZipFile;
31
32 /**
33  * @author EVITALIY.
34  * @since 02 Apr 17
35  */
36 public class ResourceWalker {
37
38   public static Map<String, String> readResourcesFromDirectory(String resourceDirectoryToStart)
39       throws
40       Exception {
41     Map<String, String> filesContent = new HashMap<>();
42     traverse(resourceDirectoryToStart, (fileName, stream) -> {
43       BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
44       try {
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(),
56             exception);
57       }
58     });
59     return filesContent;
60   }
61
62   private static void traverse(String start, BiConsumer<String, InputStream> handler) throws
63       Exception {
64
65     URL url = ResourceWalker.class.getClassLoader().getResource(start);
66     if (url == null) {
67       throw new FileNotFoundException("Resource not found: " + start);
68     }
69
70     switch (url.getProtocol().toLowerCase()) {
71
72       case "file":
73         traverseFile(new File(url.getPath()), handler);
74         break;
75       case "zip":
76       case "jar":
77         String path = url.getPath();
78         int resourcePosition = path.lastIndexOf("!/" + start);
79         traverseArchive(path.substring(0, resourcePosition), start, handler);
80         break;
81       default:
82         throw new IllegalArgumentException("Unknown protocol");
83     }
84   }
85
86   private static void traverseArchive(String file, String resource, BiConsumer<String, InputStream>
87       handler)
88       throws URISyntaxException, IOException {
89
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())) {
96
97       Predicate<ZipEntry> predicate = buildPredicate(resource);
98       Enumeration<? extends ZipEntry> entries = zip.entries();
99       while (entries.hasMoreElements()) {
100         handleZipEntry(predicate, zip, entries.nextElement(), handler);
101       }
102     }
103   }
104
105   private static Predicate<ZipEntry> buildPredicate(String resource) {
106
107     if (resource.endsWith("/")) {
108       return zipEntry ->
109           zipEntry.getName().startsWith(resource) && !zipEntry.isDirectory();
110     } else {
111       return zipEntry -> {
112         String name = zipEntry.getName();
113         return (name.equals(resource) || name.startsWith(resource + "/"))
114             && !zipEntry.isDirectory();
115       };
116     }
117   }
118
119   private static void handleZipEntry(Predicate<ZipEntry> predicate, ZipFile zip, ZipEntry zipEntry,
120                                      BiConsumer<String, InputStream> handler)
121       throws IOException {
122
123     if (predicate.test(zipEntry)) {
124
125       try (InputStream input = zip.getInputStream(zipEntry)) {
126         handler.accept(zipEntry.getName(), input);
127       }
128     }
129   }
130
131   private static void traverseFile(File file, BiConsumer<String, InputStream> handler) throws
132       IOException {
133
134     if (file.isDirectory()) {
135       for (File sub : file.listFiles()) {
136         traverseFile(sub, handler);
137       }
138     } else {
139       try (FileInputStream stream = new FileInputStream(file)) {
140         handler.accept(file.getName(), stream);
141       }
142     }
143   }
144 }