001 /**
002 *
003 * Copyright 2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.plugin.car;
019
020 import java.io.File;
021 import java.util.ArrayList;
022 import java.util.List;
023
024 import org.apache.geronimo.system.configuration.RepositoryConfigurationStore;
025 import org.apache.geronimo.system.repository.Maven2Repository;
026
027 import org.apache.maven.archiver.MavenArchiveConfiguration;
028 import org.apache.maven.archiver.MavenArchiver;
029 import org.apache.maven.plugin.MojoExecutionException;
030 import org.apache.maven.artifact.Artifact;
031
032 import org.codehaus.plexus.util.FileUtils;
033 import org.codehaus.plexus.archiver.jar.JarArchiver;
034
035 /**
036 * Build a Geronimo Configuration using the local Maven infrastructure.
037 *
038 * <p>
039 * <b>NOTE:</b> Calling pom.xml must have defined a ${geronimoVersion} property.
040 * </p>
041 *
042 * @goal package
043 * @requiresDependencyResolution runtime
044 *
045 * @version $Rev: 434144 $ $Date: 2006-08-23 21:56:43 +0200 (mer., 23 août 2006) $
046 */
047 public class PackageMojo
048 extends AbstractCarMojo
049 {
050 /**
051 * The maven archive configuration to use.
052 *
053 * See <a href="http://maven.apache.org/ref/current/maven-archiver/apidocs/org/apache/maven/archiver/MavenArchiveConfiguration.html">the Javadocs for MavenArchiveConfiguration</a>.
054 *
055 * @parameter
056 */
057 private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
058
059 /**
060 * The Jar archiver.
061 *
062 * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
063 * @required
064 * @readonly
065 */
066 private JarArchiver jarArchiver = null;
067
068 /**
069 * Directory containing the generated archive.
070 *
071 * @parameter expression="${project.build.directory}"
072 * @required
073 */
074 private File outputDirectory = null;
075
076 /**
077 * Directory containing the classes/resources.
078 *
079 * @parameter expression="${project.build.outputDirectory}"
080 * @required
081 */
082 private File classesDirectory = null;
083
084 /**
085 * Name of the generated archive.
086 *
087 * @parameter expression="${project.build.finalName}"
088 * @required
089 */
090 private String finalName = null;
091
092 /**
093 * ???
094 *
095 * @parameter expression="${settings.localRepository}"
096 * @required
097 * @readonly
098 */
099 private File repository = null;
100
101 /**
102 * ???
103 *
104 * @parameter expression="${project.build.directory}/repository"
105 * @required
106 */
107 private File targetRepository = null;
108
109 /**
110 * ???
111 *
112 * @parameter expression="org.apache.geronimo.configs/geronimo-gbean-deployer/${geronimoVersion}/car"
113 * @required
114 * @readonly
115 */
116 private String deafultDeploymentConfig = null;
117
118 /**
119 * ???
120 *
121 * @parameter
122 */
123 private ArrayList deploymentConfigs;
124
125 /**
126 * ???
127 *
128 * @parameter expression="org.apache.geronimo.configs/geronimo-gbean-deployer/${geronimoVersion}/car?j2eeType=Deployer,name=Deployer"
129 * @required
130 */
131 private String deployerName = null;
132
133 /**
134 * ???
135 *
136 * @parameter expression="${project.build.directory}/plan/plan.xml"
137 * @required
138 */
139 private File planFile = null;
140
141 /**
142 * ???
143 *
144 * @parameter
145 */
146 private File moduleFile = null;
147
148 /**
149 * ???
150 *
151 * @parameter
152 */
153 private ArtifactItem module = null;
154
155 /**
156 * The location where the properties mapping will be generated.
157 *
158 * @parameter expression="${project.build.directory}/explicit-versions.properties"
159 */
160 private File explicitResolutionProperties = null;
161
162 /**
163 * A list of {@link ClasspathElement} objects which will be used to construct the
164 * Class-Path entry of the manifest.
165 *
166 * This is needed to allow per-element prefixes to be added, which the standard Maven archiver
167 * does not provide.
168 *
169 * @parameter
170 */
171 private List classpath = null;
172
173 /**
174 * The default prefix to be applied to all elements of the <tt>classpath</tt> which
175 * do not provide a prefix.
176 *
177 * @parameter
178 */
179 private String classpathPrefix = null;
180
181 //
182 // Mojo
183 //
184
185 protected void doExecute() throws Exception {
186 // We need to make sure to clean up any previous work first or this operation will fail
187 FileUtils.forceDelete(targetRepository);
188 FileUtils.forceMkdir(targetRepository);
189
190 // Use the default configs if none specified
191 if (deploymentConfigs == null) {
192 deploymentConfigs = new ArrayList();
193 deploymentConfigs.add(deafultDeploymentConfig);
194 }
195 log.debug("Deployment configs: " + deploymentConfigs);
196
197 // If module is set, then resolve the artifact and set moduleFile
198 if (module != null) {
199 Artifact artifact = getArtifact(module);
200 moduleFile = artifact.getFile();
201 log.debug("Using module file: " + moduleFile);
202 }
203
204 generateExplicitVersionProperties(explicitResolutionProperties);
205
206 executePackageBuilderShell();
207
208 // Build the archive
209 File archive = createArchive();
210
211 // Attach the generated archive for install/deploy
212 project.getArtifact().setFile(archive);
213 }
214
215 private File getArtifactInRepositoryDir() {
216 //
217 // HACK: Generate the filename in the repo... really should delegate this to the
218 // repo impl, but need to condense PackageMojo and PackageBuilder first
219 //
220
221 File dir = new File(targetRepository, project.getGroupId().replace('.', '/'));
222 dir = new File(dir, project.getArtifactId());
223 dir = new File(dir, project.getVersion());
224 dir = new File(dir, project.getArtifactId() + "-" + project.getVersion() + ".car");
225
226 return dir;
227 }
228
229 public void executePackageBuilderShell() throws Exception {
230 log.debug("Starting builder shell...");
231
232 PackageBuilder builder = new PackageBuilder();
233
234 //
235 // NOTE: May need to run this in a controlled classloader (w/reflection or a proxy)
236 //
237 // http://www.nabble.com/PackageBuilderShellMojo-%28m2%29-and-classloaders-p5271991.html
238 //
239
240 builder.setDeployerName(deployerName);
241 builder.setDeploymentConfig(deploymentConfigs);
242 builder.setModuleFile(moduleFile);
243 builder.setPlanFile(planFile);
244 builder.setRepository(repository);
245 builder.setRepositoryClass(Maven2Repository.class.getName());
246 builder.setConfigurationStoreClass(MavenConfigStore.class.getName());
247 builder.setTargetRepository(targetRepository);
248 builder.setTargetRepositoryClass(Maven2Repository.class.getName());
249 builder.setTargetConfigurationStoreClass(RepositoryConfigurationStore.class.getName());
250 builder.setExplicitResolutionLocation(explicitResolutionProperties.getAbsolutePath());
251
252 builder.execute();
253 }
254
255 /**
256 * Generates the configuration archive.
257 */
258 private File createArchive() throws MojoExecutionException {
259 File archiveFile = getArchiveFile(outputDirectory, finalName, null);
260
261 MavenArchiver archiver = new MavenArchiver();
262 archiver.setArchiver(jarArchiver);
263 archiver.setOutputFile(archiveFile);
264
265 try {
266 // Incldue the generated artifact contents
267 archiver.getArchiver().addDirectory(getArtifactInRepositoryDir());
268
269 // Include the optional classes.resources
270 archiver.getArchiver().addDirectory(classesDirectory);
271
272 if (classpath != null) {
273 archive.addManifestEntry("Class-Path", getClassPath());
274 }
275
276 archiver.createArchive(project, archive);
277
278 return archiveFile;
279 }
280 catch (Exception e) {
281 throw new MojoExecutionException("Failed to create archive", e);
282 }
283 }
284
285 private String getClassPath() throws MojoExecutionException {
286 StringBuffer buff = new StringBuffer();
287
288 ClasspathElement[] elements = (ClasspathElement[]) classpath.toArray(new ClasspathElement[classpath.size()]);
289 for (int i=0; i < elements.length; i++) {
290 Artifact artifact = getArtifact(elements[i]);
291
292 //
293 // TODO: Need to optionally get all transitive dependencies... but dunno how to get that intel from m2
294 //
295
296 String prefix = elements[i].getClasspathPrefix();
297 if (prefix == null) {
298 prefix = classpathPrefix;
299 }
300
301 if (prefix != null) {
302 buff.append(prefix);
303
304 if (!prefix.endsWith("/")) {
305 buff.append("/");
306 }
307 }
308
309 File file = artifact.getFile();
310 buff.append(file.getName());
311
312 if (i + 1< elements.length) {
313 buff.append(" ");
314 }
315 }
316
317 log.debug("Using classpath: " + buff);
318
319 return buff.toString();
320 }
321 }