1 package org.metricshub.winrm;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.io.IOException;
24 import java.nio.charset.Charset;
25 import java.nio.charset.StandardCharsets;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.nio.file.StandardCopyOption;
30 import java.nio.file.attribute.FileTime;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Objects;
36 import java.util.concurrent.TimeoutException;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39 import org.metricshub.winrm.exceptions.WindowsRemoteException;
40 import org.metricshub.winrm.exceptions.WqlQuerySyntaxException;
41
42 public class WindowsRemoteProcessUtils {
43
44 private WindowsRemoteProcessUtils() {}
45
46 private static final String DEFAULT_CODESET = "1252";
47 private static final Charset DEFAULT_CHARSET = Charset.forName("windows-1252");
48
49
50
51
52
53
54
55
56
57 private static final Map<String, Charset> CODESET_MAP;
58
59 static {
60 final Map<String, Charset> map = new HashMap<>();
61 map.put("1250", Charset.forName("windows-1250"));
62 map.put("1251", Charset.forName("windows-1251"));
63 map.put("1252", DEFAULT_CHARSET);
64 map.put("1253", Charset.forName("windows-1253"));
65 map.put("1254", Charset.forName("windows-1254"));
66 map.put("1255", Charset.forName("windows-1255"));
67 map.put("1256", Charset.forName("windows-1256"));
68 map.put("1257", Charset.forName("windows-1257"));
69 map.put("1258", Charset.forName("windows-1258"));
70 map.put("874", Charset.forName("x-windows-874"));
71 map.put("932", Charset.forName("Shift_JIS"));
72 map.put("936", Charset.forName("GBK"));
73 map.put("949", Charset.forName("EUC-KR"));
74 map.put("950", Charset.forName("Big5"));
75 map.put("951", Charset.forName("Big5-HKSCS"));
76 map.put("28591", StandardCharsets.ISO_8859_1);
77 map.put("20127", StandardCharsets.US_ASCII);
78 map.put("65001", StandardCharsets.UTF_8);
79 map.put("1200", StandardCharsets.UTF_16LE);
80 map.put("1201", StandardCharsets.UTF_16BE);
81
82 CODESET_MAP = Collections.unmodifiableMap(map);
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public static Charset getWindowsEncodingCharset(
102 final WindowsRemoteExecutor windowsRemoteExecutor,
103 final long timeout
104 ) throws TimeoutException, WqlQuerySyntaxException, WindowsRemoteException {
105 if (windowsRemoteExecutor == null || timeout < 1) {
106 return DEFAULT_CHARSET;
107 }
108
109 final List<Map<String, Object>> result = windowsRemoteExecutor.executeWql(
110 "SELECT CodeSet FROM Win32_OperatingSystem",
111 timeout
112 );
113
114 final String codeSet = result
115 .stream()
116 .map(row -> (String) row.get("CodeSet"))
117 .filter(Objects::nonNull)
118 .findFirst()
119 .orElse(DEFAULT_CODESET);
120
121 return CODESET_MAP.getOrDefault(codeSet, DEFAULT_CHARSET);
122 }
123
124
125
126
127
128
129
130 public static String buildNewOutputFileName() {
131 return String.format(
132 "SEN_%s_%d_%d",
133 Utils.getComputerName(),
134 Utils.getCurrentTimeMillis(),
135 (long) (Math.random() * 1000000)
136 );
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150
151 public static String copyLocalFilesToShare(
152 final String command,
153 final List<String> localFiles,
154 final String uncSharePath,
155 final String remotePath
156 ) throws IOException {
157 Utils.checkNonNull(command, "command");
158
159 if (localFiles == null || localFiles.isEmpty()) {
160 return command;
161 }
162
163 Utils.checkNonNull(uncSharePath, "uncSharePath");
164 Utils.checkNonNull(remotePath, "remotePath");
165
166 try {
167 return localFiles
168 .stream()
169 .reduce(
170 command,
171 (cmd, localFile) -> {
172 try {
173 final Path localFilePath = Paths.get(localFile);
174 final Path remoteFilePath = copyToShare(localFilePath, uncSharePath, remotePath);
175
176 return caseInsensitiveReplace(cmd, localFile, remoteFilePath.toString());
177 } catch (final IOException e) {
178 throw new RuntimeException(e);
179 }
180 }
181 );
182 } catch (final Exception e) {
183 if (e.getCause() instanceof IOException) {
184 throw (IOException) e.getCause();
185 }
186 throw e;
187 }
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 static Path copyToShare(final Path localFilePath, final String uncSharePath, final String remotePath)
206 throws IOException {
207 final Path targetUncPath = Paths.get(uncSharePath, localFilePath.getFileName().toString());
208 final Path targetRemotePath = Paths.get(remotePath, localFilePath.getFileName().toString());
209
210 if (Files.exists(targetUncPath)) {
211 final FileTime sourceFileTime = Files.getLastModifiedTime(localFilePath);
212 final FileTime targetFileTime = Files.getLastModifiedTime(targetUncPath);
213 if (sourceFileTime.compareTo(targetFileTime) <= 0) {
214
215 return targetRemotePath;
216 }
217 }
218
219
220 Files.copy(localFilePath, targetUncPath, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);
221
222
223 return targetRemotePath;
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238 static String caseInsensitiveReplace(final String string, final String target, final String replacement) {
239 return string == null || target == null
240 ? string
241 : Pattern
242 .compile(target, Pattern.LITERAL | Pattern.CASE_INSENSITIVE)
243 .matcher(string)
244 .replaceAll(Matcher.quoteReplacement(replacement == null ? Utils.EMPTY : replacement));
245 }
246 }