1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
150 if (geronimoHome != null) {
151
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
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
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
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
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 }