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      public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
47      {
48          Activation activation = profile.getActivation();
49  
50          if ( activation == null )
51          {
52              return false;
53          }
54  
55          String jdk = activation.getJdk();
56  
57          if ( jdk == null )
58          {
59              return false;
60          }
61  
62          String version = context.getSystemProperties().get( "java.version" );
63  
64          if ( version == null || version.length() <= 0 )
65          {
66              problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
67                      .setMessage( "Failed to determine Java version for profile " + profile.getId() )
68                      .setLocation( activation.getLocation( "jdk" ) ) );
69              return false;
70          }
71  
72          if ( jdk.startsWith( "!" ) )
73          {
74              return !version.startsWith( jdk.substring( 1 ) );
75          }
76          else if ( isRange( jdk ) )
77          {
78              return isInRange( version, getRange( jdk ) );
79          }
80          else
81          {
82              return version.startsWith( jdk );
83          }
84      }
85  
86      private static boolean isInRange( String value, List<RangeValue> range )
87      {
88          int leftRelation = getRelationOrder( value, range.get( 0 ), true );
89  
90          if ( leftRelation == 0 )
91          {
92              return true;
93          }
94  
95          if ( leftRelation < 0 )
96          {
97              return false;
98          }
99  
100         return getRelationOrder( value, range.get( 1 ), false ) <= 0;
101     }
102 
103     private static int getRelationOrder( String value, RangeValue rangeValue, boolean isLeft )
104     {
105         if ( rangeValue.value.length() <= 0 )
106         {
107             return isLeft ? 1 : -1;
108         }
109 
110         value = value.replaceAll( "[^0-9\\.\\-\\_]", "" );
111 
112         List<String> valueTokens = new ArrayList<String>( Arrays.asList( value.split( "[\\.\\-\\_]" ) ) );
113         List<String> rangeValueTokens = new ArrayList<String>( Arrays.asList( rangeValue.value.split( "\\." ) ) );
114 
115         addZeroTokens( valueTokens, 3 );
116         addZeroTokens( rangeValueTokens, 3 );
117 
118         for ( int i = 0; i < 3; i++ )
119         {
120             int x = Integer.parseInt( valueTokens.get( i ) );
121             int y = Integer.parseInt( rangeValueTokens.get( i ) );
122             if ( x < y )
123             {
124                 return -1;
125             }
126             else if ( x > y )
127             {
128                 return 1;
129             }
130         }
131         if ( !rangeValue.closed )
132         {
133             return isLeft ? -1 : 1;
134         }
135         return 0;
136     }
137 
138     private static void addZeroTokens( List<String> tokens, int max )
139     {
140         while ( tokens.size() < max )
141         {
142             tokens.add( "0" );
143         }
144     }
145 
146     private static boolean isRange( String value )
147     {
148         return value.startsWith( "[" ) || value.startsWith( "(" );
149     }
150 
151     private static List<RangeValue> getRange( String range )
152     {
153         List<RangeValue> ranges = new ArrayList<RangeValue>();
154 
155         for ( String token : range.split( "," ) )
156         {
157             if ( token.startsWith( "[" ) )
158             {
159                 ranges.add( new RangeValue( token.replace( "[", "" ), true ) );
160             }
161             else if ( token.startsWith( "(" ) )
162             {
163                 ranges.add( new RangeValue( token.replace( "(", "" ), false ) );
164             }
165             else if ( token.endsWith( "]" ) )
166             {
167                 ranges.add( new RangeValue( token.replace( "]", "" ), true ) );
168             }
169             else if ( token.endsWith( ")" ) )
170             {
171                 ranges.add( new RangeValue( token.replace( ")", "" ), false ) );
172             }
173             else if ( token.length() <= 0 )
174             {
175                 ranges.add( new RangeValue( "", false ) );
176             }
177         }
178         if ( ranges.size() < 2 )
179         {
180             ranges.add( new RangeValue( "99999999", false ) );
181         }
182         return ranges;
183     }
184 
185     private static class RangeValue
186     {
187         private String value;
188 
189         private boolean closed;
190 
191         RangeValue( String value, boolean closed )
192         {
193             this.value = value.trim();
194             this.closed = closed;
195         }
196 
197         public String toString()
198         {
199             return value;
200         }
201     }
202 
203 }