View Javadoc

1   /**
2    *
3    * Copyright 2005 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.geronimo.plugin.car;
19  
20  import java.io.File;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.apache.geronimo.system.configuration.RepositoryConfigurationStore;
25  import org.apache.geronimo.system.repository.Maven2Repository;
26  
27  import org.apache.maven.archiver.MavenArchiveConfiguration;
28  import org.apache.maven.archiver.MavenArchiver;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.artifact.Artifact;
31  
32  import org.codehaus.plexus.util.FileUtils;
33  import org.codehaus.plexus.archiver.jar.JarArchiver;
34  
35  /**
36   * Build a Geronimo Configuration using the local Maven infrastructure.
37   *
38   * <p>
39   * <b>NOTE:</b> Calling pom.xml must have defined a ${geronimoVersion} property.
40   * </p>
41   *
42   * @goal package
43   * @requiresDependencyResolution runtime
44   *
45   * @version $Rev: 434144 $ $Date: 2006-08-23 21:56:43 +0200 (mer., 23 août 2006) $
46   */
47  public class PackageMojo
48      extends AbstractCarMojo
49  {
50      /**
51       * The maven archive configuration to use.
52       *
53       * See <a href="http://maven.apache.org/ref/current/maven-archiver/apidocs/org/apache/maven/archiver/MavenArchiveConfiguration.html">the Javadocs for MavenArchiveConfiguration</a>.
54       *
55       * @parameter
56       */
57      private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
58  
59      /**
60       * The Jar archiver.
61       *
62       * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
63       * @required
64       * @readonly
65       */
66      private JarArchiver jarArchiver = null;
67  
68      /**
69       * Directory containing the generated archive.
70       *
71       * @parameter expression="${project.build.directory}"
72       * @required
73       */
74      private File outputDirectory = null;
75  
76      /**
77       * Directory containing the classes/resources.
78       *
79       * @parameter expression="${project.build.outputDirectory}"
80       * @required
81       */
82      private File classesDirectory = null;
83  
84      /**
85       * Name of the generated archive.
86       *
87       * @parameter expression="${project.build.finalName}"
88       * @required
89       */
90      private String finalName = null;
91  
92      /**
93       * ???
94       *
95       * @parameter expression="${settings.localRepository}"
96       * @required
97       * @readonly
98       */
99      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 }