KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > terracotta > dso > ServerTracker


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package org.terracotta.dso;
5
6 import org.eclipse.core.resources.IProject;
7 import org.eclipse.core.runtime.CoreException;
8 import org.eclipse.core.runtime.IProgressMonitor;
9 import org.eclipse.core.runtime.QualifiedName;
10 import org.eclipse.debug.core.DebugEvent;
11 import org.eclipse.debug.core.DebugException;
12 import org.eclipse.debug.core.DebugPlugin;
13 import org.eclipse.debug.core.IDebugEventSetListener;
14 import org.eclipse.debug.core.ILaunch;
15 import org.eclipse.debug.core.model.IProcess;
16 import org.eclipse.jdt.core.IJavaProject;
17 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
18 import org.eclipse.jface.operation.IRunnableWithProgress;
19 import org.eclipse.swt.widgets.Shell;
20 import org.eclipse.ui.IWorkbench;
21 import org.eclipse.ui.IWorkbenchWindow;
22 import org.eclipse.ui.PlatformUI;
23 import org.terracotta.dso.decorator.ServerRunningDecorator;
24
25 import com.tc.admin.TCStop;
26
27 import java.lang.reflect.InvocationTargetException JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30
31 /**
32  * Used to start a server using the project's config information.
33  * Listens for user-initiated termination requests and shuts down the
34  * associated server.
35  *
36  * A JavaProject can only have a single server running at one time. A mapping
37  * is maintained (m_server) between the IProcess and a ServerInfo. ServerInfo
38  * contains the IJavaProject and the JMX port of the running server. The JMX port
39  * is used for stopping the server and it's done this way to because otherwise
40  * we must rely on the configuration, which the user can change.
41  *
42  * @see TcPlugin.launchServer
43  */

44
45 public class ServerTracker {
46   private static ServerTracker m_instance = new ServerTracker();
47   private HashMap JavaDoc<IProcess, ServerInfo> m_servers = new HashMap JavaDoc<IProcess, ServerInfo>();
48  
49   /**
50    * This name is used in plugin.xml for managing the start/stop menu items.
51    */

52   private static final QualifiedName SERVER_RUNNING_NAME =
53     new QualifiedName("org.terracotta.dso", "ServerRunning");
54
55   private ServerTracker() {
56     super();
57   }
58
59   public static synchronized ServerTracker getDefault() {
60     if(m_instance == null) {
61       m_instance = new ServerTracker();
62     }
63
64     return m_instance;
65   }
66     
67   private IDebugEventSetListener listener = new IDebugEventSetListener() {
68     public void handleDebugEvents(DebugEvent[] events) {
69       if(events != null && events.length > 0) {
70         if(events[0].getKind() == DebugEvent.TERMINATE) {
71           Object JavaDoc source = events[0].getSource();
72   
73           if(source instanceof IProcess) {
74             ServerInfo serverInfo = m_servers.get(source);
75   
76             if(serverInfo != null) {
77               m_servers.remove(source);
78               setRunning(serverInfo.getJavaProject(), null);
79             }
80           }
81         }
82       }
83     }
84   };
85
86   public boolean anyRunning(IJavaProject javaProj) {
87     try {
88       return javaProj.getProject().getSessionProperty(SERVER_RUNNING_NAME) != null;
89     } catch(CoreException ce) {
90       return false;
91     }
92   }
93     
94   public boolean isRunning(IJavaProject javaProj, String JavaDoc name) {
95     if(anyRunning(javaProj)) {
96       Iterator JavaDoc iter = m_servers.keySet().iterator();
97       IProcess proc;
98       ServerInfo serverInfo;
99       String JavaDoc serverName;
100       
101       while(iter.hasNext()) {
102         proc = (IProcess)iter.next();
103         serverInfo = m_servers.get(proc);
104         serverName = serverInfo.getName();
105
106         if(name.equals(serverName)) {
107           return true;
108         }
109       }
110     }
111     
112     return false;
113   }
114   
115   public void setRunning(IJavaProject javaProj, Boolean JavaDoc value) {
116     if(value != null && value.equals(Boolean.FALSE)) {
117       value = null;
118     }
119
120     IProject project = javaProj.getProject();
121     
122     if(project.isOpen()) {
123       try {
124         project.setSessionProperty(SERVER_RUNNING_NAME, value);
125         ServerRunningDecorator.updateDecorators();
126       } catch(CoreException ce) {/**/}
127     }
128   }
129
130   public void startServer(IJavaProject javaProject, String JavaDoc name)
131     throws CoreException
132   {
133     if(isRunning(javaProject, name)) {
134       internalStopServer(javaProject, true, name);
135     }
136     else {
137       internalStartServer(javaProject, name);
138     }
139   }
140
141   private void internalStartServer(IJavaProject javaProject, String JavaDoc name)
142     throws CoreException
143   {
144     TcPlugin plugin = TcPlugin.getDefault();
145     String JavaDoc projName = javaProject.getElementName();
146     int jmxPort = plugin.getJmxPort(javaProject.getProject(), name);
147     ILaunch launch = plugin.launchServer(javaProject, projName, name);
148     ServerInfo info = new ServerInfo(javaProject, name, jmxPort != 0 ? jmxPort : 9520);
149     
150     m_servers.put(launch.getProcesses()[0], info);
151     
152     DebugPlugin.getDefault().addDebugEventListener(listener);
153     setRunning(javaProject, Boolean.TRUE);
154   }
155
156   public void cancelServer(IJavaProject javaProject) {
157     Iterator JavaDoc iter = m_servers.keySet().iterator();
158     IProcess proc;
159     ServerInfo info;
160
161     while(iter.hasNext()) {
162       proc = (IProcess)iter.next();
163       info = m_servers.get(proc);
164       
165       if(info.getJavaProject().equals(javaProject)) {
166         try {
167           proc.terminate();
168         } catch(DebugException de) {
169           iter.remove();
170         }
171       }
172     }
173   }
174   
175   public void stopServer(IJavaProject javaProject) {
176     internalStopServer(javaProject, false, null);
177   }
178  
179   public void stopServer(IJavaProject javaProject, String JavaDoc name) {
180     internalStopServer(javaProject, false, name);
181   }
182
183   private void internalStopServer(IJavaProject javaProject, boolean restart, String JavaDoc name) {
184     IWorkbench workbench = PlatformUI.getWorkbench();
185     IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
186     Shell shell = window != null ? window.getShell() : null;
187   
188     try {
189       IRunnableWithProgress op = new TCStopper(javaProject, restart, name);
190       new ProgressMonitorDialog(shell).run(true, false, op);
191     } catch(InvocationTargetException JavaDoc e) {
192       TcPlugin.getDefault().openError("Cannot stop Terracotta server", e.getCause());
193     } catch(InterruptedException JavaDoc e) {/**/}
194   }
195   
196   class TCStopper implements IRunnableWithProgress {
197     IJavaProject m_javaProject;
198     boolean m_restart;
199     String JavaDoc m_name;
200     
201     TCStopper(IJavaProject javaProject) {
202       this(javaProject, false, null);
203     }
204     
205     TCStopper(IJavaProject javaProject, boolean restart, String JavaDoc name) {
206       m_javaProject = javaProject;
207       m_restart = restart;
208       m_name = name;
209     }
210     
211     public void run(IProgressMonitor monitor)
212       throws InvocationTargetException JavaDoc
213     {
214       try {
215         monitor.beginTask("Stopping Terracotta Server...", IProgressMonitor.UNKNOWN);
216         doStopServer(m_javaProject, m_name, monitor);
217         if(m_restart) {
218           internalStartServer(m_javaProject, m_name);
219         }
220       } catch(Exception JavaDoc e) {
221         throw new InvocationTargetException JavaDoc(e);
222       }
223     }
224   }
225       
226   private void doStopServer(IJavaProject targetProj, String JavaDoc targetName, IProgressMonitor monitor) {
227     Iterator JavaDoc iter = m_servers.keySet().iterator();
228     IProcess proc;
229     ServerInfo serverInfo;
230     IJavaProject javaProject;
231     int jmxPort;
232     String JavaDoc name;
233     
234     while(iter.hasNext()) {
235       proc = (IProcess)iter.next();
236       serverInfo = m_servers.get(proc);
237       javaProject = serverInfo.getJavaProject();
238       jmxPort = serverInfo.getJmxPort();
239       name = serverInfo.getName();
240       
241       if(javaProject.getProject().isOpen() &&
242          targetProj.equals(javaProject) &&
243          targetName.equals(name))
244       {
245         TCStop stopper = new TCStop("localhost", jmxPort != -1 ? jmxPort : 9520);
246         
247         try {
248           stopper.stop();
249           
250           int count = 0;
251           while(true) {
252             try {
253               proc.getExitValue();
254               iter.remove();
255               return;
256             } catch(DebugException de) {
257               try {
258                 if(count++ == 6) {
259                   proc.terminate();
260                   iter.remove();
261                   return;
262                 }
263                 Thread.sleep(1000);
264               } catch(InterruptedException JavaDoc ie) {/**/}
265             }
266           }
267         } catch(Exception JavaDoc e) {
268           return;
269         }
270       }
271     }
272   }
273     
274   public void shutdownAllServers() {
275     Iterator JavaDoc iter = m_servers.values().iterator();
276     ServerInfo info;
277     
278     while(iter.hasNext()) {
279       info = (ServerInfo)iter.next();
280       cancelServer(info.getJavaProject());
281     }
282   }
283 }
284
285 /**
286  *
287  * When an L2 is started, one of these is associated with the resulting
288  * IProcess via the m_servers map.
289  */

290 class ServerInfo {
291   IJavaProject m_javaProject;
292   int m_jmxPort;
293   String JavaDoc m_name;
294   
295   ServerInfo(IJavaProject javaProject, String JavaDoc name, int jmxPort) {
296     m_javaProject = javaProject;
297     m_name = name;
298     m_jmxPort = jmxPort;
299   }
300   
301   IJavaProject getJavaProject() {
302     return m_javaProject;
303   }
304   
305   String JavaDoc getName() {
306     return m_name;
307   }
308   
309   int getJmxPort() {
310     return m_jmxPort;
311   }
312   
313   public String JavaDoc toString() {
314     return m_name+":"+m_jmxPort;
315   }
316 }
Popular Tags