Author: olamy
Date: Wed Dec 22 18:42:50 2010
New Revision: 1052026
URL: http://svn.apache.org/viewvc?rev=1052026&view=rev
Log:
[MSHARED-176] Add support of stopping at the end of line to prevent issue with
endToken not found.
Added:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/InterpolatorFilterReaderLineEnding.java
(with props)
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
(with props)
maven/shared/trunk/maven-filtering/src/test/java/org/apache/maven/shared/filtering/MuliLinesMavenResourcesFilteringTest.java
(with props)
maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/
maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/test.properties
(with props)
Modified:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/AbstractMavenFilteringRequest.java
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesExecution.java
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesFiltering.java
Modified:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/AbstractMavenFilteringRequest.java
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/AbstractMavenFilteringRequest.java?rev=1052026&r1=1052025&r2=1052026&view=diff
==============================================================================
---
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/AbstractMavenFilteringRequest.java
(original)
+++
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/AbstractMavenFilteringRequest.java
Wed Dec 22 18:42:50 2010
@@ -75,6 +75,12 @@ public class AbstractMavenFilteringReque
*/
private LinkedHashSet delimiters = new LinkedHashSet();
+ /**
+ * not stop trying filtering tokens when reaching EOL
+ * @since 1.0-beta-5
+ */
+ private boolean supportMultiLineFiltering;
+
protected AbstractMavenFilteringRequest()
{
initDefaults();
@@ -274,4 +280,14 @@ public class AbstractMavenFilteringReque
}
}
+ public boolean isSupportMultiLineFiltering()
+ {
+ return supportMultiLineFiltering;
+ }
+
+ public void setSupportMultiLineFiltering( boolean
supportMultiLineFiltering )
+ {
+ this.supportMultiLineFiltering = supportMultiLineFiltering;
+ }
+
}
Modified:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java?rev=1052026&r1=1052025&r2=1052026&view=diff
==============================================================================
---
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java
(original)
+++
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java
Wed Dec 22 18:42:50 2010
@@ -167,9 +167,14 @@ public class DefaultMavenFileFilter
public List getDefaultFilterWrappers( final AbstractMavenFilteringRequest
req )
throws MavenFilteringException
{
+ // backup values
+ boolean supportMultiLineFiltering = req.isSupportMultiLineFiltering();
+
// compensate for null parameter value.
final AbstractMavenFilteringRequest request = req == null ? new
MavenFileFilterRequest() : req;
+ request.setSupportMultiLineFiltering( supportMultiLineFiltering );
+
// here we build some properties which will be used to read some
properties files
// to interpolate the expression ${ } in this properties file
@@ -242,7 +247,7 @@ public class DefaultMavenFileFilter
FileUtils.FilterWrapper wrapper = new Wrapper(
request.getDelimiters(), request.getMavenProject(),
request.getMavenSession(), propertiesValueSource,
request.getProjectStartExpressions(), request.getEscapeString(),
-
request.isEscapeWindowsPaths() );
+
request.isEscapeWindowsPaths(), request.isSupportMultiLineFiltering() );
defaultFilterWrappers.add( wrapper );
}
@@ -293,9 +298,11 @@ public class DefaultMavenFileFilter
private boolean escapeWindowsPaths;
private final MavenSession mavenSession;
+
+ private boolean supportMultiLineFiltering;
Wrapper( LinkedHashSet delimiters, MavenProject project, MavenSession
mavenSession, ValueSource propertiesValueSource,
- List projectStartExpressions, String escapeString,
boolean escapeWindowsPaths )
+ List projectStartExpressions, String escapeString,
boolean escapeWindowsPaths, boolean supportMultiLineFiltering )
{
super();
this.delimiters = delimiters;
@@ -305,6 +312,7 @@ public class DefaultMavenFileFilter
this.projectStartExpressions = projectStartExpressions;
this.escapeString = escapeString;
this.escapeWindowsPaths = escapeWindowsPaths;
+ this.supportMultiLineFiltering = supportMultiLineFiltering;
}
public Reader getReader( Reader reader )
@@ -359,7 +367,8 @@ public class DefaultMavenFileFilter
} );
}
- MultiDelimiterInterpolatorFilterReader filterReader = new
MultiDelimiterInterpolatorFilterReader( reader, interpolator );
+ MultiDelimiterInterpolatorFilterReaderLineEnding filterReader =
+ new MultiDelimiterInterpolatorFilterReaderLineEnding( reader,
interpolator, supportMultiLineFiltering );
filterReader.setRecursionInterceptor( ri );
filterReader.setDelimiterSpecs( delimiters );
Added:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/InterpolatorFilterReaderLineEnding.java
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/InterpolatorFilterReaderLineEnding.java?rev=1052026&view=auto
==============================================================================
---
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/InterpolatorFilterReaderLineEnding.java
(added)
+++
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/InterpolatorFilterReaderLineEnding.java
Wed Dec 22 18:42:50 2010
@@ -0,0 +1,407 @@
+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.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.RecursionInterceptor;
+import org.codehaus.plexus.interpolation.SimpleRecursionInterceptor;
+
+/**
+ * A FilterReader implementation, that works with Interpolator interface
instead of it's own interpolation
+ * implementation. This implementation is heavily based on
org.codehaus.plexus.util.InterpolationFilterReader.
+ *
+ * @author cstamas
+ * @author Olivier Lamy
+ * @version $Id$
+ * @since 1.0-beta-5
+ */
+public class InterpolatorFilterReaderLineEnding
+ extends FilterReader
+{
+
+ /** Interpolator used to interpolate */
+ private Interpolator interpolator;
+
+ private RecursionInterceptor recursionInterceptor;
+
+ /** replacement text from a token */
+ private String replaceData = null;
+
+ /** Index into replacement data */
+ private int replaceIndex = -1;
+
+ /** Index into previous data */
+ private int previousIndex = -1;
+
+ /** Default begin token. */
+ public static final String DEFAULT_BEGIN_TOKEN = "${";
+
+ /** Default end token. */
+ public static final String DEFAULT_END_TOKEN = "}";
+
+ private String beginToken;
+
+ private String orginalBeginToken;
+
+ private String endToken;
+
+ /** true by default to preserve backward comp */
+ private boolean interpolateWithPrefixPattern = true;
+
+ private String escapeString;
+
+ private boolean useEscape = false;
+
+ /** if true escapeString will be preserved \{foo} -> \{foo} */
+ private boolean preserveEscapeString = false;
+
+ private boolean supportMultiLineFiltering;
+
+ /**
+ * @param in reader to use
+ * @param interpolator interpolator instance to use
+ * @param beginToken start token to use
+ * @param endToken end token to use
+ */
+ public InterpolatorFilterReaderLineEnding( Reader in, Interpolator
interpolator, String beginToken, String endToken, boolean
supportMultiLineFiltering )
+ {
+ this( in, interpolator, beginToken, endToken, new
SimpleRecursionInterceptor(), supportMultiLineFiltering );
+ }
+
+ /**
+ * @param in reader to use
+ * @param interpolator interpolator instance to use
+ * @param beginToken start token to use
+ * @param endToken end token to use
+ * @param ri The {...@link RecursionInterceptor} to use to prevent
recursive expressions.
+ */
+ private InterpolatorFilterReaderLineEnding( Reader in, Interpolator
interpolator, String beginToken, String endToken, RecursionInterceptor ri,
boolean supportMultiLineFiltering )
+ {
+ super( in );
+
+ this.interpolator = interpolator;
+
+ this.beginToken = beginToken;
+
+ this.endToken = endToken;
+
+ recursionInterceptor = ri;
+
+ this.orginalBeginToken = this.beginToken;
+
+ this.supportMultiLineFiltering = supportMultiLineFiltering;
+ }
+
+ /**
+ * Skips characters. This method will block until some characters are
available, an I/O error occurs, or the end of
+ * the stream is reached.
+ *
+ * @param n The number of characters to skip
+ * @return the number of characters actually skipped
+ * @exception IllegalArgumentException If <code>n</code> is negative.
+ * @exception IOException If an I/O error occurs
+ */
+ public long skip( long n )
+ throws IOException
+ {
+ if ( n < 0L )
+ {
+ throw new IllegalArgumentException( "skip value is negative" );
+ }
+
+ for ( long i = 0; i < n; i++ )
+ {
+ if ( read() == -1 )
+ {
+ return i;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Reads characters into a portion of an array. This method will block
until some input is available, an I/O error
+ * occurs, or the end of the stream is reached.
+ *
+ * @param cbuf Destination buffer to write characters to. Must not be
<code>null</code>.
+ * @param off Offset at which to start storing characters.
+ * @param len Maximum number of characters to read.
+ * @return the number of characters read, or -1 if the end of the stream
has been reached
+ * @exception IOException If an I/O error occurs
+ */
+ public int read( char cbuf[], int off, int len )
+ throws IOException
+ {
+ for ( int i = 0; i < len; i++ )
+ {
+ int ch = read();
+ if ( ch == -1 )
+ {
+ if ( i == 0 )
+ {
+ return -1;
+ }
+ else
+ {
+ return i;
+ }
+ }
+ cbuf[off + i] = (char) ch;
+ }
+ return len;
+ }
+
+ /**
+ * Returns the next character in the filtered stream, replacing tokens
from the original stream.
+ *
+ * @return the next character in the resulting stream, or -1 if the end of
the resulting stream has been reached
+ * @exception IOException if the underlying stream throws an IOException
during reading
+ */
+ public int read()
+ throws IOException
+ {
+ if ( replaceIndex != -1 && replaceIndex < replaceData.length() )
+ {
+ int ch = replaceData.charAt( replaceIndex++ );
+ if ( replaceIndex >= replaceData.length() )
+ {
+ replaceIndex = -1;
+ }
+ return ch;
+ }
+
+ int ch = -1;
+ if ( previousIndex != -1 && previousIndex < this.endToken.length() )
+ {
+ ch = this.endToken.charAt( previousIndex++ );
+ }
+ else
+ {
+ ch = in.read();
+ }
+
+ if (ch == '\n' && !supportMultiLineFiltering )
+ {
+ previousIndex = -1;
+ return ch;
+ }
+
+ if ( ch == this.beginToken.charAt( 0 ) || ( useEscape && ch ==
this.orginalBeginToken.charAt( 0 ) ) )
+ {
+ StringBuffer key = new StringBuffer( );
+
+ key.append( (char) ch );
+
+ int beginTokenMatchPos = 1;
+
+ do
+ {
+ if ( previousIndex != -1 && previousIndex <
this.endToken.length() )
+ {
+ ch = this.endToken.charAt( previousIndex++ );
+ }
+ else
+ {
+ ch = in.read();
+ }
+ if ( ch != -1 && (ch != '\n' && !supportMultiLineFiltering ) )
+ {
+ key.append( (char) ch );
+ if ( ( beginTokenMatchPos < this.beginToken.length() )
+ && ( ch != this.beginToken.charAt(
beginTokenMatchPos++ ) )
+ && ( useEscape && this.orginalBeginToken.length() > (
beginTokenMatchPos - 1 ) && ch != this.orginalBeginToken
+ .charAt( beginTokenMatchPos - 1 ) ) )
+ {
+ ch = -1; // not really EOF but to trigger code below
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ // MSHARED-81 olamy : we must take care of token with length
1, escaping and same char : \...@foo@
+ // here ch == endToken == beginToken -> not going to next char
: bad :-)
+ if ( useEscape && this.orginalBeginToken == this.endToken &&
key.toString().startsWith( this.beginToken ) )
+ {
+ ch = in.read();
+ key.append( (char) ch );
+ }
+ }
+ while ( ch != this.endToken.charAt( 0 ) );
+
+ // now test endToken
+ if ( ch != -1 && this.endToken.length() > 1 )
+ {
+ int endTokenMatchPos = 1;
+
+ do
+ {
+ if ( previousIndex != -1 && previousIndex <
this.endToken.length() )
+ {
+ ch = this.endToken.charAt( previousIndex++ );
+ }
+ else
+ {
+ ch = in.read();
+ }
+
+ if ( ch != -1 )
+ {
+ key.append( (char) ch );
+
+ if ( ch != this.endToken.charAt( endTokenMatchPos++ ) )
+ {
+ ch = -1; // not really EOF but to trigger code
below
+ break;
+ }
+
+ }
+ else
+ {
+ break;
+ }
+ }
+ while ( endTokenMatchPos < this.endToken.length() );
+ }
+
+ // There is nothing left to read so we have the situation where
the begin/end token
+ // are in fact the same and as there is nothing left to read we
have got ourselves
+ // end of a token boundary so let it pass through.
+ if ( ch == -1 || ( ch =='\n' && !supportMultiLineFiltering ) )
+ {
+ replaceData = key.toString();
+ replaceIndex = 1;
+ return replaceData.charAt( 0 );
+ }
+
+ String value = null;
+ try
+ {
+ boolean escapeFound = false;
+ if ( useEscape )
+ {
+ if ( key.toString().startsWith( escapeString +
orginalBeginToken ) )
+ {
+ String keyStr = key.toString();
+ if ( !preserveEscapeString )
+ {
+ value = keyStr.substring( escapeString.length(),
keyStr.length() );
+ }
+ else
+ {
+ value = keyStr;
+ }
+ escapeFound = true;
+ }
+ }
+ if ( !escapeFound )
+ {
+ if ( interpolateWithPrefixPattern )
+ {
+ value = interpolator.interpolate( key.toString(), "",
recursionInterceptor );
+ }
+ else
+ {
+ value = interpolator.interpolate( key.toString(),
recursionInterceptor );
+ }
+ }
+ }
+ catch ( InterpolationException e )
+ {
+ IllegalArgumentException error = new IllegalArgumentException(
e.getMessage() );
+ error.initCause( e );
+
+ throw error;
+ }
+
+ if ( value != null )
+ {
+ if ( value.length() != 0 )
+ {
+ replaceData = value;
+ replaceIndex = 0;
+ }
+ return read();
+ }
+ else
+ {
+ previousIndex = 0;
+ replaceData = key.substring( 0, key.length() -
this.endToken.length() );
+ replaceIndex = 0;
+ return this.beginToken.charAt( 0 );
+ }
+ }
+
+ return ch;
+ }
+
+ public boolean isInterpolateWithPrefixPattern()
+ {
+ return interpolateWithPrefixPattern;
+ }
+
+ public void setInterpolateWithPrefixPattern( boolean
interpolateWithPrefixPattern )
+ {
+ this.interpolateWithPrefixPattern = interpolateWithPrefixPattern;
+ }
+ public String getEscapeString()
+ {
+ return escapeString;
+ }
+
+ public void setEscapeString( String escapeString )
+ {
+ // TODO NPE if escapeString is null ?
+ if ( escapeString != null && escapeString.length() >= 1 )
+ {
+ this.escapeString = escapeString;
+ this.orginalBeginToken = beginToken;
+ this.beginToken = escapeString + beginToken;
+ this.useEscape = escapeString != null && escapeString.length() >=
1;
+ }
+ }
+
+ public boolean isPreserveEscapeString()
+ {
+ return preserveEscapeString;
+ }
+
+ public void setPreserveEscapeString( boolean preserveEscapeString )
+ {
+ this.preserveEscapeString = preserveEscapeString;
+ }
+
+ public RecursionInterceptor getRecursionInterceptor()
+ {
+ return recursionInterceptor;
+ }
+
+ public InterpolatorFilterReaderLineEnding setRecursionInterceptor(
RecursionInterceptor recursionInterceptor )
+ {
+ this.recursionInterceptor = recursionInterceptor;
+ return this;
+ }
+}
Propchange:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/InterpolatorFilterReaderLineEnding.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/InterpolatorFilterReaderLineEnding.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesExecution.java
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesExecution.java?rev=1052026&r1=1052025&r2=1052026&view=diff
==============================================================================
---
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesExecution.java
(original)
+++
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesExecution.java
Wed Dec 22 18:42:50 2010
@@ -19,21 +19,20 @@ package org.apache.maven.shared.filterin
* under the License.
*/
+import java.io.File;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.interpolation.Interpolator;
-import org.codehaus.plexus.interpolation.InterpolatorFilterReader;
import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
import org.codehaus.plexus.interpolation.ValueSource;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.FileUtils.FilterWrapper;
-import java.io.File;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* A bean to configure a resources filtering execution
* @author <a href="mailto:[email protected]">olamy</a>
@@ -70,8 +69,15 @@ public class MavenResourcesExecution
*/
private boolean includeEmptyDirs = false;
+ /**
+ * not stop trying filtering tokens when reaching EOL
+ * @since 1.0-beta-5
+ */
+ private boolean supportMultiLineFiltering;
+
public MavenResourcesExecution()
{
+ // no op
}
/**
@@ -178,8 +184,9 @@ public class MavenResourcesExecution
/**
* Helper to add {...@link FileUtils.FilterWrapper}, will {...@link
RegexBasedInterpolator} with default regex Exp ${ }
- * and InterpolatorFilterReader with defaultTokens ${ }
+ * and InterpolatorFilterReaderLineEnding with defaultTokens ${ }
* @param valueSource
+ * @deprecated this doesn't support escaping use {...@link
#addFilerWrapperWithEscaping(ValueSource, String, String, String, boolean)}
*/
public void addFilerWrapper( final ValueSource valueSource )
{
@@ -189,7 +196,9 @@ public class MavenResourcesExecution
{
Interpolator propertiesInterpolator = new
RegexBasedInterpolator();
propertiesInterpolator.addValueSource( valueSource );
- return new InterpolatorFilterReader( reader,
propertiesInterpolator );
+ return new InterpolatorFilterReaderLineEnding( reader,
propertiesInterpolator,
+
InterpolatorFilterReaderLineEnding.DEFAULT_BEGIN_TOKEN,
+
InterpolatorFilterReaderLineEnding.DEFAULT_END_TOKEN, false );
}
} );
}
@@ -200,7 +209,7 @@ public class MavenResourcesExecution
* @param endRegExp
* @param startToken
* @param endToken
- * @deprecated this doesn't support escaping use {...@link
#addFilerWrapperWithEscaping(ValueSource, String, String, String)}
+ * @deprecated this doesn't support escaping use {...@link
#addFilerWrapperWithEscaping(ValueSource, String, String, String, boolean)}
*/
public void addFilerWrapper( final ValueSource valueSource, final String
startRegExp, final String endRegExp,
final String startToken, final String
endToken )
@@ -211,7 +220,7 @@ public class MavenResourcesExecution
{
Interpolator propertiesInterpolator = new
RegexBasedInterpolator( startRegExp, endRegExp );
propertiesInterpolator.addValueSource( valueSource );
- return new InterpolatorFilterReader( reader,
propertiesInterpolator, startToken, endToken );
+ return new InterpolatorFilterReaderLineEnding( reader,
propertiesInterpolator, startToken, endToken, false );
}
} );
}
@@ -222,6 +231,7 @@ public class MavenResourcesExecution
* @param endExp endToken }
* @since 1.0-beta-2
* @param escapeString
+ * @deprecated this doesn't support escaping use {...@link
#addFilerWrapperWithEscaping(ValueSource, String, String, String, boolean)}
*/
public void addFilerWrapperWithEscaping( final ValueSource valueSource,
final String startExp, final String endExp,
final String escapeString )
@@ -233,15 +243,43 @@ public class MavenResourcesExecution
StringSearchInterpolator propertiesInterpolator = new
StringSearchInterpolator( startExp, endExp );
propertiesInterpolator.addValueSource( valueSource );
propertiesInterpolator.setEscapeString( escapeString );
- InterpolatorFilterReader interpolatorFilterReader = new
InterpolatorFilterReader(
+ InterpolatorFilterReaderLineEnding interpolatorFilterReader =
new InterpolatorFilterReaderLineEnding(
+
reader,
+
propertiesInterpolator,
+
startExp, endExp, false );
+ interpolatorFilterReader.setInterpolateWithPrefixPattern(
false );
+ return interpolatorFilterReader;
+ }
+ } );
+ }
+
+ /**
+ * @param valueSource
+ * @param startExp start token like ${
+ * @param endExp endToken }
+ * @since 1.0-beta-5
+ * @param escapeString
+ * @param supportMultiLineFiltering do we support or to use filtering on
multi lines start and endotken on multi lines)
+ */
+ public void addFilerWrapperWithEscaping( final ValueSource valueSource,
final String startExp, final String endExp,
+ final String escapeString, final
boolean supportMultiLineFiltering )
+ {
+ addFilterWrapper( new FileUtils.FilterWrapper()
+ {
+ public Reader getReader( Reader reader )
+ {
+ StringSearchInterpolator propertiesInterpolator = new
StringSearchInterpolator( startExp, endExp );
+ propertiesInterpolator.addValueSource( valueSource );
+ propertiesInterpolator.setEscapeString( escapeString );
+ InterpolatorFilterReaderLineEnding interpolatorFilterReader =
new InterpolatorFilterReaderLineEnding(
reader,
propertiesInterpolator,
-
startExp, endExp );
+
startExp, endExp, supportMultiLineFiltering );
interpolatorFilterReader.setInterpolateWithPrefixPattern(
false );
return interpolatorFilterReader;
}
} );
- }
+ }
public File getResourcesBaseDirectory()
@@ -324,7 +362,7 @@ public class MavenResourcesExecution
mre.setResources( copyList( mre.getResources() ) );
mre.setResourcesBaseDirectory( mre.getResourcesBaseDirectory() );
mre.setUseDefaultFilterWrappers( mre.isUseDefaultFilterWrappers() );
-
+ mre.setSupportMultiLineFiltering( mre.isSupportMultiLineFiltering() );
return mre;
}
@@ -343,4 +381,14 @@ public class MavenResourcesExecution
return new ArrayList( lst );
}
}
+
+ public boolean isSupportMultiLineFiltering()
+ {
+ return supportMultiLineFiltering;
+ }
+
+ public void setSupportMultiLineFiltering( boolean
supportMultiLineFiltering )
+ {
+ this.supportMultiLineFiltering = supportMultiLineFiltering;
+ }
}
Modified:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesFiltering.java
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesFiltering.java?rev=1052026&r1=1052025&r2=1052026&view=diff
==============================================================================
---
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesFiltering.java
(original)
+++
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MavenResourcesFiltering.java
Wed Dec 22 18:42:50 2010
@@ -40,6 +40,7 @@ public interface MavenResourcesFiltering
* @param fileFilters {...@link List} of String which are path to a
Property file
* @param nonFilteredFileExtensions {...@link List} of String for non
filtered file extensions
* @param mavenSession Can include executionProperties that will be used
for filtering
+ * @deprecated use {...@link #filterResources(MavenResourcesExecution)}
* @throws MavenFilteringException
*/
void filterResources( List resources, File outputDirectory, MavenProject
mavenProject, String encoding,
@@ -53,6 +54,7 @@ public interface MavenResourcesFiltering
* @param filterWrappers {...@link List} of FileUtils.FilterWrapper
* @param resourcesBaseDirectory baseDirectory of resources
* @param nonFilteredFileExtensions {...@link List} of String for non
filtered file extensions
+ * @deprecated use {...@link #filterResources(MavenResourcesExecution)}
* @throws MavenFilteringException
*/
void filterResources( List resources, File outputDirectory, String
encoding, List filterWrappers,
@@ -74,7 +76,7 @@ public interface MavenResourcesFiltering
boolean filteredFileExtension( String fileName, List
userNonFilteredFileExtensions );
/**
- * @param mavenResourcesExecution
+ * @param mavenResourcesExecution {...@link MavenResourcesExecution}
* @throws MavenFilteringException
*/
void filterResources( MavenResourcesExecution mavenResourcesExecution )
Added:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java?rev=1052026&view=auto
==============================================================================
---
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
(added)
+++
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
Wed Dec 22 18:42:50 2010
@@ -0,0 +1,467 @@
+package org.apache.maven.shared.filtering;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.RecursionInterceptor;
+import org.codehaus.plexus.interpolation.SimpleRecursionInterceptor;
+import org.codehaus.plexus.interpolation.multi.DelimiterSpecification;
+
+/**
+ * A FilterReader implementation, that works with Interpolator interface
instead of it's own interpolation
+ * implementation. This implementation is heavily based on
org.codehaus.plexus.util.InterpolationFilterReader.
+ *
+ * @author cstamas
+ * @author Olivier Lamy
+ * @version $Id$
+ * @since 1.0-beta-5
+ */
+public class MultiDelimiterInterpolatorFilterReaderLineEnding
+ extends FilterReader
+{
+
+ /** Interpolator used to interpolate */
+ private Interpolator interpolator;
+
+ private RecursionInterceptor recursionInterceptor;
+
+ /** replacement text from a token */
+ private String replaceData = null;
+
+ /** Index into replacement data */
+ private int replaceIndex = -1;
+
+ /** Index into previous data */
+ private int previousIndex = -1;
+
+ /** Default begin token. */
+ public static final String DEFAULT_BEGIN_TOKEN = "${";
+
+ /** Default end token. */
+ public static final String DEFAULT_END_TOKEN = "}";
+
+ /** true by default to preserve backward comp */
+ private boolean interpolateWithPrefixPattern = true;
+
+ private String escapeString;
+
+ private boolean useEscape = false;
+
+ /** if true escapeString will be preserved \{foo} -> \{foo} */
+ private boolean preserveEscapeString = false;
+
+ private LinkedHashSet delimiters = new LinkedHashSet();
+
+ private DelimiterSpecification currentSpec;
+
+ private String beginToken;
+
+ private String originalBeginToken;
+
+ private String endToken;
+
+ private boolean supportMultiLineFiltering;
+
+ /**
+ * this constructor use default begin token ${ and default end token }
+ * @param in reader to use
+ * @param interpolator interpolator instance to use
+ */
+ public MultiDelimiterInterpolatorFilterReaderLineEnding( Reader in,
Interpolator interpolator, boolean supportMultiLineFiltering )
+ {
+ this( in, interpolator, new SimpleRecursionInterceptor(),
supportMultiLineFiltering );
+ }
+
+ /**
+ * @param in reader to use
+ * @param interpolator interpolator instance to use
+ * @param beginToken start token to use
+ * @param endToken end token to use
+ * @param ri The {...@link RecursionInterceptor} to use to prevent
recursive expressions.
+ * @since 1.12
+ */
+ public MultiDelimiterInterpolatorFilterReaderLineEnding( Reader in,
Interpolator interpolator, RecursionInterceptor ri, boolean
supportMultiLineFiltering )
+ {
+ super( in );
+
+ this.interpolator = interpolator;
+
+ // always cache answers, since we'll be sending in pure expressions,
not mixed text.
+ this.interpolator.setCacheAnswers( true );
+
+ recursionInterceptor = ri;
+
+ delimiters.add( DelimiterSpecification.DEFAULT_SPEC );
+
+ this.supportMultiLineFiltering = supportMultiLineFiltering;
+ }
+
+
+ public boolean removeDelimiterSpec( String delimiterSpec )
+ {
+ return delimiters.remove( DelimiterSpecification.parse( delimiterSpec
) );
+ }
+
+ public MultiDelimiterInterpolatorFilterReaderLineEnding setDelimiterSpecs(
HashSet specs )
+ {
+ delimiters.clear();
+ for ( Iterator it = specs.iterator(); it.hasNext(); )
+ {
+ String spec = (String) it.next();
+ delimiters.add( DelimiterSpecification.parse( spec ) );
+ }
+
+ return this;
+ }
+
+ /**
+ * Skips characters. This method will block until some characters are
available, an I/O error occurs, or the end of
+ * the stream is reached.
+ *
+ * @param n The number of characters to skip
+ * @return the number of characters actually skipped
+ * @exception IllegalArgumentException If <code>n</code> is negative.
+ * @exception IOException If an I/O error occurs
+ */
+ public long skip( long n )
+ throws IOException
+ {
+ if ( n < 0L )
+ {
+ throw new IllegalArgumentException( "skip value is negative" );
+ }
+
+ for ( long i = 0; i < n; i++ )
+ {
+ if ( read() == -1 )
+ {
+ return i;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Reads characters into a portion of an array. This method will block
until some input is available, an I/O error
+ * occurs, or the end of the stream is reached.
+ *
+ * @param cbuf Destination buffer to write characters to. Must not be
<code>null</code>.
+ * @param off Offset at which to start storing characters.
+ * @param len Maximum number of characters to read.
+ * @return the number of characters read, or -1 if the end of the stream
has been reached
+ * @exception IOException If an I/O error occurs
+ */
+ public int read( char cbuf[], int off, int len )
+ throws IOException
+ {
+ for ( int i = 0; i < len; i++ )
+ {
+ int ch = read();
+ if ( ch == -1 )
+ {
+ if ( i == 0 )
+ {
+ return -1;
+ }
+ else
+ {
+ return i;
+ }
+ }
+ cbuf[off + i] = (char) ch;
+ }
+ return len;
+ }
+
+ /**
+ * Returns the next character in the filtered stream, replacing tokens
from the original stream.
+ *
+ * @return the next character in the resulting stream, or -1 if the end of
the resulting stream has been reached
+ * @exception IOException if the underlying stream throws an IOException
during reading
+ */
+ public int read()
+ throws IOException
+ {
+ if ( replaceIndex != -1 && replaceIndex < replaceData.length() )
+ {
+ int ch = replaceData.charAt( replaceIndex++ );
+ if ( replaceIndex >= replaceData.length() )
+ {
+ replaceIndex = -1;
+ }
+ return ch;
+ }
+
+ int ch = -1;
+ if ( previousIndex != -1 && previousIndex < this.endToken.length() )
+ {
+ ch = this.endToken.charAt( previousIndex++ );
+ }
+ else
+ {
+ ch = in.read();
+ }
+ if (ch == '\n' && !supportMultiLineFiltering)
+ {
+ previousIndex = -1;
+ return ch;
+ }
+ boolean inEscape = false;
+
+ if ( ( inEscape = ( useEscape && ch == escapeString.charAt( 0 ) ) ) ||
reselectDelimiterSpec( ch ) )
+ {
+ StringBuffer key = new StringBuffer( );
+
+ key.append( (char) ch );
+
+ // this will happen when we're using an escape string, and ONLY
then.
+ boolean atEnd = false;
+
+ if ( inEscape )
+ {
+ for( int i = 0; i < escapeString.length() - 1; i++ )
+ {
+ ch = in.read();
+ if ( ch == -1 || ( ch == '\n' &&
!supportMultiLineFiltering ) )
+ {
+ atEnd = true;
+ break;
+ }
+
+ key.append( (char) ch );
+ }
+
+ if ( !atEnd )
+ {
+ ch = in.read();
+ if ( !reselectDelimiterSpec( ch ) )
+ {
+ replaceData = key.toString();
+ replaceIndex = 1;
+ return replaceData.charAt( 0 );
+ }
+ else
+ {
+ key.append( (char) ch );
+ }
+ }
+ }
+
+ int beginTokenMatchPos = 1;
+ do
+ {
+ if ( atEnd )
+ {
+ // didn't finish reading the escape string.
+ break;
+ }
+
+ if ( previousIndex != -1 && previousIndex <
this.endToken.length() )
+ {
+ ch = this.endToken.charAt( previousIndex++ );
+ }
+ else
+ {
+ ch = in.read();
+ }
+ if ( ch == '\n' && !supportMultiLineFiltering )
+ {
+ // EOL
+ key.append( (char) ch );
+ break;
+ }
+ if ( ch != -1 )
+ {
+ key.append( (char) ch );
+ if ( ( beginTokenMatchPos <
this.originalBeginToken.length() )
+ && ( ch != this.originalBeginToken.charAt(
beginTokenMatchPos ) ) )
+ {
+ ch = -1; // not really EOF but to trigger code below
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ beginTokenMatchPos++;
+ }
+ while ( ch != this.endToken.charAt( 0 ) );
+
+ // now test endToken
+ if ( ch != -1 && ( ch != '\n' && !supportMultiLineFiltering) &&
this.endToken.length() > 1 )
+ {
+ int endTokenMatchPos = 1;
+
+ do
+ {
+ if ( previousIndex != -1 && previousIndex <
this.endToken.length() )
+ {
+ ch = this.endToken.charAt( previousIndex++ );
+ }
+ else
+ {
+ ch = in.read();
+ }
+
+ if ( ch != -1 )
+ {
+ key.append( (char) ch );
+
+ if ( ch != this.endToken.charAt( endTokenMatchPos++ )
|| ( ch != '\n' && !supportMultiLineFiltering ) )
+ {
+ ch = -1; // not really EOF but to trigger code
below
+ break;
+ }
+
+ }
+ else
+ {
+ break;
+ }
+ }
+ while ( endTokenMatchPos < this.endToken.length() );
+ }
+
+ // There is nothing left to read so we have the situation where
the begin/end token
+ // are in fact the same and as there is nothing left to read we
have got ourselves
+ // end of a token boundary so let it pass through.
+ if ( ch == -1 || (ch =='\n' && !supportMultiLineFiltering ) )
+ {
+ replaceData = key.toString();
+ replaceIndex = 1;
+ return replaceData.charAt( 0 );
+ }
+
+ String value = null;
+ try
+ {
+ boolean escapeFound = false;
+ if ( useEscape )
+ {
+ if ( key.toString().startsWith( beginToken ) )
+ {
+ String keyStr = key.toString();
+ if ( !preserveEscapeString )
+ {
+ value = keyStr.substring( escapeString.length(),
keyStr.length() );
+ }
+ else
+ {
+ value = keyStr;
+ }
+ escapeFound = true;
+ }
+ }
+ if ( !escapeFound )
+ {
+ if ( interpolateWithPrefixPattern )
+ {
+ value = interpolator.interpolate( key.toString(), "",
recursionInterceptor );
+ }
+ else
+ {
+ value = interpolator.interpolate( key.toString(),
recursionInterceptor );
+ }
+ }
+ }
+ catch ( InterpolationException e )
+ {
+ IllegalArgumentException error = new IllegalArgumentException(
e.getMessage() );
+ error.initCause( e );
+
+ throw error;
+ }
+
+ if ( value != null )
+ {
+ if ( value.length() != 0 )
+ {
+ replaceData = value;
+ replaceIndex = 0;
+ }
+ return read();
+ }
+ else
+ {
+ previousIndex = 0;
+ replaceData = key.substring( 0, key.length() -
this.endToken.length() );
+ replaceIndex = 0;
+ return this.beginToken.charAt( 0 );
+ }
+ }
+
+ return ch;
+ }
+
+ private boolean reselectDelimiterSpec( int ch )
+ {
+ for ( Iterator it = delimiters.iterator(); it.hasNext(); )
+ {
+ DelimiterSpecification spec = (DelimiterSpecification) it.next();
+ if ( ch == spec.getBegin().charAt( 0 ) )
+ {
+ currentSpec = spec;
+ originalBeginToken = currentSpec.getBegin();
+ beginToken = useEscape ? escapeString + originalBeginToken :
originalBeginToken;
+ endToken = currentSpec.getEnd();
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean isInterpolateWithPrefixPattern()
+ {
+ return interpolateWithPrefixPattern;
+ }
+
+ public void setInterpolateWithPrefixPattern( boolean
interpolateWithPrefixPattern )
+ {
+ this.interpolateWithPrefixPattern = interpolateWithPrefixPattern;
+ }
+ public String getEscapeString()
+ {
+ return escapeString;
+ }
+
+ public void setEscapeString( String escapeString )
+ {
+ // TODO NPE if escapeString is null ?
+ if ( escapeString != null && escapeString.length() >= 1 )
+ {
+ this.escapeString = escapeString;
+ this.useEscape = escapeString != null && escapeString.length() >=
1;
+ }
+ }
+
+ public boolean isPreserveEscapeString()
+ {
+ return preserveEscapeString;
+ }
+
+ public void setPreserveEscapeString( boolean preserveEscapeString )
+ {
+ this.preserveEscapeString = preserveEscapeString;
+ }
+
+ public RecursionInterceptor getRecursionInterceptor()
+ {
+ return recursionInterceptor;
+ }
+
+ public MultiDelimiterInterpolatorFilterReaderLineEnding
setRecursionInterceptor( RecursionInterceptor recursionInterceptor )
+ {
+ this.recursionInterceptor = recursionInterceptor;
+ return this;
+ }
+}
Propchange:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
maven/shared/trunk/maven-filtering/src/main/java/org/apache/maven/shared/filtering/MultiDelimiterInterpolatorFilterReaderLineEnding.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added:
maven/shared/trunk/maven-filtering/src/test/java/org/apache/maven/shared/filtering/MuliLinesMavenResourcesFilteringTest.java
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/test/java/org/apache/maven/shared/filtering/MuliLinesMavenResourcesFilteringTest.java?rev=1052026&view=auto
==============================================================================
---
maven/shared/trunk/maven-filtering/src/test/java/org/apache/maven/shared/filtering/MuliLinesMavenResourcesFilteringTest.java
(added)
+++
maven/shared/trunk/maven-filtering/src/test/java/org/apache/maven/shared/filtering/MuliLinesMavenResourcesFilteringTest.java
Wed Dec 22 18:42:50 2010
@@ -0,0 +1,120 @@
+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 <a href="mailto:[email protected]">olamy</a>
+ *
+ *
+ * @version $Id$
+ */
+public class MuliLinesMavenResourcesFilteringTest
+ extends PlexusTestCase
+{
+
+ File outputDirectory = new File( getBasedir(),
"target/MuliLinesMavenResourcesFilteringTest" );
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ if ( outputDirectory.exists() )
+ {
+ FileUtils.forceDelete( outputDirectory );
+ }
+ outputDirectory.mkdirs();
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void testFilteringTokenOnce()
+ 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" );
+ mavenProject.setProperties( projectProperties );
+ MavenResourcesFiltering mavenResourcesFiltering =
(MavenResourcesFiltering) lookup( MavenResourcesFiltering.class.getName() );
+
+ String unitFilesDir = getBasedir() +
"/src/test/units-files/MRESOURCES-104";
+
+ Resource resource = new Resource();
+ List resources = new ArrayList();
+ resources.add( resource );
+ resource.setDirectory( unitFilesDir );
+ resource.setFiltering( true );
+
+ List filtersFile = new ArrayList();
+ filtersFile.add( getBasedir() +
"/src/test/units-files/MRESOURCES-104/test.properties" );
+
+ List nonFilteredFileExtensions = Collections.singletonList( "gif" );
+
+ MavenResourcesExecution mavenResourcesExecution = new
MavenResourcesExecution( resources, outputDirectory,
+
mavenProject, "UTF-8",
+
filtersFile,
+
nonFilteredFileExtensions,
+
new StubMavenSession() );
+ mavenResourcesExecution.setUseDefaultFilterWrappers( true );
+
+
+ mavenResourcesFiltering.filterResources( mavenResourcesExecution );
+
+ Properties result = new Properties();
+ FileInputStream in = null;
+ try
+ {
+ in = new FileInputStream( new File( outputDirectory,
"test.properties" ) );
+ result.load( in );
+ }
+ finally
+ {
+ IOUtil.close( in );
+ }
+
+ System.out.println("properties " + result.toString());
+ //[email protected]
+ //foo=${project.version}
+ //[email protected]@
+ assertEquals( "1.0", result.get( "foo" ) );
+ assertEquals( "1.0", result.get( "bar" ) );
+ assertEquals( "[email protected]", result.get( "email" ) );
+ }
+
+}
Propchange:
maven/shared/trunk/maven-filtering/src/test/java/org/apache/maven/shared/filtering/MuliLinesMavenResourcesFilteringTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
maven/shared/trunk/maven-filtering/src/test/java/org/apache/maven/shared/filtering/MuliLinesMavenResourcesFilteringTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added:
maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/test.properties
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/test.properties?rev=1052026&view=auto
==============================================================================
---
maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/test.properties
(added)
+++
maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/test.properties
Wed Dec 22 18:42:50 2010
@@ -0,0 +1,3 @@
[email protected]
+foo=${project.version}
[email protected]@
Propchange:
maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/test.properties
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
maven/shared/trunk/maven-filtering/src/test/units-files/MRESOURCES-104/test.properties
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision