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