1 package org.apache.maven.shared.filtering;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.Reader;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.LinkedHashSet;
28 import java.util.List;
29 import java.util.Properties;
30
31 import javax.annotation.Nonnull;
32
33 import org.apache.maven.execution.MavenSession;
34 import org.apache.maven.project.MavenProject;
35 import org.apache.maven.settings.Settings;
36 import org.apache.maven.shared.utils.StringUtils;
37 import org.apache.maven.shared.utils.io.FileUtils;
38 import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
39 import org.codehaus.plexus.interpolation.Interpolator;
40 import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
41 import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
42 import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
43 import org.codehaus.plexus.interpolation.RecursionInterceptor;
44 import org.codehaus.plexus.interpolation.SimpleRecursionInterceptor;
45 import org.codehaus.plexus.interpolation.SingleResponseValueSource;
46 import org.codehaus.plexus.interpolation.ValueSource;
47 import org.codehaus.plexus.interpolation.multi.MultiDelimiterStringSearchInterpolator;
48 import org.codehaus.plexus.logging.AbstractLogEnabled;
49
50 class BaseFilter
51 extends AbstractLogEnabled
52 implements DefaultFilterInfo
53 {
54
55 @Override
56 @Nonnull
57 public List<FileUtils.FilterWrapper> getDefaultFilterWrappers( final MavenProject mavenProject,
58 List<String> filters,
59 final boolean escapedBackslashesInFilePath,
60 MavenSession mavenSession,
61 MavenResourcesExecution mavenResourcesExecution )
62 throws MavenFilteringException
63 {
64
65 MavenResourcesExecution mre =
66 mavenResourcesExecution == null ? new MavenResourcesExecution() : mavenResourcesExecution.copyOf();
67
68 mre.setMavenProject( mavenProject );
69 mre.setMavenSession( mavenSession );
70 mre.setFilters( filters );
71 mre.setEscapedBackslashesInFilePath( escapedBackslashesInFilePath );
72
73 return getDefaultFilterWrappers( mre );
74
75 }
76
77 @Override
78 @Nonnull
79 public List<FileUtils.FilterWrapper> getDefaultFilterWrappers( final AbstractMavenFilteringRequest req )
80 throws MavenFilteringException
81 {
82
83 boolean supportMultiLineFiltering = req.isSupportMultiLineFiltering();
84
85
86 final AbstractMavenFilteringRequest request = req == null ? new MavenFileFilterRequest() : req;
87
88 request.setSupportMultiLineFiltering( supportMultiLineFiltering );
89
90
91
92
93
94
95
96 final Properties baseProps = new Properties();
97
98
99 if ( request.getMavenProject() != null )
100 {
101 baseProps.putAll( request.getMavenProject().getProperties() == null ? Collections.emptyMap()
102 : request.getMavenProject().getProperties() );
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116 if ( request.getMavenSession() != null )
117 {
118
119 baseProps.putAll( request.getMavenSession().getSystemProperties() );
120 baseProps.putAll( request.getMavenSession().getUserProperties() );
121 }
122
123
124
125 final Properties filterProperties = new Properties();
126
127 File basedir = request.getMavenProject() != null ? request.getMavenProject().getBasedir() : new File( "." );
128
129 loadProperties( filterProperties, basedir, request.getFileFilters(), baseProps );
130 if ( filterProperties.size() < 1 )
131 {
132 filterProperties.putAll( baseProps );
133 }
134
135 if ( request.getMavenProject() != null )
136 {
137 if ( request.isInjectProjectBuildFilters() )
138 {
139 List<String> buildFilters = new ArrayList<>( request.getMavenProject().getBuild().getFilters() );
140
141
142 if ( request.getFileFilters() != null )
143 {
144 buildFilters.removeAll( request.getFileFilters() );
145 }
146
147 loadProperties( filterProperties, basedir, buildFilters, baseProps );
148 }
149
150
151 filterProperties.putAll( request.getMavenProject().getProperties() == null ? Collections.emptyMap()
152 : request.getMavenProject().getProperties() );
153 }
154 if ( request.getMavenSession() != null )
155 {
156
157 filterProperties.putAll( request.getMavenSession().getSystemProperties() );
158 filterProperties.putAll( request.getMavenSession().getUserProperties() );
159 }
160
161 if ( request.getAdditionalProperties() != null )
162 {
163
164 filterProperties.putAll( request.getAdditionalProperties() );
165 }
166
167 List<FileUtils.FilterWrapper> defaultFilterWrappers =
168 request == null ? new ArrayList<FileUtils.FilterWrapper>( 1 )
169 : new ArrayList<FileUtils.FilterWrapper>( request.getDelimiters().size() + 1 );
170
171 if ( getLogger().isDebugEnabled() )
172 {
173 getLogger().debug( "properties used " + filterProperties );
174 }
175
176 final ValueSource propertiesValueSource = new PropertiesBasedValueSource( filterProperties );
177
178 if ( request != null )
179 {
180 FileUtils.FilterWrapper wrapper =
181 new Wrapper( request.getDelimiters(), request.getMavenProject(), request.getMavenSession(),
182 propertiesValueSource, request.getProjectStartExpressions(), request.getEscapeString(),
183 request.isEscapeWindowsPaths(), request.isSupportMultiLineFiltering() );
184
185 defaultFilterWrappers.add( wrapper );
186 }
187
188 return defaultFilterWrappers;
189 }
190
191
192
193
194 void loadProperties( Properties filterProperties, File basedir, List<String> propertiesFilePaths,
195 Properties baseProps )
196 throws MavenFilteringException
197 {
198 if ( propertiesFilePaths != null )
199 {
200 Properties workProperties = new Properties();
201 workProperties.putAll( baseProps );
202
203 for ( String filterFile : propertiesFilePaths )
204 {
205 if ( StringUtils.isEmpty( filterFile ) )
206 {
207
208 continue;
209 }
210 try
211 {
212 File propFile = FileUtils.resolveFile( basedir, filterFile );
213 Properties properties = PropertyUtils.loadPropertyFile( propFile, workProperties, getLogger() );
214 filterProperties.putAll( properties );
215 workProperties.putAll( properties );
216 }
217 catch ( IOException e )
218 {
219 throw new MavenFilteringException( "Error loading property file '" + filterFile + "'", e );
220 }
221 }
222 }
223 }
224
225 private static final class Wrapper
226 extends FileUtils.FilterWrapper
227 {
228
229 private LinkedHashSet<String> delimiters;
230
231 private MavenProject project;
232
233 private ValueSource propertiesValueSource;
234
235 private List<String> projectStartExpressions;
236
237 private String escapeString;
238
239 private boolean escapeWindowsPaths;
240
241 private final MavenSession mavenSession;
242
243 private boolean supportMultiLineFiltering;
244
245 Wrapper( LinkedHashSet<String> delimiters, MavenProject project, MavenSession mavenSession,
246 ValueSource propertiesValueSource, List<String> projectStartExpressions, String escapeString,
247 boolean escapeWindowsPaths, boolean supportMultiLineFiltering )
248 {
249 super();
250 this.delimiters = delimiters;
251 this.project = project;
252 this.mavenSession = mavenSession;
253 this.propertiesValueSource = propertiesValueSource;
254 this.projectStartExpressions = projectStartExpressions;
255 this.escapeString = escapeString;
256 this.escapeWindowsPaths = escapeWindowsPaths;
257 this.supportMultiLineFiltering = supportMultiLineFiltering;
258 }
259
260 @Override
261 public Reader getReader( Reader reader )
262 {
263 Interpolator interpolator = createInterpolator( delimiters, projectStartExpressions, propertiesValueSource,
264 project, mavenSession, escapeString, escapeWindowsPaths );
265
266 MultiDelimiterInterpolatorFilterReaderLineEnding filterReader =
267 new MultiDelimiterInterpolatorFilterReaderLineEnding( reader, interpolator, supportMultiLineFiltering );
268
269 final RecursionInterceptor ri;
270 if ( projectStartExpressions != null && !projectStartExpressions.isEmpty() )
271 {
272 ri = new PrefixAwareRecursionInterceptor( projectStartExpressions, true );
273 }
274 else
275 {
276 ri = new SimpleRecursionInterceptor();
277 }
278
279 filterReader.setRecursionInterceptor( ri );
280 filterReader.setDelimiterSpecs( delimiters );
281
282 filterReader.setInterpolateWithPrefixPattern( false );
283 filterReader.setEscapeString( escapeString );
284
285 return filterReader;
286 }
287
288 }
289
290 private static Interpolator createInterpolator( LinkedHashSet<String> delimiters,
291 List<String> projectStartExpressions,
292 ValueSource propertiesValueSource, MavenProject project,
293 MavenSession mavenSession, String escapeString,
294 boolean escapeWindowsPaths )
295 {
296 MultiDelimiterStringSearchInterpolator interpolator = new MultiDelimiterStringSearchInterpolator();
297 interpolator.setDelimiterSpecs( delimiters );
298
299 interpolator.addValueSource( propertiesValueSource );
300
301 if ( project != null )
302 {
303 interpolator.addValueSource( new PrefixedObjectValueSource( projectStartExpressions, project, true ) );
304 }
305
306 if ( mavenSession != null )
307 {
308 interpolator.addValueSource( new PrefixedObjectValueSource( "session", mavenSession ) );
309
310 final Settings settings = mavenSession.getSettings();
311 if ( settings != null )
312 {
313 interpolator.addValueSource( new PrefixedObjectValueSource( "settings", settings ) );
314 interpolator.addValueSource( new SingleResponseValueSource( "localRepository",
315 settings.getLocalRepository() ) );
316 }
317 }
318
319 interpolator.setEscapeString( escapeString );
320
321 if ( escapeWindowsPaths )
322 {
323 interpolator.addPostProcessor( new InterpolationPostProcessor()
324 {
325 @Override
326 public Object execute( String expression, Object value )
327 {
328 if ( value instanceof String )
329 {
330 return FilteringUtils.escapeWindowsPath( (String) value );
331 }
332
333 return value;
334 }
335 } );
336 }
337 return interpolator;
338 }
339 }