001 package org.apache.maven.model.profile.activation;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.util.ArrayList;
023 import java.util.Arrays;
024 import java.util.List;
025
026 import org.apache.maven.model.Activation;
027 import org.apache.maven.model.Profile;
028 import org.apache.maven.model.building.ModelProblemCollector;
029 import org.apache.maven.model.building.ModelProblem.Severity;
030 import org.apache.maven.model.building.ModelProblem.Version;
031 import org.apache.maven.model.building.ModelProblemCollectorRequest;
032 import org.apache.maven.model.profile.ProfileActivationContext;
033 import org.codehaus.plexus.component.annotations.Component;
034
035 /**
036 * Determines profile activation based on the version of the current Java runtime.
037 *
038 * @author Benjamin Bentmann
039 * @see Activation#getJdk()
040 */
041 @Component( role = ProfileActivator.class, hint = "jdk-version" )
042 public class JdkVersionProfileActivator
043 implements ProfileActivator
044 {
045
046 public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
047 {
048 Activation activation = profile.getActivation();
049
050 if ( activation == null )
051 {
052 return false;
053 }
054
055 String jdk = activation.getJdk();
056
057 if ( jdk == null )
058 {
059 return false;
060 }
061
062 String version = context.getSystemProperties().get( "java.version" );
063
064 if ( version == null || version.length() <= 0 )
065 {
066 problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
067 .setMessage( "Failed to determine Java version for profile " + profile.getId() )
068 .setLocation( activation.getLocation( "jdk" ) ) );
069 return false;
070 }
071
072 if ( jdk.startsWith( "!" ) )
073 {
074 return !version.startsWith( jdk.substring( 1 ) );
075 }
076 else if ( isRange( jdk ) )
077 {
078 return isInRange( version, getRange( jdk ) );
079 }
080 else
081 {
082 return version.startsWith( jdk );
083 }
084 }
085
086 private static boolean isInRange( String value, List<RangeValue> range )
087 {
088 int leftRelation = getRelationOrder( value, range.get( 0 ), true );
089
090 if ( leftRelation == 0 )
091 {
092 return true;
093 }
094
095 if ( leftRelation < 0 )
096 {
097 return false;
098 }
099
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 }