View Javadoc
1   package org.apache.maven.model.interpolation;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.Collections;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Map;
29  
30  import javax.inject.Inject;
31  
32  import org.apache.maven.api.model.Model;
33  import org.apache.maven.model.building.ModelBuildingRequest;
34  import org.apache.maven.model.building.ModelProblemCollector;
35  import org.apache.maven.model.path.PathTranslator;
36  import org.apache.maven.model.path.UrlNormalizer;
37  import org.codehaus.plexus.interpolation.AbstractValueSource;
38  import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
39  import org.codehaus.plexus.interpolation.MapBasedValueSource;
40  import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
41  import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
42  import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper;
43  import org.codehaus.plexus.interpolation.RecursionInterceptor;
44  import org.codehaus.plexus.interpolation.ValueSource;
45  
46  /**
47   * Use a regular expression search to find and resolve expressions within the POM.
48   *
49   * @author jdcasey Created on Feb 3, 2005
50   */
51  public abstract class AbstractStringBasedModelInterpolator
52      implements ModelInterpolator
53  {
54      private static final List<String> PROJECT_PREFIXES = Collections.singletonList( "project." );
55  
56      private static final Collection<String> TRANSLATED_PATH_EXPRESSIONS;
57  
58      static
59      {
60          Collection<String> translatedPrefixes = new HashSet<>();
61  
62          // MNG-1927, MNG-2124, MNG-3355:
63          // If the build section is present and the project directory is non-null, we should make
64          // sure interpolation of the directories below uses translated paths.
65          // Afterward, we'll double back and translate any paths that weren't covered during interpolation via the
66          // code below...
67          translatedPrefixes.add( "build.directory" );
68          translatedPrefixes.add( "build.outputDirectory" );
69          translatedPrefixes.add( "build.testOutputDirectory" );
70          translatedPrefixes.add( "build.sourceDirectory" );
71          translatedPrefixes.add( "build.testSourceDirectory" );
72          translatedPrefixes.add( "build.scriptSourceDirectory" );
73          translatedPrefixes.add( "reporting.outputDirectory" );
74  
75          TRANSLATED_PATH_EXPRESSIONS = translatedPrefixes;
76      }
77  
78      private final PathTranslator pathTranslator;
79      private final UrlNormalizer urlNormalizer;
80  
81      @Inject
82      public AbstractStringBasedModelInterpolator( PathTranslator pathTranslator, UrlNormalizer urlNormalizer )
83      {
84          this.pathTranslator = pathTranslator;
85          this.urlNormalizer = urlNormalizer;
86      }
87  
88      @Override
89      public org.apache.maven.model.Model interpolateModel( org.apache.maven.model.Model model, File projectDir,
90                                                            ModelBuildingRequest request, ModelProblemCollector problems )
91      {
92          return new org.apache.maven.model.Model( interpolateModel( model.getDelegate(), projectDir,
93                  request, problems ) );
94      }
95  
96      protected List<ValueSource> createValueSources( final Model model, final File projectDir,
97                                                      final ModelBuildingRequest config )
98      {
99          Map<String, String> modelProperties = model.getProperties();
100 
101         ValueSource projectPrefixValueSource = new PrefixedObjectValueSource( PROJECT_PREFIXES, model, false );
102 
103         // NOTE: Order counts here!
104         List<ValueSource> valueSources = new ArrayList<>( 8 );
105 
106         if ( projectDir != null )
107         {
108             ValueSource basedirValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false )
109             {
110                 @Override
111                 public Object getValue( String expression )
112                 {
113                     if ( "basedir".equals( expression ) )
114                     {
115                         return projectDir.getAbsolutePath();
116                     }
117                     return null;
118                 }
119             }, PROJECT_PREFIXES, true );
120             valueSources.add( basedirValueSource );
121 
122             ValueSource baseUriValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false )
123             {
124                 @Override
125                 public Object getValue( String expression )
126                 {
127                     if ( "baseUri".equals( expression ) )
128                     {
129                         return projectDir.getAbsoluteFile().toPath().toUri().toASCIIString();
130                     }
131                     return null;
132                 }
133             }, PROJECT_PREFIXES, false );
134             valueSources.add( baseUriValueSource );
135             valueSources.add( new BuildTimestampValueSource( config.getBuildStartTime(), modelProperties ) );
136         }
137 
138         valueSources.add( projectPrefixValueSource );
139 
140         valueSources.add( new MapBasedValueSource( config.getUserProperties() ) );
141 
142         valueSources.add( new MapBasedValueSource( modelProperties ) );
143 
144         valueSources.add( new MapBasedValueSource( config.getSystemProperties() ) );
145 
146         valueSources.add( new AbstractValueSource( false )
147         {
148             @Override
149             public Object getValue( String expression )
150             {
151                 return config.getSystemProperties().getProperty( "env." + expression );
152             }
153         } );
154 
155         return valueSources;
156     }
157 
158     protected List<? extends InterpolationPostProcessor> createPostProcessors( final Model model,
159                                                                                final File projectDir,
160                                                                                final ModelBuildingRequest config )
161     {
162         List<InterpolationPostProcessor> processors = new ArrayList<>( 2 );
163         if ( projectDir != null )
164         {
165             processors.add( new PathTranslatingPostProcessor( PROJECT_PREFIXES, TRANSLATED_PATH_EXPRESSIONS,
166                                                               projectDir, pathTranslator ) );
167         }
168         processors.add( new UrlNormalizingPostProcessor( urlNormalizer ) );
169         return processors;
170     }
171 
172     protected RecursionInterceptor createRecursionInterceptor()
173     {
174         return new PrefixAwareRecursionInterceptor( PROJECT_PREFIXES );
175     }
176 
177 }