diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/JdkMatcher.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/JdkMatcher.java index 1ec6286721..7368e9d21e 100644 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/JdkMatcher.java +++ b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/JdkMatcher.java @@ -165,7 +165,7 @@ public class JdkMatcher return ranges; } - private static class RangeValue + public static class RangeValue { private String value; diff --git a/maven-project/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java b/maven-project/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java index 631e3dfe2d..8b9bc6b383 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java @@ -27,6 +27,7 @@ import org.apache.maven.profiles.ProfileActivationException; import org.apache.maven.profiles.ProfileManager; import org.apache.maven.profiles.matchers.DefaultMatcher; import org.apache.maven.profiles.matchers.FileMatcher; +import org.apache.maven.profiles.matchers.JdkMatcher; import org.apache.maven.profiles.matchers.ProfileMatcher; import org.apache.maven.profiles.matchers.PropertyMatcher; import org.apache.maven.shared.model.InterpolatorProperty; @@ -50,7 +51,7 @@ public class DefaultProfileManager private static final ProfileMatcher defaultMatcher = new DefaultMatcher(); private static final List matchers = - (List) Collections.unmodifiableList( Arrays.asList( new PropertyMatcher(), new FileMatcher() ) ); + (List) Collections.unmodifiableList( Arrays.asList( new PropertyMatcher(), new FileMatcher(), new JdkMatcher() ) ); /** * the properties passed to the profile manager are the props that @@ -197,11 +198,13 @@ public class DefaultProfileManager List projectProfiles = new ArrayList(); ProfileManager externalProfileManager = config.getGlobalProfileManager(); - Properties props = new Properties(config.getExecutionProperties()); + Properties props = new Properties(); + props.putAll(config.getExecutionProperties()); props.putAll(config.getUserProperties()); - ProfileActivationContext profileActivationContext = (externalProfileManager == null) ? new ProfileActivationContext( props, false ): + ProfileActivationContext profileActivationContext = (externalProfileManager == null) ? new ProfileActivationContext( new Properties(), false ): externalProfileManager.getProfileActivationContext(); + profileActivationContext.getExecutionProperties().putAll(props); if(externalProfileManager != null) { diff --git a/maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java b/maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java index e6824784b1..e3c0f921de 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java @@ -40,7 +40,7 @@ public class ProfileActivationContext public ProfileActivationContext( Properties executionProperties, boolean isCustomActivatorFailureSuppressed ) { - this.executionProperties = executionProperties; + this.executionProperties = (executionProperties != null) ? executionProperties : new Properties(); this.isCustomActivatorFailureSuppressed = isCustomActivatorFailureSuppressed; } diff --git a/maven-project/src/main/java/org/apache/maven/profiles/matchers/JdkMatcher.java b/maven-project/src/main/java/org/apache/maven/profiles/matchers/JdkMatcher.java new file mode 100644 index 0000000000..9858aa219b --- /dev/null +++ b/maven-project/src/main/java/org/apache/maven/profiles/matchers/JdkMatcher.java @@ -0,0 +1,191 @@ +package org.apache.maven.profiles.matchers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.maven.model.Profile; +import org.apache.maven.shared.model.InterpolatorProperty; + +public class JdkMatcher + implements ProfileMatcher + { + + private static final String JDK_VERSION = "${java.version}"; + + public boolean isMatch(Profile profile, + List properties) { + String version = null; + for(InterpolatorProperty ip : properties) + { + if(ip.getKey().equals(JDK_VERSION)) + { + version = ip.getValue(); + break; + } + } + if ( version == null ) + { + return false; + } + + org.apache.maven.model.Activation activation = profile.getActivation(); + if(activation == null || activation.getJdk() == null) + { + return false; + } + + String jdk = activation.getJdk(); + if ( jdk.startsWith( "!" ) ) + { + return !version.startsWith( jdk.replaceFirst( "!", "" ) ); + } + else if ( isRange( jdk ) ) + { + return isInRange( version, getRange( jdk ) ); + } + else + { + return version.startsWith( jdk ); + } + + } + + private static boolean isInRange( String value, List range ) + { + int leftRelation = getRelationOrder( value, range.get( 0 ), true ); + + if ( leftRelation == 0 ) + { + return true; + } + + if ( leftRelation < 0 ) + { + return false; + } + + return getRelationOrder( value, range.get( 1 ), false ) <= 0; + } + + private static int getRelationOrder( String value, RangeValue rangeValue, boolean isLeft ) + { + if ( rangeValue.value.length() <= 0 ) + { + return isLeft ? 1 : -1; + } + + List valueTokens = new ArrayList( Arrays.asList( value.split( "\\." ) ) ); + List rangeValueTokens = new ArrayList( Arrays.asList( rangeValue.value.split( "\\." ) ) ); + + int max = Math.max( valueTokens.size(), rangeValueTokens.size() ); + addZeroTokens( valueTokens, max ); + addZeroTokens( rangeValueTokens, max ); + + if ( value.equals( rangeValue.value ) ) + { + if ( !rangeValue.isClosed() ) + { + return isLeft ? -1 : 1; + } + return 0; + } + + for ( int i = 0; i < valueTokens.size(); i++ ) + { + int x = Integer.parseInt( valueTokens.get( i ) ); + int y = Integer.parseInt( rangeValueTokens.get( i ) ); + if ( x < y ) + { + return -1; + } + else if ( x > y ) + { + return 1; + } + } + if ( !rangeValue.isClosed() ) + { + return isLeft ? -1 : 1; + } + return 0; + } + + private static void addZeroTokens( List tokens, int max ) + { + if ( tokens.size() < max ) + { + for ( int i = 0; i < ( max - tokens.size() ); i++ ) + { + tokens.add( "0" ); + } + } + } + + private static boolean isRange( String value ) + { + return value.contains( "," ); + } + + private static List getRange( String range ) + { + List ranges = new ArrayList(); + + for ( String token : range.split( "," ) ) + { + if ( token.startsWith( "[" ) ) + { + ranges.add( new RangeValue( token.replace( "[", "" ), true ) ); + } + else if ( token.startsWith( "(" ) ) + { + ranges.add( new RangeValue( token.replace( "(", "" ), false ) ); + } + else if ( token.endsWith( "]" ) ) + { + ranges.add( new RangeValue( token.replace( "]", "" ), true ) ); + } + else if ( token.endsWith( ")" ) ) + { + ranges.add( new RangeValue( token.replace( ")", "" ), false ) ); + } + else if ( token.length() <= 0 ) + { + ranges.add( new RangeValue( "", false ) ); + } + } + if ( ranges.size() < 2 ) + { + ranges.add( new RangeValue( "99999999", false ) ); + } + return ranges; + } + + private static class RangeValue + { + private String value; + + private boolean isClosed; + + RangeValue( String value, boolean isClosed ) + { + this.value = value.trim(); + this.isClosed = isClosed; + } + + public String getValue() + { + return value; + } + + public boolean isClosed() + { + return isClosed; + } + + public String toString() + { + return value; + } + } +} diff --git a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java index 5db4c1c5b6..eab60ceac6 100644 --- a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java @@ -440,8 +440,12 @@ public class DefaultMavenProjectBuilder List inactiveProfileIds = ( projectBuilderConfiguration != null && projectBuilderConfiguration.getGlobalProfileManager() != null && projectBuilderConfiguration .getGlobalProfileManager().getProfileActivationContext() != null ) ? projectBuilderConfiguration.getGlobalProfileManager().getProfileActivationContext().getExplicitlyInactiveProfileIds() : new ArrayList(); - - ProfileManagerInfo profileInfo = new ProfileManagerInfo(null, activeProfileIds, inactiveProfileIds); + + List interpolatorProperties = new ArrayList(); + interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( projectBuilderConfiguration.getExecutionProperties(), PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); + interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( projectBuilderConfiguration.getUserProperties(), PomInterpolatorTag.USER_PROPERTIES.name() ) ); + + ProfileManagerInfo profileInfo = new ProfileManagerInfo(interpolatorProperties, activeProfileIds, inactiveProfileIds); PomClassicDomainModel domainModel = new PomClassicDomainModel( pomFile ); domainModel.setProjectDirectory( pomFile.getParentFile() ); domainModel.setMostSpecialized( true ); @@ -510,6 +514,7 @@ public class DefaultMavenProjectBuilder // Lineage count is inclusive to add the POM read in itself. transformedDomainModel.setLineageCount( lineageCount + 1 ); + Model m = transformedDomainModel.getModel(); transformedDomainModel.setParentFile( parentFile ); return transformedDomainModel; diff --git a/maven-project/src/test/java/org/apache/maven/profiles/matchers/JdkMatcherTest.java b/maven-project/src/test/java/org/apache/maven/profiles/matchers/JdkMatcherTest.java new file mode 100644 index 0000000000..28a99c704f --- /dev/null +++ b/maven-project/src/test/java/org/apache/maven/profiles/matchers/JdkMatcherTest.java @@ -0,0 +1,24 @@ +package org.apache.maven.profiles.matchers; + +import java.util.Collections; + +import org.apache.maven.model.Activation; +import org.apache.maven.model.Profile; +import org.apache.maven.shared.model.InterpolatorProperty; + +import junit.framework.TestCase; + +public class JdkMatcherTest extends TestCase +{ + public void testJdkMatch() + throws Exception + { + Profile p = new Profile(); + Activation a = new Activation(); + a.setJdk("(1.3,100)"); + p.setActivation(a); + + JdkMatcher m = new JdkMatcher(); + assertTrue(m.isMatch(p, Collections.singletonList(new InterpolatorProperty("${java.version}", "1.5.0_16")))); + } +} diff --git a/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java index 2dad59e08e..0ffaefd46f 100644 --- a/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java @@ -23,6 +23,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; @@ -876,14 +877,10 @@ public class PomConstructionTest } /** MNG-4027*/ - /* FIXME*/ - public void testProfileInjectedDependencies() throws Exception { - //c.b,d,a PomTestWrapper pom = buildPom( "profile-injected-dependencies" ); - System.out.println(pom.getDomainModel().asString()); assertEquals( 4, ( (List) pom.getValue( "dependencies" ) ).size() ); assertEquals( "a", pom.getValue( "dependencies[1]/artifactId" ) ); assertEquals( "c", pom.getValue( "dependencies[2]/artifactId" ) ); @@ -891,18 +888,14 @@ public class PomConstructionTest assertEquals( "d", pom.getValue( "dependencies[4]/artifactId" ) ); } - public void testDependencyInheritance() throws Exception { - //c.b,d,a PomTestWrapper pom = buildPom( "dependency-inheritance/sub" ); assertEquals(1, ( (List) pom.getValue( "dependencies" ) ).size() ); assertEquals("4.4", pom.getValue("dependencies[1]/version") ); - System.out.println(pom.getDomainModel().asString()); } -//*/ /** MNG-4034 */ public void testManagedProfileDependency() throws Exception @@ -1334,6 +1327,20 @@ public class PomConstructionTest assertEquals("c", pom.getValue( "build/extensions[3]/artifactId" ) ); } + /*MNG-1957*/ + public void testJdkActivation() + throws Exception + { + Properties props = new Properties(); + props.put("java.version", "1.5.0_15"); + + PomTestWrapper pom = buildPom( "jdk-activation", props ); + assertEquals(3, pom.getMavenProject().getActiveProfiles().size()); + assertEquals("PASSED", pom.getValue("properties/jdkProperty3")); + assertEquals("PASSED", pom.getValue("properties/jdkProperty2")); + assertEquals("PASSED", pom.getValue("properties/jdkProperty1")); + } + /* MNG-2174 */ public void testProfilePluginMngDependencies() throws Exception @@ -1372,7 +1379,24 @@ public class PomConstructionTest { assertEquals( new File( value.toString() ).getPath(), value.toString() ); } + + private PomTestWrapper buildPom( String pomPath, Properties properties) + throws Exception +{ + File pomFile = new File( testDirectory , pomPath ); + if ( pomFile.isDirectory() ) + { + pomFile = new File( pomFile, "pom.xml" ); + } + ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration(); + config.setLocalRepository(new DefaultArtifactRepository("default", "", new DefaultRepositoryLayout())); + ProfileActivationContext pCtx = new ProfileActivationContext(null, true); + config.setExecutionProperties(properties); + config.setGlobalProfileManager(new DefaultProfileManager(this.getContainer(), pCtx)); + return new PomTestWrapper( pomFile, mavenProjectBuilder.build( pomFile, config ) ); +} + private PomTestWrapper buildPom( String pomPath, String... profileIds ) throws Exception { diff --git a/maven-project/src/test/resources-project-builder/jdk-activation/pom.xml b/maven-project/src/test/resources-project-builder/jdk-activation/pom.xml new file mode 100644 index 0000000000..c0431f5807 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/jdk-activation/pom.xml @@ -0,0 +1,105 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng1957 + test + 1.0-SNAPSHOT + + Maven Integration Test :: MNG-1957 + + Test that JDK profile activation allows version ranges. + + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + validate + + eval + + + target/jdk.properties + + project/properties + + + + + + + + + + + test-1 + + [1.4,) + + + PASSED + + + + test-2 + + (,100) + + + PASSED + + + + test-3 + + (1.3,100) + + + PASSED + + + + test-4 + + (100,) + + + FAILED + + + + test-5 + + (,1.4) + + + FAILED + + + +