View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.plugin.report;
20  
21  import java.util.Arrays;
22  import java.util.Map;
23  import java.util.Objects;
24  import java.util.Optional;
25  
26  import org.apache.commons.lang3.StringUtils;
27  import org.apache.maven.model.Plugin;
28  import org.apache.maven.model.Prerequisites;
29  import org.apache.maven.plugin.descriptor.PluginDescriptor;
30  import org.apache.maven.project.MavenProject;
31  import org.apache.maven.tools.plugin.ExtendedPluginDescriptor;
32  import org.codehaus.plexus.util.xml.Xpp3Dom;
33  
34  /**
35   * Plugin requirements history.
36   *
37   * @author Slawomir Jaranowski
38   */
39  public class RequirementsHistory {
40      /**
41       * The plugin version.
42       */
43      private String version;
44  
45      /**
46       * The minimum version of Maven to run this plugin.
47       */
48      private String maven;
49  
50      /**
51       * The minimum version of the JDK to run this plugin.
52       */
53      private String jdk;
54  
55      public String getVersion() {
56          return version;
57      }
58  
59      public String getMaven() {
60          return maven;
61      }
62  
63      public String getJdk() {
64          return jdk;
65      }
66  
67      @Override
68      public String toString() {
69          final StringBuilder sb = new StringBuilder("RequirementsHistory{");
70          sb.append("version='").append(version).append('\'');
71          sb.append(", maven='").append(maven).append('\'');
72          sb.append(", jdk='").append(jdk).append('\'');
73          sb.append('}');
74          return sb.toString();
75      }
76  
77      public static RequirementsHistory discoverRequirements(MavenProject project) {
78          RequirementsHistory req = new RequirementsHistory();
79          req.version = project.getVersion();
80          req.jdk = discoverJdkRequirement(project, null);
81          req.maven = discoverMavenRequirement(project, null);
82          return req;
83      }
84      /**
85       * Tries to determine the Maven requirement from either the plugin descriptor or (if not set) from the
86       * Maven prerequisites element in the POM.
87       *
88       * @param project      not null
89       * @param pluginDescriptor the plugin descriptor (can be null)
90       * @return the Maven version or null if not specified
91       */
92      public static String discoverMavenRequirement(MavenProject project, PluginDescriptor pluginDescriptor) {
93          if (pluginDescriptor != null && StringUtils.isNotBlank(pluginDescriptor.getRequiredMavenVersion())) {
94              return pluginDescriptor.getRequiredMavenVersion();
95          }
96          return Optional.ofNullable(project.getPrerequisites())
97                  .map(Prerequisites::getMaven)
98                  .orElse(null);
99      }
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 }