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.module;
021    
022    import java.io.File;
023    import java.util.List;
024    import java.util.ArrayList;
025    import java.util.Iterator;
026    
027    import javax.enterprise.deploy.spi.DeploymentManager;
028    import javax.enterprise.deploy.spi.Target;
029    import javax.enterprise.deploy.spi.TargetModuleID;
030    import javax.enterprise.deploy.spi.status.ProgressObject;
031    import javax.enterprise.deploy.spi.status.DeploymentStatus;
032    
033    import org.apache.maven.artifact.Artifact;
034    import org.apache.maven.plugin.MojoExecutionException;
035    
036    import org.apache.geronimo.mavenplugins.geronimo.ModuleConfig;
037    
038    /**
039     * Deploy modules (and optionally starting them) to a Geronimo server.
040     *
041     * @goal deploy-module
042     * 
043     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
044     */
045    public class DeployModuleMojo
046        extends ModuleMojoSupport
047    {
048        /**
049         * A file which points to a specific module's jar | war | ear | rar archive.
050         * If this parameter is set, then it will be used instead of from the
051         * modules configuration.
052         *
053         * @parameter expression="${moduleArchive}"
054         * @optional
055         */
056        protected File moduleArchive = null;
057    
058        /**
059         * The fully qualified path of the external plan file (geronimo-web.xml).
060         * The application module may already have included in the package a deployment plan or the
061         * application is so simple that may not require any deployment plan.
062         * 
063         * @parameter expression="${modulePlan}"
064         * @optional
065         */
066        private File modulePlan = null;
067    
068        /**
069         * Flag to indicate if modules should be started after they have been distributed to the server.
070         *
071         * @parameter default-value="true"
072         * @optional
073         */
074        private boolean startModules = false;
075    
076        protected void doExecute() throws Exception {
077            List completed = new ArrayList();
078    
079            if (moduleArchive != null || modulePlan != null) {
080                log.info("Using non-artifact based module archive: " + moduleArchive);
081                if (modulePlan != null) {
082                    log.info("Using non-artifact based plan: " + modulePlan);
083                }
084    
085                TargetModuleID[] ids = distribute(moduleArchive, modulePlan);
086                completed.add(ids);
087            }
088            else if (modules == null || modules.length == 0) {
089                throw new MojoExecutionException("At least one module configuration (or moduleArchive) must be specified");
090            }
091    
092            if (modules != null && modules.length != 0) {
093                log.info("Using artifact based module archive(s)...");
094    
095                for (int i=0; i<modules.length; i++) {
096                    TargetModuleID[] ids = distribute(getModuleArchive(modules[i]), modules[i].getPlan());
097                    completed.add(ids);
098                }
099            }
100    
101            if (startModules) {
102                log.info("Starting modules...");
103    
104                Iterator iter = completed.iterator();
105                while (iter.hasNext()) {
106                    TargetModuleID[] moduleIds = (TargetModuleID[])iter.next();
107                    for (int i=0; i < moduleIds.length; i++) {
108                        String url = moduleIds[i].getWebURL();
109                        log.info("Starting module: " + moduleIds[i].getModuleID() + (url == null ? "" : ("; URL: " + url)));
110                    }
111    
112                    ProgressObject progress = getDeploymentManager().start(moduleIds);
113                    DeploymentStatus status = waitFor(progress);
114    
115                    if (status.isFailed()) {
116                        throw new MojoExecutionException("Failed to start modules: " + status.getMessage());
117                    }
118    
119                    log.info("Started module(s):");
120                    logModules(moduleIds, "    ");
121                }
122            }
123        }
124    
125        private File getModuleArchive(final ModuleConfig module) throws MojoExecutionException {
126            Artifact artifact = getArtifact(module);
127    
128            File file = artifact.getFile();
129            if (file == null) {
130                throw new MojoExecutionException("Module artifact does not have an attached file: " + module);
131            }
132    
133            String type = artifact.getType();
134            log.debug("Artifact file is: " + file + " (" + type + ")");
135    
136            if ((!"war".equals(type)) &&
137                (!"ear".equals(type)) &&
138                (!"rar".equals(type)) &&
139                (!"jar".equals(type)))
140            {
141                throw new MojoExecutionException("Module does not look like a JavaEE archive: " + module);
142            }
143    
144            return file;
145        }
146    
147        private TargetModuleID[] distribute(final File file, final File plan) throws Exception {
148            if (log.isInfoEnabled()) {
149                String msg = "Distributing module artifact: " + file;
150                if (plan != null) {
151                    msg += " with plan " + plan;
152                }
153                log.info(msg);
154            }
155    
156            DeploymentManager manager = getDeploymentManager();
157            Target[] targets = manager.getTargets();
158            if (null == targets) {
159                throw new IllegalStateException("No target to distribute to");
160            }
161            targets = new Target[] {targets[0]};
162            
163            ProgressObject progress = manager.distribute(targets, file, plan);
164            DeploymentStatus status = waitFor(progress);
165    
166            if (status.isFailed()) {
167                //
168                // FIXME: There must be a better way to handle this.
169                //
170                if (status.getMessage().indexOf("already exists") < 0 ) {
171                    throw new MojoExecutionException("Distribution failed: " + status.getMessage());
172                }
173                log.info("Module already exists");
174            }
175            
176    
177            return (progress != null) ? progress.getResultTargetModuleIDs() : null;
178        }
179    
180        protected String getFullClassName() {
181            return this.getClass().getName();
182        } 
183    }