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 package org.apache.geronimo.mavenplugins.geronimo.server; 021 022 import java.io.File; 023 import java.io.IOException; 024 import java.util.Map; 025 import java.util.HashMap; 026 import java.util.Enumeration; 027 import java.util.zip.ZipFile; 028 import java.util.zip.ZipEntry; 029 030 import org.apache.maven.artifact.Artifact; 031 032 import org.apache.maven.plugin.MojoExecutionException; 033 import org.apache.maven.plugin.MojoFailureException; 034 035 import org.codehaus.plexus.util.FileUtils; 036 037 import org.apache.tools.ant.taskdefs.Expand; 038 import org.apache.tools.ant.taskdefs.Chmod; 039 040 import org.apache.geronimo.mavenplugins.geronimo.AssemblyConfig; 041 import org.apache.geronimo.mavenplugins.geronimo.reporting.ReportingMojoSupport; 042 043 /** 044 * Common assembly install support. 045 * 046 * @version $Rev: 450613 $ $Date: 2006-09-27 15:45:46 -0700 (Wed, 27 Sep 2006) $ 047 */ 048 public abstract class InstallerMojoSupport 049 extends ReportingMojoSupport 050 { 051 /** 052 * Enable forced install refresh. 053 * 054 * @parameter expression="${refresh}" default-value="false" 055 */ 056 protected boolean refresh = false; 057 058 /** 059 * List of assembly artifact configurations. Artifacts need to point to ZIP archives. 060 * 061 * @parameter 062 */ 063 protected AssemblyConfig[] assemblies = null; 064 065 /** 066 * Identifer of the assembly configuration to use. 067 * 068 * @parameter expression="${assemblyId}" 069 */ 070 protected String assemblyId = null; 071 072 /** 073 * The default assemblyId to use when no assemblyId configured. 074 * 075 * @parameter 076 */ 077 protected String defaultAssemblyId = null; 078 079 /** 080 * A file which points to a specific assembly ZIP archive. 081 * If this parameter is set, then it will be used instead of from the 082 * assemblies configuration. 083 * 084 * @parameter expression="${assemblyArchive}" 085 */ 086 protected File assemblyArchive = null; 087 088 /** 089 * Directory to install the assembly into. 090 * 091 * @parameter expression="${installDirectory}" default-value="${project.build.directory}" 092 * @required 093 */ 094 protected File installDirectory = null; 095 096 /** 097 * The directory where the assembly has been installed to. 098 * 099 * 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 }