This is an automated email from the ASF dual-hosted git repository.

jsorel pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 0c561c5971 feat(Shapefile): add DBF writer and test case
0c561c5971 is described below

commit 0c561c5971ed787316a48dc824101960af97a9bb
Author: jsorel <[email protected]>
AuthorDate: Mon Nov 20 11:29:51 2023 +0100

    feat(Shapefile): add DBF writer and test case
---
 .../apache/sis/storage/shapefile/dbf/DBFField.java | 32 ++++++++--
 .../sis/storage/shapefile/dbf/DBFFieldEncoder.java | 59 +++++++++++++++---
 .../sis/storage/shapefile/dbf/DBFHeader.java       | 49 ++++++++++++++-
 .../sis/storage/shapefile/dbf/DBFReader.java       |  9 ++-
 .../sis/storage/shapefile/dbf/DBFWriter.java       | 71 ++++++++++++++++++++++
 .../sis/storage/shapefile/dbf/DBFIOTest.java       | 67 ++++++++++++++++++--
 .../sis/storage/shapefile/shp/ShapeIOTest.java     | 16 ++---
 7 files changed, 273 insertions(+), 30 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFField.java
 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFField.java
index ca630ec6cb..308eaef438 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFField.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFField.java
@@ -18,9 +18,9 @@ package org.apache.sis.storage.shapefile.dbf;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
-import java.util.Date;
+import java.nio.charset.StandardCharsets;
 import org.apache.sis.io.stream.ChannelDataInput;
-import org.apache.sis.util.ArraysExt;
+import org.apache.sis.io.stream.ChannelDataOutput;
 
 
 /**
@@ -81,20 +81,32 @@ public final class DBFField {
     public static final int TYPE_OLE = 'g';
 
     public String fieldName;
-    public int fieldType;
+    public char fieldType;
     public int fieldAddress;
     public int fieldLength;
     public int fieldLDecimals;
 
     private DBFFieldEncoder encoder;
 
+    public DBFField() {
+    }
+
+    public DBFField(DBFField toCopy) {
+        this.fieldName = toCopy.fieldName;
+        this.fieldType = toCopy.fieldType;
+        this.fieldAddress = toCopy.fieldAddress;
+        this.fieldLength = toCopy.fieldLength;
+        this.fieldLDecimals = toCopy.fieldLDecimals;
+        this.encoder = toCopy.encoder;
+    }
+
     public void read(ChannelDataInput channel, Charset charset) throws 
IOException {
         byte[] n = channel.readBytes(11);
         int nameSize = 0;
         for (int i = 0; i < n.length && n[i] != 0; i++,nameSize++);
 
         fieldName      = new String(n, 0, nameSize);
-        fieldType      = 
Character.valueOf(((char)channel.readUnsignedByte())).toString().toLowerCase().charAt(0);
+        fieldType      = 
Character.valueOf(((char)channel.readUnsignedByte())).toString().charAt(0);
         fieldAddress   = channel.readInt();
         fieldLength    = channel.readUnsignedByte();
         fieldLDecimals = channel.readUnsignedByte();
@@ -103,6 +115,18 @@ public final class DBFField {
         encoder = DBFFieldEncoder.getEncoder(fieldType, fieldLength, 
fieldLDecimals, charset);
     }
 
+    public void write(ChannelDataOutput channel) throws IOException {
+        byte[] bytes = fieldName.getBytes(StandardCharsets.US_ASCII);
+        if (bytes.length > 11) throw new IOException("Field name length must 
not be longer then 11 characters.");
+        channel.write(bytes);
+        channel.repeat(11 - bytes.length, (byte) 0);
+        channel.writeByte(fieldType);
+        channel.writeInt(fieldAddress);
+        channel.writeByte(fieldLength);
+        channel.writeByte(fieldLDecimals);
+        channel.repeat(14, (byte) 0);
+    }
+
     public DBFFieldEncoder getEncoder() {
         return encoder;
     }
diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFFieldEncoder.java
 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFFieldEncoder.java
index 63d0b3237e..bef9167aa5 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFFieldEncoder.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFFieldEncoder.java
@@ -18,7 +18,10 @@ package org.apache.sis.storage.shapefile.dbf;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.text.NumberFormat;
 import java.time.LocalDate;
+import java.util.Locale;
 import org.apache.sis.io.stream.ChannelDataInput;
 import org.apache.sis.io.stream.ChannelDataOutput;
 import static org.apache.sis.storage.shapefile.dbf.DBFField.*;
@@ -29,8 +32,8 @@ import static org.apache.sis.storage.shapefile.dbf.DBFField.*;
  */
 public abstract class DBFFieldEncoder {
 
-    public static DBFFieldEncoder getEncoder(int fieldType, int fieldLength, 
int fieldDecimals, Charset charset) {
-        switch (fieldType) {
+    public static DBFFieldEncoder getEncoder(char fieldType, int fieldLength, 
int fieldDecimals, Charset charset) {
+        switch (Character.toLowerCase(fieldType)) {
             case TYPE_BINARY : return new Binary(fieldLength, fieldDecimals);
             case TYPE_CHAR : return new Char(fieldLength, fieldDecimals, 
charset);
             case TYPE_DATE : return new Date(fieldLength, fieldDecimals);
@@ -104,7 +107,14 @@ public abstract class DBFFieldEncoder {
 
         @Override
         public void write(ChannelDataOutput channel, Object value) throws 
IOException {
-            throw new UnsupportedOperationException("Not supported yet.");
+            final String txt = (String) value;
+            final byte[] bytes = txt.getBytes(charset);
+            if (bytes.length >= fieldLength) {
+                channel.write(bytes, 0, fieldLength);
+            } else {
+                channel.write(bytes);
+                channel.repeat(fieldLength - bytes.length, (byte)' ');
+            }
         }
     }
 
@@ -125,7 +135,23 @@ public abstract class DBFFieldEncoder {
 
         @Override
         public void write(ChannelDataOutput channel, Object value) throws 
IOException {
-            throw new UnsupportedOperationException("Not supported yet.");
+            final LocalDate date = (LocalDate) value;
+            final StringBuilder sb = new StringBuilder();
+            String year = Integer.toString(date.getYear());
+            String month = Integer.toString(date.getMonthValue());
+            String day = Integer.toString(date.getDayOfMonth());
+            switch (year.length()) {
+                case 1: sb.append("000"); break;
+                case 2: sb.append("00"); break;
+                case 3: sb.append("0"); break;
+            }
+            sb.append(year);
+            if(month.length() < 2) sb.append("0");
+            sb.append(month);
+            if(day.length() < 2) sb.append("0");
+            sb.append(day);
+            channel.repeat(fieldLength - sb.length(), (byte)' ');
+            channel.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
         }
     }
 
@@ -144,7 +170,13 @@ public abstract class DBFFieldEncoder {
 
         @Override
         public void write(ChannelDataOutput channel, Object value) throws 
IOException {
-            throw new UnsupportedOperationException("Not supported yet.");
+            final String v = ((Integer) value).toString();
+            final int length = v.length();
+            if (length > fieldLength) {
+                throw new IOException(v + " is longer then field length " + 
fieldLength);
+            }
+            channel.repeat(fieldLength - length, (byte)' ');
+            channel.write(v.getBytes(StandardCharsets.US_ASCII));
         }
     }
 
@@ -163,14 +195,23 @@ public abstract class DBFFieldEncoder {
 
         @Override
         public void write(ChannelDataOutput channel, Object value) throws 
IOException {
-            throw new UnsupportedOperationException("Not supported yet.");
+            final String v = ((Long) value).toString();
+            final int length = v.length();
+            if (length > fieldLength) {
+                throw new IOException(v + " is longer then field length " + 
fieldLength);
+            }
+            channel.repeat(fieldLength - length, (byte)' ');
+            channel.write(v.getBytes(StandardCharsets.US_ASCII));
         }
     }
 
     private static final class Decimal extends DBFFieldEncoder {
+        private final NumberFormat format = 
NumberFormat.getNumberInstance(Locale.US);
 
         public Decimal(int fieldLength, int fieldDecimals) {
             super(Double.class, fieldLength, fieldDecimals);
+            format.setMaximumFractionDigits(fieldDecimals);
+            format.setMinimumFractionDigits(fieldDecimals);
         }
 
         @Override
@@ -182,7 +223,11 @@ public abstract class DBFFieldEncoder {
 
         @Override
         public void write(ChannelDataOutput channel, Object value) throws 
IOException {
-            throw new UnsupportedOperationException("Not supported yet.");
+            final Number v = ((Number) value);
+            final String str =format.format(v.doubleValue());
+            final int length = str.length();
+            channel.repeat(fieldLength - length, (byte)' ');
+            channel.write(str.getBytes(StandardCharsets.US_ASCII));
         }
     }
 
diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFHeader.java
 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFHeader.java
index bbe3c8b475..67c95ec025 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFHeader.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFHeader.java
@@ -21,6 +21,7 @@ import java.nio.ByteOrder;
 import java.nio.charset.Charset;
 
 import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.ChannelDataOutput;
 
 /**
  *
@@ -29,6 +30,7 @@ import org.apache.sis.io.stream.ChannelDataInput;
 public final class DBFHeader {
 
     private static final int FIELD_SIZE = 32;
+    private static final int FIELD_DESCRIPTOR_TERMINATOR = 0x0D;
 
     public int year;
     public int month;
@@ -38,6 +40,33 @@ public final class DBFHeader {
     public int recordSize;
     public DBFField[] fields;
 
+    public DBFHeader() {
+    }
+
+    public DBFHeader(DBFHeader toCopy) {
+        this.year = toCopy.year;
+        this.month = toCopy.month;
+        this.day = toCopy.day;
+        this.nbRecord = toCopy.nbRecord;
+        this.headerSize = toCopy.headerSize;
+        this.recordSize = toCopy.recordSize;
+        this.fields = new DBFField[toCopy.fields.length];
+        for (int i = 0; i < this.fields.length; i++) {
+            this.fields[i] = new DBFField(toCopy.fields[i]);
+        }
+    }
+
+    /**
+     * Compute and update header size and record size.
+     */
+    public void updateSizes() {
+        headerSize = 32 + FIELD_SIZE * fields.length + 1;
+        recordSize = 1; //record state tag
+        for (DBFField field : fields) {
+            recordSize += field.fieldLength;
+        }
+    }
+
     public void read(ChannelDataInput channel, Charset charset) throws 
IOException {
         channel.buffer.order(ByteOrder.LITTLE_ENDIAN);
         if (channel.readByte()!= 0x03) {
@@ -56,7 +85,25 @@ public final class DBFHeader {
             fields[i] = new DBFField();
             fields[i].read(channel, charset);
         }
-        channel.skipBytes(1);
+        if (channel.readByte()!= FIELD_DESCRIPTOR_TERMINATOR) {
+            throw new IOException("Unvalid database III field descriptor 
terminator");
+        }
+    }
+
+    public void write(ChannelDataOutput channel) throws IOException {
+        channel.buffer.order(ByteOrder.LITTLE_ENDIAN);
+        channel.writeByte(0x03);
+        channel.writeByte(year);
+        channel.writeByte(month);
+        channel.writeByte(day);
+        channel.writeInt(nbRecord);
+        channel.writeShort(headerSize);
+        channel.writeShort(recordSize);
+        channel.repeat(20, (byte)0);
+        for (int i = 0; i < fields.length; i++) {
+            fields[i].write(channel);
+        }
+        channel.writeByte(FIELD_DESCRIPTOR_TERMINATOR);
     }
 
     @Override
diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFReader.java
 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFReader.java
index 3c235ec263..4f61f8456f 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFReader.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFReader.java
@@ -28,8 +28,9 @@ import org.apache.sis.io.stream.ChannelDataInput;
  */
 public final class DBFReader implements AutoCloseable {
 
-    private static final int TAG_PRESENT = 0x20;
-    private static final int TAG_DELETED = 0x2a;
+    static final int TAG_PRESENT = 0x20;
+    static final int TAG_DELETED = 0x2a;
+    static final int TAG_EOF = 0x1A;
 
     private final ChannelDataInput channel;
     private final DBFHeader header;
@@ -64,6 +65,8 @@ public final class DBFReader implements AutoCloseable {
     public DBFRecord next() throws IOException {
         if (nbRead >= header.nbRecord) {
             //reached records end
+            //we do not trust the EOF if we already have the expected count
+            //some writes do not have it
             return null;
         }
         nbRead++;
@@ -72,6 +75,8 @@ public final class DBFReader implements AutoCloseable {
         if (marker == TAG_DELETED) {
             channel.skipBytes(header.recordSize);
             return DBFRecord.DELETED;
+        } else if (marker == TAG_EOF) {
+            return null;
         } else if (marker != TAG_PRESENT) {
             throw new IOException("Unexpected record marker " + marker);
         }
diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFWriter.java
 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFWriter.java
new file mode 100644
index 0000000000..b5b8ba507e
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFWriter.java
@@ -0,0 +1,71 @@
+/*
+ * 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.dbf;
+
+import java.io.IOException;
+import java.nio.ByteOrder;
+import org.apache.sis.io.stream.ChannelDataOutput;
+
+/**
+ * DBF writer.
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class DBFWriter implements AutoCloseable{
+
+    private final ChannelDataOutput channel;
+    private int writtenNbRecord = 0 ;
+    private DBFHeader header;
+
+    public DBFWriter(ChannelDataOutput channel) {
+        this.channel = channel;
+    }
+
+    public void write(DBFHeader header) throws IOException {
+        this.header = new DBFHeader(header);
+        this.header.updateSizes(); //recompute sizes
+        this.header.nbRecord = 0; //force to zero, will be replaced when 
closing writer.
+        this.header.write(channel);
+    }
+
+    public void write(DBFRecord record) throws IOException {
+        channel.writeByte(DBFReader.TAG_PRESENT);
+        for (int i = 0; i < header.fields.length; i++) {
+            header.fields[i].getEncoder().write(channel, record.fields[i]);
+        }
+        writtenNbRecord++;
+    }
+
+    public void flush() throws IOException {
+        channel.writeByte(DBFReader.TAG_EOF);
+        channel.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        flush();
+
+        //update the nbRecord in the header
+        channel.seek(4);
+        channel.buffer.order(ByteOrder.LITTLE_ENDIAN);
+        channel.writeInt(writtenNbRecord);
+        channel.flush();
+
+        channel.channel.close();
+    }
+
+}
diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/dbf/DBFIOTest.java
 
b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/dbf/DBFIOTest.java
index 4a822860f8..45f3b5b132 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/dbf/DBFIOTest.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/dbf/DBFIOTest.java
@@ -17,10 +17,20 @@
 package org.apache.sis.storage.shapefile.dbf;
 
 import java.io.IOException;
+import java.net.URISyntaxException;
 import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
 import java.time.LocalDate;
 import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.ChannelDataOutput;
+import org.apache.sis.setup.OptionKey;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
 import org.junit.Test;
@@ -40,8 +50,16 @@ public class DBFIOTest {
         return cdi;
     }
 
+    private ChannelDataOutput openWrite(Path path) throws DataStoreException, 
IOException {
+        final StorageConnector cnx = new StorageConnector(path);
+        cnx.setOption(OptionKey.OPEN_OPTIONS, new 
OpenOption[]{StandardOpenOption.WRITE, StandardOpenOption.CREATE, 
StandardOpenOption.TRUNCATE_EXISTING});
+        final ChannelDataOutput cdo = 
cnx.getStorageAs(ChannelDataOutput.class);
+        cnx.closeAllExcept(cdo);
+        return cdo;
+    }
+
     @Test
-    public void readTest() throws DataStoreException, IOException {
+    public void readTest() throws DataStoreException, IOException, 
URISyntaxException {
         final String path = "/org/apache/sis/storage/shapefile/point.dbf";
         final ChannelDataInput cdi = openRead(path);
 
@@ -55,27 +73,27 @@ public class DBFIOTest {
             assertEquals(120, header.recordSize);
             assertEquals(5, header.fields.length);
             assertEquals("id", header.fields[0].fieldName);
-            assertEquals(110,  header.fields[0].fieldType);
+            assertEquals(78,  header.fields[0].fieldType);
             assertEquals(0,    header.fields[0].fieldAddress);
             assertEquals(10,   header.fields[0].fieldLength);
             assertEquals(0,    header.fields[0].fieldLDecimals);
             assertEquals("text", header.fields[1].fieldName);
-            assertEquals(99,  header.fields[1].fieldType);
+            assertEquals(67,  header.fields[1].fieldType);
             assertEquals(0,    header.fields[1].fieldAddress);
             assertEquals(80,   header.fields[1].fieldLength);
             assertEquals(0,    header.fields[1].fieldLDecimals);
             assertEquals("integer", header.fields[2].fieldName);
-            assertEquals(110,  header.fields[2].fieldType);
+            assertEquals(78,  header.fields[2].fieldType);
             assertEquals(0,    header.fields[2].fieldAddress);
             assertEquals(10,   header.fields[2].fieldLength);
             assertEquals(0,    header.fields[2].fieldLDecimals);
             assertEquals("float", header.fields[3].fieldName);
-            assertEquals(110,  header.fields[3].fieldType);
+            assertEquals(78,  header.fields[3].fieldType);
             assertEquals(0,    header.fields[3].fieldAddress);
             assertEquals(11,   header.fields[3].fieldLength);
             assertEquals(6,    header.fields[3].fieldLDecimals);
             assertEquals("date", header.fields[4].fieldName);
-            assertEquals(100,  header.fields[4].fieldType);
+            assertEquals(68,  header.fields[4].fieldType);
             assertEquals(0,    header.fields[4].fieldAddress);
             assertEquals(8,   header.fields[4].fieldLength);
             assertEquals(0,    header.fields[4].fieldLDecimals);
@@ -100,6 +118,43 @@ public class DBFIOTest {
         }
     }
 
+    @Test
+    public void writeTest() throws DataStoreException, IOException, 
URISyntaxException {
+        final String path = "/org/apache/sis/storage/shapefile/point.dbf";
+        testReadAndWrite(path);
+    }
+
+    /**
+     * Open given dbf, read it and write it to another file the compare them.
+     * They must be identical.
+     */
+    private void testReadAndWrite(String path) throws DataStoreException, 
IOException, URISyntaxException {
+        final ChannelDataInput cdi = openRead(path);
+
+        final Path tempFile = Files.createTempFile("tmp", ".dbf");
+        final ChannelDataOutput cdo = openWrite(tempFile);
+
+        try {
+            try (DBFReader reader = new DBFReader(cdi, 
StandardCharsets.US_ASCII, null);
+                 DBFWriter writer = new DBFWriter(cdo)) {
+
+                writer.write(reader.getHeader());
+
+                for (DBFRecord record = reader.next(); record != null; record 
= reader.next()) {
+                    writer.write(record);
+                }
+            }
+
+            //compare files
+            final byte[] expected = 
Files.readAllBytes(Paths.get(DBFIOTest.class.getResource(path).toURI()));
+            final byte[] result = Files.readAllBytes(tempFile);
+            assertArrayEquals(expected, result);
+
+        } finally {
+            Files.deleteIfExists(tempFile);
+        }
+    }
+
     /**
      * Test reading only selected fields.
      */
diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/shp/ShapeIOTest.java
 
b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/shp/ShapeIOTest.java
index eaec0af3d4..8f41edd0a4 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/shp/ShapeIOTest.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/shp/ShapeIOTest.java
@@ -18,6 +18,8 @@ package org.apache.sis.storage.shapefile.shp;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
+
+import org.apache.sis.setup.OptionKey;
 import org.junit.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.io.stream.ChannelDataInput;
@@ -26,10 +28,8 @@ import org.apache.sis.storage.StorageConnector;
 import java.net.URL;
 import java.nio.ByteBuffer;
 import java.nio.channels.WritableByteChannel;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
+import java.nio.file.*;
+
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.io.stream.ChannelDataOutput;
 import org.apache.sis.referencing.CommonCRS;
@@ -58,12 +58,8 @@ public class ShapeIOTest {
     }
 
     private ChannelDataOutput openWrite(Path path) throws DataStoreException, 
IOException {
-        if (true) {
-            //bypass a bug in StorageConnector
-            WritableByteChannel wbc = Files.newByteChannel(path, 
StandardOpenOption.WRITE);
-            return new ChannelDataOutput("", wbc, ByteBuffer.allocate(8000));
-        }
         final StorageConnector cnx = new StorageConnector(path);
+        cnx.setOption(OptionKey.OPEN_OPTIONS, new 
OpenOption[]{StandardOpenOption.WRITE, StandardOpenOption.CREATE, 
StandardOpenOption.TRUNCATE_EXISTING});
         final ChannelDataOutput cdo = 
cnx.getStorageAs(ChannelDataOutput.class);
         cnx.closeAllExcept(cdo);
         return cdo;
@@ -73,7 +69,7 @@ public class ShapeIOTest {
      * Open given shape file, read it and write it to another file the compare 
them.
      * They must be identical.
      */
-    private void testReadAndWrite(String path) throws DataStoreException, 
IOException, URISyntaxException, URISyntaxException {
+    private void testReadAndWrite(String path) throws DataStoreException, 
IOException, URISyntaxException {
         final ChannelDataInput cdi = openRead(path);
 
         final Path tempFile = Files.createTempFile("tmp", ".shp");

Reply via email to