Skip to content

Commit 6eee263

Browse files
author
taylor.smock
committed
Fix #23725: Drop Java 8 code in WinRegistry
git-svn-id: https://josm.openstreetmap.de/svn/trunk@19100 0c6e7542-c601-0410-84e7-c038aed88b3b
1 parent 703b385 commit 6eee263

File tree

1 file changed

+85
-77
lines changed

1 file changed

+85
-77
lines changed

src/org/openstreetmap/josm/tools/WinRegistry.java

Lines changed: 85 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public final class WinRegistry {
2828
* colors, printers, network connections, and application preferences.
2929
* See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms724836(v=vs.85).aspx">Predefined Keys</a>
3030
*/
31-
public static final int HKEY_CURRENT_USER = 0x80000001;
31+
public static final long HKEY_CURRENT_USER = 0x80000001L;
3232

3333
/**
3434
* Registry entries subordinate to this key define the physical state of the computer, including data about the bus type,
@@ -38,44 +38,62 @@ public final class WinRegistry {
3838
* names and the location of the server), and other system information.
3939
* See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms724836(v=vs.85).aspx">Predefined Keys</a>
4040
*/
41-
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
41+
public static final long HKEY_LOCAL_MACHINE = 0x80000002L;
4242

4343
private static final long REG_SUCCESS = 0L;
4444

4545
private static final int KEY_READ = 0x20019;
46-
private static final Preferences userRoot = Preferences.userRoot();
47-
private static final Preferences systemRoot = Preferences.systemRoot();
48-
private static final Class<? extends Preferences> userClass = userRoot.getClass();
49-
private static final Method regOpenKey;
50-
private static final Method regCloseKey;
51-
private static final Method regQueryValueEx;
52-
private static final Method regEnumValue;
53-
private static final Method regQueryInfoKey;
54-
private static final Method regEnumKeyEx;
55-
56-
private static boolean java11;
46+
private static final Preferences USER_ROOT = Preferences.userRoot();
47+
private static final Preferences SYSTEM_ROOT = Preferences.systemRoot();
48+
private static final Class<? extends Preferences> USER_CLASS = USER_ROOT.getClass();
49+
private static final String HKEY_EQ = "hkey=";
50+
51+
/**
52+
* Wrapper for Windows registry API RegOpenKey(long, byte[], int)
53+
* Returns {@code long[]}
54+
*/
55+
private static final Method REG_OPEN_KEY;
56+
/**
57+
* Wrapper for Windows registry API RegCloseKey(long)
58+
* Returns {@code int}
59+
*/
60+
private static final Method REG_CLOSE_KEY;
61+
/**
62+
* Wrapper for Windows registry API RegQueryValueEx(long, byte[])
63+
* Returns {@code byte[]}
64+
*/
65+
private static final Method REG_QUERY_VALUE_EX;
66+
/**
67+
* Wrapper for Windows registry API RegEnumValue(long, int, int)
68+
* Returns {@code byte[]}
69+
*/
70+
private static final Method REG_ENUM_VALUE;
71+
/**
72+
* Wrapper for RegQueryInfoKey(long)
73+
* Returns {@code long[]}
74+
*/
75+
private static final Method REG_QUERY_INFO_KEY;
76+
/**
77+
* Wrapper for RegEnumKeyEx(long, int, int)
78+
* Returns {@code byte[]}
79+
*/
80+
private static final Method REG_ENUM_KEY_EX;
5781

5882
static {
59-
regOpenKey = getDeclaredMethod("WindowsRegOpenKey", int.class, byte[].class, int.class);
60-
regCloseKey = getDeclaredMethod("WindowsRegCloseKey", int.class);
61-
regQueryValueEx = getDeclaredMethod("WindowsRegQueryValueEx", int.class, byte[].class);
62-
regEnumValue = getDeclaredMethod("WindowsRegEnumValue", int.class, int.class, int.class);
63-
regQueryInfoKey = getDeclaredMethod("WindowsRegQueryInfoKey1", int.class);
64-
regEnumKeyEx = getDeclaredMethod("WindowsRegEnumKeyEx", int.class, int.class, int.class);
65-
ReflectionUtils.setObjectsAccessible(regOpenKey, regCloseKey, regQueryValueEx, regEnumValue, regQueryInfoKey, regEnumKeyEx);
83+
REG_OPEN_KEY = getDeclaredMethod("WindowsRegOpenKey", long.class, byte[].class, int.class);
84+
REG_CLOSE_KEY = getDeclaredMethod("WindowsRegCloseKey", long.class);
85+
REG_QUERY_VALUE_EX = getDeclaredMethod("WindowsRegQueryValueEx", long.class, byte[].class);
86+
REG_ENUM_VALUE = getDeclaredMethod("WindowsRegEnumValue", long.class, int.class, int.class);
87+
REG_QUERY_INFO_KEY = getDeclaredMethod("WindowsRegQueryInfoKey1", long.class);
88+
REG_ENUM_KEY_EX = getDeclaredMethod("WindowsRegEnumKeyEx", long.class, int.class, int.class);
89+
ReflectionUtils.setObjectsAccessible(REG_OPEN_KEY, REG_CLOSE_KEY, REG_QUERY_VALUE_EX, REG_ENUM_VALUE,
90+
REG_QUERY_INFO_KEY, REG_ENUM_KEY_EX);
6691
}
6792

6893
private static Method getDeclaredMethod(String name, Class<?>... parameterTypes) {
6994
try {
70-
return userClass.getDeclaredMethod(name, parameterTypes);
95+
return USER_CLASS.getDeclaredMethod(name, parameterTypes);
7196
} catch (NoSuchMethodException e) {
72-
if (parameterTypes.length > 0 && parameterTypes[0] == int.class) {
73-
// JDK-8198899: change of signature in Java 11. Old signature to drop when we switch to Java 11
74-
Class<?>[] parameterTypesCopy = Utils.copyArray(parameterTypes);
75-
parameterTypesCopy[0] = long.class;
76-
java11 = true;
77-
return getDeclaredMethod(name, parameterTypesCopy);
78-
}
7997
Logging.log(Logging.LEVEL_ERROR, "Unable to find WindowsReg method", e);
8098
return null;
8199
} catch (RuntimeException e) {
@@ -84,10 +102,6 @@ private static Method getDeclaredMethod(String name, Class<?>... parameterTypes)
84102
}
85103
}
86104

87-
private static Number hkey(int key) {
88-
return java11 ? ((Number) Long.valueOf(key)) : ((Number) Integer.valueOf(key));
89-
}
90-
91105
private WinRegistry() {
92106
// Hide default constructor for utilities classes
93107
}
@@ -101,15 +115,16 @@ private WinRegistry() {
101115
* @throws IllegalArgumentException if hkey not HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
102116
* @throws IllegalAccessException if Java language access control is enforced and the underlying method is inaccessible
103117
* @throws InvocationTargetException if the underlying method throws an exception
118+
* @since 19100 (method definition)
104119
*/
105-
public static String readString(int hkey, String key, String valueName)
120+
public static String readString(long hkey, String key, String valueName)
106121
throws IllegalAccessException, InvocationTargetException {
107122
if (hkey == HKEY_LOCAL_MACHINE) {
108-
return readString(systemRoot, hkey, key, valueName);
123+
return readString(SYSTEM_ROOT, hkey, key, valueName);
109124
} else if (hkey == HKEY_CURRENT_USER) {
110-
return readString(userRoot, hkey, key, valueName);
125+
return readString(USER_ROOT, hkey, key, valueName);
111126
} else {
112-
throw new IllegalArgumentException("hkey=" + hkey);
127+
throw new IllegalArgumentException(HKEY_EQ + hkey);
113128
}
114129
}
115130

@@ -122,14 +137,14 @@ public static String readString(int hkey, String key, String valueName)
122137
* @throws IllegalAccessException if Java language access control is enforced and the underlying method is inaccessible
123138
* @throws InvocationTargetException if the underlying method throws an exception
124139
*/
125-
public static Map<String, String> readStringValues(int hkey, String key)
140+
public static Map<String, String> readStringValues(long hkey, String key)
126141
throws IllegalAccessException, InvocationTargetException {
127142
if (hkey == HKEY_LOCAL_MACHINE) {
128-
return readStringValues(systemRoot, hkey, key);
143+
return readStringValues(SYSTEM_ROOT, hkey, key);
129144
} else if (hkey == HKEY_CURRENT_USER) {
130-
return readStringValues(userRoot, hkey, key);
145+
return readStringValues(USER_ROOT, hkey, key);
131146
} else {
132-
throw new IllegalArgumentException("hkey=" + hkey);
147+
throw new IllegalArgumentException(HKEY_EQ + hkey);
133148
}
134149
}
135150

@@ -142,89 +157,82 @@ public static Map<String, String> readStringValues(int hkey, String key)
142157
* @throws IllegalAccessException if Java language access control is enforced and the underlying method is inaccessible
143158
* @throws InvocationTargetException if the underlying method throws an exception
144159
*/
145-
public static List<String> readStringSubKeys(int hkey, String key)
160+
public static List<String> readStringSubKeys(long hkey, String key)
146161
throws IllegalAccessException, InvocationTargetException {
147162
if (hkey == HKEY_LOCAL_MACHINE) {
148-
return readStringSubKeys(systemRoot, hkey, key);
163+
return readStringSubKeys(SYSTEM_ROOT, hkey, key);
149164
} else if (hkey == HKEY_CURRENT_USER) {
150-
return readStringSubKeys(userRoot, hkey, key);
165+
return readStringSubKeys(USER_ROOT, hkey, key);
151166
} else {
152-
throw new IllegalArgumentException("hkey=" + hkey);
167+
throw new IllegalArgumentException(HKEY_EQ + hkey);
153168
}
154169
}
155170

156171
// =====================
157172

158-
private static Number getNumber(Object array, int index) {
159-
if (array instanceof int[]) {
160-
return ((int[]) array)[index];
161-
} else if (array instanceof long[]) {
173+
private static long getNumber(Object array, int index) {
174+
if (array instanceof long[]) {
162175
return ((long[]) array)[index];
163176
}
164177
throw new IllegalArgumentException();
165178
}
166179

167-
private static String readString(Preferences root, int hkey, String key, String value)
180+
private static String readString(Preferences root, long hkey, String key, String value)
168181
throws IllegalAccessException, InvocationTargetException {
169-
if (regOpenKey == null || regQueryValueEx == null || regCloseKey == null) {
182+
if (REG_OPEN_KEY == null || REG_QUERY_VALUE_EX == null || REG_CLOSE_KEY == null) {
170183
return null;
171184
}
172-
// Need to capture both int[] (Java 8-10) and long[] (Java 11+)
173-
Object handles = regOpenKey.invoke(root, hkey(hkey), toCstr(key), Integer.valueOf(KEY_READ));
174-
if (getNumber(handles, 1).longValue() != REG_SUCCESS) {
185+
Object handles = REG_OPEN_KEY.invoke(root, hkey, toCstr(key), KEY_READ);
186+
if (getNumber(handles, 1) != REG_SUCCESS) {
175187
return null;
176188
}
177-
byte[] valb = (byte[]) regQueryValueEx.invoke(root, getNumber(handles, 0), toCstr(value));
178-
regCloseKey.invoke(root, getNumber(handles, 0));
189+
byte[] valb = (byte[]) REG_QUERY_VALUE_EX.invoke(root, getNumber(handles, 0), toCstr(value));
190+
REG_CLOSE_KEY.invoke(root, getNumber(handles, 0));
179191
return (valb != null ? new String(valb, StandardCharsets.UTF_8).trim() : null);
180192
}
181193

182-
private static Map<String, String> readStringValues(Preferences root, int hkey, String key)
194+
private static Map<String, String> readStringValues(Preferences root, long hkey, String key)
183195
throws IllegalAccessException, InvocationTargetException {
184-
if (regOpenKey == null || regQueryInfoKey == null || regEnumValue == null || regCloseKey == null) {
196+
if (REG_OPEN_KEY == null || REG_QUERY_INFO_KEY == null || REG_ENUM_VALUE == null || REG_CLOSE_KEY == null) {
185197
return Collections.emptyMap();
186198
}
187199
HashMap<String, String> results = new HashMap<>();
188-
// Need to capture both int[] (Java 8-10) and long[] (Java 11+)
189-
Object handles = regOpenKey.invoke(root, hkey(hkey), toCstr(key), Integer.valueOf(KEY_READ));
190-
if (getNumber(handles, 1).longValue() != REG_SUCCESS) {
200+
Object handles = REG_OPEN_KEY.invoke(root, hkey, toCstr(key), KEY_READ);
201+
if (getNumber(handles, 1) != REG_SUCCESS) {
191202
return Collections.emptyMap();
192203
}
193-
// Need to capture both int[] (Java 8-10) and long[] (Java 11+)
194-
Object info = regQueryInfoKey.invoke(root, getNumber(handles, 0));
204+
Object info = REG_QUERY_INFO_KEY.invoke(root, getNumber(handles, 0));
195205

196-
int count = getNumber(info, 0).intValue();
197-
int maxlen = getNumber(info, 3).intValue();
206+
int count = Math.toIntExact(getNumber(info, 0));
207+
int maxlen = Math.toIntExact(getNumber(info, 3));
198208
for (int index = 0; index < count; index++) {
199-
byte[] name = (byte[]) regEnumValue.invoke(root, getNumber(handles, 0), Integer.valueOf(index), Integer.valueOf(maxlen + 1));
209+
byte[] name = (byte[]) REG_ENUM_VALUE.invoke(root, getNumber(handles, 0), index, maxlen + 1);
200210
String value = readString(hkey, key, new String(name, StandardCharsets.UTF_8));
201211
results.put(new String(name, StandardCharsets.UTF_8).trim(), value);
202212
}
203-
regCloseKey.invoke(root, getNumber(handles, 0));
213+
REG_CLOSE_KEY.invoke(root, getNumber(handles, 0));
204214
return Collections.unmodifiableMap(results);
205215
}
206216

207-
private static List<String> readStringSubKeys(Preferences root, int hkey, String key)
217+
private static List<String> readStringSubKeys(Preferences root, long hkey, String key)
208218
throws IllegalAccessException, InvocationTargetException {
209-
if (regOpenKey == null || regQueryInfoKey == null || regEnumKeyEx == null || regCloseKey == null) {
219+
if (REG_OPEN_KEY == null || REG_QUERY_INFO_KEY == null || REG_ENUM_KEY_EX == null || REG_CLOSE_KEY == null) {
210220
return Collections.emptyList();
211221
}
212222
List<String> results = new ArrayList<>();
213-
// Need to capture both int[] (Java 8-10) and long[] (Java 11+)
214-
Object handles = regOpenKey.invoke(root, hkey(hkey), toCstr(key), Integer.valueOf(KEY_READ));
215-
if (getNumber(handles, 1).longValue() != REG_SUCCESS) {
223+
Object handles = REG_OPEN_KEY.invoke(root, hkey, toCstr(key), KEY_READ);
224+
if (getNumber(handles, 1) != REG_SUCCESS) {
216225
return Collections.emptyList();
217226
}
218-
// Need to capture both int[] (Java 8-10) and long[] (Java 11+)
219-
Object info = regQueryInfoKey.invoke(root, getNumber(handles, 0));
227+
Object info = REG_QUERY_INFO_KEY.invoke(root, getNumber(handles, 0));
220228

221-
int count = getNumber(info, 0).intValue();
222-
int maxlen = getNumber(info, 3).intValue();
229+
int count = Math.toIntExact(getNumber(info, 0));
230+
int maxlen = Math.toIntExact(getNumber(info, 3));
223231
for (int index = 0; index < count; index++) {
224-
byte[] name = (byte[]) regEnumKeyEx.invoke(root, getNumber(handles, 0), Integer.valueOf(index), Integer.valueOf(maxlen + 1));
232+
byte[] name = (byte[]) REG_ENUM_KEY_EX.invoke(root, getNumber(handles, 0), index, maxlen + 1);
225233
results.add(new String(name, StandardCharsets.UTF_8).trim());
226234
}
227-
regCloseKey.invoke(root, getNumber(handles, 0));
235+
REG_CLOSE_KEY.invoke(root, getNumber(handles, 0));
228236
return Collections.unmodifiableList(results);
229237
}
230238

0 commit comments

Comments
 (0)