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 */ 019 020 021 package org.apache.geronimo.mavenplugins.car; 022 023 import java.io.File; 024 import java.io.FileOutputStream; 025 import java.io.IOException; 026 import java.io.StringReader; 027 import java.util.Collections; 028 import java.util.List; 029 030 import org.apache.geronimo.kernel.config.ConfigurationData; 031 import org.apache.geronimo.kernel.config.ConfigurationStore; 032 import org.apache.geronimo.kernel.config.InvalidConfigException; 033 import org.apache.geronimo.kernel.config.NoSuchConfigException; 034 import org.apache.geronimo.kernel.repository.Artifact; 035 import org.apache.geronimo.system.configuration.RepositoryConfigurationStore; 036 import org.apache.geronimo.system.plugin.PluginInstallerGBean; 037 import org.apache.geronimo.system.plugin.PluginXmlUtil; 038 import org.apache.geronimo.system.plugin.model.ArtifactType; 039 import org.apache.geronimo.system.plugin.model.DependencyType; 040 import org.apache.geronimo.system.plugin.model.LicenseType; 041 import org.apache.geronimo.system.plugin.model.PluginArtifactType; 042 import org.apache.geronimo.system.plugin.model.PluginType; 043 import org.apache.geronimo.system.repository.Maven2Repository; 044 import org.apache.maven.model.License; 045 import org.apache.maven.model.Plugin; 046 import org.apache.maven.model.PluginExecution; 047 import org.apache.maven.model.Resource; 048 import org.codehaus.plexus.configuration.PlexusConfiguration; 049 import org.codehaus.plexus.util.xml.Xpp3Dom; 050 051 /** 052 * Generate a geronimo-plugin.xml file based on configuration in the pom and car-maven-plugin configuration. 053 * 054 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 055 * @goal prepare-metadata 056 */ 057 public class PluginMetadataGeneratorMojo 058 extends AbstractCarMojo { 059 060 061 /** 062 * The Geronimo repository where modules will be packaged up from. 063 * 064 * @parameter expression="${project.build.directory}/repository" 065 * @required 066 */ 067 private File targetRepository = null; 068 069 /** 070 * Directory for generated plugin metadata file. 071 * 072 * @parameter expression="${project.build.directory}/resources/" 073 * @required 074 */ 075 protected File targetDir = null; 076 077 /** 078 * Name of generated plugin metadata file. 079 * 080 * @parameter default-value="META-INF/geronimo-plugin.xml" 081 * @required 082 */ 083 protected String pluginMetadataFileName = null; 084 085 /** 086 * Full path of generated plugin metadata file. 087 * 088 * @ parameter expression="${project.build.directory}/resources/META-INF/geronimo-plugin.xml" 089 * @required 090 */ 091 // protected File targetFile = null; 092 093 /** 094 * Whether licenses (copied from maven licence elements) are OSI approved. 095 * 096 * @parameter default-value="false" 097 */ 098 private boolean osiApproved; 099 100 /** 101 * Category of the geronimo plugin. 102 * 103 * @parameter 104 */ 105 private String category; 106 107 /** 108 * Dependencies explicitly listed in the car-maven-plugin configuration 109 * 110 * @parameter 111 */ 112 private List<Dependency> dependencies = Collections.emptyList(); 113 114 /** 115 * Configuration of use of maven dependencies. If missing or if value element is false, use the explicit list in the car-maven-plugin configuration. 116 * If present and true, use the maven dependencies in the current pom file of scope null, runtime, or compile. In addition, the version of the maven 117 * dependency can be included or not depending on the includeVersion element. 118 * 119 * @parameter 120 */ 121 private UseMavenDependencies useMavenDependencies; 122 123 /** 124 * Shared configuration from parent that we merge since maven is incompetent at it. This is a plugin-artifactType element without moduleId or dependencies. 125 * Do not attempt to include more than one of these in the parent poms since maven will not merge them correctly. 126 * 127 * @parameter 128 */ 129 private PlexusConfiguration commonInstance; 130 131 /** 132 * Configuration for this instance itself. This is a plugin-artifactType element without moduleId or dependencies. Do not include more than one of these in the parent poms 133 * since maven will not merge them correctly. Actually we have to fish this out of the model since maven mangles the xml for us. 134 */ 135 // private PlexusConfiguration instance; 136 protected void doExecute() throws Exception { 137 138 PluginType metadata = new PluginType(); 139 metadata.setName(project.getName()); 140 metadata.setAuthor(project.getOrganization() == null? "unknown": project.getOrganization().getName()); 141 metadata.setUrl(project.getOrganization() == null? "unknown": project.getOrganization().getUrl()); 142 metadata.setDescription(project.getDescription()); 143 metadata.setCategory(category); 144 145 if (project.getLicenses() != null) { 146 for (Object licenseObj : project.getLicenses()) { 147 License license = (License) licenseObj; 148 LicenseType licenseType = new LicenseType(); 149 licenseType.setValue(license.getName()); 150 licenseType.setOsiApproved(osiApproved); 151 metadata.getLicense().add(licenseType); 152 } 153 } 154 155 PluginArtifactType instance; 156 Plugin plugin = (Plugin) project.getModel().getBuild().getPluginsAsMap().get("org.apache.geronimo.buildsupport:car-maven-plugin"); 157 if (plugin == null) { 158 throw new Error("Unable to resolve car plugin"); 159 } 160 161 Xpp3Dom dom; 162 if (plugin.getExecutions().isEmpty()) { 163 dom = (Xpp3Dom) plugin.getConfiguration(); 164 } else { 165 if (plugin.getExecutions().size() > 1) { 166 throw new IllegalStateException("Cannot determine correct configuration for PluginMetadataGeneratorMojo: " + plugin.getExecutionsAsMap().keySet()); 167 } 168 dom = (Xpp3Dom) ((PluginExecution) plugin.getExecutions().get(0)).getConfiguration(); 169 } 170 Xpp3Dom instanceDom = dom.getChild("instance"); 171 172 if (instanceDom == null || instanceDom.getChild("plugin-artifact") == null) { 173 instance = new PluginArtifactType(); 174 } else { 175 String instanceString = instanceDom.getChild("plugin-artifact").toString(); 176 instance = PluginXmlUtil.loadPluginArtifactMetadata(new StringReader(instanceString.replace("#{", "${"))); 177 } 178 if (this.commonInstance != null && this.commonInstance.getChild("plugin-artifact") != null) { 179 PluginArtifactType commonInstance = PluginXmlUtil.loadPluginArtifactMetadata(new StringReader(this.commonInstance.getChild("plugin-artifact").toString().replace("#{", "${"))); 180 //merge 181 if (instance.getArtifactAlias().isEmpty()) { 182 instance.getArtifactAlias().addAll(commonInstance.getArtifactAlias()); 183 } 184 if (instance.getConfigSubstitution().isEmpty()) { 185 instance.getConfigSubstitution().addAll(commonInstance.getConfigSubstitution()); 186 } 187 //it doesn't make sense to copy a "generic" config.xml content into a specific module. 188 // if ((instance.getConfigXmlContent() == null || instance.getConfigXmlContent().getGbean().isEmpty()) 189 // && (commonInstance.getConfigXmlContent() != null && !commonInstance.getConfigXmlContent().getGbean().isEmpty())) { 190 // instance.setConfigXmlContent(new ConfigXmlContentType()); 191 // instance.getConfigXmlContent().getGbean().addAll(commonInstance.getConfigXmlContent().getGbean()); 192 // } 193 if (instance.getCopyFile().isEmpty()) { 194 instance.getCopyFile().addAll(commonInstance.getCopyFile()); 195 } 196 if (instance.getDependency().isEmpty()) { 197 instance.getDependency().addAll(commonInstance.getDependency()); 198 } 199 if (instance.getGeronimoVersion().isEmpty()) { 200 instance.getGeronimoVersion().addAll(commonInstance.getGeronimoVersion()); 201 } 202 if (instance.getJvmVersion().isEmpty()) { 203 instance.getJvmVersion().addAll(commonInstance.getJvmVersion()); 204 } 205 if (instance.getObsoletes().isEmpty()) { 206 instance.getObsoletes().addAll(commonInstance.getObsoletes()); 207 } 208 if (instance.getPrerequisite().isEmpty()) { 209 instance.getPrerequisite().addAll(commonInstance.getPrerequisite()); 210 } 211 if (instance.getSourceRepository().isEmpty()) { 212 instance.getSourceRepository().addAll(commonInstance.getSourceRepository()); 213 } 214 } 215 metadata.getPluginArtifact().add(instance); 216 217 ArtifactType artifactType = new ArtifactType(); 218 artifactType.setGroupId(project.getGroupId()); 219 artifactType.setArtifactId(project.getArtifactId()); 220 artifactType.setVersion(project.getVersion()); 221 ArtifactType existingArtifact = instance.getModuleId(); 222 if (existingArtifact != null && existingArtifact.getType() != null) { 223 artifactType.setType(existingArtifact.getType()); 224 } else { 225 artifactType.setType(project.getArtifact().getType()); 226 } 227 instance.setModuleId(artifactType); 228 addDependencies(instance); 229 targetDir.mkdirs(); 230 File targetFile = new File(targetDir.toURI().resolve(pluginMetadataFileName)); 231 targetFile.getParentFile().mkdirs(); 232 FileOutputStream out = new FileOutputStream(targetFile); 233 try { 234 PluginXmlUtil.writePluginMetadata(metadata, out); 235 } finally { 236 out.close(); 237 } 238 Resource resource = new Resource(); 239 resource.setDirectory(targetDir.getPath()); 240 resource.addInclude(pluginMetadataFileName); 241 getProject().getResources().add(resource); 242 } 243 244 private void addDependencies(PluginArtifactType instance) throws InvalidConfigException, IOException, NoSuchConfigException { 245 if (useMavenDependencies == null || !useMavenDependencies.isValue()) { 246 for (Dependency dependency : dependencies) { 247 instance.getDependency().add(dependency.toDependencyType()); 248 } 249 } else { 250 if (targetRepository.exists() && targetRepository.isDirectory()) { 251 Maven2Repository targetRepo = new Maven2Repository(targetRepository); 252 ConfigurationStore configStore = new RepositoryConfigurationStore(targetRepo); 253 Artifact pluginArtifact = PluginInstallerGBean.toArtifact(instance.getModuleId()); 254 ConfigurationData data = configStore.loadConfiguration(pluginArtifact); 255 PluginInstallerGBean.addGeronimoDependencies(data, instance.getDependency(), useMavenDependencies.isIncludeVersion()); 256 } else { 257 List<org.apache.maven.model.Dependency> includedDependencies = project.getOriginalModel().getDependencies(); 258 List<org.apache.maven.model.Dependency> artifacts = project.getDependencies(); 259 for (org.apache.maven.model.Dependency dependency : includedDependencies) { 260 dependency = resolveDependency(dependency, artifacts); 261 if (includeDependency(dependency)) { 262 DependencyType gdep = toGeronimoDependency(dependency, useMavenDependencies.isIncludeVersion()); 263 instance.getDependency().add(gdep); 264 } 265 } 266 } 267 268 } 269 } 270 271 private static DependencyType toGeronimoDependency(final org.apache.maven.model.Dependency dependency, boolean includeVersion) { 272 DependencyType dependencyType = new DependencyType(); 273 dependencyType.setGroupId(dependency.getGroupId()); 274 dependencyType.setArtifactId(dependency.getArtifactId()); 275 if (includeVersion) { 276 dependencyType.setVersion(dependency.getVersion()); 277 } 278 dependencyType.setType(dependency.getType()); 279 dependencyType.setStart(true); 280 return dependencyType; 281 } 282 }