1 package org.apache.maven.plugin.assembly.interpolation;
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.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Properties;
28 import java.util.Set;
29
30 import org.apache.maven.execution.MavenSession;
31 import org.apache.maven.plugin.assembly.AssemblerConfigurationSource;
32 import org.apache.maven.plugin.assembly.model.Assembly;
33 import org.apache.maven.plugin.assembly.utils.AssemblyFileUtils;
34 import org.apache.maven.plugin.assembly.utils.InterpolationConstants;
35 import org.apache.maven.project.MavenProject;
36 import org.codehaus.plexus.interpolation.InterpolationException;
37 import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
38 import org.codehaus.plexus.interpolation.Interpolator;
39 import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
40 import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
41 import org.codehaus.plexus.interpolation.PrefixedPropertiesValueSource;
42 import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
43 import org.codehaus.plexus.interpolation.RecursionInterceptor;
44 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
45 import org.codehaus.plexus.interpolation.object.FieldBasedObjectInterpolator;
46 import org.codehaus.plexus.interpolation.object.ObjectInterpolationWarning;
47 import org.codehaus.plexus.logging.AbstractLogEnabled;
48 import org.codehaus.plexus.logging.Logger;
49 import org.codehaus.plexus.logging.console.ConsoleLogger;
50 import org.codehaus.plexus.util.cli.CommandLineUtils;
51
52
53
54
55 public class AssemblyInterpolator
56 extends AbstractLogEnabled
57 {
58 private static final Set<String> INTERPOLATION_BLACKLIST;
59
60 private static final Properties ENVIRONMENT_VARIABLES;
61
62 static
63 {
64 final Set<String> blacklist = new HashSet<String>();
65
66 blacklist.add( "outputFileNameMapping" );
67 blacklist.add( "outputDirectoryMapping" );
68 blacklist.add( "outputDirectory" );
69
70 INTERPOLATION_BLACKLIST = blacklist;
71
72 Properties environmentVariables;
73 try
74 {
75 environmentVariables = CommandLineUtils.getSystemEnvVars( false );
76 }
77 catch ( final IOException e )
78 {
79 environmentVariables = new Properties();
80 }
81
82 ENVIRONMENT_VARIABLES = environmentVariables;
83 }
84
85 public AssemblyInterpolator()
86 throws IOException
87 {
88 }
89
90 public Assembly interpolate( final Assembly assembly, final MavenProject project,
91 final AssemblerConfigurationSource configSource )
92 throws AssemblyInterpolationException
93 {
94 @SuppressWarnings( "unchecked" )
95 final Set<String> blacklistFields =
96 new HashSet<String>( FieldBasedObjectInterpolator.DEFAULT_BLACKLISTED_FIELD_NAMES );
97 blacklistFields.addAll( INTERPOLATION_BLACKLIST );
98
99 @SuppressWarnings( "unchecked" )
100 final Set<String> blacklistPkgs = FieldBasedObjectInterpolator.DEFAULT_BLACKLISTED_PACKAGE_PREFIXES;
101
102 final FieldBasedObjectInterpolator objectInterpolator =
103 new FieldBasedObjectInterpolator( blacklistFields, blacklistPkgs );
104 final Interpolator interpolator = buildInterpolator( project, configSource );
105
106
107
108 final RecursionInterceptor interceptor =
109 new PrefixAwareRecursionInterceptor( InterpolationConstants.PROJECT_PREFIXES, true );
110
111 try
112 {
113 objectInterpolator.interpolate( assembly, interpolator, interceptor );
114 }
115 catch ( final InterpolationException e )
116 {
117 throw new AssemblyInterpolationException( "Failed to interpolate assembly with ID: " + assembly.getId()
118 + ". Reason: " + e.getMessage(), e );
119 }
120 finally
121 {
122 interpolator.clearAnswers();
123 }
124
125 if ( objectInterpolator.hasWarnings() && getLogger().isDebugEnabled() )
126 {
127 final StringBuilder sb = new StringBuilder();
128
129 sb.append("One or more minor errors occurred while interpolating the assembly with ID: ").append(assembly.getId()).append(":\n");
130
131 @SuppressWarnings( "unchecked" )
132 final List<ObjectInterpolationWarning> warnings = objectInterpolator.getWarnings();
133 for (final ObjectInterpolationWarning warning : warnings) {
134 sb.append('\n').append(warning);
135 }
136
137 sb.append( "\n\nThese values were SKIPPED, but the assembly process will continue.\n" );
138
139 getLogger().debug( sb.toString() );
140 }
141
142 return assembly;
143 }
144
145 public static Interpolator buildInterpolator( final MavenProject project,
146 final AssemblerConfigurationSource configSource )
147 {
148 final StringSearchInterpolator interpolator = new StringSearchInterpolator();
149 interpolator.setCacheAnswers( true );
150
151 final MavenSession session = configSource.getMavenSession();
152
153 if ( session != null )
154 {
155 Properties userProperties = null;
156 try
157 {
158 userProperties = session.getExecutionProperties();
159 }
160 catch ( final NoSuchMethodError nsmer )
161 {
162
163 }
164
165 if ( userProperties != null )
166 {
167
168 interpolator.addValueSource( new PropertiesBasedValueSource( userProperties ) );
169 }
170 }
171
172 interpolator.addValueSource( new PrefixedPropertiesValueSource(
173 InterpolationConstants.PROJECT_PROPERTIES_PREFIXES,
174 project.getProperties(), true ) );
175 interpolator.addValueSource( new PrefixedObjectValueSource( InterpolationConstants.PROJECT_PREFIXES, project,
176 true ) );
177
178 final Properties settingsProperties = new Properties();
179 if ( configSource.getLocalRepository() != null )
180 {
181 settingsProperties.setProperty( "localRepository", configSource.getLocalRepository().getBasedir() );
182 settingsProperties.setProperty( "settings.localRepository", configSource.getLocalRepository().getBasedir() );
183 }
184 else if ( session != null && session.getSettings() != null )
185 {
186 settingsProperties.setProperty( "localRepository", session.getSettings().getLocalRepository() );
187 settingsProperties.setProperty( "settings.localRepository", configSource.getLocalRepository().getBasedir() );
188 }
189
190 interpolator.addValueSource( new PropertiesBasedValueSource( settingsProperties ) );
191
192 Properties commandLineProperties = System.getProperties();
193 if ( session != null )
194 {
195 commandLineProperties = new Properties();
196 if ( session.getExecutionProperties() != null )
197 {
198 commandLineProperties.putAll( session.getExecutionProperties() );
199 }
200
201 if ( session.getUserProperties() != null )
202 {
203 commandLineProperties.putAll( session.getUserProperties() );
204 }
205 }
206
207
208 interpolator.addValueSource( new PropertiesBasedValueSource( commandLineProperties ) );
209 interpolator.addValueSource( new PrefixedPropertiesValueSource( Collections.singletonList( "env." ),
210 ENVIRONMENT_VARIABLES, true ) );
211
212 interpolator.addPostProcessor( new PathTranslatingPostProcessor( project.getBasedir() ) );
213 return interpolator;
214 }
215
216 @Override
217 protected Logger getLogger()
218 {
219 Logger logger = super.getLogger();
220
221 if ( logger == null )
222 {
223 logger = new ConsoleLogger( Logger.LEVEL_INFO, "interpolator-internal" );
224
225 enableLogging( logger );
226 }
227
228 return logger;
229 }
230
231 private static final class PathTranslatingPostProcessor
232 implements InterpolationPostProcessor
233 {
234
235 private final File basedir;
236
237 public PathTranslatingPostProcessor( final File basedir )
238 {
239 this.basedir = basedir;
240 }
241
242 public Object execute( final String expression, final Object value )
243 {
244 final String path = String.valueOf( value );
245 return AssemblyFileUtils.makePathRelativeTo( path, basedir );
246 }
247
248 }
249 }