001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.tools;
007:
008: //#ifdef AWT
009: import java.awt.Button;
010: import java.awt.Dimension;
011: import java.awt.Font;
012: import java.awt.Frame;
013: import java.awt.GraphicsEnvironment;
014: import java.awt.GridBagConstraints;
015: import java.awt.GridBagLayout;
016: import java.awt.Image;
017: import java.awt.Insets;
018: import java.awt.Label;
019: import java.awt.MenuItem;
020: import java.awt.Panel;
021: import java.awt.PopupMenu;
022: import java.awt.SystemColor;
023: import java.awt.TextField;
024: import java.awt.Toolkit;
025: import java.awt.event.ActionEvent;
026: import java.awt.event.ActionListener;
027: import java.awt.event.MouseEvent;
028: import java.awt.event.MouseListener;
029: import java.awt.event.WindowAdapter;
030: import java.awt.event.WindowEvent;
031: import org.h2.util.IOUtils;
032:
033: import java.io.IOException;
034: import java.io.InputStream; //#endif
035: import java.sql.SQLException;
036:
037: import org.h2.constant.SysProperties;
038: import org.h2.server.ShutdownHandler;
039: import org.h2.util.StartBrowser;
040:
041: /**
042: * This tool starts the H2 Console (web-) server, as well as the TCP and PG
043: * server. For JDK 1.6, a system tray icon is created, for platforms that
044: * support it. Otherwise, a small window opens.
045: *
046: * @author Thomas Mueller, Ridvan Agar
047: */
048: public class Console implements
049: //#ifdef AWT
050: ActionListener, MouseListener,
051: //#endif
052: ShutdownHandler {
053:
054: //#ifdef AWT
055: private Font font;
056: private Image icon16, icon24;
057: private Frame frame;
058: private Button startBrowser;
059: //#endif
060: private static final int EXIT_ERROR = 1;
061: private Server web, tcp, pg;
062: private boolean isWindows;
063:
064: /**
065: * The command line interface for this tool.
066: * The command line options are the same as in the Server tool,
067: * but this tool will always start the TCP, TCP and PG server.
068: * Options are case sensitive.
069: *
070: * @param args the command line arguments
071: * @throws Exception
072: */
073: public static void main(String[] args) throws Exception {
074: int exitCode = new Console().run(args);
075: if (exitCode != 0) {
076: System.exit(exitCode);
077: }
078: }
079:
080: private int run(String[] args) {
081: isWindows = SysProperties.getStringSetting("os.name", "")
082: .startsWith("Windows");
083: int exitCode = 0;
084: try {
085: web = Server.createWebServer(args);
086: web.setShutdownHandler(this );
087: web.start();
088: } catch (SQLException e) {
089: if (web == null) {
090: e.printStackTrace();
091: } else {
092: System.out.println(web.getStatus());
093: }
094: }
095: try {
096: tcp = Server.createTcpServer(args);
097: tcp.start();
098: } catch (SQLException e) {
099: if (tcp == null) {
100: e.printStackTrace();
101: } else {
102: System.out.println(tcp.getStatus());
103: }
104: }
105: try {
106: pg = Server.createPgServer(args);
107: pg.start();
108: } catch (SQLException e) {
109: if (pg == null) {
110: e.printStackTrace();
111: } else {
112: System.out.println(pg.getStatus());
113: }
114: }
115: //#ifdef AWT
116: if (!GraphicsEnvironment.isHeadless()) {
117: if (isWindows) {
118: font = new Font("Dialog", Font.PLAIN, 11);
119: } else {
120: font = new Font("Dialog", Font.PLAIN, 12);
121: }
122: try {
123: icon16 = loadImage("/org/h2/res/h2.png");
124: icon24 = loadImage("/org/h2/res/h2b.png");
125: if (!createTrayIcon()) {
126: showWindow(true);
127: }
128: } catch (Exception e) {
129: e.printStackTrace();
130: }
131: }
132: //#endif
133:
134: // start browser anyway (even if the server is already running)
135: // because some people don't look at the output,
136: // but are wondering why nothing happens
137: StartBrowser.openURL(web.getURL());
138: if (!web.isRunning()) {
139: exitCode = EXIT_ERROR;
140: }
141: return exitCode;
142: }
143:
144: private Image loadImage(String name) throws IOException {
145: InputStream in = Console.class.getResourceAsStream(name);
146: if (in != null) {
147: byte[] imageData = IOUtils.readBytesAndClose(in, -1);
148: return Toolkit.getDefaultToolkit().createImage(imageData);
149: }
150: return null;
151: }
152:
153: /**
154: * INTERNAL
155: */
156: public void shutdown() {
157: stopAll();
158: }
159:
160: private void stopAll() {
161: if (web != null && web.isRunning()) {
162: web.stop();
163: web = null;
164: }
165: if (tcp != null && tcp.isRunning()) {
166: tcp.stop();
167: tcp = null;
168: }
169: if (pg != null && pg.isRunning()) {
170: pg.stop();
171: pg = null;
172: }
173: //#ifdef AWT
174: if (frame != null) {
175: frame.dispose();
176: frame = null;
177: }
178: //#endif
179: System.exit(0);
180: }
181:
182: //#ifdef AWT
183: private boolean createTrayIcon() {
184: try {
185: // SystemTray.isSupported();
186: Boolean supported = (Boolean) Class.forName(
187: "java.awt.SystemTray").getMethod("isSupported",
188: new Class[0]).invoke(null, new Object[0]);
189:
190: if (!supported.booleanValue()) {
191: return false;
192: }
193:
194: PopupMenu menuConsole = new PopupMenu();
195: MenuItem itemConsole = new MenuItem("H2 Console");
196: itemConsole.setActionCommand("console");
197: itemConsole.addActionListener(this );
198: itemConsole.setFont(font);
199: menuConsole.add(itemConsole);
200: MenuItem itemStatus = new MenuItem("Status");
201: itemStatus.setActionCommand("status");
202: itemStatus.addActionListener(this );
203: itemStatus.setFont(font);
204: menuConsole.add(itemStatus);
205: MenuItem itemExit = new MenuItem("Exit");
206: itemExit.setFont(font);
207: itemExit.setActionCommand("exit");
208: itemExit.addActionListener(this );
209: menuConsole.add(itemExit);
210:
211: // SystemTray tray = SystemTray.getSystemTray();
212: Object tray = Class.forName("java.awt.SystemTray")
213: .getMethod("getSystemTray", new Class[0]).invoke(
214: null, new Object[0]);
215:
216: // Dimension d = tray.getTrayIconSize();
217: Dimension d = (Dimension) Class.forName(
218: "java.awt.SystemTray").getMethod("getTrayIconSize",
219: new Class[0]).invoke(tray, new Object[0]);
220:
221: Image icon = (d.width >= 24 && d.height >= 24) ? icon24
222: : icon16;
223:
224: // TrayIcon icon = new TrayIcon(image, "H2 Database Engine", menuConsole);
225: Object trayIcon = Class.forName("java.awt.TrayIcon")
226: .getConstructor(
227: new Class[] { Image.class, String.class,
228: PopupMenu.class }).newInstance(
229: new Object[] { icon, "H2 Database Engine",
230: menuConsole });
231:
232: // trayIcon.addMouseListener(this);
233: trayIcon.getClass().getMethod("addMouseListener",
234: new Class[] { MouseListener.class }).invoke(
235: trayIcon, new Object[] { this });
236:
237: // tray.add(icon);
238: tray.getClass().getMethod("add",
239: new Class[] { Class.forName("java.awt.TrayIcon") })
240: .invoke(tray, new Object[] { trayIcon });
241:
242: return true;
243: } catch (Exception e) {
244: return false;
245: }
246: }
247:
248: private void showWindow(final boolean exit) {
249: frame = new Frame("H2 Console");
250: frame.addWindowListener(new WindowAdapter() {
251: public void windowClosing(WindowEvent we) {
252: if (exit) {
253: stopAll();
254: } else {
255: frame.dispose();
256: }
257: }
258: });
259: if (icon16 != null) {
260: frame.setIconImage(icon16);
261: }
262: frame.setResizable(false);
263: frame.setBackground(SystemColor.control);
264:
265: GridBagLayout layout = new GridBagLayout();
266: frame.setLayout(layout);
267:
268: // the main panel keeps everything together
269: Panel mainPanel = new Panel(layout);
270:
271: GridBagConstraints constraintsPanel = new GridBagConstraints();
272: constraintsPanel.gridx = 0;
273: constraintsPanel.weightx = 1.0D;
274: constraintsPanel.weighty = 1.0D;
275: constraintsPanel.fill = GridBagConstraints.BOTH;
276: constraintsPanel.insets = new Insets(0, 10, 0, 10);
277: constraintsPanel.gridy = 0;
278:
279: GridBagConstraints constraintsButton = new GridBagConstraints();
280: constraintsButton.gridx = 0;
281: constraintsButton.gridwidth = 2;
282: constraintsButton.insets = new Insets(10, 0, 0, 0);
283: constraintsButton.gridy = 1;
284: constraintsButton.anchor = GridBagConstraints.EAST;
285:
286: GridBagConstraints constraintsTextField = new GridBagConstraints();
287: constraintsTextField.fill = GridBagConstraints.HORIZONTAL;
288: constraintsTextField.gridy = 0;
289: constraintsTextField.weightx = 1.0;
290: constraintsTextField.insets = new Insets(0, 5, 0, 0);
291: constraintsTextField.gridx = 1;
292:
293: GridBagConstraints constraintsLabel = new GridBagConstraints();
294: constraintsLabel.gridx = 0;
295: constraintsLabel.gridy = 0;
296:
297: Label label = new Label("H2 Console URL:", Label.LEFT);
298: label.setFont(font);
299: mainPanel.add(label, constraintsLabel);
300:
301: TextField text = new TextField();
302: text.setEditable(false);
303: text.setFont(font);
304: text.setText(web.getURL());
305: if (isWindows) {
306: text.setFocusable(false);
307: }
308: mainPanel.add(text, constraintsTextField);
309:
310: startBrowser = new Button("Start Browser");
311: startBrowser.setFocusable(false);
312: startBrowser.setActionCommand("console");
313: startBrowser.addActionListener(this );
314: startBrowser.setFont(font);
315: mainPanel.add(startBrowser, constraintsButton);
316: frame.add(mainPanel, constraintsPanel);
317:
318: int width = 300, height = 120;
319: frame.setSize(width, height);
320: Dimension screenSize = Toolkit.getDefaultToolkit()
321: .getScreenSize();
322: frame.setLocation((screenSize.width - width) / 2,
323: (screenSize.height - height) / 2);
324: try {
325: frame.setVisible(true);
326: } catch (Throwable t) {
327: // ignore
328: // some systems don't support this method, for example IKVM
329: // however it still works
330: }
331: }
332:
333: private void startBrowser() {
334: if (web != null) {
335: StartBrowser.openURL(web.getURL());
336: }
337: }
338:
339: //#endif
340:
341: /**
342: * INTERNAL
343: */
344: //#ifdef AWT
345: public void actionPerformed(ActionEvent e) {
346: String command = e.getActionCommand();
347: if ("exit".equals(command)) {
348: stopAll();
349: } else if ("console".equals(command)) {
350: startBrowser();
351: } else if ("status".equals(command)) {
352: showWindow(false);
353: } else if (startBrowser == e.getSource()) {
354: // for some reason, IKVM ignores setActionCommand
355: startBrowser();
356: }
357: }
358:
359: //#endif
360:
361: /**
362: * INTERNAL
363: */
364: //#ifdef AWT
365: public void mouseClicked(MouseEvent e) {
366: if (e.getButton() == MouseEvent.BUTTON1) {
367: startBrowser();
368: }
369: }
370:
371: //#endif
372:
373: /**
374: * INTERNAL
375: */
376: //#ifdef AWT
377: public void mouseEntered(MouseEvent e) {
378: }
379:
380: //#endif
381:
382: /**
383: * INTERNAL
384: */
385: //#ifdef AWT
386: public void mouseExited(MouseEvent e) {
387: }
388:
389: //#endif
390:
391: /**
392: * INTERNAL
393: */
394: //#ifdef AWT
395: public void mousePressed(MouseEvent e) {
396: }
397:
398: //#endif
399:
400: /**
401: * INTERNAL
402: */
403: //#ifdef AWT
404: public void mouseReleased(MouseEvent e) {
405: }
406: //#endif
407:
408: }
|