001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.plugin.plugin.report; 020 021import java.util.Arrays; 022import java.util.Map; 023import java.util.Objects; 024import java.util.Optional; 025 026import org.apache.commons.lang3.StringUtils; 027import org.apache.maven.model.Plugin; 028import org.apache.maven.model.Prerequisites; 029import org.apache.maven.plugin.descriptor.PluginDescriptor; 030import org.apache.maven.project.MavenProject; 031import org.apache.maven.tools.plugin.ExtendedPluginDescriptor; 032import org.codehaus.plexus.util.xml.Xpp3Dom; 033 034/** 035 * Plugin requirements history. 036 * 037 * @author Slawomir Jaranowski 038 */ 039public class RequirementsHistory { 040 /** 041 * The plugin version. 042 */ 043 private String version; 044 045 /** 046 * The minimum version of Maven to run this plugin. 047 */ 048 private String maven; 049 050 /** 051 * The minimum version of the JDK to run this plugin. 052 */ 053 private String jdk; 054 055 public String getVersion() { 056 return version; 057 } 058 059 public String getMaven() { 060 return maven; 061 } 062 063 public String getJdk() { 064 return jdk; 065 } 066 067 @Override 068 public String toString() { 069 final StringBuilder sb = new StringBuilder("RequirementsHistory{"); 070 sb.append("version='").append(version).append('\''); 071 sb.append(", maven='").append(maven).append('\''); 072 sb.append(", jdk='").append(jdk).append('\''); 073 sb.append('}'); 074 return sb.toString(); 075 } 076 077 public static RequirementsHistory discoverRequirements(MavenProject project) { 078 RequirementsHistory req = new RequirementsHistory(); 079 req.version = project.getVersion(); 080 req.jdk = discoverJdkRequirement(project, null); 081 req.maven = discoverMavenRequirement(project, null); 082 return req; 083 } 084 /** 085 * Tries to determine the Maven requirement from either the plugin descriptor or (if not set) from the 086 * Maven prerequisites element in the POM. 087 * 088 * @param project not null 089 * @param pluginDescriptor the plugin descriptor (can be null) 090 * @return the Maven version or null if not specified 091 */ 092 public static String discoverMavenRequirement(MavenProject project, PluginDescriptor pluginDescriptor) { 093 if (pluginDescriptor != null && StringUtils.isNotBlank(pluginDescriptor.getRequiredMavenVersion())) { 094 return pluginDescriptor.getRequiredMavenVersion(); 095 } 096 return Optional.ofNullable(project.getPrerequisites()) 097 .map(Prerequisites::getMaven) 098 .orElse(null); 099 } 100 101 /** 102 * Tries to determine the JDK requirement from the following sources (until one is found) 103 * <ol> 104 * <li>use JDK requirement from plugin descriptor</li> 105 * <li>use {@code release} configuration of {@code org.apache.maven.plugins:maven-compiler-plugin}</li> 106 * <li>use {@code maven.compiler.release<} property</li> 107 * <li>use {@code target} configuration of {@code org.apache.maven.plugins:maven-compiler-plugin}</li> 108 * <li>use {@code maven.compiler.target} property</li> 109 * </ol> 110 * 111 * @param project not null 112 * @param pluginDescriptor the plugin descriptor (can be null) 113 * @return the JDK version 114 */ 115 public static String discoverJdkRequirement(MavenProject project, PluginDescriptor pluginDescriptor) { 116 String jdk = null; 117 if (pluginDescriptor instanceof ExtendedPluginDescriptor) { 118 ExtendedPluginDescriptor extPluginDescriptor = (ExtendedPluginDescriptor) pluginDescriptor; 119 jdk = extPluginDescriptor.getRequiredJavaVersion(); 120 } 121 if (jdk != null) { 122 return jdk; 123 } 124 Plugin compiler = getCompilerPlugin(project.getBuild().getPluginsAsMap()); 125 if (compiler == null) { 126 compiler = getCompilerPlugin(project.getPluginManagement().getPluginsAsMap()); 127 } 128 129 jdk = getPluginParameter(compiler, "release"); 130 if (jdk == null) { 131 jdk = project.getProperties().getProperty("maven.compiler.release"); 132 } 133 134 if (jdk == null) { 135 jdk = getPluginParameter(compiler, "target"); 136 } 137 138 if (jdk == null) { 139 // default value 140 jdk = project.getProperties().getProperty("maven.compiler.target"); 141 } 142 143 if (jdk == null) { 144 String version = (compiler == null) ? null : compiler.getVersion(); 145 146 if (version != null) { 147 return "Default target for maven-compiler-plugin version " + version; 148 } 149 } else { 150 if (Arrays.asList("1.5", "1.6", "1.7", "1.8").contains(jdk)) { 151 jdk = jdk.substring(2); 152 } 153 } 154 155 return jdk; 156 } 157 158 private static Plugin getCompilerPlugin(Map<String, Plugin> pluginsAsMap) { 159 return pluginsAsMap.get("org.apache.maven.plugins:maven-compiler-plugin"); 160 } 161 162 private static String getPluginParameter(Plugin plugin, String parameter) { 163 if (plugin != null) { 164 Xpp3Dom pluginConf = (Xpp3Dom) plugin.getConfiguration(); 165 166 if (pluginConf != null) { 167 Xpp3Dom target = pluginConf.getChild(parameter); 168 169 if (target != null) { 170 return target.getValue(); 171 } 172 } 173 } 174 175 return null; 176 } 177 178 public boolean hasSameRequirements(RequirementsHistory other) { 179 return Objects.equals(this.maven, other.getMaven()) && Objects.equals(this.jdk, other.getJdk()); 180 } 181}