[MSHARED-181] escapeString non follow by startToken remove character

git-svn-id: https://svn.apache.org/repos/asf/maven/shared/trunk@1057784 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java b/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
index 3d4d604..12ed37d 100644
--- a/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
+++ b/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
@@ -87,6 +87,8 @@
     
     private boolean supportMultiLineFiltering;
     
+    private Character preserveChar = null;
+    
     /**
      * This constructor uses default begin token ${ and default end token }.
      *
@@ -219,6 +221,13 @@
             }
             return ch;
         }
+        if (preserveChar != null )
+        {
+            char copy = Character.valueOf( preserveChar.charValue() ).charValue();
+            preserveChar = null;
+            replaceIndex = -1;
+            return copy;
+        }
 
         int ch = -1;
         if ( previousIndex != -1 && previousIndex < this.endToken.length() )
@@ -264,8 +273,12 @@
                     ch = in.read();
                     if ( !reselectDelimiterSpec( ch ) )
                     {
+                        // here we are after the escape but didn't found the a startToken
+                        // but we have read this means it will be removed
+                        // so we preserve it
                         replaceData = key.toString();
                         replaceIndex = 1;
+                        preserveChar = Character.valueOf( (char)ch );
                         return replaceData.charAt( 0 );
                     }
                     else
diff --git a/src/test/java/org/apache/maven/shared/filtering/EscapeStringTest.java b/src/test/java/org/apache/maven/shared/filtering/EscapeStringTest.java
new file mode 100755
index 0000000..6863050
--- /dev/null
+++ b/src/test/java/org/apache/maven/shared/filtering/EscapeStringTest.java
@@ -0,0 +1,109 @@
+package org.apache.maven.shared.filtering;

+/*

+ * 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.

+ */

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.List;

+import java.util.Properties;

+

+import org.apache.maven.model.Resource;

+import org.codehaus.plexus.PlexusTestCase;

+import org.codehaus.plexus.util.FileUtils;

+import org.codehaus.plexus.util.IOUtil;

+

+/**

+ * @author Olivier Lamy

+ *

+ */

+public class EscapeStringTest

+    extends PlexusTestCase

+{

+    

+    File outputDirectory = new File( getBasedir(), "target/EscapeStringTest" );

+

+    File unitDirectory = new File( getBasedir(), "src/test/units-files/escape-remove-char" );

+

+    protected void setUp()

+        throws Exception

+    {

+        super.setUp();

+        if ( outputDirectory.exists() )

+        {

+            FileUtils.forceDelete( outputDirectory );

+        }

+        outputDirectory.mkdirs();

+    }

+

+    public void testEscape()

+        throws Exception

+    {

+        File baseDir = new File( "c:\\foo\\bar" );

+        StubMavenProject mavenProject = new StubMavenProject( baseDir );

+        mavenProject.setVersion( "1.0" );

+        mavenProject.setGroupId( "org.apache" );

+        mavenProject.setName( "test project" );

+

+        Properties projectProperties = new Properties();

+        projectProperties.put( "foo", "bar" );

+        projectProperties.put( "java.version", "zloug" );

+        projectProperties.put( "replaceThis", "I am the replacement" );

+        mavenProject.setProperties( projectProperties );

+        MavenResourcesFiltering mavenResourcesFiltering = (MavenResourcesFiltering) lookup( MavenResourcesFiltering.class

+            .getName() );

+

+        Resource resource = new Resource();

+        List resources = new ArrayList();

+        resources.add( resource );

+        resource.setDirectory( unitDirectory.getPath() );

+        resource.setFiltering( true );

+

+        List filtersFile = new ArrayList();

+

+        List nonFilteredFileExtensions = Collections.singletonList( "gif" );

+

+        MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution( resources, outputDirectory,

+                                                                                       mavenProject, "UTF-8",

+                                                                                       filtersFile,

+                                                                                       nonFilteredFileExtensions,

+                                                                                       new StubMavenSession() );

+        mavenResourcesExecution.setUseDefaultFilterWrappers( true );

+

+        mavenResourcesExecution.setEscapeString( "!" );

+

+        mavenResourcesFiltering.filterResources( mavenResourcesExecution );

+

+        FileInputStream in = null;

+        try

+        {

+            String content = IOUtil.toString( new FileInputStream( new File( outputDirectory, "content.xml" ) ) );

+

+            System.out.println( "content " + content );

+            assertTrue( content.contains( "<broken-tag>Content with replacement: I am the replacement !</broken-tag>" ) );

+            assertTrue( content.contains( "<broken-tag>Content with escaped replacement: Do not ${replaceThis} !</broken-tag>") );

+        }

+        finally

+        {

+            IOUtil.close( in );

+        }

+

+    }

+}

diff --git a/src/test/units-files/escape-remove-char/content.xml b/src/test/units-files/escape-remove-char/content.xml
new file mode 100755
index 0000000..3721d78
--- /dev/null
+++ b/src/test/units-files/escape-remove-char/content.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<root>

+    <!-- This is a comment ... until filtering ... -->

+   <broken-tag>Why are my !\${\}\! static.content broken if the escapeString occure ?!?</broken-tag>

+   <broken-tag>Content with replacement: ${replaceThis} !</broken-tag>

+   <broken-tag>Content with escaped replacement: Do not !${replaceThis} !</broken-tag>

+</root>