/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sis.storage;

import java.util.Collection;
import org.apache.sis.util.Static;
import org.apache.sis.internal.system.Modules;
import org.apache.sis.internal.system.SystemListener;


/**
 * Static convenience methods creating {@link DataStore} instances from a given storage object.
 * Storage objects are typically {@link java.io.File} or {@link javax.sql.DataSource} instances,
 * but can also be any other objects documented in the {@link StorageConnector} class.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 * @since   0.4
 * @module
 */
public final class DataStores extends Static {
    /**
     * The registry to use for searching for {@link DataStoreProvider} implementations.
     *
     * <div class="section">Class loader</div>
     * In current implementation, this registry is instantiated when first needed using the
     * {@linkplain Thread#getContextClassLoader() context class loader}. This means that the set of
     * available formats may depend on the first thread that invoked a {@code DataStores} method.
     */
    private static volatile DataStoreRegistry registry;

    /*
     * Forces a reload of all providers when the classpath changes. Note that invoking
     * ServiceLoader.reload() is not sufficient because the ClassLoader may also change
     * in OSGi context.
     */
    static {
        SystemListener.add(new SystemListener(Modules.STORAGE) {
            @Override protected void classpathChanged() {
                registry = null;
            }
        });
    }

    /**
     * Do not allow instantiation of this class.
     */
    private DataStores() {
    }

    /**
     * Returns the registry, created when first needed.
     */
    private static DataStoreRegistry registry() {
        DataStoreRegistry r = registry;
        if (r == null) {
            synchronized (DataStores.class) {
                r = registry;
                if (r == null) {
                    registry = r = new DataStoreRegistry();
                }
            }
        }
        return r;
    }

    /**
     * Returns the list of data store providers available at this method invocation time.
     * More providers may be added later in a running JVM if new modules are added on the classpath.
     *
     * @return descriptions of available data stores.
     *
     * @since 0.8
     */
    public static Collection<DataStoreProvider> providers() {
        return registry().providers();
    }

    /**
     * Returns the MIME type of the storage file format, or {@code null} if unknown or not applicable.
     *
     * @param  storage  the input/output object as a URL, file, image input stream, <i>etc.</i>.
     * @return the storage MIME type, or {@code null} if unknown or not applicable.
     * @throws DataStoreException if an error occurred while opening the storage.
     */
    public static String probeContentType(final Object storage) throws DataStoreException {
        return registry().probeContentType(storage);
    }

    /**
     * Creates a {@link DataStore} for the given storage.
     * The {@code storage} argument can be any of the following types:
     *
     * <ul>
     *   <li>A {@link java.nio.file.Path} or a {@link java.io.File} for a file or a directory.</li>
     *   <li>A {@link java.net.URI} or a {@link java.net.URL} to a distant resource.</li>
     *   <li>A {@link java.lang.CharSequence} interpreted as a filename or a URL.</li>
     *   <li>A {@link java.nio.channels.Channel}, {@link java.io.DataInput}, {@link java.io.InputStream} or {@link java.io.Reader}.</li>
     *   <li>A {@link javax.sql.DataSource} or a {@link java.sql.Connection} to a JDBC database.</li>
     *   <li>Any other {@code DataStore}-specific object, for example {@link ucar.nc2.NetcdfFile}.</li>
     *   <li>An existing {@link StorageConnector} instance.</li>
     * </ul>
     *
     * @param  storage  the input/output object as a URL, file, image input stream, <i>etc.</i>.
     * @return the object to use for reading geospatial data from the given storage.
     * @throws UnsupportedStorageException if no {@link DataStoreProvider} is found for a given storage object.
     * @throws DataStoreException if an error occurred while opening the storage.
     */
    public static DataStore open(final Object storage) throws UnsupportedStorageException, DataStoreException {
        return registry().open(storage);
    }
}

@@ -845,26 +845,77 @@
 va.util.
-Collection
+ArrayList;%0Aimport java.util.Collection;%0Aimport java.util.List
 ;%0Aimport
@@ -1376,16 +1376,52 @@
 omatys)%0A
+ * @author  Johann Sorel (Geomatys)%0A
  * @vers
@@ -1424,19 +1424,19 @@
 version 
-0.8
+1.0
 %0A * @sin
@@ -3342,32 +3342,1195 @@
 iders();%0A    %7D%0A%0A
+    /**%0A     * Returns the list of data store providers capable of opening the given input.%0A     * Any provider causing an exception while probing the input is considered%0A     * as unsupported.%0A     *%0A     * @param input data input, usually a StorageConnector, Path or URI to test.%0A     * @return descriptions of compatible data stores.%0A     *%0A     * @since 1.0%0A     */%0A    public static Collection%3CDataStoreProvider%3E providers(Object input) %7B%0A        final StorageConnector connector = (input instanceof StorageConnector) ?%0A                (StorageConnector) input : new StorageConnector(input);%0A%0A        final List%3CDataStoreProvider%3E providers = new ArrayList%3C%3E();%0A        for (DataStoreProvider provider : registry().providers()) %7B%0A            try %7B%0A                final ProbeResult result = provider.probeContent(connector);%0A                if (result.isSupported()) %7B%0A                    providers.add(provider);%0A                %7D%0A            %7D catch (DataStoreException ex) %7B%0A                // could be caused for multiple reasons, we assume it does not%0A                // support the given input.%0A            %7D%0A        %7D%0A        return providers;%0A    %7D%0A%0A
     /**%0A     * R

DataStore : add method to find compatible datastore providers for a given input