View Javadoc
1   package org.apache.maven.model.profile.activation;
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  
24  import javax.inject.Inject;
25  import javax.inject.Named;
26  import javax.inject.Singleton;
27  
28  import org.apache.maven.model.Activation;
29  import org.apache.maven.model.ActivationFile;
30  import org.apache.maven.model.Profile;
31  import org.apache.maven.model.building.ModelProblemCollector;
32  import org.apache.maven.model.building.ModelProblem.Severity;
33  import org.apache.maven.model.building.ModelProblem.Version;
34  import org.apache.maven.model.building.ModelProblemCollectorRequest;
35  import org.apache.maven.model.path.PathTranslator;
36  import org.apache.maven.model.profile.ProfileActivationContext;
37  import org.codehaus.plexus.interpolation.AbstractValueSource;
38  import org.codehaus.plexus.interpolation.MapBasedValueSource;
39  import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
40  import org.codehaus.plexus.util.StringUtils;
41  
42  /**
43   * Determines profile activation based on the existence/absence of some file.
44   * File name interpolation support is limited to <code>${basedir}</code> (since Maven 3,
45   * see <a href="https://issues.apache.org/jira/browse/MNG-2363">MNG-2363</a>),
46   * System properties and request properties.
47   * <code>${project.basedir}</code> is intentionally not supported as this form would suggest that other
48   * <code>${project.*}</code> expressions can be used, which is however beyond the design.
49   *
50   * @author Benjamin Bentmann
51   * @see ActivationFile
52   * @see org.apache.maven.model.validation.DefaultModelValidator#validateRawModel
53   */
54  @Named( "file" )
55  @Singleton
56  public class FileProfileActivator
57      implements ProfileActivator
58  {
59  
60      @Inject
61      private PathTranslator pathTranslator;
62  
63      public FileProfileActivator setPathTranslator( PathTranslator pathTranslator )
64      {
65          this.pathTranslator = pathTranslator;
66          return this;
67      }
68  
69      @Override
70      public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
71      {
72          Activation activation = profile.getActivation();
73  
74          if ( activation == null )
75          {
76              return false;
77          }
78  
79          ActivationFile file = activation.getFile();
80  
81          if ( file == null )
82          {
83              return false;
84          }
85  
86          String path;
87          boolean missing;
88  
89          if ( StringUtils.isNotEmpty( file.getExists() ) )
90          {
91              path = file.getExists();
92              missing = false;
93          }
94          else if ( StringUtils.isNotEmpty( file.getMissing() ) )
95          {
96              path = file.getMissing();
97              missing = true;
98          }
99          else
100         {
101             return false;
102         }
103 
104         RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
105 
106         final File basedir = context.getProjectDirectory();
107 
108         if ( basedir != null )
109         {
110             interpolator.addValueSource( new AbstractValueSource( false )
111             {
112                 @Override
113                 public Object getValue( String expression )
114                 {
115                     /*
116                      * NOTE: We intentionally only support ${basedir} and not ${project.basedir} as the latter form
117                      * would suggest that other project.* expressions can be used which is however beyond the design.
118                      */
119                     if ( "basedir".equals( expression ) )
120                     {
121                         return basedir.getAbsolutePath();
122                     }
123                     return null;
124                 }
125             } );
126         }
127         else if ( path.contains( "${basedir}" ) )
128         {
129             return false;
130         }
131 
132         interpolator.addValueSource( new MapBasedValueSource( context.getProjectProperties() ) );
133 
134         interpolator.addValueSource( new MapBasedValueSource( context.getUserProperties() ) );
135 
136         interpolator.addValueSource( new MapBasedValueSource( context.getSystemProperties() ) );
137 
138         try
139         {
140             path = interpolator.interpolate( path, "" );
141         }
142         catch ( Exception e )
143         {
144             problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
145                     .setMessage( "Failed to interpolate file location " + path + " for profile " + profile.getId()
146                                  + ": " + e.getMessage() )
147                     .setLocation( file.getLocation( missing ? "missing" : "exists" ) )
148                     .setException( e ) );
149             return false;
150         }
151 
152         path = pathTranslator.alignToBaseDirectory( path, basedir );
153 
154         // replace activation value with interpolated value
155         if ( missing )
156         {
157             file.setMissing( path );
158         }
159         else
160         {
161             file.setExists( path );
162         }
163 
164         File f = new File( path );
165 
166         if ( !f.isAbsolute() )
167         {
168             return false;
169         }
170 
171         boolean fileExists = f.exists();
172 
173         return missing ? !fileExists : fileExists;
174     }
175 
176     @Override
177     public boolean presentInConfig( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
178     {
179         Activation activation = profile.getActivation();
180 
181         if ( activation == null )
182         {
183             return false;
184         }
185 
186         ActivationFile file = activation.getFile();
187 
188         if ( file == null )
189         {
190             return false;
191         }
192         return true;
193     }
194 
195 }