KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tomcat5 > ide > StartTomcat


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.tomcat5.ide;
21
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.BufferedOutputStream JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.FileInputStream JavaDoc;
26 import java.io.FileNotFoundException JavaDoc;
27 import java.io.FileOutputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.util.Collections JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Map JavaDoc;
33 import javax.enterprise.deploy.shared.ActionType JavaDoc;
34 import javax.enterprise.deploy.shared.CommandType JavaDoc;
35 import javax.enterprise.deploy.shared.StateType JavaDoc;
36 import javax.enterprise.deploy.spi.DeploymentManager JavaDoc;
37 import javax.enterprise.deploy.spi.Target JavaDoc;
38 import javax.enterprise.deploy.spi.TargetModuleID JavaDoc;
39 import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException JavaDoc;
40 import javax.enterprise.deploy.spi.status.ClientConfiguration JavaDoc;
41 import javax.enterprise.deploy.spi.status.DeploymentStatus JavaDoc;
42 import javax.enterprise.deploy.spi.status.ProgressListener JavaDoc;
43 import javax.enterprise.deploy.spi.status.ProgressObject JavaDoc;
44 import org.netbeans.api.java.platform.JavaPlatform;
45 import org.netbeans.modules.j2ee.deployment.plugins.api.StartServer;
46 import org.netbeans.modules.tomcat5.progress.ProgressEventSupport;
47 import org.netbeans.modules.tomcat5.progress.Status;
48 import org.netbeans.modules.tomcat5.util.LogManager;
49 import org.netbeans.modules.tomcat5.util.Utils;
50 import org.openide.ErrorManager;
51 import org.openide.execution.NbProcessDescriptor;
52 import org.openide.util.NbBundle;
53 import org.openide.util.RequestProcessor;
54 import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo;
55 import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerServerSettings;
56 import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerSupport;
57 import org.netbeans.modules.tomcat5.TomcatFactory;
58 import org.netbeans.modules.tomcat5.TomcatManager;
59 import org.netbeans.modules.tomcat5.TomcatManager.TomcatVersion;
60 import org.netbeans.modules.tomcat5.util.EditableProperties;
61 import org.netbeans.modules.tomcat5.util.TomcatProperties;
62 import org.openide.filesystems.FileObject;
63 import org.openide.filesystems.FileUtil;
64 import org.openide.util.Utilities;
65 import org.xml.sax.SAXException JavaDoc;
66
67 /** Extension to Deployment API that enables starting of Tomcat.
68  *
69  * @author Radim Kubacki, Pavel Buzek
70  */

71 public final class StartTomcat extends StartServer implements ProgressObject JavaDoc {
72     
73     public static final String JavaDoc CATALINA_BAT = "catalina.bat"; // NOI18N
74
public static final String JavaDoc CATALINA_SH = "catalina.sh"; // NOI18N
75
public static final String JavaDoc CATALINA_50_BAT = "catalina.50.bat"; // NOI18N
76
public static final String JavaDoc CATALINA_50_SH = "catalina.50.sh"; // NOI18N
77

78     public static final String JavaDoc SETCLASSPATH_BAT = "setclasspath.bat"; // NOI18N
79
public static final String JavaDoc SETCLASSPATH_SH = "setclasspath.sh"; // NOI18N
80

81     public static final String JavaDoc TAG_CATALINA_HOME = "catalina_home"; // NOI18N
82
public static final String JavaDoc TAG_CATALINA_BASE = "catalina_base"; // NOI18N
83

84     public static final String JavaDoc TAG_JPDA = "jpda"; // NOI18N
85
public static final String JavaDoc TAG_JPDA_STARTUP = "jpda_startup"; // NOI18N
86

87     /** Startup command tag. */
88     public static final String JavaDoc TAG_EXEC_CMD = "catalina"; // NOI18N
89
public static final String JavaDoc TAG_EXEC_STARTUP = "exec_startup"; // NOI18N
90
public static final String JavaDoc TAG_EXEC_SHUTDOWN = "exec_shutdown"; // NOI18N
91
public static final String JavaDoc TAG_SECURITY_OPT = "security_option"; //NOI18N
92
public static final String JavaDoc TAG_FORCE_OPT = "force_option"; //NOI18N
93

94     /** Debug startup/shutdown tag */
95     public static final String JavaDoc TAG_DEBUG_CMD = "catalina"; // NOI18N
96

97     /** Normal mode */
98     private static final int MODE_RUN = 0;
99     /** Debug mode */
100     private static final int MODE_DEBUG = 1;
101     /** Profile mode */
102     private static final int MODE_PROFILE = 2;
103     
104     /** For how long should we keep trying to get response from the server. */
105     private static final long TIMEOUT_DELAY = 180000;
106         
107     private TomcatManager tm;
108     
109     private ProgressEventSupport pes;
110     private int currentServerPort; // current server port Tomcat is running on
111

112     private static Map JavaDoc isDebugModeUri = Collections.synchronizedMap((Map JavaDoc)new HashMap JavaDoc(2,1));
113     
114     public StartTomcat (DeploymentManager JavaDoc manager) {
115         assert manager instanceof TomcatManager :
116             "Illegal DeploymentManager instance: " + manager.getClass().getName(); // NIO18N
117
tm = (TomcatManager)manager;
118         tm.setStartTomcat (this);
119         pes = new ProgressEventSupport (this);
120         currentServerPort = tm.getServerPort();
121     }
122     
123     public boolean supportsStartDeploymentManager () {
124         return true;
125     }
126     
127     public boolean supportsStartProfiling(Target JavaDoc target) {
128         return true;
129     }
130     
131     /** Start Tomcat server if the TomcatManager is not connected.
132      */

133     public ProgressObject JavaDoc startDeploymentManager () {
134         if (TomcatFactory.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
135             TomcatFactory.getEM ().log ("StartTomcat.startDeploymentManager called on "+tm); // NOI18N
136
}
137         pes.fireHandleProgressEvent (null, new Status JavaDoc (ActionType.EXECUTE, CommandType.START, "", StateType.RUNNING));
138         RequestProcessor.getDefault().post(
139                                         new StartRunnable(MODE_RUN, CommandType.START, null),
140                                         0,
141                                         Thread.NORM_PRIORITY);
142         isDebugModeUri.remove(tm.getUri());
143         return this;
144     }
145     
146     /**
147      * Returns true if the admin server is also a target server (share the same vm).
148      * Start/stopping/debug apply to both servers.
149      * @return true when admin is also target server
150      */

151     public boolean isAlsoTargetServer(Target JavaDoc target) { return true; }
152
153     /**
154      * Returns true if the admin server should be started before configure.
155      */

156     public boolean needsStartForConfigure() { return false; }
157
158     /**
159      * Returns true if the admin server should be started before asking for
160      * target list.
161      */

162     public boolean needsStartForTargetList() { return false; }
163
164     /**
165      * Returns true if the admin server should be started before admininistrative configuration.
166      */

167     public boolean needsStartForAdminConfig() { return false; }
168
169     /**
170      * Returns true if this admin server is running.
171      */

172     public boolean isRunning() {
173         return tm.isRunning (true);
174     }
175
176     /**
177      * Returns true if this target is in debug mode.
178      */

179     public boolean isDebuggable(Target JavaDoc target) {
180         if (!isDebugModeUri.containsKey(tm.getUri())) {
181             return false;
182         }
183         if (!isRunning()) {
184             isDebugModeUri.remove(tm.getUri());
185             return false;
186         }
187         return true;
188     }
189
190     /**
191      * Stops the admin server. The DeploymentManager object will be disconnected.
192      * All diagnostic should be communicated through ServerProgres with no
193      * exceptions thrown.
194      * @return ServerProgress object used to monitor start server progress
195      */

196     public ProgressObject JavaDoc stopDeploymentManager() {
197         if (TomcatFactory.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
198             TomcatFactory.getEM ().log ("StartTomcat.stopDeploymentManager called on "+tm); // NOI18N
199
}
200         pes.fireHandleProgressEvent (null, new Status JavaDoc (ActionType.EXECUTE, CommandType.STOP, "", StateType.RUNNING));
201         RequestProcessor.getDefault().post(
202                                         new StartRunnable(MODE_RUN, CommandType.STOP, null),
203                                         0,
204                                         Thread.NORM_PRIORITY);
205         isDebugModeUri.remove(tm.getUri());
206         return this;
207     }
208
209     /**
210      * Start or restart the target in debug mode.
211      * If target is also domain admin, the amdin is restarted in debug mode.
212      * All diagnostic should be communicated through ServerProgres with no exceptions thrown.
213      * @param target the target server
214      * @return ServerProgress object to monitor progress on start operation
215      */

216     public ProgressObject JavaDoc startDebugging(Target JavaDoc target) {
217         if (TomcatFactory.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
218             TomcatFactory.getEM ().log ("StartTomcat.startDebugging called on "+tm); // NOI18N
219
}
220         pes.fireHandleProgressEvent (null, new Status JavaDoc (ActionType.EXECUTE, CommandType.START, "", StateType.RUNNING));
221         RequestProcessor.getDefault().post(
222                                         new StartRunnable(MODE_DEBUG, CommandType.START, null),
223                                         0,
224                                         Thread.NORM_PRIORITY);
225         return this;
226     }
227     
228     public ProgressObject JavaDoc startProfiling(Target JavaDoc target, ProfilerServerSettings settings) {
229         if (TomcatFactory.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
230             TomcatFactory.getEM().log("StartTomcat.startProfiling called on " + tm); // NOI18N
231
}
232         pes.fireHandleProgressEvent(null, new Status JavaDoc(
233                                                 ActionType.EXECUTE,
234                                                 CommandType.START,
235                                                 "", // NOI18N
236
StateType.RUNNING));
237         RequestProcessor.getDefault().post(
238                             new StartRunnable(MODE_PROFILE, CommandType.START, settings),
239                             0,
240                             Thread.NORM_PRIORITY);
241         return this;
242     }
243
244     public ServerDebugInfo getDebugInfo(Target JavaDoc target) {
245         ServerDebugInfo sdi;
246         TomcatProperties tp = tm.getTomcatProperties();
247         if (tp.getDebugType().toLowerCase().indexOf("socket") != -1) { // NOI18N
248
sdi = new ServerDebugInfo("localhost", tp.getDebugPort()); // NOI18N
249
} else {
250             sdi = new ServerDebugInfo("localhost", tp.getSharedMem()); // NOI18N
251
}
252         return sdi;
253     }
254     
255     private class StartRunnable implements Runnable JavaDoc {
256         
257         private int mode;
258         private CommandType JavaDoc command = CommandType.START;
259         private ProfilerServerSettings profilerSettings;
260         
261         public StartRunnable(int mode, CommandType JavaDoc command, ProfilerServerSettings profilerSettings) {
262             this.mode = mode;
263             this.command = command;
264             this.profilerSettings = profilerSettings;
265         }
266         
267         public synchronized void run () {
268             // PENDING check whether is runs or not
269
TomcatProperties tp = tm.getTomcatProperties();
270             File JavaDoc homeDir = tp.getCatalinaHome();
271             if (homeDir == null || !homeDir.exists()) {
272                 fireCmdExecProgressEvent(
273                     command == CommandType.START ? "MSG_NoHomeDirStart" : "MSG_NoHomeDirStop",
274                     StateType.FAILED);
275                 return;
276             }
277             File JavaDoc baseDir = tp.getCatalinaBase();
278             if (baseDir == null) {
279                 baseDir = homeDir;
280             } else {
281                 if (baseDir != null) {
282                     String JavaDoc[] files = baseDir.list();
283                     if (files == null || files.length == 0) {
284                         baseDir = tm.createBaseDir(baseDir, homeDir);
285                     }
286                 }
287                 if (baseDir == null) {
288                     fireCmdExecProgressEvent(
289                         command == CommandType.START ? "MSG_NoBaseDirStart" : "MSG_NoBaseDirStop",
290                         StateType.FAILED);
291                     return;
292                 }
293             }
294             
295             // check whether the startup script - catalina.sh/bat exists
296
File JavaDoc startupScript = getStartupScript();
297             if (!startupScript.exists()) {
298                 final String JavaDoc MSG = NbBundle.getMessage(
299                         StartTomcat.class,
300                         command == CommandType.START ? "MSG_StartFailedNoStartScript" : "MSG_StopFailedNoStartScript",
301                         startupScript.getAbsolutePath());
302                 pes.fireHandleProgressEvent(
303                     null,
304                     new Status JavaDoc(ActionType.EXECUTE, command, MSG, StateType.FAILED));
305                 return;
306             }
307             
308             // install the monitor
309
if (command == CommandType.START) {
310                 try {
311                     MonitorSupport.synchronizeMonitorWithFlag(tm, true, !tm.isBundledTomcat());
312                 } catch (IOException JavaDoc e) {
313                     if (MonitorSupport.getMonitorFlag(tm)) {
314                         // tomcat has been started with monitor enabled
315
MonitorSupport.setMonitorFlag(tm, false);
316                         fireCmdExecProgressEvent(tm.isTomcat60() ? "MSG_enableMonitorSupportErr60" : "MSG_enableMonitorSupportErr", StateType.FAILED);
317                     } else {
318                         // tomcat has been started with monitor disabled
319
fireCmdExecProgressEvent("MSG_disableMonitorSupportErr", StateType.FAILED);
320                     }
321                     ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
322                     return;
323                 } catch (SAXException JavaDoc e) {
324                     // fault, but not a critical one
325
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
326                 }
327                 try {
328                     DebugSupport.allowDebugging(tm);
329                 }
330                 catch (IOException JavaDoc e) {
331                     // fault, but not a critical one
332
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
333                 }
334                 catch (SAXException JavaDoc e) {
335                     // fault, but not a critical one
336
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
337                 }
338             }
339             
340             currentServerPort = tm.getServerPort(); // remember the server port
341
int shutdownPort = tm.getShutdownPort();
342             
343             if (command == CommandType.START) {
344                 // check whether the server ports are free
345
if (!Utils.isPortFree(currentServerPort)) {
346                     fireCmdExecProgressEvent("MSG_StartFailedServerPortInUse", String.valueOf(currentServerPort), StateType.FAILED);
347                     return;
348                 }
349                 if (!Utils.isPortFree(shutdownPort)) {
350                     fireCmdExecProgressEvent("MSG_StartFailedShutdownPortInUse", String.valueOf(shutdownPort), StateType.FAILED);
351                     return;
352                 }
353             }
354             
355             // set the JAVA_OPTS value
356
String JavaDoc javaOpts = tp.getJavaOpts();
357             // use the IDE proxy settings if the 'use proxy' checkbox is selected
358
// do not override a property if it was set manually by the user
359
if (tp.getProxyEnabled()) {
360                 StringBuilder JavaDoc sb = new StringBuilder JavaDoc(javaOpts);
361                 final String JavaDoc[] PROXY_PROPS = {
362                     "http.proxyHost", // NOI18N
363
"http.proxyPort", // NOI18N
364
"http.nonProxyHosts", // NOI18N
365
"https.proxyHost", // NOI18N
366
"https.proxyPort", // NOI18N
367
};
368                 boolean isWindows = Utilities.isWindows();
369                 for (String JavaDoc prop : PROXY_PROPS) {
370                     if (javaOpts.indexOf(prop) == -1) {
371                         String JavaDoc value = System.getProperty(prop);
372                         if (value != null) {
373                             if (isWindows && "http.nonProxyHosts".equals(prop)) { // NOI18N
374
// enclose in double quotes to escape the pipes separating the hosts on windows
375
value = "\"" + value + "\""; // NOI18N
376
}
377                             sb.append(" -D").append(prop).append("=").append(value); // NOI18N
378
}
379                     }
380                 }
381                 javaOpts = sb.toString();
382             }
383             
384             JavaPlatform platform = mode == MODE_PROFILE ? profilerSettings.getJavaPlatform()
385                                                          : getJavaPlatform();
386             String JavaDoc jdkVersion = platform.getSpecification().getVersion().toString();
387             
388             if (tm.isBundledTomcat()) {
389                 // work-arounding problems caused by the compatibility pack when running on 1.5
390
// ensure that the catalina class loader is set properly
391
patchCatalinaProperties(tp.getCatalinaDir(), "1.4".equals(jdkVersion)); // NOI18N
392
}
393             
394             if ((mode == MODE_DEBUG) && (command == CommandType.START)) {
395
396                 NbProcessDescriptor pd = null;
397                 if (tp.getSecManager()) {
398                     pd = defaultDebugStartDesc (TAG_DEBUG_CMD, TAG_JPDA_STARTUP, TAG_SECURITY_OPT);
399                 } else {
400                     pd = defaultDebugStartDesc (TAG_DEBUG_CMD, TAG_JPDA_STARTUP);
401                 }
402                 try {
403                     fireCmdExecProgressEvent("MSG_startProcess", StateType.RUNNING);
404                     Process JavaDoc p = null;
405                     
406                     String JavaDoc address;
407                     String JavaDoc transport;
408                     if (tp.getDebugType().toLowerCase().indexOf("socket") != -1) { // NOI18N
409
transport = "dt_socket"; // NOI18N
410
address = Integer.toString(tp.getDebugPort());
411                     } else {
412                         transport = "dt_shmem"; // NOI18N
413
address = tp.getSharedMem();
414                     }
415                     if (TomcatFactory.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
416                         TomcatFactory.getEM ().log ("transport: " + transport); // NOI18N
417
TomcatFactory.getEM ().log ("address: " + address); // NOI18N
418
}
419                     p = pd.exec (
420                         new TomcatFormat(startupScript, homeDir),
421                         new String JavaDoc[] {
422                             "JAVA_HOME=" + getJavaHome(platform), // NOI18N
423
"JRE_HOME=", // NOI18N ensure that JRE_HOME system property won't be used instead of JAVA_HOME
424
"JAVA_OPTS=" + javaOpts, // NOI18N
425
"JPDA_TRANSPORT=" + transport, // NOI18N
426
"JPDA_ADDRESS=" + address, // NOI18N
427
"CATALINA_HOME=" + homeDir.getAbsolutePath(), // NOI18N
428
"CATALINA_BASE=" + baseDir.getAbsolutePath(), // NOI18N
429
// this is used in the setclasspath.sb/bat script for work-arounding
430
// problems caused by the compatibility pack when running on 1.5
431
"NB_TOMCAT_JDK=" + jdkVersion // NOI18N
432
},
433                         true,
434                         new File JavaDoc (homeDir, "bin") // NOI18N
435
);
436                     tm.setTomcatProcess(p);
437                     openLogs();
438                 } catch (java.io.IOException JavaDoc ioe) {
439                     if (TomcatFactory.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
440                         TomcatFactory.getEM ().notify (ErrorManager.INFORMATIONAL, ioe);
441                     }
442                     fireCmdExecProgressEvent(command == CommandType.START ? "MSG_StartFailedIOE" : "MSG_StopFailedIOE",
443                             startupScript.getAbsolutePath(), StateType.FAILED);
444                     return;
445                 }
446             } else if ((mode == MODE_PROFILE) && (command == CommandType.START)) {
447                 NbProcessDescriptor pd = null;
448                 if (tp.getSecManager()) {
449                     pd = defaultExecDesc(TAG_EXEC_CMD, TAG_EXEC_STARTUP, TAG_SECURITY_OPT);
450                 } else {
451                     pd = defaultExecDesc(TAG_EXEC_CMD, TAG_EXEC_STARTUP);
452                 }
453                 try {
454                     fireCmdExecProgressEvent("MSG_StartingInProfileMode", StateType.RUNNING);
455                     Process JavaDoc p = null;
456                     
457                     String JavaDoc[] profJvmArgs = profilerSettings.getJvmArgs();
458                     // TODO solve conflicts between profiler and tomcat vm args
459
StringBuffer JavaDoc catalinaOpts = new StringBuffer JavaDoc();
460                     for (int i = 0; i < profJvmArgs.length; i++) {
461                         catalinaOpts.append(profJvmArgs[i]).append(" "); // NOI18N
462
}
463                     String JavaDoc[] defaultEnv = new String JavaDoc[] {
464                         "JAVA_HOME=" + getJavaHome(platform), // NOI18N
465
"JRE_HOME=", // NOI18N ensure that JRE_HOME system property won't be used instead of JAVA_HOME
466
"JAVA_OPTS=" + javaOpts, // NOI18N
467
"CATALINA_OPTS=" + catalinaOpts.toString(), // NOI18N
468
"CATALINA_HOME=" + homeDir.getAbsolutePath(), // NOI18N
469
"CATALINA_BASE=" + baseDir.getAbsolutePath(), // NOI18N
470
// this is used in the setclasspath.sb/bat script for work-arounding
471
// problems caused by the compatibility pack when running on 1.5
472
"NB_TOMCAT_JDK=" + jdkVersion // NOI18N
473
};
474                     String JavaDoc[] profEnv = profilerSettings.getEnv();
475                     // merge Tomcat and profiler env properties
476
String JavaDoc[] envp = new String JavaDoc[defaultEnv.length + profEnv.length];
477                     System.arraycopy(profEnv, 0, envp, 0, profEnv.length);
478                     System.arraycopy(defaultEnv, 0, envp, profEnv.length, defaultEnv.length);
479                     p = pd.exec(
480                         new TomcatFormat(startupScript, homeDir),
481                         envp,
482                         true,
483                         new File JavaDoc(homeDir, "bin") // NOI18N
484
);
485                     tm.setTomcatProcess(p);
486                     openLogs();
487                 } catch (java.io.IOException JavaDoc ioe) {
488                     if (TomcatFactory.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
489                         TomcatFactory.getEM ().notify (ErrorManager.INFORMATIONAL, ioe);
490                     }
491                     fireCmdExecProgressEvent(command == CommandType.START ? "MSG_StartFailedIOE" : "MSG_StopFailedIOE",
492                             startupScript.getAbsolutePath(), StateType.FAILED);
493                     return;
494                 }
495             } else {
496                 NbProcessDescriptor pd = null;
497                 if (command == CommandType.START) {
498                     if (tp.getSecManager()) {
499                         pd = defaultExecDesc(TAG_EXEC_CMD, TAG_EXEC_STARTUP, TAG_SECURITY_OPT);
500                     } else {
501                         pd = defaultExecDesc(TAG_EXEC_CMD, TAG_EXEC_STARTUP);
502                     }
503                 } else {
504                     if (tp.getForceStop() && Utilities.isUnix()) {
505                         pd = defaultExecDesc(TAG_EXEC_CMD, TAG_EXEC_SHUTDOWN, TAG_FORCE_OPT);
506                     } else {
507                         pd = defaultExecDesc(TAG_EXEC_CMD, TAG_EXEC_SHUTDOWN);
508                     }
509                 }
510                 try {
511                     fireCmdExecProgressEvent(command == CommandType.START ? "MSG_startProcess" : "MSG_stopProcess",
512                             StateType.RUNNING);
513                     Process JavaDoc p = pd.exec (
514                         new TomcatFormat (startupScript, homeDir),
515                         new String JavaDoc[] {
516                             "JAVA_HOME=" + getJavaHome(platform), // NOI18N
517
"JRE_HOME=", // NOI18N ensure that JRE_HOME system property won't be used instead of JAVA_HOME
518
"JAVA_OPTS=" + javaOpts, // NOI18N
519
"CATALINA_HOME=" + homeDir.getAbsolutePath(), // NOI18N
520
"CATALINA_BASE=" + baseDir.getAbsolutePath(), // NOI18N
521
// this is used in the setclasspath.sb/bat script for work-arounding
522
// problems caused by the compatibility pack when running on 1.5
523
"NB_TOMCAT_JDK=" + jdkVersion // NOI18N
524
},
525                         true,
526                         new File JavaDoc (homeDir, "bin")
527                     );
528                     if (command == CommandType.START) {
529                         tm.setTomcatProcess(p);
530                         openLogs();
531                     } else {
532                         // #58554 workaround
533
RequestProcessor.getDefault().post(new StreamConsumer(p.getInputStream()), 0, Thread.MIN_PRIORITY);
534                         RequestProcessor.getDefault().post(new StreamConsumer(p.getErrorStream()), 0, Thread.MIN_PRIORITY);
535                     }
536                 } catch (java.io.IOException JavaDoc ioe) {
537                     if (TomcatFactory.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
538                         TomcatFactory.getEM ().notify (ErrorManager.INFORMATIONAL, ioe); // NOI18N
539
}
540                     fireCmdExecProgressEvent(command == CommandType.START ? "MSG_StartFailedIOE" : "MSG_StopFailedIOE",
541                             startupScript.getAbsolutePath(), StateType.FAILED);
542                     return;
543                 }
544             }
545             fireCmdExecProgressEvent("MSG_waiting", StateType.RUNNING);
546             if (hasCommandSucceeded()) {
547                 if (command == CommandType.START && mode == MODE_DEBUG) {
548                     isDebugModeUri.put(tm.getUri(), new Object JavaDoc());
549                 }
550                 fireCmdExecProgressEvent(command == CommandType.START ? "MSG_Started" : "MSG_Stopped",
551                                          StateType.COMPLETED);
552             } else {
553                 fireCmdExecProgressEvent(command == CommandType.START ? "MSG_StartFailed" : "MSG_StopFailed",
554                                          StateType.FAILED);
555             }
556         }
557         
558         /** Open JULI log and server output */
559         private void openLogs() {
560             LogManager logManager = tm.logManager();
561             if (logManager.hasJuliLog()) {
562                 logManager.openJuliLog();
563             }
564             logManager.closeServerLog();
565             logManager.openServerLog();
566         }
567         
568         /**
569          * Fires command progress event of action type <code>ActionType.EXECUTE</code>.
570          *
571          * @param resName event status message from the bundle, specified by the
572          * resource name.
573          * @param stateType event state type.
574          */

575         private void fireCmdExecProgressEvent(String JavaDoc resName, StateType JavaDoc stateType) {
576             String JavaDoc msg = NbBundle.getMessage(StartTomcat.class, resName);
577             pes.fireHandleProgressEvent(
578                 null,
579                 new Status JavaDoc(ActionType.EXECUTE, command, msg, stateType));
580         }
581         
582         /**
583          * Fires command progress event of action type <code>ActionType.EXECUTE</code>.
584          *
585          * @param resName event status message from the bundle, specified by the
586          * resource name.
587          * @param arg1 the argument to use when formating the message
588          * @param stateType event state type.
589          */

590         private void fireCmdExecProgressEvent(String JavaDoc resName, Object JavaDoc arg1, StateType JavaDoc stateType) {
591             String JavaDoc msg = NbBundle.getMessage(StartTomcat.class, resName, arg1);
592             pes.fireHandleProgressEvent(
593                 null,
594                 new Status JavaDoc(ActionType.EXECUTE, command, msg, stateType));
595         }
596         
597         /**
598          * Try to get response from the server, whether the START/STOP command has
599          * succeeded.
600          *
601          * @return <code>true</code> if START/STOP command completion was verified,
602          * <code>false</code> if time-out ran out.
603          */

604         private boolean hasCommandSucceeded() {
605             long timeout = System.currentTimeMillis() + TIMEOUT_DELAY;
606             while (true) {
607                 boolean isRunning = isRunning();
608                 if (command == CommandType.START) {
609                     if (isRunning) {
610                         return true;
611                     }
612                     if (isStopped()) {
613                         // Tomcat failed to start, process is finished
614
return false;
615                     }
616                     if (mode == MODE_PROFILE) {
617                         int state = ProfilerSupport.getState();
618                         if (state == ProfilerSupport.STATE_BLOCKING ||
619                             state == ProfilerSupport.STATE_RUNNING ||
620                             state == ProfilerSupport.STATE_PROFILING) {
621                             return true;
622                         } else if (state == ProfilerSupport.STATE_INACTIVE) {
623                             return false;
624                         }
625                     }
626                 }
627                 if (command == CommandType.STOP) {
628                     if (isStopped()) {
629                         // give server a few secs to finish its shutdown, not responding
630
// does not necessarily mean its is still not running
631
try {
632                             Thread.sleep(2000);
633                         } catch(InterruptedException JavaDoc ie) {}
634                         return true;
635                     }
636                 }
637                 // if time-out ran out, suppose command failed
638
if (System.currentTimeMillis() > timeout) {
639                     return false;
640                 }
641                 try {
642                     Thread.sleep(1000); // take a nap before next retry
643
} catch(InterruptedException JavaDoc ie) {}
644             }
645         }
646     }
647     
648     /** Return true if the server is stopped. If the server was started from within
649      * the IDE, determin the server state from the process exit code, otherwise try
650      * to ping it. */

651     private boolean isStopped() {
652         Process JavaDoc proc = tm.getTomcatProcess();
653         if (proc != null) {
654             try {
655                 proc.exitValue();
656                 // process is stopped
657
return true;
658             } catch (IllegalThreadStateException JavaDoc e) {
659                 // process is still running
660
return false;
661             }
662         } else {
663             int timeout = tm.getTomcatProperties().getRunningCheckTimeout();
664             return !Utils.pingTomcat(tm.getServerPort(), timeout);
665         }
666     }
667     
668     /** This implementation does nothing.
669      * Target is already started when Tomcat starts.
670      */

671     public ProgressObject JavaDoc startServer (Target JavaDoc target) {
672         return null;
673     }
674     
675     public boolean supportsStartDebugging(Target JavaDoc target) {
676         return true;
677     }
678
679     public ClientConfiguration JavaDoc getClientConfiguration (TargetModuleID JavaDoc targetModuleID) {
680         return null;
681     }
682     
683     public DeploymentStatus JavaDoc getDeploymentStatus () {
684         return pes.getDeploymentStatus ();
685     }
686     
687     public TargetModuleID JavaDoc[] getResultTargetModuleIDs () {
688         return new TargetModuleID JavaDoc [] {};
689     }
690     
691     public boolean isCancelSupported () {
692         return false;
693     }
694     
695     public void cancel ()
696     throws OperationUnsupportedException JavaDoc {
697         throw new OperationUnsupportedException JavaDoc ("");
698     }
699     
700     public boolean isStopSupported () {
701         return false;
702     }
703     
704     public void stop ()
705     throws OperationUnsupportedException JavaDoc {
706         throw new OperationUnsupportedException JavaDoc ("");
707     }
708     
709     public void addProgressListener (ProgressListener JavaDoc pl) {
710         pes.addProgressListener (pl);
711     }
712     
713     public void removeProgressListener (ProgressListener JavaDoc pl) {
714         pes.removeProgressListener (pl);
715     }
716     
717     
718     public String JavaDoc toString () {
719         return "StartTomcat [" + tm + "]"; // NOI18N
720
}
721     
722     public int getCurrentServerPort() {
723         return currentServerPort;
724     }
725     
726     // private helper methods -------------------------------------------------
727

728     private static NbProcessDescriptor defaultExecDesc(String JavaDoc command, String JavaDoc argCommand, String JavaDoc option) {
729         return new NbProcessDescriptor (
730             "{" + command + "}", // NOI18N
731
"{" + argCommand + "}" + " {" + option + "}", // NOI18N
732
NbBundle.getMessage (StartTomcat.class, "MSG_TomcatExecutionCommand")
733         );
734     }
735     
736     private static NbProcessDescriptor defaultExecDesc(String JavaDoc command, String JavaDoc argCommand) {
737         return new NbProcessDescriptor (
738             "{" + command + "}", // NOI18N
739
"{" + argCommand + "}", // NOI18N
740
NbBundle.getMessage (StartTomcat.class, "MSG_TomcatExecutionCommand")
741         );
742     }
743
744     private static NbProcessDescriptor defaultDebugStartDesc(String JavaDoc command, String JavaDoc jpdaCommand, String JavaDoc option) {
745         return new NbProcessDescriptor (
746             "{" + command + "}", // NOI18N
747
"{" + TAG_JPDA + "}" + " {" + jpdaCommand + "}" + " {" + option + "}", // NOI18N
748
NbBundle.getMessage (StartTomcat.class, "MSG_TomcatExecutionCommand")
749         );
750     }
751     
752     private static NbProcessDescriptor defaultDebugStartDesc(String JavaDoc command, String JavaDoc jpdaCommand) {
753         return new NbProcessDescriptor (
754             "{" + command + "}", // NOI18N
755
"{" + TAG_JPDA + "}" + " {" + jpdaCommand + "}", // NOI18N
756
NbBundle.getMessage (StartTomcat.class, "MSG_TomcatExecutionCommand")
757         );
758     }
759     
760     private String JavaDoc getJavaHome(JavaPlatform platform) {
761         FileObject fo = (FileObject)platform.getInstallFolders().iterator().next();
762         return FileUtil.toFile(fo).getAbsolutePath();
763     }
764     
765     /** Return the catalina startup script file. */
766     private File JavaDoc getStartupScript() {
767         TomcatProperties tp = tm.getTomcatProperties();
768         if (tp.getCustomScript()) {
769             return new File JavaDoc(tp.getScriptPath());
770         }
771         // use catalina50.sh/bat for Tomcat 5.0 on jdk1.5
772
if (tm.getTomcatVersion() == TomcatVersion.TOMCAT_50
773              && "1.5".equals(getJavaPlatform().getSpecification().getVersion().toString())) { // NOI18N
774
String JavaDoc startupScript = Utilities.isWindows() ? CATALINA_50_BAT : CATALINA_50_SH;
775             File JavaDoc scriptFile = new File JavaDoc(tp.getCatalinaHome(), "/bin/" + startupScript); // NOI18N
776
if (scriptFile.exists()) {
777                 return scriptFile;
778             }
779         }
780         String JavaDoc startupScript = Utilities.isWindows() ? CATALINA_BAT : CATALINA_SH;
781         return new File JavaDoc(tp.getCatalinaHome(), "/bin/" + startupScript); // NOI18N
782
}
783     
784     private JavaPlatform getJavaPlatform() {
785         return tm.getTomcatProperties().getJavaPlatform();
786     }
787     
788     /** enable/disable ${catalina.home}/common/endorsed/*.jar in the catalina class
789      loader in the catalina.properties file */

790     private void patchCatalinaProperties(File JavaDoc catalinaBase, final boolean endorsedEnabled) {
791         File JavaDoc catalinaProp = new File JavaDoc(catalinaBase, "conf/catalina.properties"); // NOI18N
792
if (!catalinaProp.exists()) {
793             return; // catalina.properties does not exist, can't do anything
794
}
795         EditableProperties props = new EditableProperties();
796         try {
797             InputStream JavaDoc is = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(catalinaProp));
798             try {
799                 props.load(is);
800                 String JavaDoc COMMON_LOADER = "common.loader"; // NOI18N
801
String JavaDoc commonLoader = props.getProperty(COMMON_LOADER);
802                 if (commonLoader != null) {
803                     String JavaDoc COMMON_ENDORSED = "${catalina.home}/common/endorsed/*.jar"; // NOI18N
804
int idx = commonLoader.indexOf(COMMON_ENDORSED);
805                     if (endorsedEnabled) {
806                         if (idx == -1) { // common/endorsed/*.jar is not present, add it
807
String JavaDoc COMMON_LIB = "${catalina.home}/" + tm.libFolder() + "/*.jar"; // NOI18N
808
int commonLibIdx = commonLoader.indexOf(COMMON_LIB);
809                             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(commonLibIdx == -1
810                                     ? commonLoader
811                                     : commonLoader.substring(0, commonLibIdx));
812                             if (commonLibIdx != -1) {
813                                 sb.append(COMMON_ENDORSED).append(',').append(commonLoader.substring(commonLibIdx));
814                             } else {
815                                 if (commonLoader.trim().length() != 0) {
816                                     sb.append(',');
817                                 }
818                                 sb.append(COMMON_ENDORSED);
819                             }
820                             props.setProperty(COMMON_LOADER, sb.toString());
821                         } else {
822                             return;
823                         }
824                     } else {
825                         if (idx != -1) { // common/endorsed/*.jar is present, remove it
826
String JavaDoc strBefore = commonLoader.substring(0, idx);
827                             int commaIdx = strBefore.lastIndexOf(',');
828                             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(commonLoader.substring(0, commaIdx == -1 ? idx : commaIdx));
829                             String JavaDoc strAfter = commonLoader.substring(idx + COMMON_ENDORSED.length());
830                             if (commaIdx == -1) {
831                                 // we have to cut off the trailing comman after the endorsed lib
832
int trailingCommaIdx = strAfter.indexOf(',');
833                                 if (trailingCommaIdx != -1) {
834                                     strAfter = strAfter.substring(trailingCommaIdx + 1);
835                                 }
836                             }
837                             sb.append(strAfter);
838                             props.setProperty(COMMON_LOADER, sb.toString());
839                         } else {
840                             return;
841                         }
842                     }
843                 }
844             } finally {
845                 is.close();
846             }
847             // store changes
848
BufferedOutputStream JavaDoc out = new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(catalinaProp));
849             try {
850                 props.store(out);
851             } finally {
852                 out.close();
853             }
854         } catch (FileNotFoundException JavaDoc fnfe) {
855             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, fnfe);
856         } catch (IOException JavaDoc ioe) {
857             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe);
858         }
859     }
860     
861     /** Utility class that just "consumes" the input stream - #58554 workaround
862      */

863     private static class StreamConsumer implements Runnable JavaDoc {
864         
865         private BufferedInputStream JavaDoc in;
866         
867         public StreamConsumer(InputStream JavaDoc is) {
868             in = new BufferedInputStream JavaDoc(is);
869         }
870
871         public void run() {
872             try {
873                 byte buffer[] = new byte[1024];
874                 while (true) {
875                     int n = in.read(buffer);
876                     if (n < 0) {
877                         break;
878                     }
879                     if (TomcatFactory.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
880                         TomcatFactory.getEM().log(ErrorManager.INFORMATIONAL, new String JavaDoc(buffer, 0, n));
881                     }
882                 }
883             } catch (IOException JavaDoc ioe) {
884                 if (TomcatFactory.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
885                     TomcatFactory.getEM().notify(ErrorManager.INFORMATIONAL, ioe);
886                 }
887             } finally {
888                 try { in.close(); } catch (IOException JavaDoc ioe) {};
889             }
890         }
891     };
892     
893     /** Format that provides value usefull for Tomcat execution.
894      * Currently this is only the name of startup wrapper.
895     */

896     private static class TomcatFormat extends org.openide.util.MapFormat {
897         
898         private static final long serialVersionUID = 992972967554321415L;
899         
900         public TomcatFormat(File JavaDoc startupScript, File JavaDoc homeDir) {
901             super(new java.util.HashMap JavaDoc ());
902             java.util.Map JavaDoc map = getMap ();
903             String JavaDoc scriptPath = startupScript.getAbsolutePath();
904             map.put(TAG_EXEC_CMD, scriptPath);
905             map.put(TAG_EXEC_STARTUP, "run"); // NOI18N
906
map.put(TAG_EXEC_SHUTDOWN, "stop"); // NOI18N
907
map.put(TAG_DEBUG_CMD, scriptPath);
908             map.put(TAG_JPDA, "jpda"); // NOI18N
909
map.put(TAG_JPDA_STARTUP, "run"); // NOI18N
910
map.put(TAG_SECURITY_OPT, "-security"); // NOI18N
911
map.put(TAG_FORCE_OPT, "-force"); // NOI18N
912
map.put(TAG_CATALINA_HOME, homeDir.getAbsolutePath());
913         }
914     }
915 }
916
Popular Tags