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