This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 49a5bd39ee0c372b563e8686984cc889720272a9 Author: Martin Desruisseaux <[email protected]> AuthorDate: Tue May 5 14:47:27 2026 +0200 Workaround an `IllegalAccessException` caused by module boundaries. https://issues.apache.org/jira/browse/SIS-632 --- .../resources/IndexedResourceCompiler.java | 44 ++++++++++++++-------- .../org/apache/sis/cloud/aws/s3/Resources.java | 14 +++++++ .../org/apache/sis/feature/internal/Resources.java | 14 +++++++ .../apache/sis/metadata/internal/Resources.java | 14 +++++++ .../org/apache/sis/map/internal/Resources.java | 14 +++++++ .../referencing/gazetteer/internal/Resources.java | 14 +++++++ .../apache/sis/referencing/internal/Resources.java | 14 +++++++ .../apache/sis/storage/geotiff/base/Resources.java | 14 +++++++ .../sis/storage/netcdf/internal/Resources.java | 14 +++++++ .../apache/sis/storage/sql/feature/Resources.java | 14 +++++++ .../org/apache/sis/storage/internal/Resources.java | 14 +++++++ .../main/org/apache/sis/util/resources/Errors.java | 14 +++++++ .../apache/sis/util/resources/KeyConstants.java | 37 ++++++++++-------- .../org/apache/sis/util/resources/Messages.java | 14 +++++++ .../org/apache/sis/util/resources/Vocabulary.java | 14 +++++++ .../org/apache/sis/gui/internal/Resources.java | 14 +++++++ .../org/apache/sis/storage/panama/Resources.java | 14 +++++++ 17 files changed, 259 insertions(+), 32 deletions(-) diff --git a/buildSrc/src/main/java/org/apache/sis/buildtools/resources/IndexedResourceCompiler.java b/buildSrc/src/main/java/org/apache/sis/buildtools/resources/IndexedResourceCompiler.java index ac991b2504..ebd9b436f0 100644 --- a/buildSrc/src/main/java/org/apache/sis/buildtools/resources/IndexedResourceCompiler.java +++ b/buildSrc/src/main/java/org/apache/sis/buildtools/resources/IndexedResourceCompiler.java @@ -30,7 +30,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileNotFoundException; -import java.io.InputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; @@ -122,13 +121,13 @@ public class IndexedResourceCompiler { * Integer IDs allocated to resource keys. * This map will be shared for all languages of a given resource bundle. */ - private final Map<Integer,String> allocatedIDs = new HashMap<>(); + private final Map<Integer, String> allocatedIDs = new HashMap<>(); /** * Resource keys and their localized values. * This map will be cleared for each language in a resource bundle. */ - private final Map<Object,Object> resources = new HashMap<>(); + private final Map<Object, Object> resources = new HashMap<>(); /** * Buffer to use for writing UTF data in an array of bytes. @@ -191,12 +190,12 @@ public class IndexedResourceCompiler { * @param resourcesToProcess the files to filter. This map will be modified in-place. * @param checkSourceExists whether to check that the Java source file exists. */ - static void filterLanguages(final SortedMap<File,Boolean> resourcesToProcess, final boolean checkSourceExists) { - final Iterator<Map.Entry<File,Boolean>> it = resourcesToProcess.entrySet().iterator(); - Map.Entry<File,Boolean> baseEntry = null; + static void filterLanguages(final SortedMap<File, Boolean> resourcesToProcess, final boolean checkSourceExists) { + final Iterator<Map.Entry<File, Boolean>> it = resourcesToProcess.entrySet().iterator(); + Map.Entry<File, Boolean> baseEntry = null; String baseName = null; while (it.hasNext()) { - final Map.Entry<File,Boolean> entry = it.next(); + final Map.Entry<File, Boolean> entry = it.next(); final File file = entry.getKey(); if (baseName != null && file.getName().startsWith(baseName)) { if (baseEntry != null) { @@ -248,7 +247,7 @@ public class IndexedResourceCompiler { if (files == null) { throw new FileNotFoundException(directory + " not found or is not a directory."); } - final var resourcesToProcess = new TreeMap<File,Boolean>(); + final var resourcesToProcess = new TreeMap<File, Boolean>(); for (final File file : files) { final String name = file.getName(); if (!name.isEmpty() && name.charAt(0) != '.') { @@ -264,7 +263,7 @@ public class IndexedResourceCompiler { } } filterLanguages(resourcesToProcess, true); - for (final Map.Entry<File,Boolean> entry : resourcesToProcess.entrySet()) { + for (final Map.Entry<File, Boolean> entry : resourcesToProcess.entrySet()) { final File source = entry.getKey(); if (entry.getValue()) { onJavaSource(new File(source.getParentFile(), getBaseName(source) + JAVA_EXT)); @@ -299,7 +298,7 @@ public class IndexedResourceCompiler { * @throws IOException if an error occurred while reading the source file. */ private void loadKeyValues() throws IOException { - try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(bundleClass), JAVA_ENCODING))) { + try (var in = new BufferedReader(new InputStreamReader(new FileInputStream(bundleClass), JAVA_ENCODING))) { String line; while ((line = in.readLine()) != null) { if ((line = line.trim()).startsWith(KEY_MODIFIERS)) { @@ -399,7 +398,7 @@ public class IndexedResourceCompiler { */ private static Properties loadRawProperties(final File file) throws IOException { final Properties properties; - try (InputStream input = new FileInputStream(file)) { + try (var input = new FileInputStream(file)) { properties = new Properties(); properties.load(input); } @@ -424,7 +423,7 @@ public class IndexedResourceCompiler { private void loadProperties(final File file) throws IOException { resources.clear(); final Properties properties = loadRawProperties(file); - for (final Map.Entry<Object,Object> entry : properties.entrySet()) { + for (final Map.Entry<Object, Object> entry : properties.entrySet()) { final String key = (String) entry.getKey(); final String value = (String) entry.getValue(); /* @@ -496,7 +495,7 @@ public class IndexedResourceCompiler { private static String toMessageFormatString(final String text) { int level = 0; int last = -1; - final StringBuilder buffer = new StringBuilder(text); + final var buffer = new StringBuilder(text); search: for (int i=0; i<buffer.length(); i++) { // Length of `buffer` will vary. switch (buffer.charAt(i)) { /* @@ -559,7 +558,7 @@ search: for (int i=0; i<buffer.length(); i++) { // Length of `bu private byte[] writeUTF() throws IOException { bufferUTF.reset(); final int count = allocatedIDs.isEmpty() ? 0 : Collections.max(allocatedIDs.keySet()); - try (DataOutputStream out = new DataOutputStream(bufferUTF)) { + try (var out = new DataOutputStream(bufferUTF)) { out.writeInt(count); for (int i=1; i<=count; i++) { final String value = (String) resources.get(allocatedIDs.get(i)); @@ -616,6 +615,19 @@ search: for (int i=0; i<buffer.length(); i++) { // Length of `bu buffer.append(line).append(lineSeparator); } while (!pattern.matcher(line).matches()); } + buffer.append(lineSeparator) + .append(" /**").append(lineSeparator) + .append(" * Returns the value of a field declared in this {@code Keys} class.").append(lineSeparator) + .append(" * This method is needed for encapsulation reason, because classes in").append(lineSeparator) + .append(" * other modules cannot access this class even by reflection.").append(lineSeparator) + .append(" */").append(lineSeparator) + .append(" @Override").append(lineSeparator) + .append(" protected Object getStaticValue(final Field field) throws IllegalAccessException {").append(lineSeparator) + .append(" if (field.getDeclaringClass() == Keys.class) {").append(lineSeparator) + .append(" return field.get(null);").append(lineSeparator) + .append(" }").append(lineSeparator) + .append(" throw new IllegalAccessException();").append(lineSeparator) + .append(" }").append(lineSeparator); /* * Starting from this point, the content that we are going to write in the buffer * may be different than the file content. Remember the buffer position in order @@ -635,7 +647,7 @@ search: for (int i=0; i<buffer.length(); i++) { // Length of `bu if (message != null) { message = message.replace('\t', ' '); buffer.append(KEY_MARGIN).append("/**").append(lineSeparator); - while (((message=message.trim()).length()) != 0) { + while (((message = message.trim()).length()) != 0) { buffer.append(KEY_MARGIN).append(" * "); int stop = message.indexOf('\n'); if (stop < 0) { @@ -754,7 +766,7 @@ search: for (int i=0; i<buffer.length(); i++) { // Length of `bu private void warning(final File file, final String key, final String message, final Exception exception) { - final StringBuilder buffer = new StringBuilder("ERROR "); + final var buffer = new StringBuilder("ERROR "); if (file != null) { String filename = file.getPath(); if (filename.endsWith(PROPERTIES_EXT)) { diff --git a/endorsed/src/org.apache.sis.cloud.aws/main/org/apache/sis/cloud/aws/s3/Resources.java b/endorsed/src/org.apache.sis.cloud.aws/main/org/apache/sis/cloud/aws/s3/Resources.java index d7afb279a9..cf5e2608c1 100644 --- a/endorsed/src/org.apache.sis.cloud.aws/main/org/apache/sis/cloud/aws/s3/Resources.java +++ b/endorsed/src/org.apache.sis.cloud.aws/main/org/apache/sis/cloud/aws/s3/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.cloud.aws.s3; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.apache.sis.util.resources.KeyConstants; @@ -51,6 +52,19 @@ class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Cannot change a relative path to an absolute path. */ diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/internal/Resources.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/internal/Resources.java index 8f099fc9d1..ab67b06ea4 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/internal/Resources.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.feature.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Map; import java.util.Locale; import java.util.MissingResourceException; @@ -54,6 +55,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Feature type ‘{0}’ is abstract. */ diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Resources.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Resources.java index 34598f5563..d2322ec966 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Resources.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.metadata.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.opengis.util.InternationalString; @@ -53,6 +54,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Connection to “{0}” database is already initialized. */ diff --git a/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/internal/Resources.java b/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/internal/Resources.java index e80ebd1814..a667a65cfd 100644 --- a/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/internal/Resources.java +++ b/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.map.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.apache.sis.util.resources.KeyConstants; @@ -49,6 +50,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * The “{0}” resource specifies an invalid conversion from pixel coordinates to the “{1}” * coordinate reference system. diff --git a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/internal/Resources.java b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/internal/Resources.java index e88d344cb3..d83e59997b 100644 --- a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/internal/Resources.java +++ b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.referencing.gazetteer.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; @@ -54,6 +55,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Location type parent already has a child named “{0}”. */ diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java index 641280441a..75a81983ce 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.referencing.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; @@ -54,6 +55,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Accuracy declared in a geodetic dataset. */ diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Resources.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Resources.java index e9bde86ae6..fdd6002468 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Resources.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.storage.geotiff.base; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.opengis.util.InternationalString; @@ -53,6 +54,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Cannot compute the grid geometry of “{0}” GeoTIFF file. */ diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/internal/Resources.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/internal/Resources.java index 5c37f894fb..26b5fa05ae 100644 --- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/internal/Resources.java +++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.storage.netcdf.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.opengis.util.InternationalString; @@ -53,6 +54,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * NetCDF file “{0}” provides an ambiguous axis direction for variable “{1}”. It could be * {2} or {3}. diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Resources.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Resources.java index 1edcfa8eac..225bddc0ed 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Resources.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.storage.sql.feature; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.opengis.util.InternationalString; @@ -53,6 +54,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Assume database byte/tinyint unsigned, due to a lack of metadata. */ diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java index 4f451dffab..a3b4fc5f6b 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.storage.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.opengis.util.InternationalString; @@ -53,6 +54,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Name “{3}” is ambiguous because it can be understood as either “{1}” or “{2}” in the context * of “{0}” data. diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java index 860b837840..ae65d1bfd1 100644 --- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java +++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java @@ -17,6 +17,7 @@ package org.apache.sis.util.resources; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Map; import java.util.Locale; import java.util.MissingResourceException; @@ -57,6 +58,19 @@ public class Errors extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * ‘{0}’ is already initialized. */ diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/KeyConstants.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/KeyConstants.java index 0c66565b3a..2be050872f 100644 --- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/KeyConstants.java +++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/KeyConstants.java @@ -20,7 +20,6 @@ import java.util.Arrays; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import org.apache.sis.util.ArraysExt; -import org.apache.sis.util.CharSequences; /** @@ -32,12 +31,7 @@ import org.apache.sis.util.CharSequences; * * @see IndexedResourceBundle#getKeyConstants() */ -public class KeyConstants { - /** - * The class that defines key constants. - */ - private final Class<?> keysClass; - +public abstract class KeyConstants { /** * The key names in the exact same order as {@link IndexedResourceBundle#values}. * This is usually not needed, but may be created from the {@code Keys} inner class in some occasions. @@ -51,15 +45,26 @@ public class KeyConstants { * For sub-classes constructors only. */ protected KeyConstants() { - keysClass = getClass(); } /** - * Creates a new instance for key constants defined in an independent class. + * Returns the value of the given static field. + * Subclasses should implement this method as below: + * + * {@snippet lang="java" : + * return field.get(null); + * } + * + * This implementation must be provided by subclasses for Java security reason. + * This is because this {@code KeyConstants} class is not allowed to perform the + * above call if the module that provides the {@code KeyConstants} subclass does + * not export the package that contain the subclass. + * + * @param field the field for which to get the value. + * @return value of the given field. + * @throws IllegalAccessException if access to the field is denied. */ - KeyConstants(final Class<?> keysClass) { - this.keysClass = keysClass; - } + protected abstract Object getStaticValue(Field field) throws IllegalAccessException; /** * Returns the internal array of key names. <strong>Do not modify the returned array.</strong> @@ -73,11 +78,11 @@ public class KeyConstants { String[] names; int length = 0; try { - final Field[] fields = keysClass.getFields(); + final Field[] fields = getClass().getFields(); names = new String[fields.length]; for (final Field field : fields) { if (Modifier.isStatic(field.getModifiers()) && field.getType() == Short.TYPE) { - final int index = Short.toUnsignedInt((Short) field.get(null)) - IndexedResourceBundle.FIRST; + final int index = Short.toUnsignedInt((Short) getStaticValue(field)) - IndexedResourceBundle.FIRST; if (index >= length) { length = index + 1; if (length > names.length) { @@ -89,7 +94,7 @@ public class KeyConstants { } } } catch (IllegalAccessException e) { - names = CharSequences.EMPTY_ARRAY; + throw new IllegalCallerException(e); } keys = ArraysExt.resize(names, length); } @@ -118,6 +123,6 @@ public class KeyConstants { * Returns the numerical value for the key of the given name. */ final short getKeyValue(final String name) throws NoSuchFieldException, IllegalAccessException { - return (Short) keysClass.getField(name).get(null); + return (Short) getStaticValue(getClass().getField(name)); } } diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java index 2a661986a5..fec0b6a6d7 100644 --- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java +++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java @@ -17,6 +17,7 @@ package org.apache.sis.util.resources; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.opengis.util.InternationalString; @@ -48,6 +49,19 @@ public class Messages extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * {0} “{1}” is already registered. The second instance will be ignored. */ diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java index 5400228dde..db82cf3935 100644 --- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java +++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java @@ -17,6 +17,7 @@ package org.apache.sis.util.resources; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Map; import java.util.Locale; import java.util.MissingResourceException; @@ -49,6 +50,19 @@ public class Vocabulary extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Abstract */ diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/Resources.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/Resources.java index c789f97385..49f9abb6d2 100644 --- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/Resources.java +++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.gui.internal; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import javafx.event.ActionEvent; @@ -54,6 +55,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * About… */ diff --git a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.java b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.java index d4b4c8f13a..4c728ce99d 100644 --- a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.java +++ b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.java @@ -17,6 +17,7 @@ package org.apache.sis.storage.panama; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.Locale; import java.util.MissingResourceException; import org.opengis.util.InternationalString; @@ -53,6 +54,19 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Returns the value of a field declared in this {@code Keys} class. + * This method is needed for encapsulation reason, because classes in + * other modules cannot access this class even by reflection. + */ + @Override + protected Object getStaticValue(final Field field) throws IllegalAccessException { + if (field.getDeclaringClass() == Keys.class) { + return field.get(null); + } + throw new IllegalAccessException(); + } + /** * Allowed {0} drivers for opening the file. */
