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.PluginContainer;
29  import org.apache.maven.model.Prerequisites;
30  import org.apache.maven.plugin.descriptor.PluginDescriptor;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.tools.plugin.ExtendedPluginDescriptor;
33  import org.codehaus.plexus.util.xml.Xpp3Dom;
34  
35  /**
36   * Plugin requirements history.
37   *
38   * @author Slawomir Jaranowski
39   */
40  public class RequirementsHistory {
41      /**
42       * The plugin version.
43       */
44      private String version;
45  
46      /**
47       * The minimum version of Maven to run this plugin.
48       */
49      private String maven;
50  
51      /**
52       * The minimum version of the JDK to run this plugin.
53       */
54      private String jdk;
55  
56      public String getVersion() {
57          return version;
58      }
59  
60      public String getMaven() {
61          return maven;
62      }
63  
64      public String getJdk() {
65          return jdk;
66      }
67  
68      @Override
69      public String toString() {
70          final StringBuilder sb = new StringBuilder("RequirementsHistory{");
71          sb.append("version='").append(version).append('\'');
72          sb.append(", maven='").append(maven).append('\'');
73          sb.append(", jdk='").append(jdk).append('\'');
74          sb.append('}');
75          return sb.toString();
76      }
77  
78      public static RequirementsHistory discoverRequirements(MavenProject project) {
79          RequirementsHistory req = new RequirementsHistory();
80          req.version = project.getVersion();
81          req.jdk = discoverJdkRequirement(project, null);
82          req.maven = discoverMavenRequirement(project, null);
83          return req;
84      }
85      /**
86       * Tries to determine the Maven requirement from either the plugin descriptor or (if not set) from the
87       * Maven prerequisites element in the POM.
88       *
89       * @param project      not null
90       * @param pluginDescriptor the plugin descriptor (can be null)
91       * @return the Maven version or null if not specified
92       */
93      public static String discoverMavenRequirement(MavenProject project, PluginDescriptor pluginDescriptor) {
94          if (pluginDescriptor != null && StringUtils.isNotBlank(pluginDescriptor.getRequiredMavenVersion())) {
95              return pluginDescriptor.getRequiredMavenVersion();
96          }
97          return Optional.ofNullable(project.getPrerequisites())
98                  .map(Prerequisites::getMaven)
99                  .orElse(null);
100     }
101 
102     /**
103      * Tries to determine the JDK requirement from the following sources (until one is found)
104      * <ol>
105      * <li>use JDK requirement from plugin descriptor</li>
106      * <li>use {@code release} configuration of {@code org.apache.maven.plugins:maven-compiler-plugin}</li>
107      * <li>use {@code maven.compiler.release<} property</li>
108      * <li>use {@code target} configuration of {@code org.apache.maven.plugins:maven-compiler-plugin}</li>
109      * <li>use {@code maven.compiler.target} property</li>
110      * </ol>
111      *
112      * @param project      not null
113      * @param pluginDescriptor the plugin descriptor (can be null)
114      * @return the JDK version
115      */
116     public static String discoverJdkRequirement(MavenProject project, PluginDescriptor pluginDescriptor) {
117         String jdk = null;
118         if (pluginDescriptor instanceof ExtendedPluginDescriptor) {
119             ExtendedPluginDescriptor extPluginDescriptor = (ExtendedPluginDescriptor) pluginDescriptor;
120             jdk = extPluginDescriptor.getRequiredJavaVersion();
121         }
122         if (jdk != null) {
123             return jdk;
124         }
125         Plugin compiler = getCompilerPlugin(project.getBuild());
126         if (compiler == null) {
127             compiler = getCompilerPlugin(project.getPluginManagement());
128         }
129 
130         jdk = getPluginParameter(compiler, "release");
131         if (jdk == null) {
132             jdk = project.getProperties().getProperty("maven.compiler.release");
133         }
134 
135         if (jdk == null) {
136             jdk = getPluginParameter(compiler, "target");
137         }
138 
139         if (jdk == null) {
140             // default value
141             jdk = project.getProperties().getProperty("maven.compiler.target");
142         }
143 
144         if (jdk == null) {
145             String version = (compiler == null) ? null : compiler.getVersion();
146 
147             if (version != null) {
148                 return "Default target for maven-compiler-plugin version " + version;
149             }
150         } else {
151             if (Arrays.asList("1.5", "1.6", "1.7", "1.8").contains(jdk)) {
152                 jdk = jdk.substring(2);
153             }
154         }
155 
156         return jdk;
157     }
158 
159     private static Plugin getCompilerPlugin(PluginContainer container) {
160         if (container != null) {
161             Map<String, Plugin> pluginsAsMap = container.getPluginsAsMap();
162             return pluginsAsMap.get("org.apache.maven.plugins:maven-compiler-plugin");
163         }
164         return null;
165     }
166 
167     private static String getPluginParameter(Plugin plugin, String parameter) {
168         if (plugin != null) {
169             Xpp3Dom pluginConf = (Xpp3Dom) plugin.getConfiguration();
170 
171             if (pluginConf != null) {
172                 Xpp3Dom target = pluginConf.getChild(parameter);
173 
174                 if (target != null) {
175                     return target.getValue();
176                 }
177             }
178         }
179 
180         return null;
181     }
182 
183     public boolean hasSameRequirements(RequirementsHistory other) {
184         return Objects.equals(this.maven, other.getMaven()) && Objects.equals(this.jdk, other.getJdk());
185     }
186 }