Skip to content

Commit 92a6e02

Browse files
committed
Merge branch 'release-2.2.4'
2 parents 0bd86d6 + 367f758 commit 92a6e02

File tree

15 files changed

+601
-24
lines changed

15 files changed

+601
-24
lines changed

.dependabot/config.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
version: 1
2+
update_configs:
3+
- package_manager: "java:maven"
4+
directory: "/"
5+
update_schedule: "daily"
6+
automerged_updates:
7+
- match:
8+
dependency_name: "org.apache.maven.plugins:*"
9+
- match:
10+
dependency_name: "org.codehaus.mojo:*"
11+
- match:
12+
dependency_name: "org.gaul:modernizer-maven-plugin"
13+
- match:
14+
dependency_name: "org.jacoco:jacoco-maven-plugin"
15+
- match:
16+
dependency_name: "org.checkerframework:checker-qual"
17+
- match:
18+
dependency_name: "org.assertj:assertj-core"
19+
- match:
20+
dependency_name: "org.openjdk.jmh:*"
21+
- match:
22+
dependency_name: "com.akathist.maven.plugins.launch4j:launch4j-maven-plugin"
23+
- match:
24+
dependency_name: "net.nicoulaj.maven.plugins:checksum-maven-plugin"
25+

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ deploy:
4141
- provider: releases
4242
api_key: "${GITHUB_KEY}"
4343
skip_cleanup: true
44+
draft: true
4445
on:
4546
tags: true
4647
repo: "${DEPLOY_REPO}"

java-desktop-util-chart/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>be.nbb.rd</groupId>
77
<artifactId>java-desktop-util-parent</artifactId>
8-
<version>2.2.3</version>
8+
<version>2.2.4</version>
99
</parent>
1010

1111
<artifactId>java-desktop-util-chart</artifactId>

java-desktop-util-fa/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>be.nbb.rd</groupId>
77
<artifactId>java-desktop-util-parent</artifactId>
8-
<version>2.2.3</version>
8+
<version>2.2.4</version>
99
</parent>
1010

1111
<artifactId>java-desktop-util-fa</artifactId>

java-desktop-util-os/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>be.nbb.rd</groupId>
77
<artifactId>java-desktop-util-parent</artifactId>
8-
<version>2.2.3</version>
8+
<version>2.2.4</version>
99
</parent>
1010

1111
<artifactId>java-desktop-util-os</artifactId>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright 2018 National Bank of Belgium
3+
*
4+
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
5+
* by the European Commission - subsequent versions of the EUPL (the "Licence");
6+
* You may not use this work except in compliance with the Licence.
7+
* You may obtain a copy of the Licence at:
8+
*
9+
* http://ec.europa.eu/idabc/eupl
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the Licence is distributed on an "AS IS" basis,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the Licence for the specific language governing permissions and
15+
* limitations under the Licence.
16+
*/
17+
package ec.util.desktop.impl;
18+
19+
import java.io.BufferedReader;
20+
import java.io.IOException;
21+
import java.util.ArrayList;
22+
import java.util.LinkedHashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Objects;
26+
import java.util.regex.Matcher;
27+
import java.util.regex.Pattern;
28+
import org.checkerframework.checker.nullness.qual.NonNull;
29+
import org.checkerframework.checker.nullness.qual.Nullable;
30+
31+
/**
32+
*
33+
* @author Philippe Charles
34+
*/
35+
@lombok.experimental.UtilityClass
36+
class InternalCopyOfRegWrapper {
37+
38+
public static final String COMMAND = "reg";
39+
40+
@NonNull
41+
public Map<String, List<RegValue>> query(@NonNull String keyName, boolean recursive) throws IOException {
42+
Objects.requireNonNull(keyName);
43+
try (BufferedReader reader = InternalCopyofProcessReader.newReader(getArgs(keyName, recursive))) {
44+
return parse(reader);
45+
}
46+
}
47+
48+
String[] getArgs(String keyName, boolean recursive) {
49+
List<String> args = new ArrayList<>();
50+
args.add(COMMAND);
51+
args.add("query");
52+
args.add(keyName);
53+
if (recursive) {
54+
args.add("/s");
55+
}
56+
return args.toArray(new String[0]);
57+
}
58+
59+
Map<String, List<RegValue>> parse(BufferedReader reader) throws IOException {
60+
Map<String, List<RegValue>> result = new LinkedHashMap<>();
61+
String line;
62+
String subKey = null;
63+
List<RegValue> values = null;
64+
while ((line = reader.readLine()) != null) {
65+
if (!line.isEmpty()) {
66+
if (subKey == null) {
67+
subKey = line;
68+
values = new ArrayList<>();
69+
} else {
70+
RegValue regValue = RegValue.parseOrNull(line);
71+
if (regValue != null) {
72+
values.add(regValue);
73+
} else {
74+
result.put(subKey, values);
75+
subKey = line;
76+
values = new ArrayList<>();
77+
}
78+
}
79+
}
80+
}
81+
if (subKey != null) {
82+
result.put(subKey, values);
83+
}
84+
return result;
85+
}
86+
87+
@lombok.Value
88+
public static final class RegValue {
89+
90+
private static final Pattern PATTERN = Pattern.compile("^[ ]{4}(.+)[ ]{4}(REG_(?:SZ|MULTI_SZ|EXPAND_SZ|DWORD|QWORD|BINARY|NONE))[ ]{4}(.*)$");
91+
92+
@Nullable
93+
public static RegValue parseOrNull(@NonNull CharSequence line) {
94+
Matcher m = PATTERN.matcher(line);
95+
return m.matches() ? new RegValue(m.group(1), m.group(2), m.group(3)) : null;
96+
}
97+
98+
@lombok.NonNull
99+
private String name;
100+
101+
@lombok.NonNull
102+
private String dataType;
103+
104+
@lombok.NonNull
105+
private String value;
106+
}
107+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2018 National Bank of Belgium
3+
*
4+
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
5+
* by the European Commission - subsequent versions of the EUPL (the "Licence");
6+
* You may not use this work except in compliance with the Licence.
7+
* You may obtain a copy of the Licence at:
8+
*
9+
* http://ec.europa.eu/idabc/eupl
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the Licence is distributed on an "AS IS" basis,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the Licence for the specific language governing permissions and
15+
* limitations under the Licence.
16+
*/
17+
package ec.util.desktop.impl;
18+
19+
import java.io.BufferedReader;
20+
import java.io.Closeable;
21+
import java.io.IOException;
22+
import java.io.InputStream;
23+
import java.io.InputStreamReader;
24+
import java.nio.charset.Charset;
25+
import org.checkerframework.checker.nullness.qual.NonNull;
26+
27+
/**
28+
*
29+
* @author Philippe Charles
30+
*/
31+
@lombok.experimental.UtilityClass
32+
class InternalCopyofProcessReader {
33+
34+
@NonNull
35+
public static BufferedReader newReader(@NonNull String... args) throws IOException {
36+
return newReader(new ProcessBuilder(args).start());
37+
}
38+
39+
@NonNull
40+
public static BufferedReader newReader(@NonNull Process process) throws IOException {
41+
return new BufferedReader(new InputStreamReader(new ProcessInputStream(process), Charset.defaultCharset()));
42+
}
43+
44+
private static final class ProcessInputStream extends InputStream {
45+
46+
@lombok.experimental.Delegate(excludes = Closeable.class)
47+
private final InputStream delegate;
48+
49+
private final Process process;
50+
51+
public ProcessInputStream(Process process) {
52+
this.delegate = process.getInputStream();
53+
this.process = process;
54+
}
55+
56+
@Override
57+
public void close() throws IOException {
58+
try {
59+
readUntilEnd();
60+
waitForEndOfProcess();
61+
} finally {
62+
delegate.close();
63+
}
64+
}
65+
66+
// we need the process to end, else we'll get an illegal Thread State Exception
67+
private void readUntilEnd() throws IOException {
68+
while (delegate.read() != -1) {
69+
}
70+
}
71+
72+
private void waitForEndOfProcess() throws IOException {
73+
try {
74+
process.waitFor();
75+
} catch (InterruptedException ex) {
76+
throw new IOException(ex);
77+
}
78+
}
79+
}
80+
}

java-desktop-util-os/src/main/java/ec/util/desktop/impl/JnaRegistry.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.sun.jna.platform.win32.Win32Exception;
2121
import com.sun.jna.platform.win32.WinReg;
2222
import java.io.IOException;
23+
import java.util.Objects;
2324
import java.util.SortedMap;
2425

2526
/**
@@ -30,6 +31,8 @@ final class JnaRegistry extends WinRegistry {
3031

3132
@Override
3233
public boolean keyExists(Root root, String key) throws IOException {
34+
Objects.requireNonNull(root);
35+
Objects.requireNonNull(key);
3336
try {
3437
return Advapi32Util.registryKeyExists(convert(root), key);
3538
} catch (Win32Exception | UnsatisfiedLinkError ex) {
@@ -39,6 +42,9 @@ public boolean keyExists(Root root, String key) throws IOException {
3942

4043
@Override
4144
public Object getValue(Root root, String key, String name) throws IOException {
45+
Objects.requireNonNull(root);
46+
Objects.requireNonNull(key);
47+
Objects.requireNonNull(name);
4248
try {
4349
WinReg.HKEY hkey = convert(root);
4450
return Advapi32Util.registryValueExists(hkey, key, name) ? Advapi32Util.registryGetValue(hkey, key, name) : null;
@@ -49,6 +55,8 @@ public Object getValue(Root root, String key, String name) throws IOException {
4955

5056
@Override
5157
public SortedMap<String, Object> getValues(Root root, String key) throws IOException {
58+
Objects.requireNonNull(root);
59+
Objects.requireNonNull(key);
5260
try {
5361
WinReg.HKEY hkey = convert(root);
5462
return Advapi32Util.registryKeyExists(hkey, key) ? Advapi32Util.registryGetValues(hkey, key) : Util.EMPTY_SORTED_MAP;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2020 National Bank of Belgium
3+
*
4+
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
5+
* by the European Commission - subsequent versions of the EUPL (the "Licence");
6+
* You may not use this work except in compliance with the Licence.
7+
* You may obtain a copy of the Licence at:
8+
*
9+
* http://ec.europa.eu/idabc/eupl
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the Licence is distributed on an "AS IS" basis,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the Licence for the specific language governing permissions and
15+
* limitations under the Licence.
16+
*/
17+
package ec.util.desktop.impl;
18+
19+
import ec.util.desktop.impl.InternalCopyOfRegWrapper.RegValue;
20+
import java.io.IOException;
21+
import java.util.Collections;
22+
import java.util.List;
23+
import java.util.Objects;
24+
import java.util.SortedMap;
25+
import java.util.TreeMap;
26+
import java.util.stream.Collectors;
27+
28+
/**
29+
*
30+
* @author Philippe Charles
31+
*/
32+
final class RegRegistry extends WinRegistry {
33+
34+
private static final String KEY_SEPARATOR = "\\";
35+
36+
private List<InternalCopyOfRegWrapper.RegValue> getValuesOrNull(WinRegistry.Root root, String key) throws IOException {
37+
Objects.requireNonNull(root);
38+
Objects.requireNonNull(key);
39+
String keyName = root.name() + KEY_SEPARATOR + key;
40+
return InternalCopyOfRegWrapper.query(keyName, false).get(keyName);
41+
}
42+
43+
@Override
44+
public boolean keyExists(WinRegistry.Root root, String key) throws IOException {
45+
List<InternalCopyOfRegWrapper.RegValue> data = getValuesOrNull(root, key);
46+
return data != null;
47+
}
48+
49+
@Override
50+
public Object getValue(WinRegistry.Root root, String key, String name) throws IOException {
51+
List<InternalCopyOfRegWrapper.RegValue> data = getValuesOrNull(root, key);
52+
Objects.requireNonNull(name);
53+
return data != null
54+
? data
55+
.stream()
56+
.filter(regValue -> regValue.getName().equals(name))
57+
.map(regValue -> regValue.getValue())
58+
.findFirst()
59+
.orElse(null)
60+
: null;
61+
}
62+
63+
@Override
64+
public SortedMap<String, Object> getValues(WinRegistry.Root root, String key) throws IOException {
65+
List<InternalCopyOfRegWrapper.RegValue> data = getValuesOrNull(root, key);
66+
return data != null
67+
? data.stream().collect(Collectors.toMap(RegValue::getName, regValue -> (Object) regValue.getValue(), (l, r) -> l, TreeMap::new))
68+
: Collections.emptySortedMap();
69+
}
70+
}

java-desktop-util-os/src/main/java/ec/util/desktop/impl/WinRegistry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ private static WinRegistry createInstance() {
7272
return new JnaRegistry();
7373
}
7474
// fallback
75-
log.log(Level.INFO, "Using NoOpRegistry");
76-
return noOp();
75+
log.log(Level.INFO, "Using RegRegistry");
76+
return new RegRegistry();
7777
}
7878
}
7979

0 commit comments

Comments
 (0)