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 }