View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2008 utgenome.org
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *--------------------------------------------------------------------------*/
16  //--------------------------------------
17  // utgb-shell Project
18  //
19  // UTGBPortable.java
20  // Since: Jan 30, 2008
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.shell;
26  
27  import java.awt.Dimension;
28  import java.awt.Toolkit;
29  import java.io.File;
30  import java.util.ArrayList;
31  import java.util.concurrent.ExecutorService;
32  import java.util.concurrent.Executors;
33  import java.util.concurrent.TimeUnit;
34  
35  import javax.swing.JFrame;
36  import javax.swing.SwingUtilities;
37  
38  import org.utgenome.shell.tomcat.TomcatServer;
39  import org.utgenome.shell.tomcat.TomcatServerConfiguration;
40  import org.xerial.core.XerialException;
41  import org.xerial.util.log.Logger;
42  import org.xerial.util.opt.OptionParser;
43  import org.xerial.util.opt.OptionParserException;
44  
45  /**
46   * The stand-alone UTGB server launcher
47   * 
48   * @author leo
49   * 
50   */
51  public class UTGBPortable implements TomcatServerLauncher {
52  
53  	private static Logger _logger = Logger.getLogger(UTGBPortable.class);
54  
55  	/**
56  	 * entry point of the UTGBServer
57  	 * 
58  	 * @param args
59  	 */
60  	public static void main(String[] args) {
61  		try {
62  			UTGBPortable server = new UTGBPortable(args);
63  			server.start();
64  		}
65  		catch (OptionParserException e) {
66  			_logger.error(e);
67  		}
68  		catch (Exception e) {
69  			_logger.error(e);
70  			e.printStackTrace(System.err);
71  		}
72  	}
73  
74  	// private ThreadManager threadManager = new ThreadManager();
75  	private ExecutorService threadPool = Executors.newFixedThreadPool(1);
76  
77  	private UTGBPortableConfig config = new UTGBPortableConfig();
78  	private OptionParser parser = new OptionParser(config);
79  
80  	/**
81  	 * Create an instance of the UTGBServer
82  	 * 
83  	 * @param args
84  	 *            command-line arguments
85  	 * @throws OptionParserException
86  	 */
87  	public UTGBPortable(String[] args) throws OptionParserException {
88  
89  		// parse the command-line arguments
90  		parser.parse(args);
91  	}
92  
93  	public UTGBPortable(UTGBPortableConfig config) {
94  		this.config = config;
95  	}
96  
97  	private ArrayList<ServerListener> listenerList = new ArrayList<ServerListener>();
98  
99  	public void addServerListener(ServerListener listener) {
100 		this.listenerList.add(listener);
101 	}
102 
103 	/**
104 	 * Starts the web server
105 	 * 
106 	 * @throws XerialException
107 	 */
108 	public void start() throws XerialException {
109 
110 		if (config.useGUI)
111 			runInGUIMode();
112 		else
113 			runInCUIMode();
114 
115 		try {
116 			while (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
117 			}
118 		}
119 		catch (InterruptedException e) {
120 			_logger.error(e);
121 			threadPool.shutdownNow();
122 		}
123 	}
124 
125 	public void start(int terminationTime, TimeUnit timeUnit) throws XerialException {
126 		// add a shutdown hook when JVM terminates or GUI window is closed
127 		Runtime.getRuntime().addShutdownHook(new Thread() {
128 			@Override
129 			public void run() {
130 				stopTomcatServer(config);
131 			}
132 		});
133 
134 		if (config.useGUI)
135 			runInGUIMode();
136 		else
137 			runInCUIMode();
138 
139 		threadPool.shutdownNow();
140 		try {
141 			while (!threadPool.awaitTermination(terminationTime, timeUnit)) {
142 			}
143 		}
144 		catch (InterruptedException e) {
145 
146 		}
147 		finally {
148 			threadPool.shutdownNow();
149 		}
150 	}
151 
152 	protected void runInGUIMode() {
153 		try {
154 			SwingUtilities.invokeAndWait(new Runnable() {
155 				public void run() {
156 					UTGBPortableWidget portableWidget = new UTGBPortableWidget(config);
157 					portableWidget.setTomcatServerLauncher(UTGBPortable.this);
158 					portableWidget.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
159 					Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
160 					portableWidget.setLocation((int) d.getWidth() / 4, (int) d.getHeight() / 4);
161 					portableWidget.setVisible(true);
162 					portableWidget.pushStart();
163 				}
164 			});
165 		}
166 		catch (Exception e) {
167 			_logger.error(e);
168 		}
169 
170 	}
171 
172 	protected void runInCUIMode() throws XerialException {
173 
174 		startTomcatServer(config);
175 
176 		// wait until Ctrl+C terminates the program
177 		try {
178 			while (!Thread.currentThread().isInterrupted()) {
179 				Thread.sleep(1000L);
180 			}
181 		}
182 		catch (InterruptedException e) {
183 			e.printStackTrace();
184 		}
185 	}
186 
187 	private static enum ServerStatus {
188 		STOPPED, STARTED
189 	}
190 
191 	private TomcatServer tomcatServer = null;
192 	private ServerStatus serverStatus = ServerStatus.STOPPED;
193 
194 	private class TomcatStarter implements Runnable {
195 		private UTGBPortableConfig config;
196 
197 		public TomcatStarter(UTGBPortableConfig config) {
198 			this.config = config;
199 			_logger.debug("tomcat starter: " + (SwingUtilities.isEventDispatchThread() ? "event dispatch thread" : "normal thread"));
200 		}
201 
202 		public void run() {
203 			try {
204 				// start the server
205 				for (ServerListener listener : listenerList)
206 					listener.beforeStart();
207 				_logger.debug("before start");
208 				tomcatServer.start();
209 				tomcatServer.addContext(config.contextPath, new File(config.projectRoot, config.workingDir).getAbsolutePath());
210 
211 				for (ServerListener listener : listenerList)
212 					listener.afterStart();
213 			}
214 			catch (Exception e) {
215 				e.printStackTrace();
216 			}
217 			finally {
218 				serverStatus = ServerStatus.STARTED;
219 			}
220 		}
221 	}
222 
223 	/**
224 	 * starts the Tomcat server
225 	 * 
226 	 * @throws XerialException
227 	 */
228 	public void startTomcatServer(UTGBPortableConfig utgbPortableConfig) throws XerialException {
229 		switch (serverStatus) {
230 		case STOPPED:
231 			// create a new instance of the TomcatServer
232 			TomcatServerConfiguration tomcatConfig = new TomcatServerConfiguration();
233 			// tomcatConfig.setCatalinaBase(utgbPortableConfig.workingDir);
234 			tomcatConfig.setPort(utgbPortableConfig.portNumber);
235 			tomcatServer = new TomcatServer(tomcatConfig);
236 
237 			_logger.debug(SwingUtilities.isEventDispatchThread() ? "event dispatch thread" : "normal thread");
238 			_logger.info("starting a Tomcat server: \n" + utgbPortableConfig.toString());
239 
240 			TomcatStarter starter = new TomcatStarter(utgbPortableConfig);
241 			threadPool.execute(starter);
242 			break;
243 		case STARTED:
244 			break;
245 		}
246 	}
247 
248 	/**
249 	 * stops the Tomcat server
250 	 */
251 	public void stopTomcatServer(UTGBPortableConfig config) {
252 		switch (serverStatus) {
253 		case STOPPED:
254 			break;
255 		case STARTED:
256 			try {
257 				for (ServerListener listener : listenerList)
258 					listener.beforeStop();
259 
260 				tomcatServer.stop();
261 				tomcatServer = null;
262 
263 				for (ServerListener listener : listenerList)
264 					listener.afterStop();
265 			}
266 			catch (XerialException e) {
267 				e.printStackTrace();
268 			}
269 			finally {
270 				serverStatus = ServerStatus.STOPPED;
271 			}
272 			break;
273 		}
274 	}
275 
276 }