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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
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(Throwable 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 }