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

apupier pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 7ecda889d52e CAMEL-25218: camel-jsonpath - read a remote file with a 
charset instead of failing with ClassCastException
7ecda889d52e is described below

commit 7ecda889d52e3559961bf4ed342ce6d7627f3b4b
Author: smjain <[email protected]>
AuthorDate: Wed Sep 30 16:21:51 2026 +0530

    CAMEL-25218: camel-jsonpath - read a remote file with a charset instead of 
failing with ClassCastException
    
    When the message body is a GenericFile with a charset, JsonPathEngine
    opened it with new FileInputStream((File) genericFile.getFile()). The ftp
    and ftps consumers set the endpoint charset on their RemoteFile, whose file
    is an FTPFile, so every jsonpath expression on such a message failed with
    a ClassCastException.
    
    A java.io.File is still read directly; any other generic file is read
    through the GenericFile type converter (the downloaded content), and both
    are parsed in the file charset.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../org/apache/camel/jsonpath/JsonPathEngine.java  | 12 ++-
 .../JsonPathRemoteGenericFileCharsetTest.java      | 91 ++++++++++++++++++++++
 2 files changed, 100 insertions(+), 3 deletions(-)

diff --git 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
index 67cd783abe30..c21f096911a5 100644
--- 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
+++ 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
@@ -176,9 +176,15 @@ public class JsonPathEngine {
             LOG.trace("JSonPath: {} is read as generic file: {}", path, json);
             GenericFile<?> genericFile = (GenericFile<?>) json;
             if (genericFile.getCharset() != null) {
-                // special treatment for generic file with charset
-                InputStream inputStream = new FileInputStream((File) 
genericFile.getFile());
-                return JsonPath.using(configuration).parse(inputStream, 
genericFile.getCharset()).read(path);
+                // special treatment for generic file with charset: a remote 
file (such as from the ftp consumer) is
+                // not a java.io.File, and its content is the body of the 
generic file
+                InputStream inputStream = genericFile.getFile() instanceof 
File file
+                        ? new FileInputStream(file)
+                        : 
exchange.getContext().getTypeConverter().tryConvertTo(InputStream.class, 
exchange, genericFile);
+                if (inputStream != null) {
+                    // json-path closes the stream
+                    return JsonPath.using(configuration).parse(inputStream, 
genericFile.getCharset()).read(path);
+                }
             }
         }
 
diff --git 
a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathRemoteGenericFileCharsetTest.java
 
b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathRemoteGenericFileCharsetTest.java
new file mode 100644
index 000000000000..2e4410f9ad90
--- /dev/null
+++ 
b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathRemoteGenericFileCharsetTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.camel.jsonpath;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+/**
+ * A remote file (such as from the ftp consumer) is a {@link GenericFile} 
whose file is not a {@link java.io.File}. When
+ * the consumer has a charset, the JSON must be read from the file body in 
that charset.
+ */
+public class JsonPathRemoteGenericFileCharsetTest extends CamelTestSupport {
+
+    // stands in for org.apache.commons.net.ftp.FTPFile
+    private static final class RemoteEntry {
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                
from("direct:start").transform().jsonpath("$.store.book[0].title", String.class)
+                        .to("mock:title");
+            }
+        };
+    }
+
+    @Test
+    public void testRemoteFileWithCharsetUtf8() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:title");
+        mock.expectedBodiesReceived("Joseph und seine Brüder");
+
+        template.sendBody("direct:start", 
remoteFile("src/test/resources/germanbooks-utf8.json", "UTF-8"));
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Test
+    public void testRemoteFileWithCharsetIso88591() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:title");
+        mock.expectedBodiesReceived("Joseph und seine Brüder");
+
+        template.sendBody("direct:start", 
remoteFile("src/test/resources/germanbooks-iso-8859-1.json", "ISO-8859-1"));
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Test
+    public void testRemoteFileWithoutCharset() throws Exception {
+        // control: without a charset the body is read as a stream and the 
encoding detected (UTF-8)
+        MockEndpoint mock = getMockEndpoint("mock:title");
+        mock.expectedBodiesReceived("Joseph und seine Brüder");
+
+        template.sendBody("direct:start", 
remoteFile("src/test/resources/germanbooks-utf8.json", null));
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    private static GenericFile<RemoteEntry> remoteFile(String path, String 
charset) throws Exception {
+        GenericFile<RemoteEntry> file = new GenericFile<>();
+        file.setFile(new RemoteEntry());
+        file.setEndpointPath("inbox");
+        file.setFileName("books.json");
+        file.setFileNameOnly("books.json");
+        file.setCharset(charset);
+        // the remote consumer has downloaded the content into the body
+        file.setBody(Files.readAllBytes(Paths.get(path)));
+        return file;
+    }
+}

Reply via email to