Author: desruisseaux
Date: Wed Jun 5 13:10:29 2013
New Revision: 1489846
URL: http://svn.apache.org/r1489846
Log:
First draft of a DataStoreProvider abstract class, and some tests with
NetcdfStoreProvider.
Added:
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
(with props)
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
(with props)
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/test/suite/NetcdfTestSuite.java
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java?rev=1489846&r1=1489845&r2=1489846&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
[UTF-8] Wed Jun 5 13:10:29 2013
@@ -64,6 +64,17 @@ import org.apache.sis.measure.Units;
*/
public final class ChannelDecoder extends Decoder {
/**
+ * The NetCDF magic number expected in the first integer of the stream.
+ * The comparison shall ignore the 8 lowest bits, as in the following
example:
+ *
+ * {@preformat java
+ * int header = ...; // The first integer in the stream.
+ * boolean isNetCDF = (header & 0xFFFFFF00) == MAGIC_NUMBER;
+ * }
+ */
+ public static final int MAGIC_NUMBER = ('C' << 24) | ('D' << 16) | ('F' <<
8);
+
+ /**
* The encoding of dimension, variable and attribute names. This is fixed
to {@value} by the
* NetCDF specification. Note however that the encoding of attribute
values may be different.
*
@@ -188,7 +199,7 @@ public final class ChannelDecoder extend
* The 4th byte is the version number, which we opportunistically use
after the magic number check.
*/
int version = input.readInt();
- if ((version & 0xFFFFFF00) != (('C' << 24) | ('D' << 16) | ('F' <<
8))) {
+ if ((version & 0xFFFFFF00) != MAGIC_NUMBER) {
throw new
DataStoreException(errors().getString(Errors.Keys.UnexpectedFileFormat_2,
"NetCDF", input.filename));
}
/*
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java?rev=1489846&r1=1489845&r2=1489846&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
[UTF-8] Wed Jun 5 13:10:29 2013
@@ -17,6 +17,8 @@
package org.apache.sis.storage.netcdf;
import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
@@ -25,12 +27,14 @@ import org.apache.sis.internal.netcdf.im
import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
import org.apache.sis.internal.storage.ChannelDataInput;
import org.apache.sis.internal.storage.WarningProducer;
+import org.apache.sis.storage.DataStore;
+import org.apache.sis.storage.DataStoreProvider;
import org.apache.sis.storage.DataStoreConnection;
import org.apache.sis.storage.DataStoreException;
/**
- * The provider of {@link NetcdfStore} instances. Given an {@link
DataStoreConnection} input,
+ * The provider of {@link NetcdfStore} instances. Given a {@link
DataStoreConnection} input,
* this class tries to instantiate a {@code NetcdfStore} using the embedded
NetCDF decoder.
* If the embedded decoder can not decode the given input and the UCAR library
is reachable
* on the classpath, then this class tries to instantiate a {@code
NetcdfStore} backed by
@@ -41,7 +45,12 @@ import org.apache.sis.storage.DataStoreE
* @version 0.3
* @module
*/
-public class NetcdfStoreProvider {
+public class NetcdfStoreProvider extends DataStoreProvider {
+ /**
+ * The name of the {@link ucar.nc2.NetcdfFile} class, which is {@value}.
+ */
+ private static final String UCAR_CLASSNAME = "ucar.nc2.NetcdfFile";
+
/**
* The {@link ucar.nc2.NetcdfFile} class, or {@code null} if not found. An
attempt to load this class
* will be performed when first needed since the UCAR library is optional.
If not found, then this field
@@ -50,16 +59,22 @@ public class NetcdfStoreProvider {
private static Class<?> netcdfFileClass;
/**
- * If the {@link #netcdfFileClass} has been found, then the {@link
DecoderWrapper} constructor receiving
- * in argument a UCAR {@code NetcdfFile} object. Otherwise {@code null}.
+ * If the {@link #netcdfFileClass} has been found, then the {@link
ucar.nc2.NetcdfFile#canOpen(String)}
+ * static method.
*/
- private static volatile Constructor<? extends Decoder> fromUCAR;
+ private static volatile Method canOpenFromPath;
/**
* If the {@link #netcdfFileClass} has been found, then the {@link
DecoderWrapper} constructor receiving
* in argument the name of the NetCDF file as a {@link String} object.
Otherwise {@code null}.
*/
- private static volatile Constructor<? extends Decoder> fromFilename;
+ private static volatile Constructor<? extends Decoder> createFromPath;
+
+ /**
+ * If the {@link #netcdfFileClass} has been found, then the {@link
DecoderWrapper} constructor receiving
+ * in argument a UCAR {@code NetcdfFile} object. Otherwise {@code null}.
+ */
+ private static volatile Constructor<? extends Decoder> createFromUCAR;
/**
* Creates a new provider.
@@ -68,6 +83,72 @@ public class NetcdfStoreProvider {
}
/**
+ * Returns {@code TRUE} if the given storage appears to be supported by
{@link NetcdfStore}.
+ * Returning {@code TRUE} 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 DataStoreConnection#getStorage() storage object} or
contents.
+ *
+ * @param storage Information about the storage (URL, stream, {@link
ucar.nc2.NetcdfFile} instance, <i>etc</i>).
+ * @return {@link Boolean#TRUE} if the given storage seems to be usable by
the {@code NetcdfStore} instances,
+ * {@link Boolean#FALSE} if {@code NetcdfStore} will not be able
to use the given storage,
+ * or {@code null} if this method does not have enough information.
+ * @throws DataStoreException if an I/O error occurred.
+ */
+ @Override
+ public Boolean canOpen(DataStoreConnection storage) throws
DataStoreException {
+ final ByteBuffer buffer = storage.getStorageAs(ByteBuffer.class);
+ if (buffer != null) {
+ if (buffer.remaining() < Integer.SIZE / Byte.SIZE) {
+ return null;
+ }
+ final int header = buffer.getInt(buffer.position());
+ if ((header & 0xFFFFFF00) == ChannelDecoder.MAGIC_NUMBER) {
+ return Boolean.TRUE;
+ }
+ }
+ /*
+ * If we failed to check using the embedded decoder, tries using the
UCAR library.
+ */
+ final String path = storage.getStorageAs(String.class);
+ if (path != null) {
+ ensureInitialized();
+ final Method method = canOpenFromPath;
+ if (method != null) try {
+ return (Boolean) method.invoke(null, path);
+ } catch (IllegalAccessException e) {
+ throw new AssertionError(e); // Should never happen, since the
method is public.
+ } catch (InvocationTargetException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof DataStoreException) throw
(DataStoreException) cause;
+ if (cause instanceof RuntimeException) throw
(RuntimeException) cause;
+ if (cause instanceof Error) throw (Error)
cause;
+ throw new DataStoreException(e); // The cause may be
IOException.
+ }
+ }
+ /*
+ * 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 = storage.getStorage().getClass(); type != null;
type=type.getSuperclass()) {
+ if (UCAR_CLASSNAME.equals(type.getName())) {
+ return Boolean.TRUE;
+ }
+ }
+ return Boolean.FALSE;
+ }
+
+ /**
+ * Returns a {@link NetcdfStore} implementation associated with this
provider.
+ *
+ * @param storage Information about the storage (URL, stream, {@link
ucar.nc2.NetcdfFile} instance, <i>etc</i>).
+ */
+ @Override
+ public DataStore open(DataStoreConnection storage) throws
DataStoreException {
+ throw new UnsupportedOperationException("Not supported yet."); // TODO
+ }
+
+ /**
* Creates a decoder for the given input.
*
* @param sink Where to send the warnings, or {@code null} if none.
@@ -91,7 +172,7 @@ public class NetcdfStoreProvider {
}
throw e;
}
- return createByReflection(sink, connection, true);
+ return createByReflection(sink, connection.getStorage(), true);
}
/**
@@ -110,29 +191,7 @@ public class NetcdfStoreProvider {
private static Decoder createByReflection(final WarningProducer sink,
final Object input, final boolean isUCAR)
throws IOException, DataStoreException
{
- /*
- * Get the java.lang.Class that represent the ucar.nc2.NetcdfFile
type. We do not synchronize since it
- * is not a big deal if Class.forName(…) is invoked twice. The
Class.forName(…) method performs itself
- * the required synchronization for returning the same singleton Class
instance.
- */
- if (netcdfFileClass == null) {
- try {
- netcdfFileClass = Class.forName("ucar.nc2.NetcdfFile");
- } catch (ClassNotFoundException e) {
- netcdfFileClass = Void.TYPE;
- return null;
- }
- try {
- final Class<? extends Decoder> wrapper =
-
Class.forName("org.apache.sis.internal.netcdf.ucar.DecoderWrapper").asSubclass(Decoder.class);
- final Class<?>[] parameterTypes = new Class<?>[]
{WarningProducer.class, netcdfFileClass};
- fromUCAR = wrapper.getConstructor(parameterTypes);
- parameterTypes[1] = String.class;
- fromFilename = wrapper.getConstructor(parameterTypes);
- } catch (ReflectiveOperationException e) {
- throw new AssertionError(e); // Should never happen (shall be
verified by the JUnit tests).
- }
- }
+ ensureInitialized();
/*
* Get the appropriate constructor for the isUCAR argument. This
constructor will be null
* if the above code failed to load the UCAR library. Otherwise,
instantiate the wrapper.
@@ -140,10 +199,10 @@ public class NetcdfStoreProvider {
final Constructor<? extends Decoder> constructor;
final Class<?> expectedType;
if (isUCAR) {
- constructor = fromUCAR;
+ constructor = createFromUCAR;
expectedType = netcdfFileClass;
} else {
- constructor = fromFilename;
+ constructor = createFromPath;
expectedType = String.class;
}
if (constructor == null || !expectedType.isInstance(input)) {
@@ -162,4 +221,39 @@ public class NetcdfStoreProvider {
throw new AssertionError(e); // Should never happen (shall be
verified by the JUnit tests).
}
}
+
+ /**
+ * Get the {@link java.lang.Class} that represent the {@link
ucar.nc2.NetcdfFile type}.
+ * We do not synchronize this method since it is not a big deal if {@code
Class.forName(…)} is invoked twice.
+ * The {@code Class.forName(…)} method performs itself the required
synchronization for returning the same
+ * singleton {@code Class} instance.
+ */
+ private static void ensureInitialized() {
+ if (netcdfFileClass == null) {
+ try {
+ netcdfFileClass = Class.forName(UCAR_CLASSNAME);
+ } catch (ClassNotFoundException e) {
+ netcdfFileClass = Void.TYPE;
+ return;
+ }
+ try {
+ /*
+ * UCAR API.
+ */
+ canOpenFromPath = netcdfFileClass.getMethod("canOpen",
String.class);
+ assert canOpenFromPath.getReturnType() == Boolean.TYPE;
+ /*
+ * SIS Wrapper API.
+ */
+ final Class<? extends Decoder> wrapper =
+
Class.forName("org.apache.sis.internal.netcdf.ucar.DecoderWrapper").asSubclass(Decoder.class);
+ final Class<?>[] parameterTypes = new Class<?>[]
{WarningProducer.class, netcdfFileClass};
+ createFromUCAR = wrapper.getConstructor(parameterTypes);
+ parameterTypes[1] = String.class;
+ createFromPath = wrapper.getConstructor(parameterTypes);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e); // Should never happen (shall be
verified by the JUnit tests).
+ }
+ }
+ }
}
Added:
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java?rev=1489846&view=auto
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
(added)
+++
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
[UTF-8] Wed Jun 5 13:10:29 2013
@@ -0,0 +1,105 @@
+/*
+ * 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.netcdf;
+
+import java.io.IOException;
+import ucar.nc2.NetcdfFile;
+import org.opengis.wrapper.netcdf.IOTestCase;
+import org.apache.sis.internal.netcdf.Decoder;
+import org.apache.sis.internal.netcdf.impl.ChannelDecoder;
+import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
+import org.apache.sis.internal.netcdf.impl.ChannelDecoderTest;
+import org.apache.sis.storage.DataStoreConnection;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.test.DependsOn;
+import org.junit.Test;
+
+import static org.opengis.test.Assert.*;
+import static org.opengis.wrapper.netcdf.IOTestCase.NCEP;
+
+
+/**
+ * Tests {@link NetcdfStoreProvider}.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3
+ * @version 0.3
+ * @module
+ */
+@DependsOn({
+ ChannelDecoderTest.class
+})
+public final strictfp class NetcdfStoreProviderTest extends IOTestCase {
+ /**
+ * Tests {@link NetcdfStoreProvider#canOpen(DataStoreConnection)} for an
input stream which shall
+ * be recognized as a classic NetCDF file.
+ *
+ * @throws DataStoreException Should never happen.
+ */
+ @Test
+ public void testCanOpenFromStream() throws DataStoreException {
+ final DataStoreConnection c = new
DataStoreConnection(IOTestCase.class.getResourceAsStream(NCEP));
+ final NetcdfStoreProvider provider = new NetcdfStoreProvider();
+ assertTrue(provider.canOpen(c));
+ c.closeAllExcept(null);
+ }
+
+ /**
+ * Tests {@link NetcdfStoreProvider#canOpen(DataStoreConnection)} for a
UCAR {@link NetcdfFile} object.
+ *
+ * @throws IOException If an error occurred while opening the NetCDF file.
+ * @throws DataStoreException Should never happen.
+ */
+ @Test
+ public void testCanOpenFromUCAR() throws IOException, DataStoreException {
+ final NetcdfFile file = open(NCEP);
+ final DataStoreConnection c = new DataStoreConnection(file);
+ final NetcdfStoreProvider provider = new NetcdfStoreProvider();
+ assertTrue(provider.canOpen(c));
+ file.close();
+ }
+
+ /**
+ * Tests {@link NetcdfStoreProvider#decoder(WarningProducer,
DataStoreConnection)} for an input stream which
+ * shall be recognized as a classic NetCDF file. The provider shall
instantiate a {@link ChannelDecoder}.
+ *
+ * @throws IOException If an error occurred while opening the NetCDF file.
+ * @throws DataStoreException Should never happen.
+ */
+ @Test
+ public void testDecoderFromStream() throws IOException, DataStoreException
{
+ final DataStoreConnection c = new
DataStoreConnection(IOTestCase.class.getResourceAsStream(NCEP));
+ final Decoder decoder = NetcdfStoreProvider.decoder(null, c);
+ assertInstanceOf(NCEP, ChannelDecoder.class, decoder);
+ decoder.close();
+ }
+
+ /**
+ * Tests {@link NetcdfStoreProvider#decoder(WarningProducer,
DataStoreConnection)} for a UCAR
+ * {@link NetcdfFile} object. The provider shall instantiate a {@link
DecoderWrapper}.
+ *
+ * @throws IOException If an error occurred while opening the NetCDF file.
+ * @throws DataStoreException Should never happen.
+ */
+ @Test
+ public void testDecoderFromUCAR() throws IOException, DataStoreException {
+ final DataStoreConnection c = new DataStoreConnection(open(NCEP));
+ final Decoder decoder = NetcdfStoreProvider.decoder(null, c);
+ assertInstanceOf(NCEP, DecoderWrapper.class, decoder);
+ decoder.close();
+ }
+}
Propchange:
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/test/suite/NetcdfTestSuite.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/test/suite/NetcdfTestSuite.java?rev=1489846&r1=1489845&r2=1489846&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/test/suite/NetcdfTestSuite.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/test/suite/NetcdfTestSuite.java
[UTF-8] Wed Jun 5 13:10:29 2013
@@ -39,7 +39,8 @@ import org.junit.BeforeClass;
org.apache.sis.internal.netcdf.impl.VariableInfoTest.class,
org.apache.sis.internal.netcdf.impl.GridGeometryInfoTest.class,
org.apache.sis.storage.netcdf.MetadataReaderTest.class,
- org.apache.sis.storage.netcdf.ConformanceTest.class
+ org.apache.sis.storage.netcdf.ConformanceTest.class,
+ org.apache.sis.storage.netcdf.NetcdfStoreProviderTest.class
})
public final strictfp class NetcdfTestSuite extends TestSuite {
/**
Modified:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java?rev=1489846&r1=1489845&r2=1489846&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
[UTF-8] Wed Jun 5 13:10:29 2013
@@ -295,8 +295,8 @@ public class DataStoreConnection impleme
*
* Multiple invocations of this method on the same {@code
DataStoreConnection} instance will try
* to return the same instance on a <cite>best effort</cite> basis.
Consequently, implementations
- * of {@link DataStoreProvider#canRead(DataStoreConnection)} methods shall
not close the stream or
- * database connection returned by this method. In addition, those {@code
canRead(DataStoreConnection)}
+ * of {@link DataStoreProvider#canOpen(DataStoreConnection)} methods shall
not close the stream or
+ * database connection returned by this method. In addition, those {@code
canOpen(DataStoreConnection)}
* methods are responsible for restoring the stream or byte buffer to its
original position on return.
*
* @param <T> The compile-time type of the {@code type} argument.
Added:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java?rev=1489846&view=auto
==============================================================================
---
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
(added)
+++
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
[UTF-8] Wed Jun 5 13:10:29 2013
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+
+/**
+ * Creates {@link DataStore} instances for a specific format from a given
{@link DataStoreConnection} input.
+ * There is typically a different {@code DataStoreProvider} instance for each
format provided by a library.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3
+ * @version 0.3
+ * @module
+ */
+public abstract class DataStoreProvider {
+ /**
+ * Creates a new provider.
+ */
+ protected DataStoreProvider() {
+ }
+
+ /**
+ * Returns {@code TRUE} if the given storage appears to be supported by
the {@code DataStore}.
+ * Returning {@code TRUE} 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 DataStoreConnection#getStorage() storage object} or
contents.
+ *
+ * <p>Implementations will typically check the first bytes of the stream
for a "magic number"
+ * associated with the format, as in the following example:</p>
+ *
+ * {@preformat java
+ * final ByteBuffer buffer = storage.getStorageAs(ByteBuffer.class);
+ * if (buffer == null) {
+ * // If DataStoreConnection can not provide a ByteBuffer, then
the storage is probably
+ * // not a File, URL, URI, InputStream neither a ReadableChannel.
In this example, our
+ * // provider can not handle such unknown source.
+ * return Boolean.FALSE;
+ * }
+ * if (buffer.remaining() < Integer.SIZE / Byte.SIZE) {
+ * // If the buffer does not contain enough bytes for the 'int'
type, this is not necessarily
+ * // because the file is truncated. It may be because the data
were not yet available at the
+ * // time this method has been invoked. Returning 'null' means
"don't know".
+ * return null;
+ * }
+ * // Use ByteBuffer.getInt(int) instead than ByteBuffer.getInt() in
order to keep buffer position
+ * // unchanged after this method call.
+ * return buffer.getInt(buffer.position()) == MAGIC_NUMBER;
+ * }
+ *
+ * Implementors are responsible for restoring the input to its original
stream position on return of this method.
+ * Implementors can use a mark/reset pair for this purpose. Marks are
available as
+ * {@link java.nio.ByteBuffer#mark()}, {@link
java.io.InputStream#mark(int)} and
+ * {@link javax.imageio.stream.ImageInputStream#mark()}.
+ *
+ * @param storage Information about the storage (URL, stream, JDBC
connection, <i>etc</i>).
+ * @return {@link Boolean#TRUE} if the given storage seems to be usable by
the {@code DataStore} instances
+ * create by this provider, {@link Boolean#FALSE} if the {@code
DataStore} will not be able to use
+ * the given storage, or {@code null} if this method does not have
enough information.
+ * @throws DataStoreException if an I/O or SQL error occurred. The error
shall be unrelated to the logical
+ * structure of the storage.
+ */
+ public abstract Boolean canOpen(DataStoreConnection storage) throws
DataStoreException;
+
+ /**
+ * Returns a data store implementation associated with this provider.
+ *
+ * @param storage Information about the storage (URL, stream, JDBC
connection, <i>etc</i>).
+ * @return A data store implementation associated with this provider for
the given storage.
+ * @throws DataStoreException if an error occurred while creating the data
store instance.
+ */
+ public abstract DataStore open(DataStoreConnection storage) throws
DataStoreException;
+}
Propchange:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8