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.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.List;
25  
26  import org.apache.maven.model.Activation;
27  import org.apache.maven.model.Profile;
28  import org.apache.maven.model.building.ModelProblemCollector;
29  import org.apache.maven.model.building.ModelProblem.Severity;
30  import org.apache.maven.model.building.ModelProblem.Version;
31  import org.apache.maven.model.building.ModelProblemCollectorRequest;
32  import org.apache.maven.model.profile.ProfileActivationContext;
33  import org.codehaus.plexus.component.annotations.Component;
34  
35  /**
36   * Determines profile activation based on the version of the current Java runtime.
37   *
38   * @author Benjamin Bentmann
39   * @see Activation#getJdk()
40   */
41  @Component( role = ProfileActivator.class, hint = "jdk-version" )
42  public class JdkVersionProfileActivator
43      implements ProfileActivator
44  {
45  
46      @Override
47      public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
48      {
49          Activation activation = profile.getActivation();
50  
51          if ( activation == null )
52          {
53              return false;
54          }
55  
56          String jdk = activation.getJdk();
57  
58          if ( jdk == null )
59          {
60              return false;
61          }
62  
63          String version = context.getSystemProperties().get( "java.version" );
64  
65          if ( version == null || version.length() <= 0 )
66          {
67              problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
68                      .setMessage( "Failed to determine Java version for profile " + profile.getId() )
69                      .setLocation( activation.getLocation( "jdk" ) ) );
70              return false;
71          }
72  
73          if ( jdk.startsWith( "!" ) )
74          {
75              return !version.startsWith( jdk.substring( 1 ) );
76          }
77          else if ( isRange( jdk ) )
78          {
79              return isInRange( version, getRange( jdk ) );
80          }
81          else
82          {
83              return version.startsWith( jdk );
84          }
85      }
86  
87      @Override
88      public boolean presentInConfig( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
89      {
90          Activation activation = profile.getActivation();
91  
92          if ( activation == null )
93          {
94              return false;
95          }
96  
97          String jdk = activation.getJdk();
98  
99          if ( jdk == null )
100         {
101             return false;
102         }
103         return true;
104     }
105 
106     private static boolean isInRange( String value, List<RangeValue> range )
107     {
108         int leftRelation = getRelationOrder( value, range.get( 0 ), true );
109 
110         if ( leftRelation == 0 )
111         {
112             return true;
113         }
114 
115         if ( leftRelation < 0 )
116         {
117             return false;
118         }
119 
120         return getRelationOrder( value, range.get( 1 ), false ) <= 0;
121     }
122 
123     private static int getRelationOrder( String value, RangeValue rangeValue, boolean isLeft )
124     {
125         if ( rangeValue.value.length() <= 0 )
126         {
127             return isLeft ? 1 : -1;
128         }
129 
130         value = value.replaceAll( "[^0-9\\.\\-\\_]", "" );
131 
132         List<String> valueTokens = new ArrayList<String>( Arrays.asList( value.split( "[\\.\\-\\_]" ) ) );
133         List<String> rangeValueTokens = new ArrayList<String>( Arrays.asList( rangeValue.value.split( "\\." ) ) );
134 
135         addZeroTokens( valueTokens, 3 );
136         addZeroTokens( rangeValueTokens, 3 );
137 
138         for ( int i = 0; i < 3; i++ )
139         {
140             int x = Integer.parseInt( valueTokens.get( i ) );
141             int y = Integer.parseInt( rangeValueTokens.get( i ) );
142             if ( x < y )
143             {
144                 return -1;
145             }
146             else if ( x > y )
147             {
148                 return 1;
149             }
150         }
151         if ( !rangeValue.closed )
152         {
153             return isLeft ? -1 : 1;
154         }
155         return 0;
156     }
157 
158     private static void addZeroTokens( List<String> tokens, int max )
159     {
160         while ( tokens.size() < max )
161         {
162             tokens.add( "0" );
163         }
164     }
165 
166     private static boolean isRange( String value )
167     {
168         return value.startsWith( "[" ) || value.startsWith( "(" );
169     }
170 
171     private static List<RangeValue> getRange( String range )
172     {
173         List<RangeValue> ranges = new ArrayList<RangeValue>();
174 
175         for ( String token : range.split( "," ) )
176         {
177             if ( token.startsWith( "[" ) )
178             {
179                 ranges.add( new RangeValue( token.replace( "[", "" ), true ) );
180             }
181             else if ( token.startsWith( "(" ) )
182             {
183                 ranges.add( new RangeValue( token.replace( "(", "" ), false ) );
184             }
185             else if ( token.endsWith( "]" ) )
186             {
187                 ranges.add( new RangeValue( token.replace( "]", "" ), true ) );
188             }
189             else if ( token.endsWith( ")" ) )
190             {
191                 ranges.add( new RangeValue( token.replace( ")", "" ), false ) );
192             }
193             else if ( token.length() <= 0 )
194             {
195                 ranges.add( new RangeValue( "", false ) );
196             }
197         }
198         if ( ranges.size() < 2 )
199         {
200             ranges.add( new RangeValue( "99999999", false ) );
201         }
202         return ranges;
203     }
204 
205     private static class RangeValue
206     {
207         private String value;
208 
209         private boolean closed;
210 
211         RangeValue( String value, boolean closed )
212         {
213             this.value = value.trim();
214             this.closed = closed;
215         }
216 
217         @Override
218         public String toString()
219         {
220             return value;
221         }
222     }
223 
224 }