KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > standalone > EclipseController


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.help.internal.standalone;
12
13 import java.io.*;
14 import java.net.*;
15 import java.nio.channels.*;
16
17 /**
18  * This program is used to start or stop Eclipse Infocenter application. It
19  * should be launched from command line.
20  */

21 public class EclipseController implements EclipseLifeCycleListener {
22     public static final String JavaDoc CMD_INSTALL = "install"; //$NON-NLS-1$
23

24     public static final String JavaDoc CMD_UPDATE = "update"; //$NON-NLS-1$
25

26     public static final String JavaDoc CMD_ENABLE = "enable"; //$NON-NLS-1$
27

28     public static final String JavaDoc CMD_DISABLE = "disable"; //$NON-NLS-1$
29

30     public static final String JavaDoc CMD_UNINSTALL = "uninstall"; //$NON-NLS-1$
31

32     public static final String JavaDoc CMD_SEARCH = "search"; //$NON-NLS-1$
33

34     public static final String JavaDoc CMD_LIST = "listFeatures"; //$NON-NLS-1$
35

36     public static final String JavaDoc CMD_ADDSITE = "addSite"; //$NON-NLS-1$
37

38     public static final String JavaDoc CMD_REMOVESITE = "removeSite"; //$NON-NLS-1$
39

40     public static final String JavaDoc CMD_APPLY = "apply"; //$NON-NLS-1$
41

42     // control servlet path
43
private static final String JavaDoc CONTROL_SERVLET_PATH = "/help/control"; //$NON-NLS-1$
44

45     // application to launch
46
protected String JavaDoc applicationId;
47
48     // Eclipse connection params
49
protected EclipseConnection connection;
50
51     public Eclipse eclipse = null;
52
53     // Inter process lock
54
private FileLock lock;
55
56     private boolean eclipseEnded = false;
57
58     /**
59      * Constructs help system
60      *
61      * @param applicationId
62      * ID of Eclipse help application
63      * @param args
64      * array of String options and their values Option
65      * <code>-eclipseHome dir</code> specifies Eclipse installation
66      * directory. It must be provided, when current directory is not
67      * the same as Eclipse installation directory. Additionally, most
68      * options accepted by Eclipse execuable are supported.
69      */

70     public EclipseController(String JavaDoc applicationId, String JavaDoc[] args) {
71
72         this.applicationId = applicationId;
73         Options.init(applicationId, args);
74         connection = new EclipseConnection();
75     }
76
77     /**
78      * @see org.eclipse.help.standalone.Help#shutdown()
79      */

80     public final synchronized void shutdown() throws Exception JavaDoc {
81         try {
82             obtainLock();
83             sendHelpCommandInternal("shutdown", new String JavaDoc[0]); //$NON-NLS-1$
84
} catch (MalformedURLException mue) {
85             mue.printStackTrace();
86         } catch (InterruptedException JavaDoc ie) {
87         } finally {
88             releaseLock();
89         }
90     }
91
92     /**
93      * @see org.eclipse.help.standalone.Help#start()
94      */

95     public final synchronized void start() throws Exception JavaDoc {
96         try {
97             obtainLock();
98             startEclipse();
99         } finally {
100             releaseLock();
101         }
102
103     }
104
105     /**
106      * Ensures the application is running, and sends command to the control
107      * servlet. If connection fails, retries several times, in case webapp is
108      * starting up.
109      */

110     protected final synchronized void sendHelpCommand(String JavaDoc command,
111             String JavaDoc[] parameters) throws Exception JavaDoc {
112         try {
113             obtainLock();
114             sendHelpCommandInternal(command, parameters);
115         } finally {
116             releaseLock();
117         }
118
119     }
120
121     /**
122      * Starts Eclipse if not yet running.
123      */

124     private void startEclipse() throws Exception JavaDoc {
125         boolean fullyRunning = isApplicationRunning();
126         if (fullyRunning) {
127             return;
128         }
129         if (Options.isDebug()) {
130             System.out
131                     .println("Using workspace " + Options.getWorkspace().getAbsolutePath()); //$NON-NLS-1$
132
}
133         // delete old connection file
134
Options.getConnectionFile().delete();
135         connection.reset();
136
137         if (Options.isDebug()) {
138             System.out
139                     .println("Ensured old .connection file is deleted. Launching Eclipse."); //$NON-NLS-1$
140
}
141         eclipseEnded = false;
142         eclipse = new Eclipse(this);
143         eclipse.start();
144         fullyRunning = isApplicationRunning();
145         while (!eclipseEnded && !fullyRunning) {
146             try {
147                 Thread.sleep(250);
148             } catch (InterruptedException JavaDoc ie) {
149             }
150             fullyRunning = isApplicationRunning();
151         }
152         if (eclipseEnded) {
153             if (eclipse.getStatus() == Eclipse.STATUS_ERROR) {
154                 throw eclipse.getException();
155             }
156             return;
157         }
158         if (Options.isDebug()) {
159             System.out.println("Eclipse launched"); //$NON-NLS-1$
160
}
161         // in case controller is killed
162
Runtime.getRuntime().addShutdownHook(new EclipseCleaner());
163     }
164
165     private void sendHelpCommandInternal(String JavaDoc command, String JavaDoc[] parameters)
166             throws Exception JavaDoc {
167         if (!"shutdown".equalsIgnoreCase(command)) { //$NON-NLS-1$
168
startEclipse();
169         }
170         if (!isApplicationRunning()) {
171             return;
172         }
173         if (!connection.isValid()) {
174             connection.renew();
175         }
176         try {
177             String JavaDoc trustStoreLocation = Options.getTrustStoreLocation();
178             if (trustStoreLocation != null) {
179                 System.setProperty("javax.net.ssl.trustStore", trustStoreLocation); //$NON-NLS-1$
180
}
181             String JavaDoc trustStorePassword = Options.getTrustStorePassword();
182             if (trustStorePassword != null) {
183                 System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword); //$NON-NLS-1$
184
}
185             URL url = createCommandURL(command, parameters);
186             if ("shutdown".equalsIgnoreCase(command) //$NON-NLS-1$
187
&& Options.getConnectionFile().exists()) {
188                 connection.connect(url);
189                 long timeLimit = System.currentTimeMillis() + 60 * 1000;
190                 while (Options.getConnectionFile().exists()) {
191                     Thread.sleep(200);
192                     if (System.currentTimeMillis() > timeLimit) {
193                         System.out
194                                 .println("Shutting down is taking too long. Will not wait."); //$NON-NLS-1$
195
break;
196                     }
197                 }
198
199             } else {
200                 connection.connect(url);
201             }
202         } catch (MalformedURLException mue) {
203             mue.printStackTrace();
204         } catch (InterruptedException JavaDoc ie) {
205         }
206     }
207
208     /**
209      * Builds a URL that communicates the specified command to help control
210      * servlet.
211      *
212      * @param command
213      * standalone help system command e.g. "displayHelp"
214      * @param parameters
215      * array of parameters of the command e.g.
216      * {"http://www.eclipse.org"}
217      */

218     private URL createCommandURL(String JavaDoc command, String JavaDoc[] parameters)
219             throws MalformedURLException {
220         StringBuffer JavaDoc urlStr = new StringBuffer JavaDoc();
221         urlStr.append("http://"); //$NON-NLS-1$
222
urlStr.append(connection.getHost());
223         urlStr.append(":"); //$NON-NLS-1$
224
urlStr.append(connection.getPort());
225         urlStr.append(CONTROL_SERVLET_PATH);
226         urlStr.append("?command="); //$NON-NLS-1$
227
urlStr.append(command);
228         for (int i = 0; i < parameters.length; i++) {
229             urlStr.append("&"); //$NON-NLS-1$
230
urlStr.append(parameters[i]);
231         }
232         if (Options.isDebug()) {
233             System.out.println("Control servlet URL=" + urlStr.toString()); //$NON-NLS-1$
234
}
235         return new URL(urlStr.toString());
236     }
237
238     public void eclipseEnded() {
239         eclipseEnded = true;
240         connection.reset();
241     }
242
243     private void obtainLock() throws IOException {
244         if (lock != null) {
245             // we already have lock
246
return;
247         }
248         if (!Options.getLockFile().exists()) {
249             Options.getLockFile().getParentFile().mkdirs();
250         }
251         RandomAccessFile raf = new RandomAccessFile(Options.getLockFile(), "rw"); //$NON-NLS-1$
252
lock = raf.getChannel().lock();
253         if (Options.isDebug()) {
254             System.out.println("Lock obtained."); //$NON-NLS-1$
255
}
256     }
257
258     private void releaseLock() {
259         if (lock != null) {
260             try {
261                 lock.channel().close();
262                 if (Options.isDebug()) {
263                     System.out.println("Lock released."); //$NON-NLS-1$
264
}
265                 lock = null;
266             } catch (IOException ioe) {
267             }
268         }
269     }
270
271     /**
272      * Tests whether HelpApplication is running by testing if .applicationlock
273      * is locked
274      */

275     private boolean isApplicationRunning() {
276         File applicationLockFile = new File(Options.getLockFile()
277                 .getParentFile(), ".applicationlock"); //$NON-NLS-1$
278
RandomAccessFile randomAccessFile = null;
279         FileLock applicationLock = null;
280         try {
281             randomAccessFile = new RandomAccessFile(applicationLockFile, "rw"); //$NON-NLS-1$
282
applicationLock = randomAccessFile.getChannel().tryLock();
283         } catch (IOException ioe) {
284         } finally {
285             if (applicationLock != null) {
286                 try {
287                     applicationLock.release();
288                 } catch (IOException ioe) {
289                 }
290             }
291             if (randomAccessFile != null) {
292                 try {
293                     randomAccessFile.close();
294                 } catch (IOException ioe) {
295                 }
296             }
297             if (Options.isDebug()) {
298                 System.out
299                         .println("isApplicationRunning? " + (applicationLock == null)); //$NON-NLS-1$
300
}
301         }
302         return applicationLock == null;
303     }
304
305     public class EclipseCleaner extends Thread JavaDoc {
306         public void run() {
307             if (eclipse != null) {
308                 eclipse.killProcess();
309             }
310         }
311     }
312
313     /**
314      * @return true if commands contained a known command and it was executed
315      */

316     protected boolean executeUpdateCommand(String JavaDoc updateCommand)
317             throws Exception JavaDoc {
318         String JavaDoc[] parameters = Options.getUpdateParameters();
319         sendHelpCommandInternal(updateCommand, parameters);
320         return true;
321     }
322 }
323
Popular Tags