From 82ab85d3bcadccf016f653590cba938408fb9a00 Mon Sep 17 00:00:00 2001 From: Andreas Gudian Date: Thu, 22 Oct 2015 20:18:27 +0200 Subject: [PATCH] #642 Simplify handling of toolchains file by autodetecting which JDKs are configured there. --- .../itest/testutil/runner/ProcessorSuite.java | 12 +-- .../testutil/runner/ProcessorSuiteRunner.java | 101 ++++++++++++------ .../itest/testutil/runner/Toolchain.java | 51 +++++++++ .../itest/testutil/runner/xml/Toolchains.java | 87 +++++++++++++++ 4 files changed, 215 insertions(+), 36 deletions(-) create mode 100644 integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/Toolchain.java create mode 100644 integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/xml/Toolchains.java diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuite.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuite.java index 826b4384e..27d59a515 100644 --- a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuite.java +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuite.java @@ -52,12 +52,12 @@ public @interface ProcessorSuite { /** * Use an Oracle JDK 1.6 (or 1.6.x) via toolchain support to perform the processing */ - ORACLE_JAVA_6( "oracle-[1.6,1.7)", "javac", "1.6" ), + ORACLE_JAVA_6( new Toolchain( "oracle", "1.6", "1.7" ), "javac", "1.6" ), /** * Use an Oracle JDK 1.7 (or 1.7.x) via toolchain support to perform the processing */ - ORACLE_JAVA_7( "oracle-[1.7,1.8)", "javac", "1.7" ), + ORACLE_JAVA_7( new Toolchain( "oracle", "1.7", "1.8" ), "javac", "1.7" ), /** * Use the same JDK that runs the mvn build to perform the processing @@ -67,7 +67,7 @@ public @interface ProcessorSuite { /** * Use an Oracle JDK 1.9 (or 1.9.x) via toolchain support to perform the processing */ - ORACLE_JAVA_9( "oracle-[1.9,1.10)", "javac", "1.9" ), + ORACLE_JAVA_9( new Toolchain( "oracle", "9", "10" ), "javac", "1.9" ), /** * Use the eclipse compiler with 1.7 source/target level from tycho-compiler-jdt to perform the build and @@ -100,11 +100,11 @@ public @interface ProcessorSuite { private ProcessorType[] included = { }; - private String toolchain; + private Toolchain toolchain; private String compilerId; private String sourceTargetVersion; - private ProcessorType(String toolchain, String compilerId, String sourceTargetVersion) { + private ProcessorType(Toolchain toolchain, String compilerId, String sourceTargetVersion) { this.toolchain = toolchain; this.compilerId = compilerId; this.sourceTargetVersion = sourceTargetVersion; @@ -124,7 +124,7 @@ public @interface ProcessorSuite { /** * @return the toolchain */ - public String getToolchain() { + public Toolchain getToolchain() { return toolchain; } diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuiteRunner.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuiteRunner.java index 494dc9918..2687c4335 100644 --- a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuiteRunner.java +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuiteRunner.java @@ -18,13 +18,23 @@ */ package org.mapstruct.itest.testutil.runner; +import static org.apache.maven.it.util.ResourceExtractor.extractResourceToDestination; +import static org.apache.maven.shared.utils.io.FileUtils.copyURLToFile; +import static org.apache.maven.shared.utils.io.FileUtils.deleteDirectory; + import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + import org.apache.maven.it.Verifier; import org.junit.internal.AssumptionViolatedException; import org.junit.internal.runners.model.EachTestNotifier; @@ -35,10 +45,8 @@ import org.junit.runners.ParentRunner; import org.junit.runners.model.InitializationError; import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner.ProcessorTestCase; - -import static org.apache.maven.it.util.ResourceExtractor.extractResourceToDestination; -import static org.apache.maven.shared.utils.io.FileUtils.copyURLToFile; -import static org.apache.maven.shared.utils.io.FileUtils.deleteDirectory; +import org.mapstruct.itest.testutil.runner.xml.Toolchains; +import org.mapstruct.itest.testutil.runner.xml.Toolchains.ProviderDescription; /** * Runner for processor integration tests. Requires the annotation {@link ProcessorSuite} on the test class. @@ -57,7 +65,9 @@ public class ProcessorSuiteRunner extends ParentRunner { */ public static final String SYS_PROP_DEBUG = "processorIntegrationTest.debug"; - public static final String SYS_PROP_CAN_USE_JDK_9 = "processorIntegrationTest.canUseJdk9"; + private static final File TOOLCHAINS_FILE = getToolchainsFile(); + + private static final Collection ENABLED_PROCESSOR_TYPES = detectSupportedTypes( TOOLCHAINS_FILE ); public static final class ProcessorTestCase { private final String baseDir; @@ -67,16 +77,10 @@ public class ProcessorSuiteRunner extends ParentRunner { public ProcessorTestCase(String baseDir, ProcessorType processor) { this.baseDir = baseDir; this.processor = processor; - this.ignored = - ( !TOOLCHAINS_ENABLED && processor.getToolchain() != null ) - || ( processor == ProcessorType.ORACLE_JAVA_9 && !CAN_USE_JDK_9 ); + this.ignored = !ENABLED_PROCESSOR_TYPES.contains( processor ); } } - private static final File SPECIFIED_TOOLCHAINS_FILE = getSpecifiedToolchainsFile(); - private static final boolean TOOLCHAINS_ENABLED = toolchainsFileExists(); - private static final boolean CAN_USE_JDK_9 = canUseJdk9(); - private final List methods; /** @@ -227,15 +231,13 @@ public class ProcessorSuiteRunner extends ParentRunner { private void configureToolchains(ProcessorTestCase child, Verifier verifier, List goals, PrintStream originalOut) { if ( child.processor.getToolchain() != null ) { - if ( null != SPECIFIED_TOOLCHAINS_FILE ) { - verifier.addCliOption( "--toolchains" ); - verifier.addCliOption( SPECIFIED_TOOLCHAINS_FILE.getPath().replace( '\\', '/' ) ); - } + verifier.addCliOption( "--toolchains" ); + verifier.addCliOption( TOOLCHAINS_FILE.getPath().replace( '\\', '/' ) ); - String[] parts = child.processor.getToolchain().split( "-" ); + Toolchain toolchain = child.processor.getToolchain(); - verifier.addCliOption( "-Dtoolchain-jdk-vendor=" + parts[0] ); - verifier.addCliOption( "-Dtoolchain-jdk-version=" + parts[1] ); + verifier.addCliOption( "-Dtoolchain-jdk-vendor=" + toolchain.getVendor() ); + verifier.addCliOption( "-Dtoolchain-jdk-version=" + toolchain.getVersionRangeString() ); goals.add( "toolchains:toolchain" ); } @@ -257,7 +259,7 @@ public class ProcessorSuiteRunner extends ParentRunner { return extractResourceToDestination( getClass(), "/" + child.baseDir, tempDir, true ); } - private static File getSpecifiedToolchainsFile() { + private static File getToolchainsFile() { String specifiedToolchainsFile = System.getProperty( SYS_PROP_TOOLCHAINS_FILE ); if ( null != specifiedToolchainsFile ) { try { @@ -278,20 +280,59 @@ public class ProcessorSuiteRunner extends ParentRunner { } } - return null; + // use default location + String defaultPath = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + ".m2"; + return new File( defaultPath, "toolchains.xml" ); } - private static boolean canUseJdk9() { - return Boolean.parseBoolean( System.getProperty( SYS_PROP_CAN_USE_JDK_9, "true" ) ); - } - - private static boolean toolchainsFileExists() { - if ( null != SPECIFIED_TOOLCHAINS_FILE ) { - return SPECIFIED_TOOLCHAINS_FILE.exists(); + private static Collection detectSupportedTypes(File toolchainsFile) { + Toolchains toolchains; + try { + if ( toolchainsFile.exists() ) { + Unmarshaller unmarshaller = JAXBContext.newInstance( Toolchains.class ).createUnmarshaller(); + toolchains = (Toolchains) unmarshaller.unmarshal( toolchainsFile ); + } + else { + toolchains = null; + } + } + catch ( JAXBException e ) { + toolchains = null; } - String defaultPath = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + ".m2"; - return new File( defaultPath, "toolchains.xml" ).exists(); + Collection supported = new HashSet<>(); + for ( ProcessorType type : ProcessorType.values() ) { + if ( isSupported( type, toolchains ) ) { + supported.add( type ); + } + } + + return supported; } + private static boolean isSupported(ProcessorType type, Toolchains toolchains) { + if ( type.getToolchain() == null ) { + return true; + } + + if ( toolchains == null ) { + return false; + } + + Toolchain required = type.getToolchain(); + + for ( Toolchains.Toolchain tc : toolchains.getToolchains() ) { + if ( "jdk".equals( tc.getType() ) ) { + ProviderDescription desc = tc.getProviderDescription(); + if ( desc != null + && required.getVendor().equals( desc.getVendor() ) + && desc.getVersion() != null + && desc.getVersion().startsWith( required.getVersionMinInclusive() ) ) { + return true; + } + } + } + + return false; + } } diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/Toolchain.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/Toolchain.java new file mode 100644 index 000000000..1b31f5349 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/Toolchain.java @@ -0,0 +1,51 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.itest.testutil.runner; + +/** + * Describes a required entry in the Maven toolchains.xml file. + * + * @author Andreas Gudian + */ +class Toolchain { + private final String vendor; + private final String versionMinInclusive; + private final String versionMaxExclusive; + + Toolchain(String vendor, String versionMinInclusive, String versionMaxExclusive) { + this.vendor = vendor; + this.versionMinInclusive = versionMinInclusive; + this.versionMaxExclusive = versionMaxExclusive; + } + + String getVendor() { + return vendor; + } + + String getVersionMinInclusive() { + return versionMinInclusive; + } + + /** + * @return the version range string to be used in the Maven execution to select the toolchain + */ + String getVersionRangeString() { + return "[" + versionMinInclusive + "," + versionMaxExclusive + ")"; + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/xml/Toolchains.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/xml/Toolchains.java new file mode 100644 index 000000000..7a7e1aad9 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/xml/Toolchains.java @@ -0,0 +1,87 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.itest.testutil.runner.xml; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * JAXB representation of some of the parts in the Maven toolchains.xml file. + * + * @author Andreas Gudian + */ +@XmlRootElement +public class Toolchains { + @XmlElement(name = "toolchain") + private List toolchains = new ArrayList<>(); + + public List getToolchains() { + return toolchains; + } + + @Override + public String toString() { + return "Toolchains [toolchains=" + toolchains + "]"; + } + + public static class Toolchain { + @XmlElement + private String type; + + @XmlElement(name = "provides") + private ProviderDescription providerDescription; + + public String getType() { + return type; + } + + public ProviderDescription getProviderDescription() { + return providerDescription; + } + + @Override + public String toString() { + return "Toolchain [type=" + type + ", providerDescription=" + providerDescription + "]"; + } + } + + public static class ProviderDescription { + @XmlElement + private String version; + + @XmlElement + private String vendor; + + public String getVersion() { + return version; + } + + public String getVendor() { + return vendor; + } + + @Override + public String toString() { + return "ProviderDescription [version=" + version + ", vendor=" + vendor + "]"; + } + } +}