| package org.apache.maven.plugin.assembly.interpolation; |
| |
| /* |
| * 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.IOException; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.Set; |
| |
| import org.apache.maven.execution.MavenSession; |
| import org.apache.maven.plugin.assembly.AssemblerConfigurationSource; |
| import org.apache.maven.plugin.assembly.io.DefaultAssemblyReader; |
| import org.apache.maven.plugin.assembly.model.Assembly; |
| import org.apache.maven.plugin.assembly.utils.AssemblyFileUtils; |
| import org.apache.maven.plugin.assembly.utils.InterpolationConstants; |
| import org.apache.maven.project.MavenProject; |
| import org.codehaus.plexus.interpolation.InterpolationException; |
| import org.codehaus.plexus.interpolation.InterpolationPostProcessor; |
| import org.codehaus.plexus.interpolation.Interpolator; |
| import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor; |
| import org.codehaus.plexus.interpolation.PrefixedObjectValueSource; |
| import org.codehaus.plexus.interpolation.PrefixedPropertiesValueSource; |
| import org.codehaus.plexus.interpolation.PropertiesBasedValueSource; |
| import org.codehaus.plexus.interpolation.RecursionInterceptor; |
| import org.codehaus.plexus.interpolation.StringSearchInterpolator; |
| import org.codehaus.plexus.interpolation.object.FieldBasedObjectInterpolator; |
| import org.codehaus.plexus.interpolation.object.ObjectInterpolationWarning; |
| import org.codehaus.plexus.logging.AbstractLogEnabled; |
| import org.codehaus.plexus.logging.Logger; |
| import org.codehaus.plexus.logging.console.ConsoleLogger; |
| import org.codehaus.plexus.util.cli.CommandLineUtils; |
| |
| /** |
| * @version $Id$ |
| */ |
| public class AssemblyInterpolator |
| extends AbstractLogEnabled |
| { |
| private static final Set<String> INTERPOLATION_BLACKLIST; |
| |
| private static final Properties ENVIRONMENT_VARIABLES; |
| |
| static |
| { |
| final Set<String> blacklist = new HashSet<String>(); |
| |
| blacklist.add( "outputFileNameMapping" ); |
| blacklist.add( "outputDirectoryMapping" ); |
| blacklist.add( "outputDirectory" ); |
| |
| INTERPOLATION_BLACKLIST = blacklist; |
| |
| Properties environmentVariables; |
| try |
| { |
| environmentVariables = CommandLineUtils.getSystemEnvVars( false ); |
| } |
| catch ( final IOException e ) |
| { |
| environmentVariables = new Properties(); |
| } |
| |
| ENVIRONMENT_VARIABLES = environmentVariables; |
| } |
| |
| public AssemblyInterpolator() |
| throws IOException |
| { |
| } |
| |
| public Assembly interpolate( final Assembly assembly, final MavenProject project, |
| final AssemblerConfigurationSource configSource ) |
| throws AssemblyInterpolationException |
| { |
| @SuppressWarnings( "unchecked" ) |
| final Set<String> blacklistFields = |
| new HashSet<String>( FieldBasedObjectInterpolator.DEFAULT_BLACKLISTED_FIELD_NAMES ); |
| blacklistFields.addAll( INTERPOLATION_BLACKLIST ); |
| |
| @SuppressWarnings( "unchecked" ) |
| final Set<String> blacklistPkgs = FieldBasedObjectInterpolator.DEFAULT_BLACKLISTED_PACKAGE_PREFIXES; |
| |
| final FieldBasedObjectInterpolator objectInterpolator = |
| new FieldBasedObjectInterpolator( blacklistFields, blacklistPkgs ); |
| final Interpolator interpolator = buildInterpolator( project, configSource ); |
| |
| // TODO: Will this adequately detect cycles between prefixed property references and prefixed project |
| // references?? |
| final RecursionInterceptor interceptor = |
| new PrefixAwareRecursionInterceptor( InterpolationConstants.PROJECT_PREFIXES, true ); |
| |
| try |
| { |
| objectInterpolator.interpolate( assembly, interpolator, interceptor ); |
| } |
| catch ( final InterpolationException e ) |
| { |
| throw new AssemblyInterpolationException( "Failed to interpolate assembly with ID: " + assembly.getId() |
| + ". Reason: " + e.getMessage(), e ); |
| } |
| finally |
| { |
| interpolator.clearAnswers(); |
| } |
| |
| if ( objectInterpolator.hasWarnings() && getLogger().isDebugEnabled() ) |
| { |
| final StringBuilder sb = new StringBuilder(); |
| |
| sb.append( "One or more minor errors occurred while interpolating the assembly with ID: " ).append( assembly.getId() ).append( ":\n" ); |
| |
| @SuppressWarnings( "unchecked" ) |
| final List<ObjectInterpolationWarning> warnings = objectInterpolator.getWarnings(); |
| for ( final ObjectInterpolationWarning warning : warnings ) |
| { |
| sb.append( '\n' ).append( warning ); |
| } |
| |
| sb.append( "\n\nThese values were SKIPPED, but the assembly process will continue.\n" ); |
| |
| getLogger().debug( sb.toString() ); |
| } |
| |
| return assembly; |
| } |
| |
| public static Interpolator buildInterpolator( final MavenProject project, |
| final AssemblerConfigurationSource configSource ) |
| { |
| final StringSearchInterpolator interpolator = new StringSearchInterpolator(); |
| interpolator.setCacheAnswers( true ); |
| |
| final MavenSession session = configSource.getMavenSession(); |
| |
| if ( session != null ) |
| { |
| Properties userProperties = null; |
| try |
| { |
| userProperties = session.getExecutionProperties(); |
| } |
| catch ( final NoSuchMethodError nsmer ) |
| { |
| // OK, so user is using Maven <= 2.0.8. No big deal. |
| } |
| |
| if ( userProperties != null ) |
| { |
| // 4 |
| interpolator.addValueSource( new PropertiesBasedValueSource( userProperties ) ); |
| } |
| } |
| |
| interpolator.addValueSource( new PrefixedPropertiesValueSource( |
| InterpolationConstants.PROJECT_PROPERTIES_PREFIXES, |
| project.getProperties(), true ) ); |
| interpolator.addValueSource( new PrefixedObjectValueSource( InterpolationConstants.PROJECT_PREFIXES, project, |
| true ) ); |
| |
| final Properties settingsProperties = new Properties(); |
| if ( configSource.getLocalRepository() != null ) |
| { |
| settingsProperties.setProperty( "localRepository", configSource.getLocalRepository().getBasedir() ); |
| settingsProperties.setProperty( "settings.localRepository", configSource.getLocalRepository().getBasedir() ); |
| } |
| else if ( session != null && session.getSettings() != null ) |
| { |
| settingsProperties.setProperty( "localRepository", session.getSettings().getLocalRepository() ); |
| settingsProperties.setProperty( "settings.localRepository", configSource.getLocalRepository().getBasedir() ); |
| } |
| |
| interpolator.addValueSource( new PropertiesBasedValueSource( settingsProperties ) ); |
| |
| Properties commandLineProperties = DefaultAssemblyReader.mergeExecutionPropertiesWithSystemPropertiew( session ); |
| |
| // 7 |
| interpolator.addValueSource( new PropertiesBasedValueSource( commandLineProperties ) ); |
| interpolator.addValueSource( new PrefixedPropertiesValueSource( Collections.singletonList( "env." ), |
| ENVIRONMENT_VARIABLES, true ) ); |
| |
| interpolator.addPostProcessor( new PathTranslatingPostProcessor( project.getBasedir() ) ); |
| return interpolator; |
| } |
| |
| @Override |
| protected Logger getLogger() |
| { |
| Logger logger = super.getLogger(); |
| |
| if ( logger == null ) |
| { |
| logger = new ConsoleLogger( Logger.LEVEL_INFO, "interpolator-internal" ); |
| |
| enableLogging( logger ); |
| } |
| |
| return logger; |
| } |
| |
| private static final class PathTranslatingPostProcessor |
| implements InterpolationPostProcessor |
| { |
| |
| private final File basedir; |
| |
| public PathTranslatingPostProcessor( final File basedir ) |
| { |
| this.basedir = basedir; |
| } |
| |
| public Object execute( final String expression, final Object value ) |
| { |
| final String path = String.valueOf( value ); |
| return AssemblyFileUtils.makePathRelativeTo( path, basedir ); |
| } |
| |
| } |
| } |