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.plugins.plugin.descriptor; 020 021import java.io.IOException; 022import java.io.Reader; 023import java.util.ArrayList; 024import java.util.List; 025 026import org.apache.maven.plugin.descriptor.MojoDescriptor; 027import org.apache.maven.plugin.descriptor.Parameter; 028import org.apache.maven.plugin.descriptor.PluginDescriptor; 029import org.codehaus.plexus.component.repository.ComponentDependency; 030import org.codehaus.plexus.component.repository.ComponentRequirement; 031import org.codehaus.plexus.configuration.PlexusConfiguration; 032import org.codehaus.plexus.configuration.PlexusConfigurationException; 033import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; 034import org.codehaus.plexus.util.xml.Xpp3DomBuilder; 035import org.codehaus.plexus.util.xml.pull.XmlPullParserException; 036 037/** 038 * Build plugin descriptor object from {@code plugin.xml}. 039 * 040 * @author Jason van Zyl 041 */ 042public class PluginDescriptorBuilder { 043 044 private boolean isV4; 045 046 public PluginDescriptor build(Reader reader) throws PlexusConfigurationException { 047 return build(reader, null); 048 } 049 050 public PluginDescriptor build(Reader reader, String source) throws PlexusConfigurationException { 051 PlexusConfiguration c = buildConfiguration(reader); 052 053 PluginDescriptor pluginDescriptor = new PluginDescriptor(); 054 055 pluginDescriptor.setSource(source); 056 pluginDescriptor.setGroupId(c.getChild("groupId").getValue()); 057 pluginDescriptor.setArtifactId(c.getChild("artifactId").getValue()); 058 pluginDescriptor.setVersion(c.getChild("version").getValue()); 059 pluginDescriptor.setGoalPrefix(c.getChild("goalPrefix").getValue()); 060 061 pluginDescriptor.setName(c.getChild("name").getValue()); 062 pluginDescriptor.setDescription(c.getChild("description").getValue()); 063 064 String isolatedRealm = c.getChild("isolatedRealm").getValue(); 065 066 if (isolatedRealm != null) { 067 pluginDescriptor.setIsolatedRealm(Boolean.parseBoolean(isolatedRealm)); 068 } 069 070 String inheritedByDefault = c.getChild("inheritedByDefault").getValue(); 071 072 if (inheritedByDefault != null) { 073 pluginDescriptor.setInheritedByDefault(Boolean.parseBoolean(inheritedByDefault)); 074 } 075 076 String requiredMavenVersion = c.getChild("requiredMavenVersion").getValue(); 077 if (requiredMavenVersion != null) { 078 isV4 = requiredMavenVersion.startsWith("4"); 079 } else { 080 isV4 = false; 081 } 082 083 // ---------------------------------------------------------------------- 084 // Components 085 // ---------------------------------------------------------------------- 086 087 PlexusConfiguration[] mojoConfigurations = c.getChild("mojos").getChildren("mojo"); 088 089 for (PlexusConfiguration component : mojoConfigurations) { 090 MojoDescriptor mojoDescriptor = buildComponentDescriptor(component, pluginDescriptor); 091 092 pluginDescriptor.addMojo(mojoDescriptor); 093 } 094 095 // ---------------------------------------------------------------------- 096 // Dependencies 097 // ---------------------------------------------------------------------- 098 099 PlexusConfiguration[] dependencyConfigurations = 100 c.getChild("dependencies").getChildren("dependency"); 101 102 List<ComponentDependency> dependencies = new ArrayList<>(); 103 104 for (PlexusConfiguration d : dependencyConfigurations) { 105 ComponentDependency cd = new ComponentDependency(); 106 107 cd.setArtifactId(d.getChild("artifactId").getValue()); 108 109 cd.setGroupId(d.getChild("groupId").getValue()); 110 111 cd.setType(d.getChild("type").getValue()); 112 113 cd.setVersion(d.getChild("version").getValue()); 114 115 dependencies.add(cd); 116 } 117 118 pluginDescriptor.setDependencies(dependencies); 119 120 return pluginDescriptor; 121 } 122 123 @SuppressWarnings("checkstyle:methodlength") 124 public MojoDescriptor buildComponentDescriptor(PlexusConfiguration c, PluginDescriptor pluginDescriptor) 125 throws PlexusConfigurationException { 126 MojoDescriptor mojo = new MojoDescriptor(); 127 mojo.setPluginDescriptor(pluginDescriptor); 128 129 mojo.setGoal(c.getChild("goal").getValue()); 130 131 mojo.setImplementation(c.getChild("implementation").getValue()); 132 133 PlexusConfiguration langConfig = c.getChild("language"); 134 135 if (langConfig != null) { 136 mojo.setLanguage(langConfig.getValue()); 137 } 138 139 PlexusConfiguration configuratorConfig = c.getChild("configurator"); 140 141 if (configuratorConfig != null) { 142 mojo.setComponentConfigurator(configuratorConfig.getValue()); 143 } 144 145 PlexusConfiguration composerConfig = c.getChild("composer"); 146 147 if (composerConfig != null) { 148 mojo.setComponentComposer(composerConfig.getValue()); 149 } 150 151 String since = c.getChild("since").getValue(); 152 153 if (since != null) { 154 mojo.setSince(since); 155 } 156 157 PlexusConfiguration deprecated = c.getChild("deprecated", false); 158 159 if (deprecated != null) { 160 mojo.setDeprecated(deprecated.getValue()); 161 } 162 163 String phase = c.getChild("phase").getValue(); 164 165 if (phase != null) { 166 mojo.setPhase(phase); 167 } 168 169 String executePhase = c.getChild("executePhase").getValue(); 170 171 if (executePhase != null) { 172 mojo.setExecutePhase(executePhase); 173 } 174 175 String executeMojo = c.getChild("executeGoal").getValue(); 176 177 if (executeMojo != null) { 178 mojo.setExecuteGoal(executeMojo); 179 } 180 181 String executeLifecycle = c.getChild("executeLifecycle").getValue(); 182 183 if (executeLifecycle != null) { 184 mojo.setExecuteLifecycle(executeLifecycle); 185 } 186 187 mojo.setInstantiationStrategy(c.getChild("instantiationStrategy").getValue()); 188 189 mojo.setDescription(c.getChild("description").getValue()); 190 191 PlexusConfiguration dependencyResolution = c.getChild("requiresDependencyResolution", false); 192 193 if (dependencyResolution != null) { 194 mojo.setDependencyResolutionRequired(dependencyResolution.getValue()); 195 } 196 197 PlexusConfiguration dependencyCollection = c.getChild("requiresDependencyCollection", false); 198 199 if (dependencyCollection != null) { 200 mojo.setDependencyCollectionRequired(dependencyCollection.getValue()); 201 } 202 203 String directInvocationOnly = c.getChild("requiresDirectInvocation").getValue(); 204 205 if (directInvocationOnly != null) { 206 mojo.setDirectInvocationOnly(Boolean.parseBoolean(directInvocationOnly)); 207 } 208 209 String requiresProject = c.getChild("requiresProject").getValue(); 210 211 if (requiresProject != null) { 212 mojo.setProjectRequired(Boolean.parseBoolean(requiresProject)); 213 } 214 215 String requiresReports = c.getChild("requiresReports").getValue(); 216 217 if (requiresReports != null) { 218 mojo.setRequiresReports(Boolean.parseBoolean(requiresReports)); 219 } 220 221 String aggregator = c.getChild("aggregator").getValue(); 222 223 if (aggregator != null) { 224 mojo.setAggregator(Boolean.parseBoolean(aggregator)); 225 } 226 227 String requiresOnline = c.getChild("requiresOnline").getValue(); 228 229 if (requiresOnline != null) { 230 mojo.setOnlineRequired(Boolean.parseBoolean(requiresOnline)); 231 } 232 233 String inheritedByDefault = c.getChild("inheritedByDefault").getValue(); 234 235 if (inheritedByDefault != null) { 236 mojo.setInheritedByDefault(Boolean.parseBoolean(inheritedByDefault)); 237 } 238 239 String threadSafe = c.getChild("threadSafe").getValue(); 240 241 if (threadSafe != null) { 242 mojo.setThreadSafe(Boolean.parseBoolean(threadSafe)); 243 } 244 245 // ---------------------------------------------------------------------- 246 // Configuration 247 // ---------------------------------------------------------------------- 248 249 PlexusConfiguration mojoConfig = c.getChild("configuration"); 250 mojo.setMojoConfiguration(mojoConfig); 251 252 // ---------------------------------------------------------------------- 253 // Parameters 254 // ---------------------------------------------------------------------- 255 256 PlexusConfiguration[] parameterConfigurations = c.getChild("parameters").getChildren("parameter"); 257 258 List<Parameter> parameters = new ArrayList<>(); 259 260 for (PlexusConfiguration d : parameterConfigurations) { 261 Parameter parameter = new Parameter(); 262 263 parameter.setName(d.getChild("name").getValue()); 264 265 parameter.setAlias(d.getChild("alias").getValue()); 266 267 parameter.setType(d.getChild("type").getValue()); 268 269 String required = d.getChild("required").getValue(); 270 271 parameter.setRequired(Boolean.parseBoolean(required)); 272 273 PlexusConfiguration editableConfig = d.getChild("editable"); 274 275 // we need the null check for pre-build legacy plugins... 276 if (editableConfig != null) { 277 String editable = d.getChild("editable").getValue(); 278 279 parameter.setEditable(editable == null || Boolean.parseBoolean(editable)); 280 } 281 282 parameter.setDescription(d.getChild("description").getValue()); 283 284 parameter.setDeprecated(d.getChild("deprecated").getValue()); 285 286 parameter.setImplementation(d.getChild("implementation").getValue()); 287 288 parameter.setSince(d.getChild("since").getValue()); 289 290 if (isV4) { 291 parameter.setExpression(d.getChild("expression").getValue()); 292 parameter.setDefaultValue(d.getChild("defaultValue").getValue()); 293 } else { 294 PlexusConfiguration paramConfig = mojoConfig.getChild(parameter.getName(), false); 295 if (paramConfig != null) { 296 parameter.setExpression(paramConfig.getValue(null)); 297 parameter.setDefaultValue(paramConfig.getAttribute("default-value")); 298 } 299 } 300 301 parameters.add(parameter); 302 } 303 304 mojo.setParameters(parameters); 305 306 // TODO this should not need to be handed off... 307 308 // ---------------------------------------------------------------------- 309 // Requirements 310 // ---------------------------------------------------------------------- 311 312 PlexusConfiguration[] requirements = c.getChild("requirements").getChildren("requirement"); 313 314 for (PlexusConfiguration requirement : requirements) { 315 ComponentRequirement cr = new ComponentRequirement(); 316 317 cr.setRole(requirement.getChild("role").getValue()); 318 319 cr.setRoleHint(requirement.getChild("role-hint").getValue()); 320 321 cr.setFieldName(requirement.getChild("field-name").getValue()); 322 323 mojo.addRequirement(cr); 324 } 325 326 return mojo; 327 } 328 329 // ---------------------------------------------------------------------- 330 // 331 // ---------------------------------------------------------------------- 332 333 public PlexusConfiguration buildConfiguration(Reader configuration) throws PlexusConfigurationException { 334 try { 335 return new XmlPlexusConfiguration(Xpp3DomBuilder.build(configuration)); 336 } catch (IOException | XmlPullParserException e) { 337 throw new PlexusConfigurationException(e.getMessage(), e); 338 } 339 } 340}