This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 86bff97aa011aeb192d99307004eb2dff88f08dd Author: Martin Desruisseaux <[email protected]> AuthorDate: Sun Mar 29 13:11:55 2026 +0200 Avoid misleading classname as display name of a data store. --- .../main/org/apache/sis/storage/DataStore.java | 18 ++++++---------- .../org/apache/sis/storage/StorageConnector.java | 25 +++++++++++++++++++++- .../main/org/apache/sis/storage/csv/Store.java | 13 ++++++----- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java index 151cb4d78a..5317bc2658 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java @@ -67,7 +67,7 @@ import org.apache.sis.storage.event.StoreListeners; * * @author Johann Sorel (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 1.3 + * @version 1.7 * * @see DataStores#open(Object) * @@ -132,7 +132,7 @@ public abstract class DataStore implements Resource, Localized, AutoCloseable { @SuppressWarnings("this-escape") // `this` appears in a cyclic graph. Should not be accessible before completion. protected DataStore(final DataStoreProvider provider, final StorageConnector connector) throws DataStoreException { this.provider = provider; - this.displayName = connector.getStorageName(); + this.displayName = connector.getDisplayName(); this.locale = Locale.getDefault(Locale.Category.DISPLAY); this.listeners = new StoreListeners(connector.getOption(DataOptionKey.PARENT_LISTENERS), this); /* @@ -162,7 +162,7 @@ public abstract class DataStore implements Resource, Localized, AutoCloseable { final boolean hidden) throws DataStoreException { this.provider = provider; - displayName = connector.getStorageName(); + displayName = connector.getDisplayName(); final StoreListeners forwardTo; if (parent != null) { locale = parent.locale; @@ -263,14 +263,10 @@ public abstract class DataStore implements Resource, Localized, AutoCloseable { * The name may also contain any Unicode characters, including characters usually not allowed * in identifiers like white spaces.</p> * - * <p>This method should never throw an exception since it may be invoked for producing error - * messages, in which case throwing an exception here would hide the original exception.</p> - * - * <p>This method differs from {@link #getIdentifier()} in that it is typically a file name - * known at construction time instead of a property read from metadata. - * Default implementation returns the {@link StorageConnector#getStorageName()} value, - * or {@code null} if this data store has been created by the no-argument constructor. - * Subclasses should override this method if they can provide a better name.</p> + * <p>This method differs from {@link #getIdentifier()} in that the returned value is typically + * a file name known at construction time instead of a property read from metadata. + * Furthermore, this method should never throw an exception because it may be invoked for producing + * error messages, in which case throwing an exception here would hide the original exception.</p> * * @return a short name of label for this data store, or {@code null} if unknown. * diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java index 5860a06ac8..0650b4824c 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java @@ -110,7 +110,7 @@ import org.apache.sis.setup.OptionKey; * * @author Martin Desruisseaux (Geomatys) * @author Alexis Manin (Geomatys) - * @version 1.5 + * @version 1.7 * @since 0.3 */ public class StorageConnector implements Serializable { @@ -270,6 +270,15 @@ public class StorageConnector implements Serializable { */ private transient String name; + /** + * Whether {@linkplain #name} is uninformative for the purpose of {@link DataStore#getDisplayName()}. + * This flag is {@code true} if {@link #name} is the {@link #storage} class name, which is a fallback + * used in last resort only for the purpose of exception messages. + * + * @see #getDisplayName() + */ + private boolean isNameUninformative; + /** * The filename extension, or {@code null} if none. * This field is initialized only when first needed. @@ -713,12 +722,26 @@ public class StorageConnector implements Serializable { name = Strings.trimOrNull(IOUtilities.toString(storage)); if (name == null) { name = Classes.getShortClassName(storage); + isNameUninformative = true; } } } return name; } + /** + * Returns a short name of the input/output object, or {@code null} if that name does not identify the file. + * The difference between this method and {@link #getStorageName()} is that this method does not return the + * class name of the {@link #storage} object. + * + * @return a short name of the storage object, or {@code null} if none. + */ + final String getDisplayName() { + @SuppressWarnings("LocalVariableHidesMemberVariable") + final String name = getStorageName(); + return isNameUninformative ? null : name; + } + /** * Returns the filename extension of the input/output object. The default implementation performs * the following choices based on the type of the {@linkplain #getStorage() storage} object: diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java index 03e192e096..58d5d7760b 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java @@ -53,6 +53,7 @@ import org.apache.sis.util.CharSequences; import org.apache.sis.util.collection.Containers; import org.apache.sis.util.internal.shared.Numerics; import org.apache.sis.util.resources.Errors; +import org.apache.sis.util.resources.Vocabulary; import org.apache.sis.temporal.LenientDateFormat; import org.apache.sis.storage.DataOptionKey; import org.apache.sis.storage.DataStoreException; @@ -231,7 +232,7 @@ final class Store extends URIDataStore implements FeatureSet { @SuppressWarnings("LocalVariableHidesMemberVariable") FeatureType featureType = null; @SuppressWarnings("LocalVariableHidesMemberVariable") Foliation foliation = null; try { - final List<String> elements = new ArrayList<>(); + final var elements = new ArrayList<String>(); source.mark(StorageConnector.READ_AHEAD_LIMIT); String line; while ((line = source.readLine()) != null) { @@ -502,7 +503,7 @@ final class Store extends URIDataStore implements FeatureSet { private FeatureType parseFeatureType(final List<String> elements) throws DataStoreException { AttributeType[] characteristics = null; final int size = elements.size(); - final List<PropertyType> properties = new ArrayList<>(); + final var properties = new ArrayList<PropertyType>(); for (int i=1; i<size; i++) { final String name = elements.get(i); Class<?> type = null; @@ -568,8 +569,10 @@ final class Store extends URIDataStore implements FeatureSet { } properties.add(createProperty(name, type, minOccurrence, maxOccurrence, characteristics)); } - // Do not use Map.of(…) because `name` may be null. Let constructor throw the exception. - final String name = IOUtilities.filenameWithoutExtension(super.getDisplayName()); + String name = IOUtilities.filenameWithoutExtension(super.getDisplayName()); + if (name == null) { + name = Vocabulary.forLocale(getLocale()).getString(Vocabulary.Keys.Unnamed); + } return new DefaultFeatureType(Collections.singletonMap(DefaultFeatureType.NAME_KEY, name), false, null, properties.toArray(PropertyType[]::new)); } @@ -749,7 +752,7 @@ final class Store extends URIDataStore implements FeatureSet { */ private static String decode(CharSequence text, final int lower, final int upper, final boolean hasQuotes) { if (hasQuotes) { - final StringBuilder buffer = new StringBuilder(upper - lower).append(text, lower, upper); + final var buffer = new StringBuilder(upper - lower).append(text, lower, upper); for (int i=0; i<buffer.length(); i++) { if (buffer.charAt(i) == QUOTE) { buffer.deleteCharAt(i);
