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 f1883b4207ba9056f482ad42381a8fca0d747d8a Author: Martin Desruisseaux <[email protected]> AuthorDate: Wed Apr 15 13:25:49 2026 +0200 Edit documentation, add `@see` tags, avoid forcing conversion to URI. --- .../org/apache/sis/storage/StorageConnector.java | 83 ++++++++++++---------- 1 file changed, 46 insertions(+), 37 deletions(-) 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 830fa4d50d..5237e8e985 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 @@ -52,6 +52,7 @@ import javax.sql.DataSource; import org.apache.sis.util.Debug; import org.apache.sis.util.Classes; import org.apache.sis.util.Workaround; +import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ObjectConverters; import org.apache.sis.util.UnconvertibleObjectException; import org.apache.sis.util.resources.Errors; @@ -77,7 +78,6 @@ import org.apache.sis.io.stream.ChannelImageOutputStream; import org.apache.sis.io.stream.InternalOptionKey; import org.apache.sis.system.Configuration; import org.apache.sis.setup.OptionKey; -import org.apache.sis.util.ArgumentChecks; /** @@ -631,7 +631,7 @@ public class StorageConnector implements Serializable { * Creates a new data store connection wrapping the given input/output object. * The object can be of any type, but the class javadoc lists the most typical ones. * - * @param storage the input/output object as a URL, file, image input stream, <i>etc.</i>. + * @param storage the input/output object as a <abbr>URL</abbr>, file, image input stream, <i>etc.</i>. */ public StorageConnector(final Object storage) { this.storage = Objects.requireNonNull(storage); @@ -642,7 +642,7 @@ public class StorageConnector implements Serializable { * The new storage connector inherits all options that were specified in the parent connector. * * @param parent the storage connector from which to inherit options. - * @param storage the input/output object as a URL, file, image input stream, <i>etc.</i>. + * @param storage the input/output object as a <abbr>URL</abbr>, file, image input stream, <i>etc.</i>. * * @since 1.5 */ @@ -659,7 +659,7 @@ public class StorageConnector implements Serializable { * * <ul> * <li>{@link OptionKey#ENCODING} for decoding characters in an input stream, if needed.</li> - * <li>{@link OptionKey#URL_ENCODING} for converting URL to URI or filename, if needed.</li> + * <li>{@link OptionKey#URL_ENCODING} for converting <abbr>URL</abbr> to <abbr>URI</abbr> or filename, if needed.</li> * <li>{@link OptionKey#OPEN_OPTIONS} for specifying whether the data store shall be read only or read/write.</li> * <li>{@link OptionKey#BYTE_BUFFER} for allowing users to control the byte buffer to be created.</li> * </ul> @@ -708,7 +708,7 @@ public class StorageConnector implements Serializable { * * <ul> * <li>For {@link Path}, {@link File}, {@link URI} or {@link URL} - * instances, this method uses dedicated API like {@link Path#getFileName()}.</li> + * instances, this method uses dedicated <abbr>API</abbr> like {@link Path#getFileName()}.</li> * <li>For {@link CharSequence} instances, this method gets a string representation of the storage object * and returns the part after the last {@code '/'} character or platform-dependent name separator.</li> * <li>For instances of unknown type, this method builds a string representation using the class name. @@ -749,15 +749,17 @@ public class StorageConnector implements Serializable { * the following choices based on the type of the {@linkplain #getStorage() storage} object: * * <ul> - * <li>For {@link Path}, {@link File}, {@link URI}, {@link URL} or - * {@link CharSequence} instances, this method returns the string after the last {@code '.'} character - * in the filename, provided that the {@code '.'} is not the first filename character. This may be an - * empty string if the filename has no extension, but never {@code null}.</li> - * <li>For instances of unknown type, this method returns {@code null}.</li> + * <li>For {@link Path}, {@link File}, {@link URI}, {@link URL} or {@link CharSequence} instances, + * returns the sub-string after the last {@code '.'} character in the filename, + * provided that the {@code '.'} is not the first filename character. + * If the filename has no extension, returns an empty string (not {@code null}).</li> + * <li>For instances of unknown type, returns {@code null}.</li> * </ul> * * @return the filename extension, or an empty string if none, * or {@code null} if the storage is an object of unknown type. + * + * @see #pathEndsWith(String, boolean) */ public String getFileExtension() { if (extension == null) { @@ -1101,28 +1103,29 @@ public class StorageConnector implements Serializable { } /** - * Tests if the content of the storage from this connector starts with the given signature. - * <p> + * Tests if the content of the storage specified by this connector starts with the given signature. * If the storage cannot be read as a sequence of bytes, for example if the storage is a connection to a database, * then this method returns {@code UNSUPPORTED_STORAGE}. * - * @param signature to test, not null - * @return {@code SUPPORTED} if content matches, + * @param signature sequence of bytes to test as a signature. + * @return {@code SUPPORTED} if content matches the given signature, * {@code INSUFFICIENT_BYTES} if the buffer is too small, * {@code UNSUPPORTED_STORAGE} otherwise. + * @throws NullPointerException if {@code signature} is null. * @throws DataStoreException if an error occurred while opening or reading. + * + * @see DataStoreProvider#probeContent(StorageConnector) + * * @since 1.7 */ - public ProbeResult contentStartsWith(byte[] signature) throws DataStoreException { + public ProbeResult contentStartsWith(final byte[] signature) throws DataStoreException { ArgumentChecks.ensureNonNull("signature", signature); - final ByteBuffer buffer = getStorageAs(ByteBuffer.class); if (buffer == null) return ProbeResult.UNSUPPORTED_STORAGE; + buffer.mark(); try { - buffer.mark(); + // Compare signatures. final int remaining = buffer.remaining(); - - // compare signatures for (int i = 0; i < signature.length; i++) { if (i >= remaining) { return ProbeResult.INSUFFICIENT_BYTES; @@ -1138,30 +1141,36 @@ public class StorageConnector implements Serializable { } /** - * Tests if the data path from this connector ends with the given suffix. - * We test the suffix here and not the extension because several formats - * used combined extensions, like .meta.xml or .bin.gz. - * Restricting ourselves to file extension is ambigious in such cases, this is why suffix is used instead. - * <p> - * This method fallback on {@linkplain String#regionMatches(boolean, int, java.lang.String, int, int) } - * for the suffix test. - * - * @param suffix to test, not null - * @param ignoreCase if true, ignore case when comparing characters. + * Tests if the path or <abbr>URI</abbr> of the input/output object ends with the given suffix. + * The suffix is compared with no special treatment for the {@code '.'} character. + * Therefore, this method is better suited than {@link #getFileExtension()} + * for combined extensions such as {@code ".meta.xml"} or {@code ".bin.gz"}. + * + * <p>The default implementation compare the suffix using + * {@linkplain String#regionMatches(boolean, int, java.lang.String, int, int) String.regionMatches(…)}. + * See that method for details about how cases are ignored if {@code ignoreCase} is true.</p> + * + * @param suffix the suffix to test. Shall not be empty. + * @param ignoreCase if true, ignore case when comparing characters. * @return {@code SUPPORTED} if suffix matches, * {@code UNSUPPORTED_STORAGE} otherwise. * @throws DataStoreException if an error occurred while opening or reading. + * + * @see #getFileExtension() + * @see DataStoreProvider#probeContent(StorageConnector) + * * @since 1.7 */ - public ProbeResult pathEndsWith(String suffix, boolean ignoreCase) throws DataStoreException { + public ProbeResult pathEndsWith(final String suffix, final boolean ignoreCase) throws DataStoreException { ArgumentChecks.ensureNonEmpty("suffix", suffix); - final URI uri = getStorageAs(URI.class); - if (uri == null) return ProbeResult.UNSUPPORTED_STORAGE; - - name = uri.isOpaque() ? uri.getSchemeSpecificPart() : uri.getPath(); - final int suffixLength = suffix.length(); - return name.regionMatches(ignoreCase, name.length()-suffixLength, suffix, 0, suffixLength) ? - ProbeResult.SUPPORTED : ProbeResult.UNSUPPORTED_STORAGE; + final String filename = IOUtilities.filename(storage); + if (filename != null) { + final int suffixLength = suffix.length(); + if (filename.regionMatches(ignoreCase, filename.length() - suffixLength, suffix, 0, suffixLength)) { + return ProbeResult.SUPPORTED; + } + } + return ProbeResult.UNSUPPORTED_STORAGE; } /**
