1 package org.apache.maven.project.interpolation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.model.Model;
23 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
24 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
25 import org.codehaus.plexus.logging.AbstractLogEnabled;
26 import org.codehaus.plexus.logging.Logger;
27 import org.codehaus.plexus.util.StringUtils;
28 import org.codehaus.plexus.util.cli.CommandLineUtils;
29 import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
30 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
31
32 import java.io.IOException;
33 import java.io.StringReader;
34 import java.io.StringWriter;
35 import java.util.Map;
36 import java.util.Properties;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40
41
42
43
44
45
46
47 public class RegexBasedModelInterpolator
48 extends AbstractLogEnabled
49 implements ModelInterpolator
50 {
51 private static final Pattern EXPRESSION_PATTERN = Pattern.compile( "\\$\\{(pom\\.|project\\.|env\\.)?([^}]+)\\}" );
52
53 private Properties envars;
54
55 public RegexBasedModelInterpolator( Properties envars )
56 {
57 this.envars = envars;
58 }
59
60 public RegexBasedModelInterpolator()
61 throws IOException
62 {
63 envars = CommandLineUtils.getSystemEnvVars();
64 }
65
66 public Model interpolate( Model model, Map context )
67 throws ModelInterpolationException
68 {
69 return interpolate( model, context, true );
70 }
71
72
73
74
75
76
77
78
79
80
81
82 public Model interpolate( Model model, Map context, boolean strict )
83 throws ModelInterpolationException
84 {
85 StringWriter sWriter = new StringWriter();
86
87 MavenXpp3Writer writer = new MavenXpp3Writer();
88 try
89 {
90 writer.write( sWriter, model );
91 }
92 catch ( IOException e )
93 {
94 throw new ModelInterpolationException( "Cannot serialize project model for interpolation.", e );
95 }
96
97 String serializedModel = sWriter.toString();
98 serializedModel = interpolateInternal( serializedModel, model, context );
99
100 StringReader sReader = new StringReader( serializedModel );
101
102 MavenXpp3Reader modelReader = new MavenXpp3Reader();
103 try
104 {
105 model = modelReader.read( sReader );
106 }
107 catch ( IOException e )
108 {
109 throw new ModelInterpolationException(
110 "Cannot read project model from interpolating filter of serialized version.", e );
111 }
112 catch ( XmlPullParserException e )
113 {
114 throw new ModelInterpolationException(
115 "Cannot read project model from interpolating filter of serialized version.", e );
116 }
117
118 return model;
119 }
120
121 private String interpolateInternal( String src, Model model, Map context )
122 throws ModelInterpolationException
123 {
124 String result = src;
125 Matcher matcher = EXPRESSION_PATTERN.matcher( result );
126 while ( matcher.find() )
127 {
128 String wholeExpr = matcher.group( 0 );
129 String realExpr = matcher.group( 2 );
130
131 Object value = context.get( realExpr );
132
133 if ( value == null )
134 {
135
136 if ( context.containsKey( realExpr ) )
137 {
138
139 continue;
140 }
141
142 value = model.getProperties().getProperty( realExpr );
143 }
144
145 if ( value == null )
146 {
147 try
148 {
149
150
151
152 value = ReflectionValueExtractor.evaluate( realExpr, model, false );
153 }
154 catch ( Exception e )
155 {
156 Logger logger = getLogger();
157 if ( logger != null )
158 {
159 logger.debug( "POM interpolation cannot proceed with expression: " + wholeExpr + ". Skipping...", e );
160 }
161 }
162 }
163
164 if ( value == null )
165 {
166 value = envars.getProperty( realExpr );
167 }
168
169
170 if ( String.valueOf( value ).indexOf( wholeExpr ) > -1 )
171 {
172 throw new ModelInterpolationException( wholeExpr, "Expression value '" + value + "' references itself in '" + model.getId() + "'." );
173 }
174
175 if ( value != null )
176 {
177 result = StringUtils.replace( result, wholeExpr, String.valueOf( value ) );
178
179
180
181 matcher.reset( result );
182 }
183
184
185
186
187
188
189
190
191
192
193 }
194
195 return result;
196 }
197
198 }