Copilot commented on code in PR #9526:
URL: https://github.com/apache/seatunnel/pull/9526#discussion_r2178853151


##########
seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/reader/AbstractReadStrategy.java:
##########
@@ -45,8 +45,13 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigDecimal;
+import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;

Review Comment:
   The imports for `LocalDate` and `LocalDateTime` are unused and can be 
removed to clean up the code.
   ```suggestion
   
   ```



##########
seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/reader/AbstractReadStrategy.java:
##########
@@ -145,6 +155,50 @@ public List<String> getFileNamesByPath(String path) throws 
IOException {
         return fileNames;
     }
 
+    private boolean filterFileByModificationDate(FileStatus fileStatus) {
+
+        Instant fileModifiedDate = 
Instant.ofEpochMilli(fileStatus.getModificationTime());
+
+        DateTimeFormatter formatter =
+                
DateTimeFormatter.ofPattern(modifiedDateFormat).withZone(ZoneId.of("GMT+8"));
+

Review Comment:
   If `modifiedDateFormat` is null or unset, `ofPattern` will throw a 
NullPointerException. Either default `modifiedDateFormat` or guard against null 
before creating the formatter.
   ```suggestion
           if (StringUtils.isEmpty(modifiedDateFormat)) {
               modifiedDateFormat = "yyyy-MM-dd"; // Default date format
           }
           DateTimeFormatter formatter =
                   
DateTimeFormatter.ofPattern(modifiedDateFormat).withZone(ZoneId.of("GMT+8"));
   ```



##########
seatunnel-connectors-v2/connector-file/connector-file-base/src/test/java/org/apache/seatunnel/connectors/seatunnel/file/source/reader/AbstractReadStrategyTest.java:
##########
@@ -131,4 +144,97 @@ public static void deleteFile(String file) {
             }
         }
     }
+
+    @BeforeEach
+    void setUp() throws Exception {
+        strategy = new CsvReadStrategy();
+        filterMethod =
+                AbstractReadStrategy.class.getDeclaredMethod(
+                        "filterFileByModificationDate", FileStatus.class);
+        filterMethod.setAccessible(true);
+    }
+
+    @AfterEach
+    void tearDown() {
+        strategy = null;
+        filterMethod = null;
+    }
+
+    @Test
+    void testBothStartAndEndWithinRange() throws Exception {
+        try (MockedStatic<LocalDate> localDateMockedStatic = 
mockStatic(LocalDate.class)) {
+
+            String startDateStr = "2024-01-01";
+            String endDateStr = "2024-12-31";
+            String format = "yyyy-MM-dd";
+
+            strategy.fileModifiedStartDate = startDateStr;
+            strategy.fileModifiedEndDate = endDateStr;
+            strategy.modifiedDateFormat = format;
+
+            long modificationTime = 
Instant.parse("2024-06-01T00:00:00Z").toEpochMilli();
+
+            FileStatus mockFileStatus = mock(FileStatus.class);
+            
when(mockFileStatus.getModificationTime()).thenReturn(modificationTime);
+
+            Boolean result = (Boolean) filterMethod.invoke(strategy, 
mockFileStatus);
+
+            Assertions.assertTrue(result);
+        }
+    }
+
+    @Test
+    void testOnlyEndDateOutOfRange() throws Exception {
+        try (MockedStatic<LocalDate> localDateMockedStatic = 
mockStatic(LocalDate.class)) {
+            String endDateStr = "2024-07-01";
+            String format = "yyyy-MM-dd";
+
+            strategy.fileModifiedStartDate = null;
+            strategy.fileModifiedEndDate = endDateStr;
+            strategy.modifiedDateFormat = format;
+
+            long modificationTime = 
Instant.parse("2024-06-01T00:00:00Z").toEpochMilli();
+
+            FileStatus mockFileStatus = mock(FileStatus.class);
+            
when(mockFileStatus.getModificationTime()).thenReturn(modificationTime);
+
+            Boolean result = (Boolean) filterMethod.invoke(strategy, 
mockFileStatus);
+
+            Assertions.assertTrue(result);
+        }

Review Comment:
   [nitpick] Mocking `LocalDate` is unnecessary since the code under test 
doesn't use it; remove this static mock to simplify tests.
   ```suggestion
           String startDateStr = "2024-01-01";
           String endDateStr = "2024-12-31";
           String format = "yyyy-MM-dd";
   
           strategy.fileModifiedStartDate = startDateStr;
           strategy.fileModifiedEndDate = endDateStr;
           strategy.modifiedDateFormat = format;
   
           long modificationTime = 
Instant.parse("2024-06-01T00:00:00Z").toEpochMilli();
   
           FileStatus mockFileStatus = mock(FileStatus.class);
           
when(mockFileStatus.getModificationTime()).thenReturn(modificationTime);
   
           Boolean result = (Boolean) filterMethod.invoke(strategy, 
mockFileStatus);
   
           Assertions.assertTrue(result);
       }
   
       @Test
       void testOnlyEndDateOutOfRange() throws Exception {
           String endDateStr = "2024-07-01";
           String format = "yyyy-MM-dd";
   
           strategy.fileModifiedStartDate = null;
           strategy.fileModifiedEndDate = endDateStr;
           strategy.modifiedDateFormat = format;
   
           long modificationTime = 
Instant.parse("2024-06-01T00:00:00Z").toEpochMilli();
   
           FileStatus mockFileStatus = mock(FileStatus.class);
           
when(mockFileStatus.getModificationTime()).thenReturn(modificationTime);
   
           Boolean result = (Boolean) filterMethod.invoke(strategy, 
mockFileStatus);
   
           Assertions.assertTrue(result);
   ```



##########
seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/reader/AbstractReadStrategy.java:
##########
@@ -145,6 +155,50 @@ public List<String> getFileNamesByPath(String path) throws 
IOException {
         return fileNames;
     }
 
+    private boolean filterFileByModificationDate(FileStatus fileStatus) {
+
+        Instant fileModifiedDate = 
Instant.ofEpochMilli(fileStatus.getModificationTime());
+
+        DateTimeFormatter formatter =
+                
DateTimeFormatter.ofPattern(modifiedDateFormat).withZone(ZoneId.of("GMT+8"));
+
+        Instant startDate = parseDateToInstant(fileModifiedStartDate, 
formatter);
+        Instant endDate = parseDateToInstant(fileModifiedEndDate, formatter);
+
+        // Both start and end date are set
+        if (startDate != null && endDate != null) {
+            return !fileModifiedDate.isBefore(startDate) && 
!fileModifiedDate.isAfter(endDate);
+        }
+
+        // Only start date is set
+        if (startDate != null) {
+            return !fileModifiedDate.isBefore(startDate);
+        }
+
+        // Only end date is set
+        if (endDate != null) {
+            return !fileModifiedDate.isAfter(endDate);
+        }
+
+        // Neither start nor end date is set
+        return true;
+    }
+
+    private Instant parseDateToInstant(String dateTime, DateTimeFormatter 
dateTimeFormatter) {
+        if (dateTime == null || dateTime.isEmpty()) {
+            return null;
+        }
+        try {
+
+            TemporalAccessor temporal = dateTimeFormatter.parse(dateTime);
+
+            return Instant.from(temporal);
+        } catch (DateTimeParseException e) {
+            // no throw exception

Review Comment:
   [nitpick] Silently catching parse exceptions may mask configuration errors. 
Consider logging a warning or surfacing an error when a date fails to parse.
   ```suggestion
               log.warn("Failed to parse date '{}' with format '{}'. Returning 
null.", dateTime, dateTimeFormatter, e);
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to