sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mlebi...@apache.org
Subject svn commit: r1649413 [1/2] - in /sis/branches/JDK8: core/sis-utility/src/main/java/org/apache/sis/util/logging/ storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile...
Date Sun, 04 Jan 2015 20:36:47 GMT
Author: mlebihan
Date: Sun Jan  4 20:36:47 2015
New Revision: 1649413

URL: http://svn.apache.org/r1649413
Log:
SIS-185 : Shapefile content is read through an InputFeatureStream.

Added:
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/InvalidShapefileFormatException.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileDescriptor.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileNotFoundException.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractDbase3ByteReader.java
      - copied, changed from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractByteReader.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/CommonByteReader.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBase3FieldDescriptor.java
      - copied, changed from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/Dbase3ByteReader.java
      - copied, changed from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/ByteReader.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DbaseFileNotFoundException.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/package-info.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/InputFeatureStream.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/AbstractDbase3ByteReader.properties
      - copied unchanged from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/resultset/AbstractByteReader.properties
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/AbstractDbase3ByteReader_fr.properties
      - copied unchanged from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/resultset/AbstractByteReader_fr.properties
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/CommonByteReader.properties
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/DBase3FieldDescriptor.properties
      - copied unchanged from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor.properties
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/DBase3FieldDescriptor_fr.properties
      - copied unchanged from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor_fr.properties
Removed:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/AbstractAutoCheckerList.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractByteReader.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/ByteReader.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor.properties
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor_fr.properties
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/resultset/AbstractByteReader.properties
    sis/branches/JDK8/storage/sis-shapefile/src/main/resources/org/apache/sis/internal/shapefile/jdbc/resultset/AbstractByteReader_fr.properties
Modified:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/AbstractAutoChecker.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBFDriver.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/MappedByteReader.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/connection/DBFConnection.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/package-info.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFBuiltInMemoryResultSetForColumnsListing.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFRecordBasedResultSet.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
    sis/branches/JDK8/storage/sis-shapefile/src/test/java/org/apache/sis/storage/shapefile/ShapeFileTest.java

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/AbstractAutoChecker.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/AbstractAutoChecker.java?rev=1649413&r1=1649412&r2=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/AbstractAutoChecker.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/AbstractAutoChecker.java [UTF-8] Sun Jan  4 20:36:47 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.util.logging;
 
+import java.lang.reflect.Constructor;
 import java.text.MessageFormat;
 import java.util.MissingResourceException;
 import java.util.Objects;
@@ -125,6 +126,43 @@ abstract public class AbstractAutoChecke
         if (logger.isLoggable(logLevel))
             format(logLevel, key, args);
     }
+
+    /**
+     * Throw an exception by reflection.
+     * @param <E> Class of the exception to build.
+     * @param classException Class of the exception to build.
+     * @param message Exception message.
+     * @param cause Exception root cause.
+     * @throws E wished exception.
+     */
+    static public <E extends Throwable> void throwException(Class<E> classException, String message, Throwable cause) throws E {
+       throw(exception(classException, message, cause));
+    }
+    
+    /**
+     * Build an exception by reflection.
+     * @param <E> Class of the exception to build.
+     * @param classException Class of the exception to build.
+     * @param message Exception message.
+     * @param cause Exception root cause.
+     * @return E wished exception.
+     */
+    static private <E extends Throwable> E exception(Class<E> classException, String message, Throwable cause) {
+       Objects.requireNonNull(classException, "The class of the exception to throw cannot be null."); //$NON-NLS-1$
+       
+       try
+       {
+            Constructor<E> cstr = classException.getConstructor(String.class, Throwable.class);
+            E exception = cstr.newInstance(message, cause);
+            return(exception);
+       }
+       catch(Exception e) {
+            // Create the error message manually to avoid re-entrance in function of this class, that if it has a trouble here could have also a problem everywhere.
+            String format = "The exception of class {0} (message ''{1}'') can''t be created by reflection. An exception of class {2} happened with the message {3}.";
+            String msg = MessageFormat.format(format, classException.getName(), message, e.getClass().getName(), e.getMessage());
+            throw new RuntimeException(msg, e);
+       }
+    }
     
     /**
      * Return the class logger.

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/InvalidShapefileFormatException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/InvalidShapefileFormatException.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/InvalidShapefileFormatException.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/InvalidShapefileFormatException.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,47 @@
+/*
+ * 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.internal.shapefile;
+
+/**
+ * Thrown when the Shapefile format seems to be invalid.
+ *
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+public class InvalidShapefileFormatException extends Exception {
+    /** Serial UID. */
+    private static final long serialVersionUID = -2724950178838120005L;
+
+    /**
+     * Construct an exception.
+     * @param message Message of the exception.
+     */
+    public InvalidShapefileFormatException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct an exception.
+     * @param message Message of the exception.
+     * @param cause Root cause of the exception.
+     */
+    public InvalidShapefileFormatException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,278 @@
+/*
+ * 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.internal.shapefile;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteOrder;
+import java.text.MessageFormat;
+import java.util.*;
+
+import org.apache.sis.feature.DefaultAttributeType;
+import org.apache.sis.feature.DefaultFeatureType;
+import org.apache.sis.internal.shapefile.jdbc.*;
+import org.apache.sis.storage.shapefile.ShapeTypeEnum;
+import org.opengis.feature.Feature;
+
+import com.esri.core.geometry.*;
+
+/**
+ * Reader of a Shapefile Binary content by the way of a {@link java.nio.MappedByteBuffer}
+ *
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+public class ShapefileByteReader extends CommonByteReader<InvalidShapefileFormatException, ShapefileNotFoundException> {
+    /** Name of the Geometry field. */
+    private static final String GEOMETRY_NAME = "geometry";
+    
+    /** Shapefile descriptor. */
+    private ShapefileDescriptor shapefileDescriptor; 
+    
+    /** Database Field descriptors. */
+    private List<DBase3FieldDescriptor> databaseFieldsDescriptors;
+    
+    /** Type of the features contained in this shapefile. */
+    private DefaultFeatureType featuresType;
+
+    /**
+     * Construct a shapefile byte reader.
+     * @param shapefile Shapefile.
+     * @param dbaseFile underlying database file name.
+     * @throws InvalidShapefileFormatException if the shapefile format is invalid.
+     * @throws InvalidDbaseFileFormatException if the database file format is invalid.
+     * @throws ShapefileNotFoundException if the shapefile has not been found. 
+     * @throws DbaseFileNotFoundException if the database file has not been found.
+     */
+    public ShapefileByteReader(File shapefile, File dbaseFile) throws InvalidShapefileFormatException, InvalidDbaseFileFormatException, ShapefileNotFoundException, DbaseFileNotFoundException {
+        super(shapefile, InvalidShapefileFormatException.class, ShapefileNotFoundException.class);
+        loadDatabaseFieldDescriptors(dbaseFile);
+        loadDescriptor();
+
+        featuresType = getFeatureType(shapefile.getName());
+    }
+    
+    /**
+     * Returns the DBase 3 fields descriptors.
+     * @return Fields descriptors.
+     */
+    public List<DBase3FieldDescriptor> getFieldsDescriptors() {
+        return databaseFieldsDescriptors;
+    }
+    
+    /**
+     * Returns the shapefile descriptor.
+     * @return Shapefile descriptor.
+     */
+    public ShapefileDescriptor getShapefileDescriptor() {
+        return shapefileDescriptor;
+    }
+    
+    /**
+     * Returns the type of the features contained in this shapefile.
+     * @return Features type.
+     */
+    public DefaultFeatureType getFeaturesType() {
+        return featuresType;
+    }
+    
+    /**
+     * Create a feature descriptor.
+     * @param name Name of the field.
+     * @return The feature type.
+     */
+    private DefaultFeatureType getFeatureType(final String name) {
+        Objects.requireNonNull(name, "The feature name cannot be null.");
+        
+        final int n = databaseFieldsDescriptors.size();
+        final DefaultAttributeType<?>[] attributes = new DefaultAttributeType<?>[n + 1];
+        final Map<String, Object> properties = new HashMap<>(4);
+
+        // Load data field.
+        for (int i = 0; i < n; i++) {
+            properties.put(DefaultAttributeType.NAME_KEY, databaseFieldsDescriptors.get(i).getName());
+            attributes[i] = new DefaultAttributeType<>(properties, String.class, 1, 1, null);
+        }
+
+        // Add geometry field.
+        properties.put(DefaultAttributeType.NAME_KEY, GEOMETRY_NAME);
+        attributes[n] = new DefaultAttributeType<>(properties, Geometry.class, 1, 1, null);
+
+        // Add name.
+        properties.put(DefaultAttributeType.NAME_KEY, name);
+        return new DefaultFeatureType(properties, false, null, attributes);
+    }
+
+    /**
+     * Load shapefile descriptor.
+     */
+    private void loadDescriptor() {
+        shapefileDescriptor = new ShapefileDescriptor(getByteBuffer());
+    }
+
+    /**
+     * Load database field descriptors.
+     * @param dbaseFile Database file.
+     * @throws InvalidDbaseFileFormatException if the database format is incorrect.
+     * @throws DbaseFileNotFoundException if the database file cannot be found.
+     */
+    private void loadDatabaseFieldDescriptors(File dbaseFile) throws InvalidDbaseFileFormatException, DbaseFileNotFoundException {
+        MappedByteReader databaseReader = null;
+        
+        try {
+            databaseReader = new MappedByteReader(dbaseFile);
+            databaseFieldsDescriptors = databaseReader.getFieldsDescriptors();
+        }
+        finally {
+            if (databaseReader != null) {
+                try {
+                    databaseReader.close();
+                }
+                catch(IOException e) {
+                }
+            }
+        }
+    }
+    
+    /**
+     * Complete a feature with shapefile content.
+     * @param feature Feature to complete.
+     * @throws InvalidShapefileFormatException if a validation problem occurs.
+     */
+    public void completeFeature(Feature feature) throws InvalidShapefileFormatException {
+        // insert points into some type of list
+        int RecordNumber = getByteBuffer().getInt();
+        @SuppressWarnings("unused")
+        int ContentLength = getByteBuffer().getInt();
+
+        getByteBuffer().order(ByteOrder.LITTLE_ENDIAN);
+        int iShapeType = getByteBuffer().getInt();
+
+        ShapeTypeEnum type = ShapeTypeEnum.get(iShapeType);
+
+        if (type == null)
+            throw new InvalidShapefileFormatException(MessageFormat.format("The shapefile feature type {0} doesn''t match to any known feature type.", featuresType));
+
+        switch (type) {
+            case Point:
+                loadPointFeature(feature);
+                break;
+    
+            case Polygon:
+                loadPolygonFeature(feature);
+                break;
+    
+            case PolyLine:
+                loadPolylineFeature(feature);
+                break;
+    
+            default:
+                throw new InvalidShapefileFormatException("Unsupported shapefile type: " + iShapeType);
+        }
+
+        getByteBuffer().order(ByteOrder.BIG_ENDIAN);
+    }
+
+    /**
+     * Load point feature.
+     * @param feature Feature to fill.
+     */
+    private void loadPointFeature(Feature feature) {
+        double x = getByteBuffer().getDouble();
+        double y = getByteBuffer().getDouble();
+        Point pnt = new Point(x, y);
+        feature.setPropertyValue(GEOMETRY_NAME, pnt);
+    }
+
+    /**
+     * Load polygon feature.
+     * @param feature Feature to fill.
+     * @throws InvalidShapefileFormatException if the polygon cannot be handled. 
+     */
+    private void loadPolygonFeature(Feature feature) throws InvalidShapefileFormatException {
+        /* double xmin = */getByteBuffer().getDouble();
+        /* double ymin = */getByteBuffer().getDouble();
+        /* double xmax = */getByteBuffer().getDouble();
+        /* double ymax = */getByteBuffer().getDouble();
+        int NumParts = getByteBuffer().getInt();
+        int NumPoints = getByteBuffer().getInt();
+
+        if (NumParts > 1) {
+            throw new InvalidShapefileFormatException("Polygons with multiple linear rings have not implemented yet.");
+        }
+
+        // read the one part
+        @SuppressWarnings("unused")
+        int Part = getByteBuffer().getInt();
+        Polygon poly = new Polygon();
+
+        // create a line from the points
+        double xpnt = getByteBuffer().getDouble();
+        double ypnt = getByteBuffer().getDouble();
+        // Point oldpnt = new Point(xpnt, ypnt);
+        poly.startPath(xpnt, ypnt);
+
+        for (int j = 0; j < NumPoints - 1; j++) {
+            xpnt = getByteBuffer().getDouble();
+            ypnt = getByteBuffer().getDouble();
+            poly.lineTo(xpnt, ypnt);
+        }
+
+        feature.setPropertyValue(GEOMETRY_NAME, poly);
+    }
+
+    /**
+     * Load polyline feature.
+     * @param feature Feature to fill.
+     */
+    private void loadPolylineFeature(Feature feature) {
+        /* double xmin = */getByteBuffer().getDouble();
+        /* double ymin = */getByteBuffer().getDouble();
+        /* double xmax = */getByteBuffer().getDouble();
+        /* double ymax = */getByteBuffer().getDouble();
+
+        int NumParts = getByteBuffer().getInt();
+        int NumPoints = getByteBuffer().getInt();
+
+        int[] NumPartArr = new int[NumParts + 1];
+
+        for (int n = 0; n < NumParts; n++) {
+            int idx = getByteBuffer().getInt();
+            NumPartArr[n] = idx;
+        }
+        NumPartArr[NumParts] = NumPoints;
+
+        double xpnt, ypnt;
+        Polyline ply = new Polyline();
+
+        for (int m = 0; m < NumParts; m++) {
+            xpnt = getByteBuffer().getDouble();
+            ypnt = getByteBuffer().getDouble();
+            ply.startPath(xpnt, ypnt);
+
+            for (int j = NumPartArr[m]; j < NumPartArr[m + 1] - 1; j++) {
+                xpnt = getByteBuffer().getDouble();
+                ypnt = getByteBuffer().getDouble();
+                ply.lineTo(xpnt, ypnt);
+            }
+        }
+
+        feature.setPropertyValue(GEOMETRY_NAME, ply);
+    }
+}

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileDescriptor.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileDescriptor.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileDescriptor.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,122 @@
+/*
+ * 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.internal.shapefile;
+
+import java.nio.ByteOrder;
+import java.nio.MappedByteBuffer;
+
+import org.apache.sis.storage.shapefile.ShapeTypeEnum;
+
+/**
+ * Shapefile Descriptor.
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+public class ShapefileDescriptor {
+    /** File code. */
+    private int m_fileCode; // big
+
+    /** File length. */
+    private int m_fileLength; // big // The value for file length is the total length of the file in 16-bit words
+
+    /** File version. */
+    private int m_version; // little
+
+    /** Shapefile type. */
+    private ShapeTypeEnum m_shapeType; // little
+
+    /** X Min. */
+    private double m_xmin; // little
+
+    /** Y Min. */
+    private double m_ymin; // little
+
+    /** X Max. */
+    private double m_xmax; // little
+
+    /** Y Max. */
+    private double m_ymax; // little
+
+    /** Z Min. */
+    private double m_zmin; // little
+
+    /** Z Max. */
+    private double m_zmax; // little
+
+    /** M Min. */
+    private double m_mmin; // little
+
+    /** M Max. */
+    private double m_mmax; // little
+    
+    /**
+     * Create a shapefile descriptor.
+     * @param byteBuffer Source Bytebuffer.
+     */
+    public ShapefileDescriptor(MappedByteBuffer byteBuffer) {
+        m_fileCode = byteBuffer.getInt();
+        byteBuffer.getInt();
+        byteBuffer.getInt();
+        byteBuffer.getInt();
+        byteBuffer.getInt();
+        byteBuffer.getInt();
+        m_fileLength = byteBuffer.getInt() * 2;
+
+        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+        m_version = byteBuffer.getInt();
+        m_shapeType = ShapeTypeEnum.get(byteBuffer.getInt());
+        m_xmin = byteBuffer.getDouble();
+        m_ymin = byteBuffer.getDouble();
+        m_xmax = byteBuffer.getDouble();
+        m_ymax = byteBuffer.getDouble();
+        m_zmin = byteBuffer.getDouble();
+        m_zmax = byteBuffer.getDouble();
+        m_mmin = byteBuffer.getDouble();
+        m_mmax = byteBuffer.getDouble();
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+
+        //dbf.byteBuffer.get(); // should be 0d for field terminator
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        String lineSeparator = System.getProperty("line.separator", "\n");
+
+        s.append("FileCode: ").append(m_fileCode).append(lineSeparator);
+        s.append("FileLength: ").append(m_fileLength).append(lineSeparator);
+        s.append("Version: ").append(m_version).append(lineSeparator);
+        s.append("ShapeType: ").append(m_shapeType).append(lineSeparator);
+        s.append("xmin: ").append(m_xmin).append(lineSeparator);
+        s.append("ymin: ").append(m_ymin).append(lineSeparator);
+        s.append("xmax: ").append(m_xmax).append(lineSeparator);
+        s.append("ymax: ").append(m_ymax).append(lineSeparator);
+        s.append("zmin: ").append(m_zmin).append(lineSeparator);
+        s.append("zmax: ").append(m_zmax).append(lineSeparator);
+        s.append("mmin: ").append(m_mmin).append(lineSeparator);
+        s.append("mmax: ").append(m_mmax).append(lineSeparator);
+        s.append("------------------------").append(lineSeparator);
+
+        return s.toString();
+    }
+}
+

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileNotFoundException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileNotFoundException.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileNotFoundException.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileNotFoundException.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,50 @@
+/*
+ * 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.internal.shapefile;
+
+import java.sql.SQLNonTransientException;
+
+
+/**
+ * Thrown when a shapefile has not been found.
+ *
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+public class ShapefileNotFoundException extends SQLNonTransientException {
+    /** Serial UID. */
+    private static final long serialVersionUID = -3235671561698931817L;
+
+    /**
+     * Construct an exception.
+     * @param message Message of the exception.
+     */
+    public ShapefileNotFoundException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct an exception.
+     * @param message Message of the exception.
+     * @param cause Root cause of the exception.
+     */
+    public ShapefileNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Copied: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractDbase3ByteReader.java (from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractByteReader.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractDbase3ByteReader.java?p2=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractDbase3ByteReader.java&p1=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractByteReader.java&r1=1649405&r2=1649413&rev=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractByteReader.java (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/AbstractDbase3ByteReader.java Sun Jan  4 20:36:47 2015
@@ -25,16 +25,14 @@ import java.util.HashMap;
 import java.util.Objects;
 import java.util.logging.Level;
 
-import org.apache.sis.util.logging.AbstractAutoChecker;
-
 /**
  * The Abstract Byte Reader.
- * @author Marc LE BIHAN
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
  */
-abstract class AbstractByteReader extends AbstractAutoChecker implements ByteReader {
-    /** Database filename. */
-    protected String dbfFile;
-
+abstract class AbstractDbase3ByteReader extends CommonByteReader<InvalidDbaseFileFormatException, DbaseFileNotFoundException> implements Dbase3ByteReader {
     /** Number of bytes in the header. */
     protected short dbaseHeaderBytes;
 
@@ -92,6 +90,16 @@ abstract class AbstractByteReader extend
     protected int rowNum;
     
     /**
+     * Map a dbf file.
+     * @param file Database file.
+     * @throws DbaseFileNotFoundException if the DBF file has not been found.
+     * @throws InvalidDbaseFileFormatException if the database has an invalid format.
+     */
+    public AbstractDbase3ByteReader(File file) throws DbaseFileNotFoundException, InvalidDbaseFileFormatException {
+        super(file, InvalidDbaseFileFormatException.class, DbaseFileNotFoundException.class);
+    }
+    
+    /**
      * Returns the charset.
      * @return Charset.
      */
@@ -153,13 +161,13 @@ abstract class AbstractByteReader extend
         
         // If the code page is invalid, the database itself has chances to be invalid too.
         if (dbfCodePage.equals("invalid")) {
-            String message = format(Level.WARNING, "excp.illegal_codepage", codePageBinaryValue, new File(dbfFile).getAbsolutePath());
+            String message = format(Level.WARNING, "excp.illegal_codepage", codePageBinaryValue, getFile().getAbsolutePath());
             throw new InvalidDbaseFileFormatException(message);
         }
         
         // If the code page cannot find a match for a more recent Charset, we wont be able to handle this DBF.
         if (dbfCodePage.equals("unsupported")) {
-            String message = format(Level.WARNING, "excp.unsupported_codepage", dbfCodePage, new File(dbfFile).getAbsolutePath());
+            String message = format(Level.WARNING, "excp.unsupported_codepage", dbfCodePage, getFile().getAbsolutePath());
             throw new UnsupportedCharsetException(message);
         }
         
@@ -168,7 +176,7 @@ abstract class AbstractByteReader extend
         }
         catch(IllegalArgumentException e) {
             // If this happens here, it means that we have selected a wrong charset. We have a bug.
-            String message = format(Level.WARNING, "assert.wrong_charset_selection", dbfCodePage, new File(dbfFile).getAbsolutePath());
+            String message = format(Level.WARNING, "assert.wrong_charset_selection", dbfCodePage, getFile().getAbsolutePath());
             throw new RuntimeException(message);
         }
     }

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/CommonByteReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/CommonByteReader.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/CommonByteReader.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/CommonByteReader.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,132 @@
+/*
+ * 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.internal.shapefile.jdbc;
+
+import java.io.*;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Objects;
+import java.util.logging.Level;
+
+import org.apache.sis.util.logging.AbstractAutoChecker;
+
+/**
+ * Common byte reader.
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @param <InvalidFormatException> Invalid format Exception to throw in case of trouble.
+ * @param <FNFException> File not found Exception to throw in case of missing file.
+ * @since   0.5
+ * @module
+ */
+public abstract class CommonByteReader<InvalidFormatException extends Exception, FNFException extends Exception> extends AbstractAutoChecker  implements AutoCloseable  {
+    /** The File. */
+    private File m_file;
+    
+    /** Input Stream on the DBF. */
+    private FileInputStream m_fis;
+
+    /** File channel on the file. */
+    private FileChannel m_fc;
+
+    /** Buffer reader. */
+    private MappedByteBuffer m_byteBuffer;
+    
+    /** Indicates if the byte buffer is closed. */
+    private boolean m_isClosed = false;
+
+    /** Invalid Exception to throw in case of invalid file format. */
+    private Class<InvalidFormatException> m_classInvalidFormatException;
+
+    /** Invalid Exception to throw in case of file not found exception. */
+    private Class<FNFException> m_classFNFException;
+    
+    /**
+     * Create and open a byte reader based on a file.
+     * @param file File.
+     * @param classInvalidFormatException Invalid Exception to throw in case of invalid file format.
+     * @param classFileNotFoundException Invalid Exception to throw in case of file not found exception.
+     * @throws FNFException if the file cannot be opened.
+     * @throws InvalidFormatException if the file format is invalid.
+     */
+    public CommonByteReader(File file, Class<InvalidFormatException> classInvalidFormatException, Class<FNFException> classFileNotFoundException) throws FNFException, InvalidFormatException {
+        Objects.requireNonNull(file, "The file cannot be null.");
+        m_classInvalidFormatException = classInvalidFormatException;
+        m_classFNFException = classFileNotFoundException;
+        
+        m_file = file;
+        
+        try {
+            m_fis = new FileInputStream(file);
+        }
+        catch(FileNotFoundException e) {
+            throwException(m_classInvalidFormatException, e.getMessage(), e);
+            throw new RuntimeException("this place should not be reached.");
+        }
+        
+        m_fc = m_fis.getChannel();
+        
+        try {
+            int fsize = (int)m_fc.size();
+            m_byteBuffer = m_fc.map(FileChannel.MapMode.READ_ONLY, 0, fsize);
+        }
+        catch(IOException e) {
+            String message = format(Level.WARNING, "excp.reader_cannot_be_created", m_file.getAbsolutePath(), e.getMessage());
+            throwException(m_classFNFException, message, e);
+            throw new RuntimeException("this place should not be reached.");
+        }
+   }
+
+    /**
+     * Close the MappedByteReader.
+     * @throws IOException if the close operation fails.
+     */
+    @Override 
+    public void close() throws IOException {
+        if (m_fc != null)
+            m_fc.close();
+
+        if (m_fis != null)
+            m_fis.close();
+        
+        m_isClosed = true;
+    }
+
+    /**
+     * Returns the closed state of this binary reader.
+     * @return true if it is closed.
+     */
+    public boolean isClosed() {
+        return m_isClosed;
+    }
+
+    /**
+     * Returns the byte buffer.
+     * @return Byte Buffer.
+     */
+    public MappedByteBuffer getByteBuffer() {
+        return m_byteBuffer;
+    }
+    
+    /**
+     * Return the file mapped.
+     * @return File.
+     */
+    public File getFile() {
+        return m_file;
+    }
+}

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBFDriver.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBFDriver.java?rev=1649413&r1=1649412&r2=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBFDriver.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBFDriver.java [UTF-8] Sun Jan  4 20:36:47 2015
@@ -63,19 +63,17 @@ public class DBFDriver extends AbstractJ
      * @param  url  The path to a {@code .dbf} file.
      * @param  info Ignored in current implementation.
      * @return A connection to the given DBF file.
-     * @throws SQLException if this method can not create a connection to the given file.
+     * @throws InvalidDbaseFileFormatException if the database file format is invalid.
+     * @throws DbaseFileNotFoundException if the database file doesn't exist.
+     * @throws InvalidDbaseFileFormatException if the database file has a wrong format.
      */
     @Override
-    public Connection connect(final String url, @SuppressWarnings("unused") Properties info) throws SQLException {
+    @SuppressWarnings("resource") // the function opens a connection.
+    public Connection connect(final String url, @SuppressWarnings("unused") Properties info) throws InvalidDbaseFileFormatException, DbaseFileNotFoundException {
         Objects.requireNonNull(url, "the DBase3 url cannot be null");
         File file = new File(url);
         
-        try {
-            return new DBFConnection(file, new MappedByteReader(file));
-        }
-        catch(FileNotFoundException e) {
-            throw new SQLException(e.getMessage(), e);
-        }
+        return new DBFConnection(file, new MappedByteReader(file));
     }
 
     /**

Copied: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBase3FieldDescriptor.java (from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBase3FieldDescriptor.java?p2=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBase3FieldDescriptor.java&p1=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor.java&r1=1649405&r2=1649413&rev=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/FieldDescriptor.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DBase3FieldDescriptor.java [UTF-8] Sun Jan  4 20:36:47 2015
@@ -29,7 +29,7 @@ import org.apache.sis.util.logging.Abstr
  * @version 0.5
  * @module
  */
-public class FieldDescriptor extends AbstractAutoChecker {
+public class DBase3FieldDescriptor extends AbstractAutoChecker {
     /** Field name. */
     private byte[] fieldName = new byte[11];
 
@@ -63,7 +63,7 @@ public class FieldDescriptor extends Abs
      * Create a field descriptor from the current position of the binary stream.
      * @param byteBuffer ByteBuffer.
      */
-    public FieldDescriptor(MappedByteBuffer byteBuffer) {
+    public DBase3FieldDescriptor(MappedByteBuffer byteBuffer) {
         // Field name.
         byteBuffer.get(fieldName);
 

Copied: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/Dbase3ByteReader.java (from r1649405, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/ByteReader.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/Dbase3ByteReader.java?p2=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/Dbase3ByteReader.java&p1=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/ByteReader.java&r1=1649405&r2=1649413&rev=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/ByteReader.java (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/Dbase3ByteReader.java Sun Jan  4 20:36:47 2015
@@ -30,7 +30,7 @@ import org.opengis.feature.Feature;
  * Database byte reader contract. Used to allow refactoring of core byte management of a DBase file.
  * @author Marc LE BIHAN
  */
-public interface ByteReader {
+public interface Dbase3ByteReader {
     /**
      * Close the MappedByteReader.
      * @throws IOException if the close operation fails.
@@ -47,7 +47,7 @@ public interface ByteReader {
      * Returns the fields descriptors in their binary format.
      * @return Fields descriptors.
      */
-    public List<FieldDescriptor> getFieldsDescriptors();
+    public List<DBase3FieldDescriptor> getFieldsDescriptors();
     
     /**
      * Returns the column index for the given column name.

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DbaseFileNotFoundException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DbaseFileNotFoundException.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DbaseFileNotFoundException.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/DbaseFileNotFoundException.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,50 @@
+/*
+ * 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.internal.shapefile.jdbc;
+
+import java.sql.SQLNonTransientException;
+
+
+/**
+ * Thrown when a DBF file has not been found.
+ *
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+public class DbaseFileNotFoundException extends SQLNonTransientException {
+    /** Serial UID. */
+    private static final long serialVersionUID = 2572691456125734352L;
+
+    /**
+     * Construct an exception.
+     * @param message Message of the exception.
+     */
+    public DbaseFileNotFoundException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct an exception.
+     * @param message Message of the exception.
+     * @param cause Root cause of the exception.
+     */
+    public DbaseFileNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/MappedByteReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/MappedByteReader.java?rev=1649413&r1=1649412&r2=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/MappedByteReader.java (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/MappedByteReader.java Sun Jan  4 20:36:47 2015
@@ -16,10 +16,9 @@
  */
 package org.apache.sis.internal.shapefile.jdbc;
 
-import java.io.*;
+import java.io.File;
+import java.nio.BufferUnderflowException;
 import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
 import java.util.*;
 import java.util.logging.Level;
 
@@ -27,77 +26,42 @@ import org.apache.sis.internal.shapefile
 import org.apache.sis.internal.shapefile.jdbc.resultset.SQLNoSuchFieldException;
 import org.opengis.feature.Feature;
 
+
 /**
  * Reader of a Database Binary content by the way of a {@link java.nio.MappedByteBuffer}
- * @author Marc LE BIHAN
+ *
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
  */
-class MappedByteReader extends AbstractByteReader {
-    /** The DBF file. */
-    private File file;
-    
-    /** Input Stream on the DBF. */
-    private FileInputStream fis;
-
-    /** File channel on the file. */
-    private FileChannel fc;
-
-    /** Buffer reader. */
-    private MappedByteBuffer df;
-    
-    /** Indicates if the byte buffer is closed. */
-    private boolean isClosed = false;
-    
+public class MappedByteReader extends AbstractDbase3ByteReader implements AutoCloseable {
     /** List of field descriptors. */
-    private List<FieldDescriptor> m_fieldsDescriptors = new ArrayList<>();
+    private List<DBase3FieldDescriptor> m_fieldsDescriptors = new ArrayList<>();
     
     /**
      * Construct a mapped byte reader on a file.
      * @param dbase3File File.
-     * @throws FileNotFoundException the file name cannot be null.
      * @throws InvalidDbaseFileFormatException if the database seems to be invalid.
+     * @throws DbaseFileNotFoundException if the Dbase file has not been found. 
      */
-    public MappedByteReader(File dbase3File) throws FileNotFoundException, InvalidDbaseFileFormatException {
-        Objects.requireNonNull(dbase3File, "The file cannot be null.");
-        
-        this.file = dbase3File;
-        fis = new FileInputStream(dbase3File);
-        fc = fis.getChannel();
+    public MappedByteReader(File dbase3File) throws InvalidDbaseFileFormatException, DbaseFileNotFoundException {
+        super(dbase3File);
         loadDescriptor();
     }
 
     /**
-     * Close the MappedByteReader.
-     * @throws IOException if the close operation fails.
-     */
-    @Override public void close() throws IOException {
-        if (fc != null)
-            fc.close();
-
-        if (fis != null)
-            fis.close();
-        
-        isClosed = true;
-    }
-
-    /**
-     * @see org.apache.sis.internal.shapefile.jdbc.ByteReader#isClosed()
-     */
-    @Override public boolean isClosed() {
-        return isClosed;
-    }
-
-    /**
      * Load a row into a feature.
      * @param feature Feature to fill.
      */
     @Override public void loadRowIntoFeature(Feature feature) {
         // TODO: ignore deleted records
-        df.get(); // denotes whether deleted or current
+        getByteBuffer().get(); // denotes whether deleted or current
         // read first part of record
 
-        for (FieldDescriptor fd : m_fieldsDescriptors) {
+        for (DBase3FieldDescriptor fd : m_fieldsDescriptors) {
             byte[] data = new byte[fd.getLength()];
-            df.get(data);
+            getByteBuffer().get(data);
 
             int length = data.length;
             while (length != 0 && data[length - 1] <= ' ') {
@@ -117,7 +81,7 @@ class MappedByteReader extends AbstractB
      */
     @Override 
     public boolean nextRowAvailable() {
-        return df.hasRemaining();
+        return getByteBuffer().hasRemaining();
     }
 
     /**
@@ -127,14 +91,14 @@ class MappedByteReader extends AbstractB
     @Override 
     public Map<String, Object> readNextRowAsObjects() {
         // TODO: ignore deleted records
-        byte isDeleted = df.get(); // denotes whether deleted or current
+        byte isDeleted = getByteBuffer().get(); // denotes whether deleted or current
         // read first part of record
 
         HashMap<String, Object> fieldsValues = new HashMap<>();
 
-        for (FieldDescriptor fd : m_fieldsDescriptors) {
+        for (DBase3FieldDescriptor fd : m_fieldsDescriptors) {
             byte[] data = new byte[fd.getLength()];
-            df.get(data);
+            getByteBuffer().get(data);
 
             int length = data.length;
             while (length != 0 && data[length - 1] <= ' ') {
@@ -155,51 +119,48 @@ class MappedByteReader extends AbstractB
      */
     private void loadDescriptor() throws InvalidDbaseFileFormatException {
         try {
-            int fsize = (int) fc.size();
-            df = fc.map(FileChannel.MapMode.READ_ONLY, 0, fsize);
-    
-            this.dbaseVersion = df.get();
-            df.get(this.dbaseLastUpdate);
+            this.dbaseVersion = getByteBuffer().get();
+            getByteBuffer().get(this.dbaseLastUpdate);
     
-            df.order(ByteOrder.LITTLE_ENDIAN);
-            this.rowCount = df.getInt();
-            this.dbaseHeaderBytes = df.getShort();
-            this.dbaseRecordBytes = df.getShort();
-            df.order(ByteOrder.BIG_ENDIAN);
+            getByteBuffer().order(ByteOrder.LITTLE_ENDIAN);
+            this.rowCount = getByteBuffer().getInt();
+            this.dbaseHeaderBytes = getByteBuffer().getShort();
+            this.dbaseRecordBytes = getByteBuffer().getShort();
+            getByteBuffer().order(ByteOrder.BIG_ENDIAN);
             
-            df.get(reservedFiller1);
-            this.reservedIncompleteTransaction = df.get();
-            this.reservedEncryptionFlag = df.get();
-            df.get(reservedFreeRecordThread);
-            df.get(reservedMultiUser);
-            reservedMDXFlag = df.get();
+            getByteBuffer().get(reservedFiller1);
+            this.reservedIncompleteTransaction = getByteBuffer().get();
+            this.reservedEncryptionFlag = getByteBuffer().get();
+            getByteBuffer().get(reservedFreeRecordThread);
+            getByteBuffer().get(reservedMultiUser);
+            reservedMDXFlag = getByteBuffer().get();
             
             // Translate code page value to a known charset.
-            this.codePage = df.get();
+            this.codePage = getByteBuffer().get();
             this.charset = toCharset(this.codePage);             
             
-            df.get(reservedFiller2); 
+            getByteBuffer().get(reservedFiller2); 
     
-            while(df.position() < this.dbaseHeaderBytes - 1) {
-                FieldDescriptor fd = new FieldDescriptor(df); 
+            while(getByteBuffer().position() < this.dbaseHeaderBytes - 1) {
+                DBase3FieldDescriptor fd = new DBase3FieldDescriptor(getByteBuffer()); 
                 this.m_fieldsDescriptors.add(fd);
                 // loop until you hit the 0Dh field terminator
             }
             
-            this.descriptorTerminator = df.get();
+            this.descriptorTerminator = getByteBuffer().get();
 
             // If the last character read after the field descriptor isn't 0x0D, the expected mark has not been found and the DBF is corrupted.
             if (descriptorTerminator != 0x0D) {
-                String message = format(Level.WARNING, "excp.filedescriptor_problem", file.getAbsolutePath(), "Character marking the end of the fields descriptors (0x0D) has not been found.");
+                String message = format(Level.WARNING, "excp.filedescriptor_problem", getFile().getAbsolutePath(), "Character marking the end of the fields descriptors (0x0D) has not been found.");
                 throw new InvalidDbaseFileFormatException(message);
             }
         }
-        catch(IOException e) {
+        catch(BufferUnderflowException e) {
             // This exception doesn't denote a trouble of file opening because the file has been checked before 
             // the calling of this private function.
             // Therefore, an internal structure problem cause maybe a premature End of file or anything else, but the only thing
             // we can conclude is : we are not before a device trouble, but a file format trouble.
-            String message = format(Level.WARNING, "excp.filedescriptor_problem", file.getAbsolutePath(), e.getMessage());
+            String message = format(Level.WARNING, "excp.filedescriptor_problem", getFile().getAbsolutePath(), e.getMessage());
             throw new InvalidDbaseFileFormatException(message);
         }
     }
@@ -209,7 +170,7 @@ class MappedByteReader extends AbstractB
      * @return Fields descriptors.
      */
     @Override 
-    public List<FieldDescriptor> getFieldsDescriptors() {
+    public List<DBase3FieldDescriptor> getFieldsDescriptors() {
         return m_fieldsDescriptors;
     }
 
@@ -226,7 +187,7 @@ class MappedByteReader extends AbstractB
     }
 
     /**
-     * @see org.apache.sis.internal.shapefile.jdbc.ByteReader#getColumnCount()
+     * @see org.apache.sis.internal.shapefile.jdbc.Dbase3ByteReader#getColumnCount()
      */
     @Override 
     public int getColumnCount() {
@@ -245,8 +206,8 @@ class MappedByteReader extends AbstractB
     public int findColumn(String columnLabel, String sql) throws SQLNoSuchFieldException {
         // If the column name is null, no search is needed.
         if (columnLabel == null) {
-            String message = format(Level.WARNING, "excp.no_such_column_in_resultset", columnLabel, sql, file.getName());
-            throw new SQLNoSuchFieldException(message, sql, file, columnLabel);
+            String message = format(Level.WARNING, "excp.no_such_column_in_resultset", columnLabel, sql, getFile().getName());
+            throw new SQLNoSuchFieldException(message, sql, getFile(), columnLabel);
         }
         
         // Search the field among the fields descriptors.
@@ -257,8 +218,8 @@ class MappedByteReader extends AbstractB
         }
 
         // If we are here, we haven't found our field. Throw an exception.
-        String message = format(Level.WARNING, "excp.no_such_column_in_resultset", columnLabel, sql, file.getName());
-        throw new SQLNoSuchFieldException(message, sql, file, columnLabel);
+        String message = format(Level.WARNING, "excp.no_such_column_in_resultset", columnLabel, sql, getFile().getName());
+        throw new SQLNoSuchFieldException(message, sql, getFile(), columnLabel);
     }
     
     /**
@@ -268,10 +229,10 @@ class MappedByteReader extends AbstractB
      * @return Field Descriptor.
      * @throws SQLIllegalColumnIndexException if the index is out of bounds.
      */
-    private FieldDescriptor getField(int columnIndex, String sql) throws SQLIllegalColumnIndexException {
+    private DBase3FieldDescriptor getField(int columnIndex, String sql) throws SQLIllegalColumnIndexException {
         if (columnIndex < 1 || columnIndex > getColumnCount()) {
             String message = format(Level.WARNING, "excp.illegal_column_index", columnIndex, getColumnCount());
-            throw new SQLIllegalColumnIndexException(message, sql, file, columnIndex);
+            throw new SQLIllegalColumnIndexException(message, sql, getFile(), columnIndex);
         }
         
         return m_fieldsDescriptors.get(columnIndex-1);

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/connection/DBFConnection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/connection/DBFConnection.java?rev=1649413&r1=1649412&r2=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/connection/DBFConnection.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/connection/DBFConnection.java [UTF-8] Sun Jan  4 20:36:47 2015
@@ -24,9 +24,7 @@ import java.util.*;
 import java.util.logging.Level;
 import java.util.stream.Collectors;
 
-import org.apache.sis.internal.shapefile.jdbc.ByteReader;
-import org.apache.sis.internal.shapefile.jdbc.FieldDescriptor;
-import org.apache.sis.internal.shapefile.jdbc.SQLConnectionClosedException;
+import org.apache.sis.internal.shapefile.jdbc.*;
 import org.apache.sis.internal.shapefile.jdbc.metadata.DBFDatabaseMetaData;
 import org.apache.sis.internal.shapefile.jdbc.resultset.*;
 import org.apache.sis.internal.shapefile.jdbc.statement.DBFStatement;
@@ -47,23 +45,23 @@ public class DBFConnection extends Abstr
     private HashSet<DBFStatement> m_openedStatements = new HashSet<>(); 
     
     /** ByteReader. */
-    private ByteReader m_byteReader;
+    private Dbase3ByteReader m_byteReader;
     
     /**
      * Constructs a connection to the given database.
      * @param datafile Data file ({@code .dbf} extension).
      * @param byteReader Byte reader to use for reading binary content.
-     * @throws SQLException if the Database file cannot be found or is not a file. 
+     * @throws DbaseFileNotFoundException if the Database file cannot be found or is not a file. 
      */
-    public DBFConnection(final File datafile, ByteReader byteReader) throws SQLException {
+    public DBFConnection(final File datafile, Dbase3ByteReader byteReader) throws DbaseFileNotFoundException {
         // Check that file exists.
         if (!datafile.exists()) {
-            throw new SQLException(format(Level.WARNING, "excp.file_not_found", datafile.getAbsolutePath()));
+            throw new DbaseFileNotFoundException(format(Level.WARNING, "excp.file_not_found", datafile.getAbsolutePath()));
         }
         
         // Check that its not a directory.
         if (datafile.isDirectory()) {
-            throw new SQLException(format(Level.WARNING, "excp.directory_not_expected", datafile.getAbsolutePath()));
+            throw new DbaseFileNotFoundException(format(Level.WARNING, "excp.directory_not_expected", datafile.getAbsolutePath()));
         }
         
        databaseFile = datafile;
@@ -75,7 +73,7 @@ public class DBFConnection extends Abstr
      * Closes the connection to the database.
      */
     @Override
-    public void close() throws SQLClosingIOFailureException {
+    public void close() {
         if (isClosed())
             return;
         
@@ -88,7 +86,7 @@ public class DBFConnection extends Abstr
             
             m_byteReader.close();
         } catch (IOException e) {
-            throw new SQLClosingIOFailureException(format(e.getLocalizedMessage(), e), null, getFile());
+            format(Level.FINE, e.getMessage(), e);
         }
     }
 
@@ -289,7 +287,7 @@ public class DBFConnection extends Abstr
      * Returns the fields descriptors in their binary format.
      * @return Fields descriptors.
      */
-    public List<FieldDescriptor> getFieldsDescriptors() {
+    public List<DBase3FieldDescriptor> getFieldsDescriptors() {
         return m_byteReader.getFieldsDescriptors();
     }
 

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/package-info.java?rev=1649413&r1=1649412&r2=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/package-info.java [UTF-8] Sun Jan  4 20:36:47 2015
@@ -16,9 +16,8 @@
  */
 
 /**
- * Allows access to {@link org.apache.sis.storage.shapefile} storage through JDBC driver.
- * Many exceptions are declared inside this package, to help trouble descriptions, allow easier JPA detections
- * and permit precise unit tests. 
+ * Allows access to the DBase3 part of a shapefile through JDBC driver.
+ * Many exceptions are declared inside this package, to help trouble descriptions and permit precise unit tests. 
  * @author  Marc Le Bihan
  * @version 0.5
  * @since   0.5

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFBuiltInMemoryResultSetForColumnsListing.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFBuiltInMemoryResultSetForColumnsListing.java?rev=1649413&r1=1649412&r2=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFBuiltInMemoryResultSetForColumnsListing.java (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFBuiltInMemoryResultSetForColumnsListing.java Sun Jan  4 20:36:47 2015
@@ -23,7 +23,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.logging.Level;
 
-import org.apache.sis.internal.shapefile.jdbc.FieldDescriptor;
+import org.apache.sis.internal.shapefile.jdbc.DBase3FieldDescriptor;
 import org.apache.sis.internal.shapefile.jdbc.statement.DBFStatement;
 
 /**
@@ -32,10 +32,10 @@ import org.apache.sis.internal.shapefile
  */
 public class DBFBuiltInMemoryResultSetForColumnsListing extends AbstractBuiltInMemoryResultSet {
     /** Current field descriptor. */
-    private FieldDescriptor m_current;
+    private DBase3FieldDescriptor m_current;
     
     /** Iterator. */
-    private Iterator<FieldDescriptor> m_it;
+    private Iterator<DBase3FieldDescriptor> m_it;
     
     /** Column index. */
     private int m_columnIndex;
@@ -48,7 +48,7 @@ public class DBFBuiltInMemoryResultSetFo
      * @param stmt Statement.
      * @param fieldsDescriptors Fields descriptors.
      */
-    public DBFBuiltInMemoryResultSetForColumnsListing(DBFStatement stmt, List<FieldDescriptor> fieldsDescriptors) {
+    public DBFBuiltInMemoryResultSetForColumnsListing(DBFStatement stmt, List<DBase3FieldDescriptor> fieldsDescriptors) {
         super(stmt, "driver list columns in this DBase 3 file");
         m_it = fieldsDescriptors.iterator();
     }

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFRecordBasedResultSet.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFRecordBasedResultSet.java?rev=1649413&r1=1649412&r2=1649413&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFRecordBasedResultSet.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/jdbc/resultset/DBFRecordBasedResultSet.java [UTF-8] Sun Jan  4 20:36:47 2015
@@ -6,6 +6,7 @@ import java.math.RoundingMode;
 import java.nio.charset.Charset;
 import java.sql.Date;
 import java.sql.ResultSetMetaData;
+import java.sql.SQLFeatureNotSupportedException;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.Map;
@@ -293,8 +294,82 @@ public class DBFRecordBasedResultSet ext
         DBFResultSetMataData meta = new DBFResultSetMataData(this); 
         return meta;
     }
+    
+    /**
+     * @see org.apache.sis.internal.shapefile.jdbc.resultset.AbstractUnimplementedFeaturesOfResultSet#getObject(int)
+     */
+    @Override 
+    public Object getObject(int column) throws SQLConnectionClosedException, SQLIllegalColumnIndexException, SQLFeatureNotSupportedException, SQLNoSuchFieldException, SQLNotNumericException, SQLNotDateException {
+        try(DBFBuiltInMemoryResultSetForColumnsListing field = (DBFBuiltInMemoryResultSetForColumnsListing)getFieldDesc(column, m_sql)) {
+            String fieldType;
+            
+            try
+            {
+                fieldType = field.getString("TYPE_NAME");
+            }
+            catch(SQLNoSuchFieldException e) {
+                // This is an internal trouble because the field type must be found.
+                throw new RuntimeException(e.getMessage(), e);
+            }
+            
+            switch(fieldType) {
+                case "AUTO_INCREMENT":
+                case "INTEGER":
+                    return getInt(column);
+                    
+                case "CHAR":
+                    return getString(column);
+                    
+                case "DATE":
+                    return getDate(column);
+                    
+                case "DOUBLE":
+                case "DECIMAL":
+                case "CURRENCY":
+                    return getDouble(column);
+                    
+                case "FLOAT":
+                    return getFloat(column);
+                    
+                case "BOOLEAN":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on Boolean");
+                    
+                case "DATETIME":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on DateTime");
+                    
+                case "TIMESTAMP":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on TimeStamp");
+                    
+                case "MEMO":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on Memo");
+                    
+                case "PICTURE":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on Picture");
+                    
+                case "VARIFIELD":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on VariField");
+                    
+                case "VARIANT":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on Variant");
+                    
+                case "UNKNOWN":
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on " + fieldType);
+                    
+                default:
+                    throw unsupportedOperation("ResultSetMetaData.getColumnClassName(..) on " + fieldType);
+            }            
+        }
+    }
 
     /**
+     * @see org.apache.sis.internal.shapefile.jdbc.resultset.AbstractResultSet#getObject(java.lang.String)
+     */
+    @Override 
+    public Object getObject(String columnLabel) throws SQLConnectionClosedException, SQLIllegalColumnIndexException, SQLFeatureNotSupportedException, SQLNoSuchFieldException, SQLNotNumericException, SQLNotDateException {
+        return getObject(findColumn(columnLabel));
+    }
+    
+    /**
      * @see java.sql.ResultSet#getShort(java.lang.String)
      * @throws SQLConnectionClosedException if the connection is closed.
      * @throws SQLNoSuchFieldException if the field looked for doesn't exist.

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/package-info.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/package-info.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/package-info.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+/**
+ * Function to describe and access to {@link org.apache.sis.storage.shapefile}.
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+package org.apache.sis.internal.shapefile;

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/InputFeatureStream.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/InputFeatureStream.java?rev=1649413&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/InputFeatureStream.java (added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/InputFeatureStream.java Sun Jan  4 20:36:47 2015
@@ -0,0 +1,187 @@
+/*
+ * 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.shapefile;
+
+import java.io.File;
+import java.io.InputStream;
+import java.sql.SQLFeatureNotSupportedException;
+import java.text.MessageFormat;
+
+import org.apache.sis.feature.DefaultFeatureType;
+import org.apache.sis.internal.shapefile.InvalidShapefileFormatException;
+import org.apache.sis.internal.shapefile.ShapefileByteReader;
+import org.apache.sis.internal.shapefile.ShapefileNotFoundException;
+import org.apache.sis.internal.shapefile.jdbc.*;
+import org.apache.sis.internal.shapefile.jdbc.connection.DBFConnection;
+import org.apache.sis.internal.shapefile.jdbc.metadata.DBFDatabaseMetaData;
+import org.apache.sis.internal.shapefile.jdbc.resultset.*;
+import org.apache.sis.internal.shapefile.jdbc.sql.SQLIllegalParameterException;
+import org.apache.sis.internal.shapefile.jdbc.sql.SQLInvalidStatementException;
+import org.apache.sis.internal.shapefile.jdbc.sql.SQLUnsupportedParsingFeatureException;
+import org.apache.sis.internal.shapefile.jdbc.statement.DBFStatement;
+import org.opengis.feature.Feature;
+
+/**
+ * Input Stream of features.
+ *
+ * @author  Marc Le Bihan
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+public class InputFeatureStream extends InputStream {
+    /** Dedicated connection to DBF. */
+    private DBFConnection m_connection;
+    
+    /** Statement. */
+    private DBFStatement m_stmt;
+    
+    /** ResultSet. */
+    private DBFRecordBasedResultSet m_rs;
+    
+    /** SQL Statement executed. */
+    private String m_sql;
+    
+    /** Marks the end of file. */
+    private boolean m_endOfFile;
+    
+    /** Shapefile. */
+    private File m_shapefile;
+    
+    /** Database file. */
+    private File m_databaseFile;
+
+    /** Type of the features contained in this shapefile. */
+    private DefaultFeatureType m_featuresType;
+    
+    /** Shapefile reader. */
+    private ShapefileByteReader m_shapefileReader;
+
+    /**
+     * Create an input stream of features over a connection.
+     * @param shapefile Shapefile.
+     * @param dbaseFile Database file.
+     * @throws SQLInvalidStatementException if the given SQL Statement is invalid.
+     * @throws InvalidShapefileFormatException if the shapefile format is invalid. 
+     * @throws InvalidDbaseFileFormatException if the Dbase file format is invalid.
+     * @throws ShapefileNotFoundException if the shapefile has not been found.
+     * @throws DbaseFileNotFoundException if the database file has not been found.
+     */
+    public InputFeatureStream(File shapefile, File dbaseFile) throws SQLInvalidStatementException, InvalidDbaseFileFormatException, InvalidShapefileFormatException, ShapefileNotFoundException, DbaseFileNotFoundException {
+        m_connection = (DBFConnection)new DBFDriver().connect(dbaseFile.getAbsolutePath(), null);
+        m_sql = MessageFormat.format("SELECT * FROM {0}", dbaseFile.getName());
+        m_shapefile = shapefile;
+        m_databaseFile = dbaseFile;
+        
+        m_shapefileReader = new ShapefileByteReader(m_shapefile, m_databaseFile);
+        m_featuresType = m_shapefileReader.getFeaturesType(); 
+        
+        try {
+            executeQuery();
+        }
+        catch(SQLConnectionClosedException e) {
+            // This would be an internal trouble because in this function (at least) it should be open.
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+    
+    /**
+     * @see java.io.InputStream#read()
+     */
+    @Override
+    public int read() {
+        throw new UnsupportedOperationException("InputFeatureStream doesn't allow the use of read(). Use readFeature() instead.");
+    }
+
+    /**
+     * @see java.io.InputStream#available()
+     */
+    @Override 
+    public int available() {
+        throw new UnsupportedOperationException("InputFeatureStream doesn't allow the use of available(). Use readFeature() will return null when feature are no more available.");
+    }
+    
+    /**
+     * @see java.io.InputStream#close()
+     */
+    @Override 
+    public void close() {
+        m_rs.close();
+        m_stmt.close();
+        m_connection.close();
+    }
+    
+    /**
+     * Read next feature responding to the SQL request.
+     * @return Feature, null if no more feature is available.
+     * @throws SQLNotNumericException if a field expected numeric isn't. 
+     * @throws SQLNotDateException if a field expected of date kind, isn't.
+     * @throws SQLNoSuchFieldException if a field doesn't exist.
+     * @throws SQLIllegalParameterException if a parameter is illegal in the query.
+     * @throws SQLInvalidStatementException if the SQL statement is invalid.
+     * @throws SQLConnectionClosedException if the connection is closed.
+     * @throws SQLUnsupportedParsingFeatureException if a SQL ability is not currently available through this driver.
+     * @throws SQLIllegalColumnIndexException if a column index is illegal.
+     * @throws SQLFeatureNotSupportedException if a SQL ability is not currently available through this driver.
+     * @throws InvalidShapefileFormatException if the shapefile format is invalid.
+     */
+    public Feature readFeature() throws SQLConnectionClosedException, SQLInvalidStatementException, SQLIllegalParameterException, SQLNoSuchFieldException, SQLUnsupportedParsingFeatureException, SQLNotNumericException, SQLNotDateException, SQLFeatureNotSupportedException, SQLIllegalColumnIndexException, InvalidShapefileFormatException {
+        try {
+            if (m_endOfFile == false) {
+                m_endOfFile = true;
+                return null;
+            }
+            
+            if (m_rs.next() == false) {
+                m_endOfFile = true;
+                return null;
+            }
+            
+            Feature feature = m_featuresType.newInstance();
+            m_shapefileReader.completeFeature(feature);
+            DBFDatabaseMetaData metadata = (DBFDatabaseMetaData)m_connection.getMetaData();
+            
+            try(DBFBuiltInMemoryResultSetForColumnsListing rsDatabase = (DBFBuiltInMemoryResultSetForColumnsListing)metadata.getColumns(null, null, null, null)) {
+                while(rsDatabase.next()) {
+                    String fieldName = rsDatabase.getString("COLUMN_NAME");
+                    Object fieldValue = m_rs.getObject(fieldName);
+                    feature.setPropertyValue(fieldName, fieldValue);
+                }
+                
+                return feature;
+            }
+            catch(SQLNoResultException e) {
+                // This an internal trouble, if it occurs.
+                throw new RuntimeException(e.getMessage(), e);
+            }
+        }
+        catch(SQLNoResultException e) {
+            // We are trying to prevent this. If it occurs, we have an internal problem.
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * Execute the wished SQL query.
+     * @throws SQLConnectionClosedException if the connection is closed. 
+     * @throws SQLInvalidStatementException if the given SQL Statement is invalid.
+     */
+    private void executeQuery() throws SQLConnectionClosedException, SQLInvalidStatementException {
+        m_stmt = (DBFStatement)m_connection.createStatement(); 
+        m_rs = (DBFRecordBasedResultSet)m_stmt.executeQuery(m_sql);
+    }
+}



Mime
View raw message