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.profile.ProfileActivationContext; 031 import org.codehaus.plexus.component.annotations.Component; 032 033 /** 034 * Determines profile activation based on the version of the current Java runtime. 035 * 036 * @author Benjamin Bentmann 037 */ 038 @Component( role = ProfileActivator.class, hint = "jdk-version" ) 039 public class JdkVersionProfileActivator 040 implements ProfileActivator 041 { 042 043 public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems ) 044 { 045 boolean active = false; 046 047 Activation activation = profile.getActivation(); 048 049 if ( activation != null ) 050 { 051 String jdk = activation.getJdk(); 052 053 if ( jdk != null ) 054 { 055 String version = context.getSystemProperties().get( "java.version" ); 056 057 if ( version == null || version.length() <= 0 ) 058 { 059 problems.add( Severity.ERROR, "Failed to determine Java version for profile " + profile.getId(), 060 activation.getLocation( "jdk" ), null ); 061 return false; 062 } 063 064 if ( jdk.startsWith( "!" ) ) 065 { 066 active = !version.startsWith( jdk.substring( 1 ) ); 067 } 068 else if ( isRange( jdk ) ) 069 { 070 active = isInRange( version, getRange( jdk ) ); 071 } 072 else 073 { 074 active = version.startsWith( jdk ); 075 } 076 } 077 } 078 079 return active; 080 } 081 082 private static boolean isInRange( String value, List<RangeValue> range ) 083 { 084 int leftRelation = getRelationOrder( value, range.get( 0 ), true ); 085 086 if ( leftRelation == 0 ) 087 { 088 return true; 089 } 090 091 if ( leftRelation < 0 ) 092 { 093 return false; 094 } 095 096 return getRelationOrder( value, range.get( 1 ), false ) <= 0; 097 } 098 099 private static int getRelationOrder( String value, RangeValue rangeValue, boolean isLeft ) 100 { 101 if ( rangeValue.value.length() <= 0 ) 102 { 103 return isLeft ? 1 : -1; 104 } 105 106 value = value.replaceAll( "[^0-9\\.\\-\\_]", "" ); 107 108 List<String> valueTokens = new ArrayList<String>( Arrays.asList( value.split( "[\\.\\-\\_]" ) ) ); 109 List<String> rangeValueTokens = new ArrayList<String>( Arrays.asList( rangeValue.value.split( "\\." ) ) ); 110 111 addZeroTokens( valueTokens, 3 ); 112 addZeroTokens( rangeValueTokens, 3 ); 113 114 for ( int i = 0; i < 3; i++ ) 115 { 116 int x = Integer.parseInt( valueTokens.get( i ) ); 117 int y = Integer.parseInt( rangeValueTokens.get( i ) ); 118 if ( x < y ) 119 { 120 return -1; 121 } 122 else if ( x > y ) 123 { 124 return 1; 125 } 126 } 127 if ( !rangeValue.closed ) 128 { 129 return isLeft ? -1 : 1; 130 } 131 return 0; 132 } 133 134 private static void addZeroTokens( List<String> tokens, int max ) 135 { 136 while ( tokens.size() < max ) 137 { 138 tokens.add( "0" ); 139 } 140 } 141 142 private static boolean isRange( String value ) 143 { 144 return value.startsWith( "[" ) || value.startsWith( "(" ); 145 } 146 147 private static List<RangeValue> getRange( String range ) 148 { 149 List<RangeValue> ranges = new ArrayList<RangeValue>(); 150 151 for ( String token : range.split( "," ) ) 152 { 153 if ( token.startsWith( "[" ) ) 154 { 155 ranges.add( new RangeValue( token.replace( "[", "" ), true ) ); 156 } 157 else if ( token.startsWith( "(" ) ) 158 { 159 ranges.add( new RangeValue( token.replace( "(", "" ), false ) ); 160 } 161 else if ( token.endsWith( "]" ) ) 162 { 163 ranges.add( new RangeValue( token.replace( "]", "" ), true ) ); 164 } 165 else if ( token.endsWith( ")" ) ) 166 { 167 ranges.add( new RangeValue( token.replace( ")", "" ), false ) ); 168 } 169 else if ( token.length() <= 0 ) 170 { 171 ranges.add( new RangeValue( "", false ) ); 172 } 173 } 174 if ( ranges.size() < 2 ) 175 { 176 ranges.add( new RangeValue( "99999999", false ) ); 177 } 178 return ranges; 179 } 180 181 private static class RangeValue 182 { 183 private String value; 184 185 private boolean closed; 186 187 RangeValue( String value, boolean closed ) 188 { 189 this.value = value.trim(); 190 this.closed = closed; 191 } 192 193 public String toString() 194 { 195 return value; 196 } 197 } 198 199 }