001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.deployment.cli;
019    
020    import java.io.File;
021    import java.io.PrintWriter;
022    import java.util.Arrays;
023    import java.util.List;
024    import java.util.StringTokenizer;
025    
026    import javax.enterprise.deploy.spi.DeploymentManager;
027    import javax.enterprise.deploy.spi.Target;
028    import javax.enterprise.deploy.spi.TargetModuleID;
029    import javax.enterprise.deploy.spi.status.ProgressObject;
030    
031    import org.apache.geronimo.cli.deployer.CommandArgs;
032    import org.apache.geronimo.cli.deployer.DistributeCommandArgs;
033    import org.apache.geronimo.common.DeploymentException;
034    import org.apache.geronimo.deployment.plugin.jmx.JMXDeploymentManager;
035    
036    /**
037     * The CLI deployer logic to distribute.
038     *
039     * @version $Rev: 535507 $ $Date: 2007-05-05 07:22:39 -0400 (Sat, 05 May 2007) $
040     */
041    public class CommandDistribute extends AbstractCommand {
042    
043        protected ProgressObject runCommand(DeploymentManager mgr, PrintWriter out, boolean inPlace, Target[] tlist, File module, File plan) throws DeploymentException {
044            if (inPlace) {
045                if (!(mgr instanceof JMXDeploymentManager)) {
046                    throw new DeploymentSyntaxException(
047                            "Target DeploymentManager is not a Geronimo one. \n" +
048                            "Cannot perform in-place deployment.");
049                }
050                JMXDeploymentManager jmxMgr = (JMXDeploymentManager) mgr;
051                try {
052                    jmxMgr.setInPlace(true);
053                    return mgr.distribute(tlist, module, plan);
054                } finally {
055                    jmxMgr.setInPlace(false);
056                }
057            } else {
058                return mgr.distribute(tlist, module, plan);
059            }
060        }
061    
062        protected String getAction() {
063            return "Distributed";
064        }
065    
066        public void execute(PrintWriter out, ServerConnection connection, CommandArgs commandArgs) throws DeploymentException {
067            if (!(commandArgs instanceof DistributeCommandArgs)) {
068                throw new DeploymentSyntaxException("CommandArgs has the type [" + commandArgs.getClass() + "]; expected [" + DistributeCommandArgs.class + "]");
069            }
070            DistributeCommandArgs distributeCommandArgs = (DistributeCommandArgs) commandArgs;
071            
072            BooleanHolder inPlaceHolder = new BooleanHolder();
073            inPlaceHolder.inPlace = distributeCommandArgs.isInPlace();
074            
075            List<String> targets = Arrays.asList(distributeCommandArgs.getTargets());
076    
077            String[] args = distributeCommandArgs.getArgs();
078            File module = null;
079            File plan = null;
080            if(args.length > 0) {
081                File test = new File(args[0]);
082                if(DeployUtils.isJarFile(test) || test.isDirectory()) {
083                    if(module != null) {
084                        throw new DeploymentSyntaxException("Module and plan cannot both be JAR files or directories!");
085                    }
086                    module = test;
087                } else {
088                    if(plan != null) {
089                        throw new DeploymentSyntaxException("Module or plan must be a JAR file or directory!");
090                    }
091                    plan = test;
092                }
093            }
094            if(args.length > 1) {
095                File test = new File(args[1]);
096                if(DeployUtils.isJarFile(test) || test.isDirectory()) {
097                    if(module != null) {
098                        throw new DeploymentSyntaxException("Module and plan cannot both be JAR files or directories!");
099                    }
100                    module = test;
101                } else {
102                    if(plan != null) {
103                        throw new DeploymentSyntaxException("Module or plan must be a JAR file or directory!");
104                    }
105                    plan = test;
106                }
107            }
108            if(module != null) {
109                module = module.getAbsoluteFile();
110            }
111            if(plan != null) {
112                plan = plan.getAbsoluteFile();
113            }
114            executeOnline(connection, inPlaceHolder.inPlace, targets, out, module, plan);
115        }
116    
117        private void executeOnline(ServerConnection connection, boolean inPlace, List targets, PrintWriter out, File module, File plan) throws DeploymentException {
118            final DeploymentManager mgr = connection.getDeploymentManager();
119            TargetModuleID[] results;
120            boolean multipleTargets;
121            ProgressObject po;
122            if(targets.size() > 0) {
123                Target[] tlist = identifyTargets(targets, mgr);
124                multipleTargets = tlist.length > 1;
125                po = runCommand(mgr, out, inPlace, tlist, module, plan);
126                waitForProgress(out, po);
127            } else {
128                final Target[] tlist = mgr.getTargets();
129                multipleTargets = tlist.length > 1;
130                po = runCommand(mgr, out, inPlace, tlist, module, plan);
131                waitForProgress(out, po);
132            }
133    
134            // print the results that succeeded
135            results = po.getResultTargetModuleIDs();
136            for (int i = 0; i < results.length; i++) {
137                TargetModuleID result = results[i];
138                out.print(DeployUtils.reformat(getAction()+" "+result.getModuleID()+(multipleTargets ? " to "+result.getTarget().getName() : "")+(result.getWebURL() == null || !getAction().equals("Deployed") ? "" : " @ "+result.getWebURL()), 4, 72));
139                if(result.getChildTargetModuleID() != null) {
140                    for (int j = 0; j < result.getChildTargetModuleID().length; j++) {
141                        TargetModuleID child = result.getChildTargetModuleID()[j];
142                        out.print(DeployUtils.reformat("  `-> "+child.getModuleID()+(child.getWebURL() == null || !getAction().equals("Deployed") ? "" : " @ "+child.getWebURL()),4, 72));
143                    }
144                }
145            }
146    
147            // if any results failed then throw so that we'll return non-0
148            // to the operating system
149            if(po.getDeploymentStatus().isFailed()) {
150                throw new DeploymentException("Operation failed: "+po.getDeploymentStatus().getMessage());
151            }
152        }
153    
154        private String[] processTargets(String[] args, List targets) {
155            if(args.length >= 2 && args[0].equals("--targets")) {
156                String value = args[1];
157                StringTokenizer tok = new StringTokenizer(value, ";", false);
158                while(tok.hasMoreTokens()) {
159                    targets.add(tok.nextToken());
160                }
161                String[] temp = new String[args.length-2];
162                System.arraycopy(args, 2, temp, 0, temp.length);
163                args = temp;
164            }
165            return args;
166        }
167        
168        private String[] processInPlace(String[] args, BooleanHolder inPlaceHolder) {
169            if(args.length >= 2 && args[0].equals("--inPlace")) {
170                    inPlaceHolder.inPlace = true;
171                String[] temp = new String[args.length - 1];
172                System.arraycopy(args, 1, temp, 0, temp.length);
173                args = temp;
174            }
175            return args;
176        }
177        
178        private final class BooleanHolder {
179            public boolean inPlace;
180        }
181    }