You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2012/04/25 13:31:45 UTC

svn commit: r1330210 - in /camel/branches/camel-2.9.x: ./ camel-core/src/main/java/org/apache/camel/component/file/ camel-core/src/main/java/org/apache/camel/converter/ camel-core/src/main/java/org/apache/camel/util/ camel-core/src/test/java/org/apache...

Author: davsclaus
Date: Wed Apr 25 11:31:44 2012
New Revision: 1330210

URL: http://svn.apache.org/viewvc?rev=1330210&view=rev
Log:
CAMEL-5215: Fixed file producer to use charset when writing files if given.

Added:
    camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/component/file/FileProducerCharsetUTFOptimizedTest.java
      - copied unchanged from r1330208, camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FileProducerCharsetUTFOptimizedTest.java
    camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/component/file/FileProducerCharsetUTFtoISOTest.java
      - copied unchanged from r1330208, camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FileProducerCharsetUTFtoISOTest.java
    camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/component/file/FileProducerCharsetUTFtoUTFTest.java
      - copied unchanged from r1330208, camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FileProducerCharsetUTFtoUTFTest.java
Modified:
    camel/branches/camel-2.9.x/   (props changed)
    camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileBinding.java
    camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java
    camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java
    camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java
    camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/util/IOHelper.java

Propchange: camel/branches/camel-2.9.x/
------------------------------------------------------------------------------
  Merged /camel/trunk:r1330208

Propchange: camel/branches/camel-2.9.x/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileBinding.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileBinding.java?rev=1330210&r1=1330209&r2=1330210&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileBinding.java (original)
+++ camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileBinding.java Wed Apr 25 11:31:44 2012
@@ -54,7 +54,7 @@ public class FileBinding implements Gene
     public void loadContent(Exchange exchange, GenericFile<?> file) throws IOException {
         if (content == null) {
             try {
-                content = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, file.getFile());
+                content = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, exchange, file.getFile());
             } catch (NoTypeConversionAvailableException e) {
                 throw new IOException("Cannot load file content: " + file.getAbsoluteFilePath(), e);
             }

Modified: camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java?rev=1330210&r1=1330209&r2=1330210&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java (original)
+++ camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java Wed Apr 25 11:31:44 2012
@@ -21,7 +21,10 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.io.Writer;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.Date;
@@ -29,6 +32,8 @@ import java.util.List;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.WrappedFile;
+import org.apache.camel.converter.IOConverter;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
@@ -173,10 +178,24 @@ public class FileOperations implements G
         // 3. write stream to file
         try {
 
-            // is the body file based
+            // determine charset, exchange property overrides endpoint configuration
+            String charset = IOHelper.getCharsetName(exchange, false);
+            if (charset == null) {
+                charset = endpoint.getCharset();
+            }
+
+            // we can optimize and use file based if no charset must be used, and the input body is a file
             File source = null;
-            // get the File Object from in message
-            source = exchange.getIn().getBody(File.class);
+            if (charset == null) {
+                // if no charset, then we can try using file directly (optimized)
+                Object body = exchange.getIn().getBody();
+                if (body instanceof WrappedFile) {
+                    body = ((WrappedFile) body).getFile();
+                }
+                if (body instanceof File) {
+                    source = (File) body;
+                }
+            }
 
             if (source != null) {
                 // okay we know the body is a file type
@@ -205,9 +224,22 @@ public class FileOperations implements G
                 }
             }
 
-            // fallback and use stream based
-            InputStream in = exchange.getIn().getMandatoryBody(InputStream.class);
-            writeFileByStream(in, file);
+            if (charset != null) {
+                // charset configured so we must use a reader so we can write with encoding
+                Reader in = exchange.getIn().getBody(Reader.class);
+                if (in == null) {
+                    // okay no direct reader conversion, so use an input stream (which a lot can be converted as)
+                    InputStream is = exchange.getIn().getMandatoryBody(InputStream.class);
+                    in = new InputStreamReader(is);
+                }
+                // buffer the reader
+                in = IOHelper.buffered(in);
+                writeFileByReaderWithCharset(in, file, charset);
+            } else {
+                // fallback and use stream based
+                InputStream in = exchange.getIn().getMandatoryBody(InputStream.class);
+                writeFileByStream(in, file);
+            }
             // try to keep last modified timestamp if configured to do so
             keepLastModified(exchange, file);
             return true;
@@ -239,7 +271,6 @@ public class FileOperations implements G
 
     private boolean writeFileByLocalWorkPath(File source, File file) throws IOException {
         LOG.trace("Using local work file being renamed from: {} to: {}", source, file);
-
         return FileUtil.renameFile(source, file, endpoint.isCopyAndDeleteOnRenameFail());
     }
 
@@ -286,6 +317,19 @@ public class FileOperations implements G
         }
     }
 
+    private void writeFileByReaderWithCharset(Reader in, File target, String charset) throws IOException {
+        boolean append = endpoint.getFileExist() == GenericFileExist.Append;
+        Writer out = IOConverter.toWriter(target, append, charset);
+        try {
+            LOG.trace("Using Reader to transfer from: {} to: {} with charset: {}", new Object[]{in, out, charset});
+            int size = endpoint.getBufferSize();
+            IOHelper.copy(in, out, size);
+        } finally {
+            IOHelper.close(in, target.getName(), LOG);
+            IOHelper.close(out, target.getName(), LOG);
+        }
+    }
+
     /**
      * Creates and prepares the output file channel. Will position itself in correct position if the file is writable
      * eg. it should append or override any existing content.

Modified: camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java?rev=1330210&r1=1330209&r2=1330210&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java (original)
+++ camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java Wed Apr 25 11:31:44 2012
@@ -17,7 +17,6 @@
 package org.apache.camel.component.file;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
@@ -25,9 +24,9 @@ import java.io.Serializable;
 import org.apache.camel.Converter;
 import org.apache.camel.Exchange;
 import org.apache.camel.FallbackConverter;
+import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.spi.TypeConverterRegistry;
-import org.apache.camel.util.IOHelper;
 
 /**
  * A set of converter methods for working with generic file types
@@ -64,11 +63,15 @@ public final class GenericFileConverter 
     }
 
     @Converter
-    public static InputStream genericFileToInputStream(GenericFile<?> file, Exchange exchange) throws IOException {
+    public static InputStream genericFileToInputStream(GenericFile<?> file, Exchange exchange) throws IOException, NoTypeConversionAvailableException {
         if (exchange != null) {
-            // use a file input stream if its a java.io.File
             if (file.getFile() instanceof java.io.File) {
-                return IOHelper.buffered(new FileInputStream((File) file.getFile()));
+                // prefer to use a file input stream if its a java.io.File (must use type converter to take care of encoding)
+                File f = (File) file.getFile();
+                InputStream is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, exchange, f);
+                if (is != null) {
+                    return is;
+                }
             }
             // otherwise ensure the body is loaded as we want the input stream of the body
             file.getBinding().loadContent(exchange, file);

Modified: camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java?rev=1330210&r1=1330209&r2=1330210&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java (original)
+++ camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java Wed Apr 25 11:31:44 2012
@@ -101,12 +101,16 @@ public final class IOConverter {
      */
     @Deprecated
     public static BufferedWriter toWriter(File file) throws IOException {
-        return toWriter(file, null);
+        return toWriter(file, false, IOHelper.getCharsetName(null, true));
     }
     
     @Converter
     public static BufferedWriter toWriter(File file, Exchange exchange) throws IOException {
-        return IOHelper.buffered(new EncodingFileWriter(file, IOHelper.getCharsetName(exchange)));
+        return toWriter(file, false, IOHelper.getCharsetName(exchange));
+    }
+
+    public static BufferedWriter toWriter(File file, boolean append, String charset) throws IOException {
+        return IOHelper.buffered(new EncodingFileWriter(file, append, charset));
     }
 
     /**
@@ -434,6 +438,16 @@ public final class IOConverter {
             super(new FileOutputStream(file), charset);
         }
 
+        /**
+         * @param file file to write
+         * @param append whether to append to the file
+         * @param charset character set to use
+         */
+        public EncodingFileWriter(File file, boolean append, String charset)
+            throws FileNotFoundException, UnsupportedEncodingException {
+            super(new FileOutputStream(file, append), charset);
+        }
+
     }
     
     /**

Modified: camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/util/IOHelper.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/util/IOHelper.java?rev=1330210&r1=1330209&r2=1330210&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/util/IOHelper.java (original)
+++ camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/util/IOHelper.java Wed Apr 25 11:31:44 2012
@@ -192,6 +192,20 @@ public final class IOHelper {
         close(input, null, LOG);
     }
 
+    public static int copy(final Reader input, final Writer output, int bufferSize) throws IOException {
+        final char[] buffer = new char[bufferSize];
+        int n = input.read(buffer);
+        int total = 0;
+        while (-1 != n) {
+            output.write(buffer, 0, n);
+            total += n;
+            n = input.read(buffer);
+        }
+        output.flush();
+        return total;
+    }
+
+
     /**
      * Forces any updates to this channel's file to be written to the storage device that contains it.
      *