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.plugin.local;
019    
020    import java.io.PrintWriter;
021    import java.io.StringWriter;
022    import java.util.ArrayList;
023    import java.util.Arrays;
024    import java.util.HashMap;
025    import java.util.HashSet;
026    import java.util.Iterator;
027    import java.util.List;
028    import java.util.Map;
029    import java.util.Set;
030    import javax.enterprise.deploy.shared.ActionType;
031    import javax.enterprise.deploy.shared.CommandType;
032    import javax.enterprise.deploy.shared.ModuleType;
033    import javax.enterprise.deploy.shared.StateType;
034    import javax.enterprise.deploy.spi.TargetModuleID;
035    import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException;
036    import javax.enterprise.deploy.spi.status.ClientConfiguration;
037    import javax.enterprise.deploy.spi.status.DeploymentStatus;
038    import javax.enterprise.deploy.spi.status.ProgressEvent;
039    import javax.enterprise.deploy.spi.status.ProgressListener;
040    import javax.enterprise.deploy.spi.status.ProgressObject;
041    import org.apache.geronimo.deployment.plugin.TargetModuleIDImpl;
042    import org.apache.geronimo.deployment.plugin.jmx.CommandContext;
043    import org.apache.geronimo.gbean.AbstractName;
044    import org.apache.geronimo.gbean.AbstractNameQuery;
045    import org.apache.geronimo.kernel.InternalKernelException;
046    import org.apache.geronimo.kernel.Kernel;
047    import org.apache.geronimo.kernel.config.ConfigurationModuleType;
048    
049    /**
050     * @version $Rev: 562021 $ $Date: 2007-08-02 01:51:18 -0400 (Thu, 02 Aug 2007) $
051     */
052    public abstract class CommandSupport implements ProgressObject, Runnable {
053        private final CommandType command;
054        private ActionType action;
055        private StateType state;
056        private String message;
057        private final Set listeners = new HashSet();
058        private final List moduleIDs = new ArrayList();
059        protected CommandContext commandContext = null; //todo: this is pretty bad; should add it into constructor
060    
061        private ProgressEvent event = null;
062    
063        protected CommandSupport(CommandType command) {
064            this.command = command;
065            this.action = ActionType.EXECUTE;
066            this.state = StateType.RUNNING;
067            this.message = null;
068        }
069    
070        protected synchronized void addModule(TargetModuleID moduleID) {
071            moduleIDs.add(moduleID);
072        }
073    
074        protected synchronized int getModuleCount() {
075            return moduleIDs.size();
076        }
077    
078        public synchronized TargetModuleID[] getResultTargetModuleIDs() {
079            return (TargetModuleID[]) moduleIDs.toArray(new TargetModuleID[moduleIDs.size()]);
080        }
081    
082        public synchronized DeploymentStatus getDeploymentStatus() {
083            return new Status(command, action, state, message);
084        }
085    
086        public ClientConfiguration getClientConfiguration(TargetModuleID id) {
087            return null;
088        }
089    
090        public boolean isCancelSupported() {
091            return false;
092        }
093    
094        public void cancel() throws OperationUnsupportedException {
095            throw new OperationUnsupportedException("cancel not supported");
096        }
097    
098        public boolean isStopSupported() {
099            return false;
100        }
101    
102        public void stop() throws OperationUnsupportedException {
103            throw new OperationUnsupportedException("stop not supported");
104        }
105    
106        public void addProgressListener(ProgressListener pol) {
107            ProgressEvent event;
108            synchronized (this) {
109                listeners.add(pol);
110                event = this.event;
111            }
112            if(event != null) {
113                pol.handleProgressEvent(event);
114            }
115        }
116    
117        public synchronized void removeProgressListener(ProgressListener pol) {
118            listeners.remove(pol);
119        }
120    
121        public final void fail(String message) {
122            sendEvent(message, StateType.FAILED);
123        }
124    
125        protected final void complete(String message) {
126            sendEvent(message, StateType.COMPLETED);
127        }
128    
129        public final void updateStatus(String message) {
130            sendEvent(message, state);
131        }
132    
133        public void doFail(Exception e) {
134            if (e instanceof InternalKernelException) {
135                Exception test = (Exception)e.getCause();
136                if(test != null) {
137                    e = test;
138                }
139            }
140    
141            if (commandContext.isLogErrors()) {
142                System.err.println("Deployer operation failed: " + e.getMessage());
143                if (commandContext.isVerbose()) {
144                    e.printStackTrace(System.err);
145                }
146            }
147    
148            StringWriter writer = new StringWriter();
149            PrintWriter printWriter = new PrintWriter(writer);
150            printWriter.println(e.getMessage());
151            if (commandContext.isVerbose()) {
152                e.printStackTrace(printWriter);
153            } else {
154                Throwable throwable = e;
155                while (null != (throwable = throwable.getCause())) {
156                    printWriter.println("\t" + throwable.getMessage());
157                }
158            }
159            fail(writer.toString());
160        }
161    
162        private void sendEvent(String message, StateType state) {
163            assert !Thread.holdsLock(this) : "Trying to send event whilst holding lock";
164    
165            ProgressListener[] toNotify;
166            DeploymentStatus newStatus;
167            synchronized (this) {
168                this.message = message;
169                this.state = state;
170                newStatus = new Status(command, action, state, message);
171                toNotify = (ProgressListener[]) listeners.toArray(new ProgressListener[listeners.size()]);
172                event = new ProgressEvent(this, null, newStatus);
173            }
174    
175            for (int i = 0; i < toNotify.length; i++) {
176                toNotify[i].handleProgressEvent(event);
177            }
178        }
179    
180        protected static String clean(String value) {
181            if(value.startsWith("\"") && value.endsWith("\"")) {
182                return value.substring(1, value.length()-1);
183            }
184            return value;
185        }
186    
187        private static class Status implements DeploymentStatus {
188            private final CommandType command;
189            private final ActionType action;
190            private final StateType state;
191            private final String message;
192    
193            public Status(CommandType command, ActionType action, StateType state, String message) {
194                this.command = command;
195                this.action = action;
196                this.state = state;
197                this.message = message;
198            }
199    
200            public CommandType getCommand() {
201                return command;
202            }
203    
204            public ActionType getAction() {
205                return action;
206            }
207    
208            public String getMessage() {
209                return message;
210            }
211    
212            public StateType getState() {
213                return state;
214            }
215    
216            public boolean isRunning() {
217                return StateType.RUNNING.equals(state);
218            }
219    
220            public boolean isCompleted() {
221                return StateType.COMPLETED.equals(state);
222            }
223    
224            public boolean isFailed() {
225                return StateType.FAILED.equals(state);
226            }
227    
228            public String toString() {
229                StringBuffer buf = new StringBuffer();
230                buf.append("DeploymentStatus[").append(command).append(',');
231                buf.append(action).append(',');
232                buf.append(state);
233                if (message != null) {
234                    buf.append(',').append(message);
235                }
236                buf.append(']');
237                return buf.toString();
238            }
239        }
240    
241        public CommandContext getCommandContext() {
242            return commandContext;
243        }
244    
245        public void setCommandContext(CommandContext commandContext) {
246            this.commandContext = new CommandContext(commandContext);
247        }
248    
249        public static ModuleType convertModuleType(ConfigurationModuleType type) {
250            if(type.getValue() == ConfigurationModuleType.WAR.getValue()) {
251                return ModuleType.WAR;
252            }
253            if(type.getValue() == ConfigurationModuleType.RAR.getValue()) {
254                return ModuleType.RAR;
255            }
256            if(type.getValue() == ConfigurationModuleType.EJB.getValue()) {
257                return ModuleType.EJB;
258            }
259            if(type.getValue() == ConfigurationModuleType.EAR.getValue()) {
260                return ModuleType.EAR;
261            }
262            if(type.getValue() == ConfigurationModuleType.CAR.getValue()) {
263                return ModuleType.CAR;
264            }
265            return null;
266        }
267    
268        public static boolean isWebApp(Kernel kernel, String configName) {
269            Map filter = new HashMap();
270            filter.put("j2eeType", "WebModule");
271            filter.put("name", configName);
272            Set set = kernel.listGBeans(new AbstractNameQuery(null, filter));
273            return set.size() > 0;
274        }
275    
276        protected void addWebURLs(Kernel kernel) throws Exception{
277            addWebContextPaths(kernel, moduleIDs);
278        }
279    
280        /**
281         * Given a list of TargetModuleIDs, figure out which ones represent web
282         * modules and add a WebURL to each if possible.
283         */
284        public static void addWebContextPaths(Kernel kernel, List moduleIDs) throws Exception{
285            Set webApps = null;
286            for (int i = 0; i < moduleIDs.size(); i++) {
287                TargetModuleIDImpl id = (TargetModuleIDImpl) moduleIDs.get(i);
288                if(id.getType() != null && id.getType().getValue() == ModuleType.WAR.getValue()) {
289                    if(webApps == null) {
290                        webApps = kernel.listGBeans(new AbstractNameQuery("org.apache.geronimo.management.geronimo.WebModule"));
291                    }
292                    for (Iterator it = webApps.iterator(); it.hasNext();) {
293                        AbstractName name = (AbstractName) it.next();
294                        if(name.getName().get("name").equals(id.getModuleID())) {
295                            id.setWebURL(kernel.getAttribute(name, "contextPath").toString());
296                        }
297                    }
298                }
299                if(id.getChildTargetModuleID() != null) {
300                    addWebContextPaths(kernel, Arrays.asList(id.getChildTargetModuleID()));
301                }
302            }
303        }
304    
305        public static List loadChildren(Kernel kernel, String configName) {
306            List kids = new ArrayList();
307    
308            Map filter = new HashMap();
309            filter.put("J2EEApplication", configName);
310    
311            filter.put("j2eeType", "WebModule");
312            Set test = kernel.listGBeans(new AbstractNameQuery(null, filter));
313            for (Iterator it = test.iterator(); it.hasNext();) {
314                AbstractName child = (AbstractName) it.next();
315                String childName = child.getNameProperty("name");
316                kids.add(childName);
317            }
318    
319            filter.put("j2eeType", "EJBModule");
320            test = kernel.listGBeans(new AbstractNameQuery(null, filter));
321            for (Iterator it = test.iterator(); it.hasNext();) {
322                AbstractName child = (AbstractName) it.next();
323                String childName = child.getNameProperty("name");
324                kids.add(childName);
325            }
326    
327            filter.put("j2eeType", "AppClientModule");
328            test = kernel.listGBeans(new AbstractNameQuery(null, filter));
329            for (Iterator it = test.iterator(); it.hasNext();) {
330                AbstractName child = (AbstractName) it.next();
331                String childName = child.getNameProperty("name");
332                kids.add(childName);
333            }
334    
335            filter.put("j2eeType", "ResourceAdapterModule");
336            test = kernel.listGBeans(new AbstractNameQuery(null, filter));
337            for (Iterator it = test.iterator(); it.hasNext();) {
338                AbstractName child = (AbstractName) it.next();
339                String childName = child.getNameProperty("name");
340                kids.add(childName);
341            }
342            return kids;
343        }
344    }