Search in sources :

Example 1 with CanNotProbeException

use of org.apache.sis.storage.CanNotProbeException in project sis by apache.

the class NetcdfStoreProvider method probeContent.

/**
 * Returns {@link ProbeResult#SUPPORTED} if the given storage appears to be supported by {@link NetcdfStore}.
 * Returning {@code SUPPORTED} from this method does not guarantee that reading or writing will succeed,
 * only that there appears to be a reasonable chance of success based on a brief inspection of the
 * {@linkplain StorageConnector#getStorage() storage object} or contents.
 *
 * @param  connector  information about the storage (URL, stream, {@link ucar.nc2.NetcdfFile} instance, <i>etc</i>).
 * @return {@code SUPPORTED} if the given storage seems to be usable by {@code NetcdfStore} instances.
 * @throws DataStoreException if an I/O error occurred.
 */
@Override
public ProbeResult probeContent(final StorageConnector connector) throws DataStoreException {
    int version = 0;
    boolean hasVersion = false;
    boolean isSupported = false;
    ByteBuffer buffer = connector.getStorageAs(ByteBuffer.class);
    if (buffer != null) {
        if (buffer.remaining() < Integer.BYTES) {
            return ProbeResult.INSUFFICIENT_BYTES;
        }
        // Get a buffer with ByteOrder.BIG_ENDIAN.
        buffer = buffer.duplicate();
        final int header = buffer.getInt();
        if ((header & 0xFFFFFF00) == ChannelDecoder.MAGIC_NUMBER) {
            hasVersion = true;
            version = header & 0xFF;
            isSupported = (version >= 1 && version <= ChannelDecoder.MAX_VERSION);
        }
    }
    /*
         * If we failed to check using the embedded decoder, tries using the UCAR library.
         * The UCAR library is an optional dependency. If that library is present and the
         * input is a String, then the following code may trigs a large amount of classes
         * loading.
         *
         * Note that the UCAR library expects a String argument, not a File, because it
         * has special cases for "file:", "http:", "nodods:" and "slurp:" protocols.
         */
    if (!isSupported) {
        final String path = connector.getStorageAs(String.class);
        if (path != null) {
            ensureInitialized(false);
            final Method method = canOpenFromPath;
            if (method != null)
                try {
                    isSupported = (Boolean) method.invoke(null, path);
                } catch (IllegalAccessException e) {
                    // Should never happen, since the method is public.
                    throw (Error) new IncompatibleClassChangeError("canOpen").initCause(e);
                } catch (InvocationTargetException e) {
                    final Throwable cause = e.getCause();
                    if (cause instanceof DataStoreException) {
                        throw (DataStoreException) cause;
                    } else if (cause instanceof IOException) {
                        /*
                         * Happen if the String argument uses any protocol not recognized by the UCAR library,
                         * in which case UCAR tries to open it as a file even if it is not a file. For example
                         * we get this exception for "jar:file:/file.jar!/entry.nc".
                         */
                        Logging.recoverableException(getLogger(), NetcdfStoreProvider.class, "probeContent", cause);
                        return ProbeResult.UNSUPPORTED_STORAGE;
                    }
                    throw new CanNotProbeException(this, connector, cause);
                }
        } else {
            /*
                 * Check if the given input is itself an instance of the UCAR oject.
                 * We check classnames instead of netcdfFileClass.isInstance(storage)
                 * in order to avoid loading the UCAR library if not needed.
                 */
            for (Class<?> type = connector.getStorage().getClass(); type != null; type = type.getSuperclass()) {
                if (UCAR_CLASSNAME.equals(type.getName())) {
                    isSupported = true;
                    break;
                }
            }
        }
    }
    /*
         * At this point, the readability status has been determined. The file version number
         * is unknown if we are able to open the file only through the UCAR library.
         */
    if (hasVersion) {
        return new ProbeResult(isSupported, MIME_TYPE, Version.valueOf(version));
    }
    return isSupported ? new ProbeResult(true, MIME_TYPE, null) : ProbeResult.UNSUPPORTED_STORAGE;
}
Also used : DataStoreException(org.apache.sis.storage.DataStoreException) InternalDataStoreException(org.apache.sis.storage.InternalDataStoreException) Method(java.lang.reflect.Method) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) InvocationTargetException(java.lang.reflect.InvocationTargetException) CanNotProbeException(org.apache.sis.storage.CanNotProbeException) ProbeResult(org.apache.sis.storage.ProbeResult)

Example 2 with CanNotProbeException

use of org.apache.sis.storage.CanNotProbeException in project sis by apache.

the class FirstKeywordPeek method probeContent.

/**
 * Returns {@link ProbeResult#SUPPORTED} if the given storage appears to begin with an expected keyword.
 * Returning {@code SUPPORTED} from this method does not guarantee that reading or writing will succeed,
 * only that there appears to be a reasonable chance of success based on a brief inspection of the storage
 * header.
 *
 * @param  provider   the data store provider which is performing the probe operation.
 * @param  connector  information about the storage (URL, stream, <i>etc</i>).
 * @return {@link ProbeResult#SUPPORTED} if the given storage seems to be readable.
 * @throws DataStoreException if an I/O error occurred.
 */
public final ProbeResult probeContent(final DataStoreProvider provider, final StorageConnector connector) throws DataStoreException {
    try {
        final ByteBuffer buffer = connector.getStorageAs(ByteBuffer.class);
        final Reader reader;
        if (buffer != null) {
            buffer.mark();
            reader = null;
        } else {
            /*
                 * If we do not have a `ByteBuffer`, maybe the user gave us explicitly a `Reader` wrapping
                 * something else than a stream (e.g. a `StringReader` wrapping a `String` instance).
                 */
            reader = connector.getStorageAs(Reader.class);
            if (reader != null) {
                reader.mark(READ_AHEAD_LIMIT);
            } else {
                final Path file = getAuxiliaryPath(connector);
                if (file != null) {
                    return probeContent(file);
                } else {
                    return ProbeResult.UNSUPPORTED_STORAGE;
                }
            }
        }
        return probeContent(buffer, reader);
    } catch (IOException e) {
        throw new CanNotProbeException(provider, connector, e);
    }
}
Also used : Path(java.nio.file.Path) Reader(java.io.Reader) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) CanNotProbeException(org.apache.sis.storage.CanNotProbeException)

Aggregations

IOException (java.io.IOException)2 ByteBuffer (java.nio.ByteBuffer)2 CanNotProbeException (org.apache.sis.storage.CanNotProbeException)2 Reader (java.io.Reader)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 Path (java.nio.file.Path)1 DataStoreException (org.apache.sis.storage.DataStoreException)1 InternalDataStoreException (org.apache.sis.storage.InternalDataStoreException)1 ProbeResult (org.apache.sis.storage.ProbeResult)1