View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.geronimo.mavenplugins.geronimo.server;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.Map;
25  import java.util.HashMap;
26  import java.util.Enumeration;
27  import java.util.zip.ZipFile;
28  import java.util.zip.ZipEntry;
29  
30  import org.apache.maven.artifact.Artifact;
31  
32  import org.apache.maven.plugin.MojoExecutionException;
33  import org.apache.maven.plugin.MojoFailureException;
34  
35  import org.codehaus.plexus.util.FileUtils;
36  
37  import org.apache.tools.ant.taskdefs.Expand;
38  import org.apache.tools.ant.taskdefs.Chmod;
39  
40  import org.apache.geronimo.mavenplugins.geronimo.AssemblyConfig;
41  import org.apache.geronimo.mavenplugins.geronimo.reporting.ReportingMojoSupport;
42  
43  /**
44   * Common assembly install support.
45   *
46   * @version $Rev: 450613 $ $Date: 2006-09-27 15:45:46 -0700 (Wed, 27 Sep 2006) $
47   */
48  public abstract class InstallerMojoSupport
49      extends ReportingMojoSupport
50  {
51      /**
52       * Enable forced install refresh.
53       *
54       * @parameter expression="${refresh}" default-value="false"
55       */
56      protected boolean refresh = false;
57  
58      /**
59       * List of assembly artifact configurations.  Artifacts need to point to ZIP archives.
60       *
61       * @parameter
62       */
63      protected AssemblyConfig[] assemblies = null;
64  
65      /**
66       * Identifer of the assembly configuration to use.
67       *
68       * @parameter expression="${assemblyId}"
69       */
70      protected String assemblyId = null;
71  
72      /**
73       * The default assemblyId to use when no assemblyId configured.
74       *
75       * @parameter
76       */
77      protected String defaultAssemblyId = null;
78  
79      /**
80       * A file which points to a specific assembly ZIP archive.
81       * If this parameter is set, then it will be used instead of from the
82       * assemblies configuration.
83       *
84       * @parameter expression="${assemblyArchive}"
85       */
86      protected File assemblyArchive = null;
87  
88      /**
89       * Directory to install the assembly into.
90       *
91       * @parameter expression="${installDirectory}" default-value="${project.build.directory}"
92       * @required
93       */
94      protected File installDirectory = null;
95  
96      /**
97       * The directory where the assembly has been installed to.
98       *
99       * Normally this value is detected,
100      * but if it is set, then it is assumed to be the location where a pre-installed assembly exists
101      * and no installation will be done.
102      *
103      * @parameter expression="${geronimoHome}"
104      */
105     protected File geronimoHome;
106 
107     protected static final int INSTALL_FROM_ARTIFACT = 0;
108 
109     protected static final int INSTALL_FROM_FILE = 1;
110 
111     protected static final int INSTALL_ALREADY_EXISTS = 2;
112 
113     protected int installType;
114 
115     private File discoverGeronimoHome(final File archive) throws MojoExecutionException {
116         log.debug("Attempting to discover geronimoHome...");
117 
118         File dir = null;
119 
120         try {
121             ZipFile zipFile = new ZipFile(archive);
122 
123             Enumeration enum = zipFile.entries();
124             while (enum.hasMoreElements()) {
125                 ZipEntry entry = (ZipEntry)enum.nextElement();
126                 if (entry.getName().endsWith("bin/server.jar")) {
127                     File file = new File(installDirectory, entry.getName());
128                     dir = file.getParentFile().getParentFile();
129                     break;
130                 }
131             }
132 
133             zipFile.close();
134         }
135         catch (IOException e) {
136             throw new MojoExecutionException("Failed to determine geronimoHome while scanning archive for 'bin/server.jar'", e);
137         }
138 
139         if (dir == null) {
140             throw new MojoExecutionException("Archive does not contain a Geronimo assembly: " + archive);
141         }
142 
143         return dir;
144     }
145 
146     protected void init() throws MojoExecutionException, MojoFailureException {
147         super.init();
148 
149         // First check if geronimoHome is set, if it is, then we can skip this
150         if (geronimoHome != null) {
151             // Quick sanity check
152             File file = new File(geronimoHome, "bin/server.jar");
153             if (!file.exists()) {
154                 throw new MojoExecutionException("When geronimoHome is set, it must point to a directory that contains 'bin/server.jar'");
155             }
156             log.info("Using pre-installed assembly: " + geronimoHome);
157 
158             installType = INSTALL_ALREADY_EXISTS;
159         }
160         else {
161             if (assemblyArchive != null) {
162                 log.info("Using non-artifact based assembly archive: " + assemblyArchive);
163 
164                 installType = INSTALL_FROM_FILE;
165             }
166             else {
167                 Artifact artifact = getAssemblyArtifact();
168 
169                 if (!"zip".equals(artifact.getType())) {
170                     throw new MojoExecutionException("Assembly file does not look like a ZIP archive");
171                 }
172 
173                 log.info("Using assembly artifact: " + artifact);
174 
175                 assemblyArchive = artifact.getFile();
176 
177                 installType = INSTALL_FROM_ARTIFACT;
178             }
179 
180             geronimoHome = discoverGeronimoHome(assemblyArchive);
181             log.info("Using geronimoHome: " + geronimoHome);
182         }
183     }
184 
185     /**
186      * Selects the assembly artifact tp be used for installation.
187      *
188      * @return The assembly artifact selected to be installed.
189      *
190      * @throws MojoExecutionException   Failed to select assembly artifact
191      */
192     protected Artifact getAssemblyArtifact() throws MojoExecutionException {
193         AssemblyConfig config;
194 
195         if (assemblies == null || assemblies.length == 0) {
196             throw new MojoExecutionException("At least one assembly configuration must be specified");
197         }
198         else if (assemblies.length > 1 && assemblyId == null && defaultAssemblyId == null) {
199             throw new MojoExecutionException("Must specify assemblyId (or defaultAssemblyId) when more than on assembly configuration is given");
200         }
201         else if (assemblies.length == 1) {
202             config = assemblies[0];
203         }
204         else {
205             if (assemblyId == null) {
206                 assemblyId = defaultAssemblyId;
207             }
208 
209             log.debug("Searching for assembly config for id: " + assemblyId);
210 
211             // Make sure there are no duplicate ids
212             Map idMap = new HashMap();
213 
214             for (int i=0; i < assemblies.length; i++) {
215                 String id = assemblies[i].getId();
216 
217                 if (id == null) {
218                     throw new MojoExecutionException("Missing id for assembly configuration: " + assemblies[i]);
219                 }
220 
221                 if (idMap.containsKey(id)) {
222                     throw new MojoExecutionException("Duplicate assembly id: " + id);
223                 }
224 
225                 idMap.put(id, assemblies[i]);
226             }
227 
228             config = (AssemblyConfig) idMap.get(assemblyId);
229             if (config == null) {
230                 throw new MojoExecutionException("Missing assembly configuration for id: " + assemblyId);
231             }
232         }
233 
234         log.info("Using assembly configuration: " + config.getId());
235         Artifact artifact = getArtifact(config);
236 
237         if (artifact.getFile() == null) {
238             throw new MojoExecutionException("Assembly artifact does not have an attached file: " + artifact);
239         }
240 
241         return artifact;
242     }
243 
244     /**
245      * Performs assembly installation unless the install type is pre-existing.
246      *
247      * @throws Exception
248      */
249     protected void installAssembly() throws Exception {
250         if (installType == INSTALL_ALREADY_EXISTS) {
251             log.info("Installation type is pre-existing; skipping installation");
252             return;
253         }
254 
255         // Check if there is a newer archive or missing marker to trigger assembly install
256         File installMarker = new File(geronimoHome, ".installed");
257 
258         if (!refresh) {
259             if (!installMarker.exists()) {
260                 refresh = true;
261             }
262             else if (assemblyArchive.lastModified() > installMarker.lastModified()) {
263                 log.debug("Detected new assembly archive");
264                 refresh = true;
265             }
266         }
267         else {
268             log.debug("User requested installation refresh");
269         }
270 
271         if (refresh) {
272             if (geronimoHome.exists()) {
273                 log.info("Uninstalling: " + geronimoHome);
274                 FileUtils.forceDelete(geronimoHome);
275             }
276         }
277 
278         // Install the assembly
279         if (!installMarker.exists()) {
280             log.info("Installing assembly...");
281 
282             FileUtils.forceMkdir(geronimoHome);
283             
284             Expand unzip = (Expand)createTask("unzip");
285             unzip.setSrc(assemblyArchive);
286             unzip.setDest(installDirectory);
287             unzip.execute();
288 
289             // Make scripts executable, since Java unzip ignores perms
290             Chmod chmod = (Chmod)createTask("chmod");
291             chmod.setPerm("ugo+rx");
292             chmod.setDir(geronimoHome);
293             chmod.setIncludes("bin/*.sh");
294             chmod.execute();
295 
296             installMarker.createNewFile();
297         }
298         else {
299             log.info("Re-using previously installed assembly");
300         }
301     }
302 }