KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > deployment > impl > ServerInstance


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
21 package org.netbeans.modules.j2ee.deployment.impl;
22
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import javax.enterprise.deploy.spi.*;
26 import javax.enterprise.deploy.shared.*;
27 import javax.enterprise.deploy.spi.exceptions.ConfigurationException JavaDoc;
28 import javax.enterprise.deploy.spi.status.*;
29 import javax.swing.JButton JavaDoc;
30 import javax.swing.SwingUtilities JavaDoc;
31 import org.netbeans.api.debugger.DebuggerManager;
32 import org.netbeans.api.debugger.DebuggerManagerAdapter;
33 import org.netbeans.api.debugger.Session;
34 import org.netbeans.api.debugger.jpda.AttachingDICookie;
35 import org.netbeans.api.debugger.jpda.JPDADebugger;
36 import org.netbeans.modules.j2ee.deployment.common.api.Datasource;
37 import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException;
38 import org.netbeans.modules.j2ee.deployment.plugins.api.*;
39 import org.openide.filesystems.*;
40 import java.util.*;
41 import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException JavaDoc;
42 import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
43 import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
44 import org.netbeans.modules.j2ee.deployment.impl.ui.ProgressUI;
45 import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerServerSettings;
46 import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerSupport;
47 import org.netbeans.modules.j2ee.deployment.profiler.spi.Profiler;
48 import org.openide.nodes.Node;
49 import org.openide.ErrorManager;
50 import org.openide.util.NbBundle;
51 import org.openide.NotifyDescriptor;
52 import org.openide.DialogDisplayer;
53 import org.openide.util.RequestProcessor;
54 import org.openide.windows.InputOutput;
55
56
57 public class ServerInstance implements Node.Cookie, Comparable JavaDoc {
58     
59     /** Server state is being checked or state changes is in progress */
60     public static final int STATE_WAITING = 1;
61     /** Server is stopped */
62     public static final int STATE_STOPPED = 2;
63     /** Server is running in normal mode */
64     public static final int STATE_RUNNING = 3;
65     /** Server is running in debug mode */
66     public static final int STATE_DEBUGGING = 4;
67     /** Server is suspended on a break point (in debug mode and not responding) */
68     public static final int STATE_SUSPENDED = 5;
69     /** Server is running in profile mode */
70     public static final int STATE_PROFILING = 6;
71     /** Server is ready for the profiler to connect, server JVM is blocked. */
72     public static final int STATE_PROFILER_BLOCKING = 7;
73     /** Server is starting in profile mode. */
74     public static final int STATE_PROFILER_STARTING = 8;
75     
76     /** For how long should plugins be allowed to block in the isRunning method */
77     private static final int RUNNING_CHECK_TIMEOUT = 10000; // in millis
78
/** For how long should plugins be allowed to block in the isDebuggable method */
79     private static final int DEBUGGING_CHECK_TIMEOUT = 10000; // in millis
80

81     /** Maximum amount of time the server should finish starting/stopping in */
82     private static final long TIMEOUT = 1200000; // in millis
83

84     private final String JavaDoc url;
85     private final Server server;
86     private DeploymentManager manager;
87     private DeploymentManager disconnectedManager;
88     private IncrementalDeployment incrementalDeployment;
89     private TargetModuleIDResolver tmidResolver;
90     private J2eePlatform j2eePlatform;
91     private J2eePlatformImpl j2eePlatformImpl;
92     private StartServer startServer;
93     private FindJSPServlet findJSPServlet;
94     private DatasourceManager dsMgr;
95     private DatasourceManager ddsMgr;
96     private final Set targetsStartedByIde = new HashSet(); // valued by target name
97
private Map targets; // keyed by target name, valued by ServerTarget
98
private boolean managerStartedByIde = false;
99     private ServerTarget coTarget = null;
100     private boolean commandSucceed = false;
101     private InstancePropertiesImpl instanceProperties;
102     private HashMap/*<Target, ServerDebugInfo>*/ debugInfo = new HashMap();
103     
104     // last known server state, the initial value is stopped
105
private int serverState = STATE_STOPPED;
106     // server state listeners
107
private List stateListeners = new ArrayList();
108     
109     // running check helpers
110
private long lastCheck = 0;
111     private boolean isRunning = false;
112     
113     
114     private static ServerInstance profiledServerInstance;
115     private ProfilerServerSettings profilerSettings;
116     
117     private final DebuggerStateListener debuggerStateListener;
118     
119     // PENDING how to manage connected/disconnected servers with the same manager?
120
// maybe concept of 'default unconnected instance' is broken?
121
public ServerInstance(Server server, String JavaDoc url) {
122         this.server = server;
123         this.url = url;
124         instanceProperties = new InstancePropertiesImpl(url);
125         // listen to debugger changes so that we can update server status accordingly
126
debuggerStateListener = new DebuggerStateListener();
127         DebuggerManager.getDebuggerManager().addDebuggerListener(debuggerStateListener);
128     }
129     
130     /** Return this server instance InstanceProperties. */
131     public InstancePropertiesImpl getInstanceProperties() {
132         return instanceProperties;
133     }
134     
135     /** Return display name of this server instance.*/
136     public String JavaDoc getDisplayName() {
137         return instanceProperties.getProperty(InstanceProperties.DISPLAY_NAME_ATTR);
138     }
139     
140     public Server getServer() {
141         return server;
142     }
143     
144     public String JavaDoc getUrl() {
145         return url;
146     }
147     
148     public DeploymentManager getDeploymentManager() {
149         DeploymentManager managerTmp = null;
150         synchronized (this) {
151             managerTmp = manager;
152         }
153         if (managerTmp != null) {
154             return managerTmp;
155         }
156         try {
157             FileObject fo = ServerRegistry.getInstanceFileObject(url);
158             if (fo == null) {
159                 String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_NullInstanceFileObject", url);
160                 throw new IllegalStateException JavaDoc(msg);
161             }
162             String JavaDoc username = (String JavaDoc) fo.getAttribute(ServerRegistry.USERNAME_ATTR);
163             String JavaDoc password = (String JavaDoc) fo.getAttribute(ServerRegistry.PASSWORD_ATTR);
164             managerTmp = server.getDeploymentManager(url, username, password);
165             synchronized (this) {
166                 manager = managerTmp;
167             }
168         } catch(javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException JavaDoc e) {
169             throw new RuntimeException JavaDoc(e);
170         }
171         return managerTmp;
172     }
173     
174     public synchronized boolean isConnected () {
175         return manager != null;
176     }
177     
178     public DeploymentManager getDisconnectedDeploymentManager() throws DeploymentManagerCreationException JavaDoc {
179         DeploymentManager disconnectedManagerTmp = null;
180         synchronized (this) {
181             disconnectedManagerTmp = disconnectedManager;
182         }
183         if (disconnectedManagerTmp != null) {
184             return disconnectedManagerTmp;
185         }
186         FileObject fo = ServerRegistry.getInstanceFileObject(url);
187         if (fo == null) {
188             String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_NullInstanceFileObject", url);
189             throw new IllegalStateException JavaDoc(msg);
190         }
191         disconnectedManagerTmp = server.getDisconnectedDeploymentManager(url);
192         synchronized (this) {
193             disconnectedManager = disconnectedManagerTmp;
194         }
195         return disconnectedManagerTmp;
196     }
197     
198     public J2eePlatform getJ2eePlatform() {
199         return j2eePlatform;
200     }
201     
202     public void setJ2eePlatform(J2eePlatform aJ2eePlatform ) {
203         j2eePlatform = aJ2eePlatform;
204     }
205     
206     public J2eePlatformImpl getJ2eePlatformImpl() {
207         if (j2eePlatformImpl == null) {
208             J2eePlatformFactory fact = server.getJ2eePlatformFactory();
209             // TODO this will be removed, implementation of J2EEPlatformFactory will be mandatory
210
if (fact != null) {
211                 try {
212                     j2eePlatformImpl = fact.getJ2eePlatformImpl(isConnected() ? getDeploymentManager() : getDisconnectedDeploymentManager());
213                 } catch (DeploymentManagerCreationException JavaDoc dmce) {
214                     ErrorManager.getDefault().notify(dmce);
215                 }
216             }
217         }
218         return j2eePlatformImpl;
219     }
220     
221     public ServerDebugInfo getServerDebugInfo(Target target) {
222         assert debugInfo != null;
223         ServerDebugInfo sdi = null;
224         if (target == null) { //performance: treat as special simple case
225
sdi = (ServerDebugInfo) debugInfo.get(null);
226         } else {
227             for (Iterator it = debugInfo.keySet().iterator(); sdi == null && it.hasNext(); ) {
228                 Target t = (Target) it.next();
229                 if (t == target || (t != null && t.getName().equals(target.getName()))) {
230                     sdi = (ServerDebugInfo) debugInfo.get(t);
231                 }
232             }
233         }
234         
235         return sdi;
236     }
237     
238     public void refresh() {
239         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
240             public void run() {
241                 try {
242                     int oldState = getServerState();
243                     setServerState(STATE_WAITING);
244                     if (ServerInstance.this == profiledServerInstance) {
245                         int profState = ProfilerSupport.getState();
246                         if (profState == ProfilerSupport.STATE_STARTING) {
247                             setServerState(ServerInstance.STATE_PROFILER_STARTING);
248                             return;
249                         } else if (profState == ProfilerSupport.STATE_BLOCKING) {
250                             setServerState(ServerInstance.STATE_PROFILER_BLOCKING);
251                             return;
252                         } else if (profState == ProfilerSupport.STATE_PROFILING
253                                    || profState == ProfilerSupport.STATE_RUNNING) {
254                             initCoTarget();
255                             setServerState(ServerInstance.STATE_PROFILING);
256                             return;
257                         } else {
258                             // profiler is inactive - has been shutdown
259
profiledServerInstance = null;
260                         }
261                     }
262                     if (isSuspended()) {
263                         setServerState(ServerInstance.STATE_SUSPENDED);
264                     } else if (isDebuggable(null)) {
265                         if (oldState != ServerInstance.STATE_SUSPENDED) {
266                             // this will decrease the possibility of accessing server
267
// when it is in suspended mode when we might freeze
268
reset();
269                         }
270                         initCoTarget();
271                         setServerState(ServerInstance.STATE_DEBUGGING);
272                     } else if (isReallyRunning()) {
273                         reset();
274                         initCoTarget();
275                         setServerState(ServerInstance.STATE_RUNNING);
276                     } else {
277                         reset();
278                         setServerState(ServerInstance.STATE_STOPPED);
279                     }
280                 } finally {
281                     // safety catch - make sure that we are not still waiting
282
if (getServerState() == STATE_WAITING) {
283                         setServerState(ServerInstance.STATE_STOPPED);
284                     }
285                 }
286             }
287         });
288     }
289     
290     public void reset() {
291         DeploymentManager managerTmp = null;
292         synchronized (this) {
293             managerTmp = manager;
294             manager = null;
295         }
296         if (managerTmp != null) {
297             managerTmp.release();
298         }
299         synchronized (this) {
300             disconnectedManager = null;
301             incrementalDeployment = null;
302             tmidResolver = null;
303             startServer = null;
304             findJSPServlet = null;
305             coTarget = null;
306             targets = null;
307         }
308     }
309     
310     /** Remove this server instance and stop it if it has been started from within the IDE */
311     public void remove() {
312         DebuggerManager.getDebuggerManager().removeDebuggerListener(debuggerStateListener);
313         stopIfStartedByIde();
314         // close the server io window
315
InputOutput io = UISupport.getServerIO(url);
316         if (!io.isClosed()) {
317             io.closeInputOutput();
318         }
319         ServerRegistry.getInstance().removeServerInstance(getUrl());
320     }
321     
322     /** Stop the server if it has been started from within the IDE, do nothing otherwise */
323     public void stopIfStartedByIde() {
324         if (managerStartedByIde) {
325             if (canStopDontWait()) {
326                 stopDontWait();
327             } else {
328                 String JavaDoc title = NbBundle.getMessage(ServerInstance.class, "LBL_ShutDownServer", getDisplayName());
329                 final ProgressUI progressUI = new ProgressUI(title, true, null);
330                 progressUI.start();
331                 RequestProcessor.getDefault().post(new Runnable JavaDoc() {
332                     public void run() {
333                         try {
334                             for (Iterator it = targetsStartedByIde.iterator(); it.hasNext();) {
335                                 ServerTarget serverTarget = getServerTarget((String JavaDoc)it.next());
336                                 if (serverTarget != null) {
337                                     try {
338                                         _stop(serverTarget.getTarget(), progressUI);
339                                     } catch (ServerException ex) {
340                                         ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
341                                     }
342                                 }
343                             }
344                             if (isReallyRunning() || isSuspended()) {
345                                 try {
346                                     _stop(progressUI);
347                                 } catch (ServerException ex) {
348                                     ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
349                                 }
350                             }
351                         } finally {
352                             progressUI.finish();
353                         }
354                     }
355                 });
356                 progressUI.showProgressDialog();
357             }
358         }
359     }
360     
361     /** Set the server state and notify all listeners */
362     public void setServerState(int newState) {
363         int oldState = serverState;
364         serverState = newState;
365         fireStateChanged(oldState, newState);
366     }
367     
368     /** Return the current server state */
369     public int getServerState() {
370         return serverState;
371     }
372     
373     /** Is it forbidden to remove this server instance from the server registry? */
374     public boolean isRemoveForbidden() {
375         String JavaDoc removeForbid = instanceProperties.getProperty(InstanceProperties.REMOVE_FORBIDDEN);
376         return Boolean.valueOf(removeForbid).booleanValue();
377     }
378     
379     public ServerTarget[] getTargets() {
380         Map targets = getTargetMap();
381         synchronized (this) {
382             return (ServerTarget[]) targets.values().toArray(new ServerTarget[targets.size()]);
383         }
384     }
385     
386     public Collection getTargetList() {
387         Map targets = getTargetMap();
388         synchronized (this) {
389             return targets.values();
390         }
391     }
392     
393     // PENDING use targets final variable?
394
private Map getTargetMap() {
395         Map tmpTargets = null;
396         synchronized (this) {
397             tmpTargets = targets;
398         }
399         if (tmpTargets == null) {
400             Target[] targs = null;
401             StartServer startServer = getStartServer();
402             try {
403                 if (! isRunning() && startServer != null && startServer.needsStartForTargetList()) {
404                     start();
405                 }
406                 
407                 targs = getDeploymentManager().getTargets();
408             } catch(IllegalStateException JavaDoc e) {
409                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
410             }
411             if(targs == null) {
412                 targs = new Target[0];
413             }
414             
415             tmpTargets = new HashMap();
416             for (int i = 0; i < targs.length; i++) {
417                 //System.out.println("getTargetMap: targ["+i+"]="+targs[i]);
418
tmpTargets.put(targs[i].getName(), new ServerTarget(this, targs[i]));
419             }
420             synchronized (this) {
421                 targets = tmpTargets;
422             }
423         }
424         return tmpTargets;
425     }
426     
427     public ServerTarget getServerTarget(String JavaDoc targetName) {
428         return (ServerTarget) getTargetMap().get(targetName);
429     }
430     
431     public Target getTarget(String JavaDoc targetName) {
432         return getServerTarget(targetName).getTarget();
433     }
434     
435     public StartServer getStartServer() {
436         DeploymentManager dm = null;
437         try {
438             dm = getDisconnectedDeploymentManager();
439         } catch (DeploymentManagerCreationException JavaDoc dmce) {
440             throw new RuntimeException JavaDoc(dmce);
441         }
442         synchronized (this) {
443             if (startServer == null) {
444                 startServer = server.getOptionalFactory().getStartServer(dm);
445             }
446             return startServer;
447         }
448     }
449     
450     public IncrementalDeployment getIncrementalDeployment() {
451         DeploymentManager dm = getDeploymentManager();
452         synchronized (this) {
453             if (incrementalDeployment == null) {
454                 incrementalDeployment = server.getOptionalFactory().getIncrementalDeployment(dm);
455             }
456             return incrementalDeployment;
457         }
458     }
459     
460     public AntDeploymentProvider getAntDeploymentProvider() {
461         try {
462             return server.getOptionalFactory().getAntDeploymentProvider(getDisconnectedDeploymentManager());
463         } catch (DeploymentManagerCreationException JavaDoc ex) {
464             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
465             return null;
466         }
467     }
468     
469     public TargetModuleIDResolver getTargetModuleIDResolver() {
470         DeploymentManager dm = getDeploymentManager();
471         synchronized (this) {
472             if (tmidResolver == null) {
473                 tmidResolver = server.getOptionalFactory().getTargetModuleIDResolver(dm);
474             }
475             return tmidResolver;
476         }
477     }
478     
479     public FindJSPServlet getFindJSPServlet() {
480         DeploymentManager dm = null;
481         try {
482             dm = getDisconnectedDeploymentManager();
483         } catch (DeploymentManagerCreationException JavaDoc dmce) {
484             throw new RuntimeException JavaDoc(dmce);
485         }
486         synchronized (this) {
487             if (findJSPServlet == null) {
488                 findJSPServlet = server.getOptionalFactory().getFindJSPServlet(dm);
489             }
490             return findJSPServlet;
491         }
492     }
493     
494     private DatasourceManager getDatasourceManager() {
495         DeploymentManager dm = getDeploymentManager();
496         synchronized (this) {
497             if (dsMgr == null) {
498                 dsMgr = server.getOptionalFactory().getDatasourceManager(dm);
499             }
500             return dsMgr;
501         }
502     }
503     
504     private DatasourceManager getDisconnectedDatasourceManager() {
505         DeploymentManager dm = null;
506         try {
507             dm = getDisconnectedDeploymentManager();
508         } catch (DeploymentManagerCreationException JavaDoc dmce) {
509             throw new RuntimeException JavaDoc(dmce);
510         }
511         synchronized (this) {
512             if (ddsMgr == null) {
513                 ddsMgr = server.getOptionalFactory().getDatasourceManager(dm);
514             }
515             return ddsMgr;
516         }
517     }
518     
519     /**
520      * Gets the data sources deployed on the this server instance.
521      *
522      * @return set of data sources
523      */

524     public Set<Datasource> getDatasources() {
525         
526         DatasourceManager ddsMgr = getDisconnectedDatasourceManager();
527                 
528         Set deployedDS = Collections.<Datasource>emptySet();
529         if (ddsMgr != null)
530             deployedDS = ddsMgr.getDatasources();
531         
532         return deployedDS;
533     }
534     
535     /**
536      * Deploys data sources saved in the module.
537      *
538      * @exception ConfigurationException if there is some problem with data source configuration
539      * @exception DatasourceAlreadyExistsException if module data source(s) are conflicting
540      * with data source(s) already deployed on the server
541      */

542     public void deployDatasources(Set<Datasource> datasources) throws ConfigurationException JavaDoc, DatasourceAlreadyExistsException {
543         
544         DatasourceManager dsMgr = getDatasourceManager();
545
546         if (dsMgr != null)
547             dsMgr.deployDatasources(datasources);
548     }
549     
550     //---------- State API's: running, debuggable, startedByIDE -----------
551

552     public boolean isRunningLastCheck() {
553         if (lastCheck > 0) {
554             return isRunning;
555         } else {
556             return false;
557         }
558     }
559     
560     public boolean isReallyRunning() {
561         return isRunningWithinMillis(0);
562     }
563     
564     public boolean isRunning() {
565         return isRunningWithinMillis(2000);
566     }
567     
568     public boolean isRunningWithinMillis(long millisecs) {
569         if (System.currentTimeMillis() - lastCheck < millisecs) {
570             return isRunning;
571         }
572         final StartServer ss = getStartServer();
573         if (ss != null) {
574             isRunning = safeTrueTest(new SafeTrueTest() {
575                                          public void run() {
576                                              result = ss.isRunning();
577                                          }
578                                      },
579                                      RUNNING_CHECK_TIMEOUT);
580         } else {
581             isRunning = false;
582         }
583         lastCheck = System.currentTimeMillis();
584         return isRunning;
585     }
586     
587     public boolean isDebuggable(final Target target) {
588         final StartServer ss = getStartServer();
589         if (ss != null) {
590             return safeTrueTest(new SafeTrueTest() {
591                                     public void run() {
592                                         result = ss.isDebuggable(target);
593                                     }
594                                 },
595                                 DEBUGGING_CHECK_TIMEOUT);
596         } else {
597             return false;
598         }
599     }
600     
601     /**
602      * @return conflict data instance for server instance running in debug mode with the same socket number
603      * or shared memory id. If no such server instance exists then null is returned.
604      */

605     public ConflictData anotherServerDebuggable(Target target) {
606         
607         ConflictData cd = null;
608         //get debug info for this instance
609
StartServer thisSS = getStartServer();
610         if (thisSS == null) //this case should not occur =>
611
return null; //attempt to start server (serverInstance remains null)
612
ServerDebugInfo thisSDI = getServerDebugInfo(target);
613         if (thisSDI == null) {
614             Target t = _retrieveTarget(target);
615             thisSDI = thisSS.getDebugInfo(t);
616             if (thisSDI == null) {
617                 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "DebuggerInfo cannot be found for: " + this.toString());
618                 return null;
619             }
620         }
621         
622         //get all server instances
623
ServerInstance[] serverInstances = ServerRegistry.getInstance().getServerInstances();
624         //check existence of a server instance running in debug mode with the same parameters
625
for (int i = 0; cd == null && i < serverInstances.length; i++) {
626             ServerInstance si = serverInstances[i];
627             if (url.equalsIgnoreCase(si.getUrl())) continue;
628             if (si.isDebuggable(null)) { //running in debug mode
629
Target t = si._retrieveTarget(null);
630                 ServerDebugInfo sdi = si.getServerDebugInfo(t);
631                 if (sdi == null) continue; //should not occur -> workaround for issue #56714
632
if (thisSDI.getTransport().equals(sdi.getTransport())) { //transport matches
633
if (thisSDI.getTransport() == ServerDebugInfo.TRANSPORT_SOCKET) {
634                         if (thisSDI.getHost().equalsIgnoreCase(sdi.getHost())) //host matches
635
if (thisSDI.getPort() == sdi.getPort()) //port matches
636
cd = new ConflictData(si, thisSDI);
637                     } else if (thisSDI.getShmemName().equalsIgnoreCase(sdi.getShmemName()))
638                         cd = new ConflictData(si, thisSDI);
639                 }
640             }
641         }
642         
643         return cd;
644     }
645     
646     /**
647      * Returns true if this server is started in debug mode AND debugger is attached to it
648      * AND threads are suspended (e.g. debugger stopped on breakpoint)
649      */

650     public boolean isSuspended() {
651         
652         Session[] sessions = DebuggerManager.getDebuggerManager().getSessions();
653         
654         Target target = _retrieveTarget(null);
655         ServerDebugInfo sdi = getServerDebugInfo(target);
656         if (sdi == null) {
657             ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "DebuggerInfo cannot be found for: " + this.toString());
658             return false; // give user a chance to start server even if we don't know whether she will success
659
}
660         
661         for (int i = 0; i < sessions.length; i++) {
662             Session s = sessions[i];
663             if (s == null) continue;
664             Object JavaDoc o = s.lookupFirst(null, AttachingDICookie.class);
665             if (o == null) continue;
666             AttachingDICookie attCookie = (AttachingDICookie)o;
667             if (sdi.getTransport().equals(ServerDebugInfo.TRANSPORT_SHMEM)) {
668                 String JavaDoc shmem = attCookie.getSharedMemoryName();
669                 if (shmem == null) continue;
670                 if (shmem.equalsIgnoreCase(sdi.getShmemName())) {
671                     Object JavaDoc d = s.lookupFirst(null, JPDADebugger.class);
672                     if (d != null) {
673                         JPDADebugger jpda = (JPDADebugger)d;
674                         if (jpda.getState() == JPDADebugger.STATE_STOPPED) {
675                             return true;
676                         }
677                     }
678                 }
679             } else {
680                 String JavaDoc host = stripHostName(attCookie.getHostName());
681                 if (host == null) continue;
682                 if (host.equalsIgnoreCase(stripHostName(sdi.getHost()))) {
683                     if (attCookie.getPortNumber() == sdi.getPort()) {
684                         Object JavaDoc d = s.lookupFirst(null, JPDADebugger.class);
685                         if (d != null) {
686                             JPDADebugger jpda = (JPDADebugger)d;
687                             if (jpda.getState() == JPDADebugger.STATE_STOPPED) {
688                                 return true;
689                             }
690                         }
691                     }
692                 }
693             }
694         }
695         return false;
696     }
697     
698     /**
699      * Can be this server started in the debug mode? Currently the only case when
700      * the server cannot be started in the debugged is when the admin server is
701      * not also the target server.
702      *
703      * @return <code>true</code> if the server can be started in the debug mode,
704      * <code>false/code> otherwise.
705      */

706     public boolean isDebugSupported() {
707         StartServer ss = getStartServer();
708         return ss.supportsStartDebugging(null);
709     }
710     
711     /**
712      * Can be this server started in profile mode? Currently the only case when
713      * the server cannot be started in the debugged is when the admin server is
714      * not also the target server.
715      */

716     public boolean isProfileSupported() {
717         Profiler profiler = ServerRegistry.getProfiler();
718         if (profiler == null) {
719             return false;
720         }
721         StartServer ss = getStartServer();
722         return ss.supportsStartProfiling(null);
723     }
724     
725     /**
726      * Return set of ServerTarget's that have been started from inside IDE.
727      * @return set of ServerTarget objects.
728      */

729     public Set getTargetsStartedByIde() {
730         Set ret = new HashSet();
731         for (Iterator i=targetsStartedByIde.iterator(); i.hasNext(); ) {
732             String JavaDoc targetName = (String JavaDoc) i.next();
733             ret.add(getServerTarget(targetName));
734         }
735         return ret;
736     }
737     
738     //----------- State Transistion API's: ----------------------
739

740     /**
741      * Start the admin server. Show UI feedback.
742      * Note: for debug mode, always use startDebugTarget() calls because
743      * it is sure then the target need to be started.
744      *
745      * @throws ServerException if the server cannot be started.
746      */

747     public void start(ProgressUI ui) throws ServerException {
748         try {
749             setServerState(STATE_WAITING);
750             startTarget(null, ui);
751         } finally {
752             refresh();
753         }
754     }
755     
756     /** Start the admin server in the debug mode. Show UI feedback.
757      *
758      * @throws ServerException if the server cannot be started.
759      */

760     public void startDebug(ProgressUI ui) throws ServerException {
761         try {
762             setServerState(STATE_WAITING);
763             startTarget(null, ui, true);
764             _retrieveDebugInfo(null);
765         } finally {
766             refresh();
767         }
768     }
769     
770     /** Start the admin server in the profile mode. Show UI feedback.
771      * @param settings settings that will be used to start the server
772      *
773      * @throws ServerException if the server cannot be started.
774      */

775     public void startProfile(ProfilerServerSettings settings, boolean forceRestart, ProgressUI ui)
776     throws ServerException {
777         // check whether another server not already running in profile mode
778
// and ask whether it is ok to stop it
779
if (profiledServerInstance != null && profiledServerInstance != this) {
780             String JavaDoc msg = NbBundle.getMessage(
781                                     ServerInstance.class,
782                                     "MSG_AnotherServerProfiling",
783                                     profiledServerInstance.getDisplayName());
784             NotifyDescriptor nd = new NotifyDescriptor.Confirmation(msg, NotifyDescriptor.OK_CANCEL_OPTION);
785             if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.CANCEL_OPTION) {
786                 // start in profile mode has been cancelled
787
String JavaDoc err = NbBundle.getMessage(ServerInstance.class, "MSG_ProfilingCancelled", getDisplayName());
788                 throw new ServerException(err);
789             }
790         }
791         try {
792             setServerState(STATE_WAITING);
793             // target == null - admin server
794
startProfileImpl(null, settings, forceRestart, ui);
795         } finally {
796             refresh();
797         }
798     }
799     
800     /** Restart the admin server in the mode the server was running in before.
801      * Show UI feedback.
802      *
803      * @throws ServerException if the server cannot be restarted.
804      */

805     public void restart(ProgressUI ui) throws ServerException {
806         try {
807             setServerState(STATE_WAITING);
808             boolean inDebug = isDebuggable(null);
809             boolean inProfile = profiledServerInstance == this;
810             boolean stopped = true;
811             
812             if (inProfile || isReallyRunning() || isSuspended()) {
813                 _stop(ui);
814             }
815             if (stopped) {
816                 // restart in the mode the server was running in before
817
if (inProfile) {
818                     startProfileImpl(null, profilerSettings, true, ui);
819                 } else if (inDebug) {
820                     startDebugTarget(null, ui);
821                 } else {
822                     startTarget(null, ui);
823                 }
824             }
825         } finally {
826             refresh();
827         }
828     }
829     
830     /** Stop admin server. Show UI feedback.
831      *
832      * @throws ServerException if the server cannot be stopped.
833      */

834     public void stop(ProgressUI ui) throws ServerException {
835         try {
836             setServerState(STATE_WAITING);
837             if (profiledServerInstance == this || isReallyRunning() || isSuspended()) {
838                 _stop(ui);
839             }
840             debugInfo.clear();
841         } finally {
842             refresh();
843         }
844     }
845     
846     // Note: configuration needs
847
/**
848      * Return a connected DeploymentManager if needed by server platform for configuration
849      * @return DeploymentManager object for configuration.
850      */

851     public DeploymentManager getDeploymentManagerForConfiguration() throws DeploymentManagerCreationException JavaDoc {
852         StartServer ss = getStartServer();
853         if (ss != null && ss.needsStartForConfigure()) {
854             start();
855             return getDeploymentManager();
856         } else {
857             return getDisconnectedDeploymentManager();
858         }
859     }
860     
861     // Note: execution only need these 3 state transition APIs
862

863     /**
864      * Start specified target server. If it is also admin server only make sure
865      * admin server is running.
866      * @param target target server to be started
867      * @param ui DeployProgressUI to display start progress
868      *
869      * @throws ServerException if the target cannot be started.
870      */

871     public void startTarget(Target target, ProgressUI ui) throws ServerException {
872         startTarget(target, ui, false);
873     }
874     
875     /**
876      * Start specified target server in debug mode. If target is also admin
877      * server only make sure admin server is running.
878      * @param target target server to be started
879      * @param ui DeployProgressUI to display start progress
880      *
881      * @throws ServerException if the server cannot be started.
882      */

883     public void startDebugTarget(Target target, ProgressUI ui) throws ServerException {
884         startTarget(target, ui, true);
885         _retrieveDebugInfo(target);
886     }
887     
888     /**
889      * Start admin server, mainly for registry actions with no existing progress UI
890      *
891      * @throws ServerException if the server cannot be started.
892      */

893     private void start() {
894         if (SwingUtilities.isEventDispatchThread()) {
895             //PENDING maybe a modal dialog instead of async is needed here
896
RequestProcessor.getDefault().post(new Runnable JavaDoc() {
897                 public void run() {
898                     start();
899                 }
900             });
901             return;
902         }
903         if (isRunning()) {
904             return;
905         }
906         String JavaDoc title = NbBundle.getMessage(ServerInstance.class, "LBL_StartServerProgressMonitor", getDisplayName());
907         ProgressUI ui = new ProgressUI(title, false);
908         try {
909             ui.start();
910             start(ui);
911         } catch (ServerException ex) {
912             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
913         } finally {
914             ui.finish();
915         }
916     }
917     
918     /**
919      * Start admin server for profiling, mainly for registry actions with no existing progress UI
920      * @param settings settings that will be used to start the server
921      *
922      * @throws ServerException if the server cannot be started.
923      */

924     public boolean startProfile(final ProfilerServerSettings settings, boolean forceRestart, Deployment.Logger logger) {
925         String JavaDoc title = NbBundle.getMessage(ServerInstance.class, "LBL_StartServerInProfileMode", getDisplayName());
926         ProgressUI ui = new ProgressUI(title, false, logger);
927         try {
928             ui.start();
929             startProfile(settings, forceRestart, ui);
930             return true;
931         } catch (ServerException ex) {
932             return false;
933         } finally {
934             ui.finish();
935         }
936     }
937     
938     /** Stop the server and do not wait for response.
939      * This will be used at IDE exit.
940      */

941     public void stopDontWait() {
942         if (isReallyRunning()) {
943             StartServer startServ = getStartServer();
944             assert startServ.canStopDeploymentManagerSilently() : "server does not support silent stop of deployment manager";
945             startServ.stopDeploymentManagerSilently();
946         }
947     }
948     
949     /** see stopDontWait */
950     public boolean canStopDontWait() {
951         StartServer startServ = getStartServer();
952         return startServ.canStopDeploymentManagerSilently();
953     }
954     
955     //------------------------------------------------------------
956
/**
957      * @throws ServerException if the conflict has not been resolved.
958      */

959     private void resolveServerConflict(Target target, ProgressUI ui, ConflictData cd) throws ServerException {
960         
961         ServerInstance si = cd.getServerInstance();
962         //inform a user and allow him to stop the running instance
963
NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
964                 NbBundle.getMessage(
965                 ServerInstance.class,
966                 "MSG_AnotherServerRunning",
967                 new Object JavaDoc[] {
968             si.getDisplayName(),
969                     cd.getServerDebugInfo().getHost(),
970                     cd.getServerDebugInfo().getTransport().equals(ServerDebugInfo.TRANSPORT_SOCKET) ?
971                         "socket" : "shared memory",
972                     cd.getServerDebugInfo().getTransport().equals(ServerDebugInfo.TRANSPORT_SOCKET) ?
973                         new Integer JavaDoc(cd.getServerDebugInfo().getPort()).toString() : cd.getServerDebugInfo().getShmemName()
974         }),
975                 NotifyDescriptor.QUESTION_MESSAGE
976                 );
977         nd.setOptionType(NotifyDescriptor.OK_CANCEL_OPTION);
978         JButton JavaDoc yes = new JButton JavaDoc(NbBundle.getMessage(ServerInstance.class, "MSG_AnotherServerStopYes"));
979         JButton JavaDoc no = new JButton JavaDoc(NbBundle.getMessage(ServerInstance.class, "MSG_AnotherServerStopNo"));
980         yes.setDefaultCapable(true);
981         nd.setOptions(new Object JavaDoc[] { yes, no });
982         Object JavaDoc option = DialogDisplayer.getDefault().notify(nd);
983         if (option != yes) { //user pressed No
984
String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_ServerStartupCancelled", getDisplayName());
985             throw new ServerException(msg);
986         }
987         //try to stop running server
988
if (si.getStartServer().supportsStartDeploymentManager()) {
989             si.stop(ui);
990         } else {
991             String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StartingThisServerNotSupported", getDisplayName());
992             throw new ServerException(msg);
993         }
994     }
995     
996     // multiplexor state-machine core
997
/**
998      * @throws ServerException if the server cannot be started.
999      */

1000    private void startTarget(Target target, ProgressUI ui, boolean debugMode) throws ServerException {
1001        StartServer ss = getStartServer();
1002        
1003        // No StartServer, have to assume manually started
1004
if (ss == null) {
1005            ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_PluginHasNoStartServerClass", getServer()));
1006            return;
1007        }
1008        if (isSuspended()) {
1009            // cannot do anything with the server right now
1010
String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_ServerSuspended", getServer());
1011            throw new ServerException(msg);
1012        }
1013        boolean canControlAdmin = ss.supportsStartDeploymentManager();
1014        boolean canDebug = ss.supportsStartDebugging(target);
1015        boolean needsRestart = ss.needsRestart(target);
1016        
1017        if (ss.isAlsoTargetServer(target)) {
1018            if (debugMode) {
1019                if (ss.isDebuggable(target)) { // already running in debug mode
1020
if (! needsRestart) {
1021                        return;
1022                    }
1023                    if (!canControlAdmin || !canDebug) {
1024                        String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_RestartingThisServerNotSupported", getDisplayName());
1025                        throw new ServerException(msg);
1026                    }
1027                    _stop(ui);
1028                } else if (isReallyRunning()) { // running but not debuggable
1029
if (!canControlAdmin || !canDebug) {
1030                        String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_DebugginThisServerNotSupported", getDisplayName());
1031                        throw new ServerException(msg);
1032                    }
1033                    _stop(ui);
1034                }
1035                // the server is stopped now
1036
if (!canDebug) {
1037                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_DebugginThisServerNotSupported", getDisplayName());
1038                    throw new ServerException(msg);
1039                }
1040                // resolve conflicts with other servers
1041
ConflictData cd = anotherServerDebuggable(target);
1042                if (cd != null) { // another server instance with the same parameters
1043
resolveServerConflict(target, ui, cd);
1044                }
1045                _startDebug(target, ui);
1046            } else {
1047                if (isReallyRunning()) { // already running
1048
if (! needsRestart) {
1049                        return;
1050                    }
1051                    if (!canControlAdmin) {
1052                        String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_RestartingThisServerNotSupported", getDisplayName());
1053                        throw new ServerException(msg);
1054                    }
1055                    _stop(ui);
1056                }
1057                if (!canControlAdmin) {
1058                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StartingThisServerNotSupported", getDisplayName());
1059                    throw new ServerException(msg);
1060                }
1061                _start(ui);
1062            }
1063        } else { // not also target server
1064
// this block ensure a running admin server to control other targets
1065
if (! isReallyRunning()) {
1066                if (!canControlAdmin) {
1067                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StartingThisServerNotSupported", getDisplayName());
1068                    throw new ServerException(msg);
1069                }
1070                _start(ui);
1071            }
1072            if (debugMode) {
1073                if (ss.isDebuggable(target)) {
1074                    if ( ! needsRestart) {
1075                        return;
1076                    }
1077                    _stop(target, ui);
1078                } else if (ss.isRunning(target)) {
1079                    _stop(target, ui);
1080                }
1081                ConflictData cd = anotherServerDebuggable(target);
1082                if (cd != null) { //another server instance with the same parameters
1083
resolveServerConflict(target, ui, cd);
1084                }
1085                _startDebug(target, ui);
1086            } else {
1087                if (ss.isRunning(target)) {
1088                    if (! needsRestart) {
1089                        return;
1090                    }
1091                    _stop(target, ui);
1092                }
1093                _start(target, ui);
1094            }
1095        }
1096    }
1097    
1098    //------------------------------------------------------------
1099
// state-transition atomic operations (always do-it w/o checking state)
1100
//------------------------------------------------------------
1101
// startDeploymentManager
1102
private synchronized void _start(ProgressUI ui) throws ServerException {
1103        
1104        String JavaDoc displayName = getDisplayName();
1105        
1106        ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_StartingServer", displayName));
1107        
1108        ProgressObject po = null;
1109        StartProgressHandler handler = new StartProgressHandler();
1110        
1111        try {
1112            setCommandSucceeded(false);
1113            po = getStartServer().startDeploymentManager();
1114            if (ui != null) {
1115                ui.setProgressObject(po);
1116            }
1117            po.addProgressListener(handler);
1118            
1119            if (isProgressing(po)) {
1120                // wait until done or cancelled
1121
boolean done = sleep();
1122                if (! done) {
1123                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StartServerTimeout", displayName);
1124                    throw new ServerException(msg);
1125                } else if (! hasCommandSucceeded()) {
1126                    DeploymentStatus status = po.getDeploymentStatus();
1127                    throw new ServerException(status.getMessage());
1128                }
1129            } else if (hasFailed(po)) {
1130                DeploymentStatus status = po.getDeploymentStatus();
1131                throw new ServerException(status.getMessage());
1132            }
1133            managerStartedByIde = true;
1134            coTarget = null;
1135            targets = null;
1136            initCoTarget();
1137        } finally {
1138            if (ui != null) {
1139                ui.setProgressObject(null);
1140            }
1141            if (po != null) {
1142                po.removeProgressListener(handler);
1143            }
1144        }
1145    }
1146    
1147    // startDebugging
1148
private synchronized void _startDebug(Target target, ProgressUI ui) throws ServerException {
1149        
1150        String JavaDoc displayName = getDisplayName();
1151        ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_StartingDebugServer", displayName));
1152        
1153        ProgressObject po = null;
1154        StartProgressHandler handler = new StartProgressHandler();
1155        
1156        try {
1157            setCommandSucceeded(false);
1158            po = getStartServer().startDebugging(target);
1159            if (ui != null) {
1160                ui.setProgressObject(po);
1161            }
1162            po.addProgressListener(handler);
1163            
1164            if (isProgressing(po)) {
1165                // wait until done or cancelled
1166
boolean done = sleep();
1167                if (! done) {
1168                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StartDebugTimeout", displayName);
1169                    throw new ServerException(msg);
1170                } else if (! hasCommandSucceeded()) {
1171                    DeploymentStatus status = po.getDeploymentStatus();
1172                    throw new ServerException(status.getMessage());
1173                }
1174            } else if (hasFailed(po)) {
1175                DeploymentStatus status = po.getDeploymentStatus();
1176                throw new ServerException(status.getMessage());
1177            }
1178            managerStartedByIde = true;
1179            coTarget = null;
1180            targets = null;
1181            initCoTarget();
1182        } finally {
1183            if (ui != null) {
1184                ui.setProgressObject(null);
1185            }
1186            if (po != null) {
1187                po.removeProgressListener(handler);
1188            }
1189        }
1190    }
1191    
1192    /** start server in the profile mode */
1193    private synchronized void startProfileImpl(
1194                                    Target target,
1195                                    ProfilerServerSettings settings,
1196                                    boolean forceRestart,
1197                                    ProgressUI ui) throws ServerException {
1198        if (profiledServerInstance == this && !forceRestart && settings.equals(profilerSettings)) {
1199            return; // server is already runnning in profile mode, no need to restart the server
1200
}
1201        if (profiledServerInstance != null && profiledServerInstance != this) {
1202            // another server currently running in profiler mode
1203
profiledServerInstance.stop(ui);
1204            profiledServerInstance = null;
1205        }
1206        if (profiledServerInstance == this || isReallyRunning() || isDebuggable(target)) {
1207            _stop(ui);
1208            debugInfo.clear();
1209            profiledServerInstance = null;
1210        }
1211        
1212        String JavaDoc displayName = getDisplayName();
1213        ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_StartingProfileServer", displayName));
1214        
1215        ProgressObject po = null;
1216        StartProgressHandler handler = new StartProgressHandler();
1217        
1218        try {
1219            setCommandSucceeded(false);
1220            Profiler profiler = ServerRegistry.getProfiler();
1221            if (profiler == null) {
1222                // this should not occur, but it is safer this way
1223
String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_ProfilerNotRegistered");
1224                throw new ServerException(msg);
1225            }
1226            profiler.notifyStarting();
1227            po = getStartServer().startProfiling(target, settings);
1228            ui.setProgressObject(po);
1229            po.addProgressListener(handler);
1230            
1231            if (isProgressing(po)) {
1232                // wait until done or cancelled
1233
boolean done = sleep();
1234                if (! done) {
1235                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StartProfileTimeout", displayName);
1236                    throw new ServerException(msg);
1237                } else if (! hasCommandSucceeded()) {
1238                    DeploymentStatus status = po.getDeploymentStatus();
1239                    throw new ServerException(status.getMessage());
1240                }
1241            } else if (hasFailed(po)) {
1242                DeploymentStatus status = po.getDeploymentStatus();
1243                throw new ServerException(status.getMessage());
1244            }
1245            profiledServerInstance = this;
1246            profilerSettings = settings;
1247            managerStartedByIde = true;
1248        } finally {
1249            if (ui != null) {
1250                ui.setProgressObject(null);
1251            }
1252            if (po != null) {
1253                po.removeProgressListener(handler);
1254            }
1255        }
1256    }
1257    
1258    /** Tell the profiler to shutdown */
1259    private synchronized void shutdownProfiler(ProgressUI ui) throws ServerException {
1260        ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_StoppingProfiler"));
1261        StartProgressHandler handler = new StartProgressHandler();
1262        ProgressObject po = null;
1263        try {
1264            Profiler profiler = ServerRegistry.getProfiler();
1265            if (profiler != null) {
1266                po = profiler.shutdown();
1267                ui.setProgressObject(po);
1268                po.addProgressListener(handler);
1269                if (isProgressing(po)) {
1270                    // wait until done or cancelled
1271
boolean done = sleep();
1272                    if (!done) {
1273                        String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_ProfilerShutdownTimeout");
1274                        throw new ServerException(msg);
1275                    } else if (! hasCommandSucceeded()) {
1276                        DeploymentStatus status = po.getDeploymentStatus();
1277                        throw new ServerException(status.getMessage());
1278                    }
1279                } else if (hasFailed(po)) {
1280                    DeploymentStatus status = po.getDeploymentStatus();
1281                    throw new ServerException(status.getMessage());
1282                }
1283            }
1284        } finally {
1285            if (ui != null) {
1286                ui.setProgressObject(null);
1287            }
1288            if (po != null) {
1289                po.removeProgressListener(handler);
1290            }
1291        }
1292    }
1293    
1294    // stopDeploymentManager
1295
private synchronized void _stop(ProgressUI ui) throws ServerException {
1296        // if the server is started in profile mode, deattach profiler first
1297
if (profiledServerInstance == this) {
1298            shutdownProfiler(ui);
1299            profiledServerInstance = null;
1300        }
1301        // if the server is suspended, the debug session has to be terminated first
1302
if (isSuspended()) {
1303            Target target = _retrieveTarget(null);
1304            ServerDebugInfo sdi = getServerDebugInfo(target);
1305            Session[] sessions = DebuggerManager.getDebuggerManager().getSessions();
1306            for (int i = 0; i < sessions.length; i++) {
1307                Session s = sessions[i];
1308                if (s != null) {
1309                    AttachingDICookie attCookie = (AttachingDICookie)s.lookupFirst(null, AttachingDICookie.class);
1310                    if (attCookie != null) {
1311                        if (sdi.getTransport().equals(ServerDebugInfo.TRANSPORT_SHMEM)) {
1312                            String JavaDoc shmem = attCookie.getSharedMemoryName();
1313                            if (shmem != null && shmem.equalsIgnoreCase(sdi.getShmemName())) {
1314                                s.kill();
1315                            }
1316                        } else {
1317                            String JavaDoc host = stripHostName(attCookie.getHostName());
1318                            if (host != null && host.equalsIgnoreCase(stripHostName(sdi.getHost()))
1319                                && attCookie.getPortNumber() == sdi.getPort()) {
1320                                s.kill();
1321                            }
1322                        }
1323                    }
1324                }
1325            }
1326        }
1327        
1328        String JavaDoc displayName = getDisplayName();
1329        ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_StoppingServer", displayName));
1330        
1331        StartProgressHandler handler = new StartProgressHandler();
1332        ProgressObject po = null;
1333        try {
1334            setCommandSucceeded(false);
1335            po = getStartServer().stopDeploymentManager();
1336            ui.setProgressObject(po);
1337            po.addProgressListener(handler);
1338            
1339            if (isProgressing(po)) {
1340                // wait until done or cancelled
1341
boolean done = sleep();
1342                if (! done) {
1343                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StopServerTimeout", displayName);
1344                    throw new ServerException(msg);
1345                } else if (! hasCommandSucceeded()) {
1346                    DeploymentStatus status = po.getDeploymentStatus();
1347                    throw new ServerException(status.getMessage());
1348                }
1349            } else if (hasFailed(po)) {
1350                DeploymentStatus status = po.getDeploymentStatus();
1351                throw new ServerException(status.getMessage());
1352            }
1353            managerStartedByIde = false;
1354            reset();
1355        } finally {
1356            if (ui != null) {
1357                ui.setProgressObject(null);
1358            }
1359            if (po != null) {
1360                po.removeProgressListener(handler);
1361            }
1362        }
1363    }
1364    
1365    private void _start(Target target, ProgressUI ui) throws ServerException {
1366        ServerTarget serverTarget = getServerTarget(target.getName());
1367        if (serverTarget.isRunning()) {
1368            return;
1369        }
1370        
1371        String JavaDoc displayName = target.getName();
1372        ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_StartingServer", displayName));
1373        StartProgressHandler handler = new StartProgressHandler();
1374        ProgressObject po = null;
1375        
1376        try {
1377            setCommandSucceeded(false);
1378            po = serverTarget.start();
1379            if (ui != null) {
1380                ui.setProgressObject(po);
1381            }
1382            po.addProgressListener(handler);
1383            
1384            if (isProgressing(po)) {
1385                // wait until done or cancelled
1386
boolean done = sleep();
1387                if (! done) {
1388                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StartServerTimeout", displayName);
1389                    throw new ServerException(msg);
1390                } else if (! hasCommandSucceeded()) {
1391                    DeploymentStatus status = po.getDeploymentStatus();
1392                    throw new ServerException(status.getMessage());
1393                }
1394            } else if (hasFailed(po)) {
1395                DeploymentStatus status = po.getDeploymentStatus();
1396                throw new ServerException(status.getMessage());
1397            }
1398            targetsStartedByIde.add(serverTarget.getName());
1399        } finally {
1400            if (ui != null) {
1401                ui.setProgressObject(null);
1402            }
1403            if (po != null) {
1404                po.removeProgressListener(handler);
1405            }
1406        }
1407    }
1408    
1409    private void _stop(Target target, ProgressUI ui) throws ServerException {
1410        ServerTarget serverTarget = getServerTarget(target.getName());
1411        if (serverTarget.isRunning()) {
1412            return;
1413        }
1414        
1415        String JavaDoc displayName = target.getName();
1416        ui.progress(NbBundle.getMessage(ServerInstance.class, "MSG_StoppingServer", displayName));
1417        StartProgressHandler handler = new StartProgressHandler();
1418        ProgressObject po = null;
1419        
1420        try {
1421            setCommandSucceeded(false);
1422            po = serverTarget.stop();
1423            if (ui != null) {
1424                ui.setProgressObject(po);
1425            }
1426            po.addProgressListener(handler);
1427            
1428            if (isProgressing(po)) {
1429                // wait until done or cancelled
1430
boolean done = sleep();
1431                if (! done) {
1432                    String JavaDoc msg = NbBundle.getMessage(ServerInstance.class, "MSG_StopServerTimeout", displayName);
1433                    throw new ServerException(msg);
1434                } else if (! hasCommandSucceeded()) {
1435                    DeploymentStatus status = po.getDeploymentStatus();
1436                    throw new ServerException(status.getMessage());
1437                }
1438            } else if (hasFailed(po)) {
1439                DeploymentStatus status = po.getDeploymentStatus();
1440                throw new ServerException(status.getMessage());
1441            }
1442            targetsStartedByIde.remove(serverTarget.getName());
1443        } finally {
1444            if (ui != null) {
1445                ui.setProgressObject(null);
1446            }
1447            if (po != null) {
1448                po.removeProgressListener(handler);
1449            }
1450        }
1451    }
1452    
1453    //-------------- End state-machine operations -------------------
1454

1455    public boolean canStartServer() {
1456        return this.getStartServer() != null && getStartServer().supportsStartDeploymentManager();
1457    }
1458    
1459    private class StartProgressHandler implements ProgressListener {
1460        Boolean JavaDoc completed = null;
1461        public StartProgressHandler() {
1462        }
1463        public void handleProgressEvent(ProgressEvent progressEvent) {
1464            if (completed != null)
1465                return;
1466            DeploymentStatus status = progressEvent.getDeploymentStatus();
1467            if (status.isCompleted()) {
1468                completed = Boolean.TRUE;
1469                ServerInstance.this.setCommandSucceeded(true);
1470                ServerInstance.this.wakeUp();
1471            } else if (status.isFailed()) {
1472                completed = Boolean.FALSE;
1473                ServerInstance.this.wakeUp();
1474            }
1475        }
1476        public boolean isCompleted() {
1477            if (completed == null)
1478                return false;
1479            return completed.booleanValue();
1480        }
1481    }
1482    
1483    private synchronized void wakeUp() {
1484        notify();
1485    }
1486    
1487    //return false when timeout or interrupted
1488
private synchronized boolean sleep() {
1489        try {
1490            long t0 = System.currentTimeMillis();
1491            wait(TIMEOUT);
1492            return (System.currentTimeMillis() - t0) < TIMEOUT;
1493        } catch (Exception JavaDoc e) { return false; }
1494    }
1495    
1496    public boolean isManagerOf(Target target) {
1497        return getTargetMap().keySet().contains(target.getName());
1498    }
1499    
1500    public synchronized ServerTarget getCoTarget() {
1501        return coTarget;
1502    }
1503    
1504    private void initCoTarget() {
1505        ServerTarget[] childs = getTargets();
1506        for (int i=0; i<childs.length; i++) {
1507            if (getStartServer().isAlsoTargetServer(childs[i].getTarget())) {
1508                synchronized (this) {
1509                    coTarget = childs[i];
1510                }
1511            }
1512        }
1513    }
1514    
1515    public boolean isDefault() {
1516        return url.equals(ServerRegistry.getInstance().getDefaultInstance().getUrl());
1517    }
1518    
1519    public String JavaDoc toString() {
1520        return getDisplayName();
1521    }
1522    
1523    public static boolean isProgressing(ProgressObject po) {
1524        StateType state = po.getDeploymentStatus().getState();
1525        return (state == StateType.RUNNING || state == StateType.RELEASED);
1526    }
1527    public static boolean hasFailed(ProgressObject po) {
1528        StateType state = po.getDeploymentStatus().getState();
1529        return (state == StateType.FAILED);
1530    }
1531    
1532    // StateListener ----------------------------------------------------------
1533

1534    /** Listener that allows to listen to server state changes */
1535    public static interface StateListener {
1536        void stateChanged(int oldState, int newState);
1537    }
1538    
1539    public void addStateListener(StateListener sl) {
1540        synchronized (stateListeners) {
1541            stateListeners.add(sl);
1542        }
1543    }
1544    
1545    public void removeStateListener(StateListener sl) {
1546        synchronized (stateListeners) {
1547            stateListeners.remove(sl);
1548        }
1549    }
1550    
1551    private void fireStateChanged(int oldState, int newState) {
1552        StateListener[] listeners;
1553        synchronized (stateListeners) {
1554            listeners = (StateListener[])stateListeners.toArray(new StateListener[stateListeners.size()]);
1555        }
1556        for (int i = 0; i < listeners.length; i++) {
1557            listeners[i].stateChanged(oldState, newState);
1558        }
1559    }
1560    
1561    // private helper classes & methods ---------------------------------------
1562

1563    private static class ConflictData {
1564        private ServerInstance si;
1565        private ServerDebugInfo sdi;
1566        
1567        public ConflictData(ServerInstance si, ServerDebugInfo sdi) {
1568            this.si = si;
1569            this.sdi = sdi;
1570        }
1571        
1572        public ServerInstance getServerInstance() {
1573            return si;
1574        }
1575        
1576        public ServerDebugInfo getServerDebugInfo() {
1577            return sdi;
1578        }
1579    };
1580    
1581    /** Safe true/false test useful. */
1582    private abstract static class SafeTrueTest implements Runnable JavaDoc {
1583        protected boolean result = false;
1584        
1585        public abstract void run();
1586        
1587        public final boolean result() {
1588            return result;
1589        }
1590    };
1591    
1592    /** Return the result of the test or false if the given time-out ran out. */
1593    private boolean safeTrueTest(SafeTrueTest test, int timeout) {
1594        try {
1595           new RequestProcessor().post(test).waitFinished(timeout);
1596        } catch (InterruptedException JavaDoc ie) {
1597            ErrorManager.getDefault().notify(ie);
1598        } finally {
1599            return test.result();
1600        }
1601    }
1602    
1603    private synchronized boolean hasCommandSucceeded() {
1604        return commandSucceed;
1605    }
1606    private synchronized void setCommandSucceeded(boolean val) {
1607        commandSucceed = val;
1608    }
1609    
1610    private ServerDebugInfo _retrieveDebugInfo(Target target) {
1611        StartServer ss = getStartServer();
1612        if (ss == null) {
1613            return null;
1614        }
1615        
1616        Target t = _retrieveTarget(target);
1617        ServerDebugInfo sdi = ss.getDebugInfo(t);
1618        
1619        if (sdi != null || t != null) {
1620            debugInfo.remove(t);
1621            debugInfo.put(t, sdi);//cache debug info for given target
1622
}
1623        
1624        return sdi;
1625    }
1626    
1627    private Target _retrieveTarget(Target target) {
1628        StartServer ss = getStartServer();
1629        if (ss == null) {
1630            return null;
1631        }
1632        
1633        Target t = null;
1634        
1635        // Getting targets from AS8.1 requires start server which would hang UI, so avoid start server
1636
if (! isReallyRunning() && ss.needsStartForTargetList()) {
1637            if (t == null) {
1638                for (Iterator it = debugInfo.keySet().iterator(); t == null && it.hasNext(); ) {
1639                    Target cachedTarget = (Target) it.next();
1640                    if (ss.isAlsoTargetServer(cachedTarget)) {
1641                        t = cachedTarget;
1642                    }
1643                }
1644            } else {
1645                if (ss.isAlsoTargetServer(target))
1646                    t = target;
1647            }
1648        } else {
1649            ServerTarget[] targets = getTargets();
1650            for (int i = 0; t == null && i < targets.length; i++) {
1651                if (ss.isAlsoTargetServer(targets[i].getTarget())) {
1652                    t = targets[i].getTarget();
1653                }
1654            }
1655            
1656            if (t == null && targets.length > 0) {
1657                t = targets[0].getTarget();
1658            }
1659        }
1660        
1661        return t;
1662    }
1663
1664    public int compareTo(Object JavaDoc other) {
1665        if (!(other instanceof ServerInstance)) {
1666            throw new IllegalArgumentException JavaDoc();
1667        }
1668        return getDisplayName().compareTo(((ServerInstance)other).getDisplayName());
1669    }
1670    
1671    /** Take for example myhost.xyz.org and return myhost */
1672    private String JavaDoc stripHostName(String JavaDoc host) {
1673        if (host == null) {
1674            return null;
1675        }
1676        int idx = host.indexOf('.');
1677        return idx != -1 ? host.substring(0, idx) : host;
1678    }
1679    
1680    /** DebugStatusListener listens to debugger state changes and calls refresh()
1681     * if needed. If the debugger stops at a breakpoint, the server status will
1682     * thus change to suspended, etc. */

1683    private class DebuggerStateListener extends DebuggerManagerAdapter {
1684            
1685            private RequestProcessor.Task refreshTask;
1686            
1687            public void sessionAdded(Session session) {
1688                Target target = _retrieveTarget(null);
1689                ServerDebugInfo sdi = getServerDebugInfo(target);
1690                if (sdi == null) {
1691                    ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "DebuggerInfo cannot be found for: " + ServerInstance.this);
1692                    return; // give it up
1693
}
1694                AttachingDICookie attCookie = (AttachingDICookie)session.lookupFirst(null, AttachingDICookie.class);
1695                if (attCookie == null) {
1696                    ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "AttachingDICookie cannot be found for: " + ServerInstance.this);
1697                    return; // give it up
1698
}
1699                if (ServerDebugInfo.TRANSPORT_SHMEM.equals(sdi.getTransport())) {
1700                    String JavaDoc shmem = attCookie.getSharedMemoryName();
1701                    if (shmem != null && shmem.equalsIgnoreCase(sdi.getShmemName())) {
1702                        registerListener(session);
1703                    }
1704                } else {
1705                    String JavaDoc host = stripHostName(attCookie.getHostName());
1706                    if (host != null && host.equalsIgnoreCase(stripHostName(sdi.getHost()))) {
1707                        if (attCookie.getPortNumber() == sdi.getPort()) {
1708                            registerListener(session);
1709                        }
1710                    }
1711                }
1712            }
1713            
1714            public synchronized void sessionRemoved(Session session) {
1715                refreshTask = null;
1716            }
1717            
1718            private void registerListener(Session session) {
1719                final JPDADebugger jpda = (JPDADebugger)session.lookupFirst(null, JPDADebugger.class);
1720                if (jpda != null) {
1721                    jpda.addPropertyChangeListener(JPDADebugger.PROP_STATE, new PropertyChangeListener JavaDoc() {
1722                        public void propertyChange(PropertyChangeEvent JavaDoc evt) {
1723                            RequestProcessor.Task task;
1724                            synchronized (DebuggerStateListener.this) {
1725                                if (refreshTask == null) {
1726                                    refreshTask = RequestProcessor.getDefault().create(new Runnable JavaDoc() {
1727                                        public void run() {
1728                                            if (jpda.getState() == JPDADebugger.STATE_STOPPED) {
1729                                                setServerState(ServerInstance.STATE_SUSPENDED);
1730                                            } else {
1731                                                setServerState(ServerInstance.STATE_DEBUGGING);
1732                                            }
1733                                        }
1734                                    });
1735                                }
1736                                task = refreshTask;
1737                            }
1738                            // group fast arriving refresh calls
1739
task.schedule(500);
1740                        }
1741                    });
1742                }
1743            }
1744        }
1745}
1746
Popular Tags