Author: olamy
Date: Wed Jul 24 10:23:08 2013
New Revision: 1506482

URL: http://svn.apache.org/r1506482
Log:
[MASSEMBLY-637] fileSet <lineEnding>unix</lineEnding> strips last newline of 
file
Submitted by Stephen Colebourne

Modified:
    
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java
    
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java
    
maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java

Modified: 
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java?rev=1506482&r1=1506481&r2=1506482&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java
 (original)
+++ 
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java
 Wed Jul 24 10:23:08 2013
@@ -31,11 +31,10 @@ import org.codehaus.plexus.util.StringUt
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.Reader;
 import java.util.Locale;
 
@@ -120,20 +119,9 @@ public class FileFormatter
         Reader contentReader = null;
         try
         {
-            if ( encoding == null )
-            {
-                // Use default encoding
-                contentReader = new InputStreamReader( new FileInputStream( 
source ) );
-            }
-            else
-            {
-                //  MASSEMBLY-371
-                contentReader = new InputStreamReader( new FileInputStream( 
source ), encoding );
-            }
-
             File target = FileUtils.createTempFile( source.getName() + ".", 
".formatted", tempRoot );
 
-            AssemblyFileUtils.convertLineEndings( contentReader, target, 
lineEndingChars, encoding );
+            AssemblyFileUtils.convertLineEndings( source, target, 
lineEndingChars, null, encoding );
 
             return target;
         }

Modified: 
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java?rev=1506482&r1=1506481&r2=1506482&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java
 (original)
+++ 
maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java
 Wed Jul 24 10:23:08 2013
@@ -22,11 +22,12 @@ package org.apache.maven.plugin.assembly
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.RandomAccessFile;
-import java.io.Reader;
 import java.nio.channels.FileChannel;
 
 import org.apache.maven.plugin.assembly.archive.ArchiveExpansionException;
@@ -134,53 +135,94 @@ public final class AssemblyFileUtils
     }
 
     /**
-     * NOTE: It is the responsibility of the caller to close the source Reader 
instance.
-     * The file content is written using platform encoding.
+     * Converts the line endings of a file, writing a new file.
+     * The encoding of reading and writing can be specified.
+     * 
+     * @param source The source file, not null
+     * @param dest The destination file, not null
      * @param lineEndings This is the result of the getLineEndingChars(..) 
method in this utility class; the actual
-     *   line-ending characters.
+     *   line-ending characters, not null.
+     * @param atEndOfFile The end-of-file line ending,
+     *  if true then the resulting file will have a new line at the end even 
if the input didn't have one,
+     *  if false then the resulting file will have no new line at the end even 
if the input did have one,
+     *  null to determine whether to have a new line at the end of the file 
based on the input file
+     * @param encoding The encoding to use, null for platform encoding
      */
-    public static void convertLineEndings( @Nonnull Reader source, File dest, 
String lineEndings, String encoding )
+    public static void convertLineEndings( @Nonnull File source, @Nonnull File 
dest, String lineEndings, Boolean atEndOfFile, String encoding )
         throws IOException
     {
-        BufferedWriter out = null;
-        BufferedReader bufferedSource;
-        try
-        {
-            if ( source instanceof BufferedReader )
-            {
-                bufferedSource = (BufferedReader) source;
+        // MASSEMBLY-637, MASSEMBLY-96
+        // find characters at the end of the file
+        // needed to preserve the last line ending
+        // only check for LF (as CRLF also ends in LF)
+        String eofChars = "";
+        if ( atEndOfFile == null) {
+            RandomAccessFile raf = null;
+            try {
+                if ( source.length() >= 1 ) {
+                    raf = new RandomAccessFile( source, "r" );
+                    raf.seek( source.length() - 1 );
+                    byte last = raf.readByte();
+                    if ( last == '\n' ) {
+                      eofChars = lineEndings;
+                    }
+                }
             }
-            else
+            finally
             {
-                bufferedSource = new BufferedReader( source );
+                if ( raf != null ) {
+                    try {
+                        raf.close();
+                    }
+                    catch ( IOException ex )
+                    {
+                        // ignore
+                    }
+                }
             }
+        } else if ( atEndOfFile.booleanValue() == true ) {
+            eofChars = lineEndings;
+        }
 
+        BufferedReader in = null;
+        BufferedWriter out = null;
+        try
+        {
             if ( encoding == null )
             {
-                out = new BufferedWriter( new OutputStreamWriter( new 
FileOutputStream( dest ) ) ); // platform encoding
+                // platform encoding
+                in = new BufferedReader( new InputStreamReader( new 
FileInputStream( source ) ) );
+                out = new BufferedWriter( new OutputStreamWriter( new 
FileOutputStream( dest ) ) );
             }
             else
             {
+                // MASSEMBLY-371
+                in = new BufferedReader( new InputStreamReader( new 
FileInputStream( source ), encoding ) );
                 out = new BufferedWriter( new OutputStreamWriter( new 
FileOutputStream( dest ), encoding ) );
             }
 
             String line;
 
-            line = bufferedSource.readLine();
+            line = in.readLine();
             while ( line != null )
             {
                 out.write( line );
-                line = bufferedSource.readLine();
+                line = in.readLine();
                 if ( line != null )
                 {
                     out.write( lineEndings );
                 }
+                else
+                {
+                    out.write( eofChars );
+                }
             }
 
             out.flush();
         }
         finally
         {
+            IOUtil.close( in );
             IOUtil.close( out );
         }
     }

Modified: 
maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java?rev=1506482&r1=1506481&r2=1506482&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java
 (original)
+++ 
maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java
 Wed Jul 24 10:23:08 2013
@@ -21,6 +21,7 @@ package org.apache.maven.plugin.assembly
 
 import java.io.File;
 import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
@@ -100,6 +101,7 @@ public class AssemblyFileUtilsTest
     public void testGetLineEndingChars_ShouldReturnDosLineEnding()
         throws AssemblyFormattingException
     {
+        assertEquals( "\r\n", AssemblyFileUtils.getLineEndingCharacters( 
"windows" ) );
         assertEquals( "\r\n", AssemblyFileUtils.getLineEndingCharacters( "dos" 
) );
         assertEquals( "\r\n", AssemblyFileUtils.getLineEndingCharacters( 
"crlf" ) );
     }
@@ -136,7 +138,16 @@ public class AssemblyFileUtilsTest
         String test = "This is a \ntest.";
         String check = "This is a \r\ntest.";
 
-        testConversion( test, check, "\r\n" );
+        testConversion( test, check, "\r\n", null );
+    }
+
+    public void testConvertLineEndings_ShouldReplaceLFWithCRLFAtEOF()
+        throws IOException
+    {
+        String test = "This is a \ntest.\n";
+        String check = "This is a \r\ntest.\r\n";
+
+        testConversion( test, check, "\r\n", null );
     }
 
     public void testConvertLineEndings_ShouldReplaceCRLFWithLF()
@@ -145,7 +156,16 @@ public class AssemblyFileUtilsTest
         String test = "This is a \r\ntest.";
         String check = "This is a \ntest.";
 
-        testConversion( test, check, "\n" );
+        testConversion( test, check, "\n", null );
+    }
+
+    public void testConvertLineEndings_ShouldReplaceCRLFWithLFAtEOF()
+        throws IOException
+    {
+        String test = "This is a \r\ntest.\r\n";
+        String check = "This is a \ntest.\n";
+
+        testConversion( test, check, "\n", null );
     }
 
     public void testConvertLineEndings_ShouldReplaceLFWithLF()
@@ -154,7 +174,16 @@ public class AssemblyFileUtilsTest
         String test = "This is a \ntest.";
         String check = "This is a \ntest.";
 
-        testConversion( test, check, "\n" );
+        testConversion( test, check, "\n", null );
+    }
+
+    public void testConvertLineEndings_ShouldReplaceLFWithLFAtEOF()
+        throws IOException
+    {
+        String test = "This is a \ntest.\n";
+        String check = "This is a \ntest.\n";
+
+        testConversion( test, check, "\n", null );
     }
 
     public void testConvertLineEndings_ShouldReplaceCRLFWithCRLF()
@@ -163,33 +192,128 @@ public class AssemblyFileUtilsTest
         String test = "This is a \r\ntest.";
         String check = "This is a \r\ntest.";
 
-        testConversion( test, check, "\r\n" );
+        testConversion( test, check, "\r\n", null );
+    }
+
+    public void testConvertLineEndings_ShouldReplaceCRLFWithCRLFAtEOF()
+        throws IOException
+    {
+        String test = "This is a \r\ntest.\r\n";
+        String check = "This is a \r\ntest.\r\n";
+
+        testConversion( test, check, "\r\n", null );
+    }
+
+    public void testConvertLineEndings_LFToCRLFNoEOFForceEOF()
+        throws IOException
+    {
+        String test = "This is a \ntest.";
+        String check = "This is a \r\ntest.\r\n";
+
+        testConversion( test, check, "\r\n", true );
+    }
+
+    public void testConvertLineEndings_LFToCRLFWithEOFForceEOF()
+        throws IOException
+    {
+        String test = "This is a \ntest.\n";
+        String check = "This is a \r\ntest.\r\n";
+
+        testConversion( test, check, "\r\n", true );
+    }
+
+    public void testConvertLineEndings_LFToCRLFNoEOFStripEOF()
+        throws IOException
+    {
+        String test = "This is a \ntest.";
+        String check = "This is a \r\ntest.";
+
+        testConversion( test, check, "\r\n", false );
     }
 
-    private void testConversion( String test, String check, String 
lineEndingChars )
+    public void testConvertLineEndings_LFToCRLFWithEOFStripEOF()
         throws IOException
     {
-        File dest = File.createTempFile( "line-conversion-test.", "" );
+        String test = "This is a \ntest.\n";
+        String check = "This is a \r\ntest.";
+
+        testConversion( test, check, "\r\n", false );
+    }
+
+    public void testConvertLineEndings_CRLFToLFNoEOFForceEOF()
+        throws IOException
+    {
+        String test = "This is a \r\ntest.";
+        String check = "This is a \ntest.\n";
+
+        testConversion( test, check, "\n", true );
+    }
+
+    public void testConvertLineEndings_CRLFToLFWithEOFForceEOF()
+        throws IOException
+    {
+        String test = "This is a \r\ntest.\r\n";
+        String check = "This is a \ntest.\n";
+
+        testConversion( test, check, "\n", true );
+    }
+
+    public void testConvertLineEndings_CRLFToLFNoEOFStripEOF()
+        throws IOException
+    {
+        String test = "This is a \r\ntest.";
+        String check = "This is a \ntest.";
+
+        testConversion( test, check, "\n", false );
+    }
+
+    public void testConvertLineEndings_CRLFToLFWithEOFStripEOF()
+        throws IOException
+    {
+        String test = "This is a \r\ntest.\r\n";
+        String check = "This is a \ntest.";
+
+        testConversion( test, check, "\n", false );
+    }
+
+    private void testConversion( String test, String check, String 
lineEndingChars, Boolean eof )
+        throws IOException
+    {
+        File source = File.createTempFile( "line-conversion-test-in.", "" );
+        source.deleteOnExit();
+        File dest = File.createTempFile( "line-conversion-test-out.", "" );
         dest.deleteOnExit();
+        
+        FileWriter sourceWriter = null;
+        StringReader sourceReader = new StringReader( test );
+        try
+        {
+            sourceWriter = new FileWriter( source );
 
-        // Using platform encoding for the conversion tests in this class is OK
-        AssemblyFileUtils.convertLineEndings( new StringReader( test ), dest, 
lineEndingChars, null );
+            IOUtil.copy( sourceReader, sourceWriter );
+        }
+        finally
+        {
+            IOUtil.close( sourceWriter );
+        }
 
-        FileReader reader = null;
-        StringWriter writer = new StringWriter();
+        // Using platform encoding for the conversion tests in this class is OK
+        AssemblyFileUtils.convertLineEndings( source, dest, lineEndingChars, 
eof, null );
 
+        FileReader destReader = null;
+        StringWriter destWriter = new StringWriter();
         try
         {
-            reader = new FileReader( dest );
+            destReader = new FileReader( dest );
 
-            IOUtil.copy( reader, writer );
+            IOUtil.copy( destReader, destWriter );
         }
         finally
         {
-            IOUtil.close( reader );
+            IOUtil.close( destReader );
         }
 
-        assertEquals( check, writer.toString() );
+        assertEquals( check, destWriter.toString() );
     }
 
 }


Reply via email to