View Javadoc
1   package com.nilhcem.fakesmtp;
2   
3   import java.awt.*;
4   import java.net.InetAddress;
5   import java.net.URL;
6   import java.net.UnknownHostException;
7   
8   import javax.swing.UIManager;
9   
10  import org.apache.commons.cli.ParseException;
11  import org.slf4j.Logger;
12  import org.slf4j.LoggerFactory;
13  
14  import com.apple.eawt.Application;
15  import com.nilhcem.fakesmtp.core.ArgsHandler;
16  import com.nilhcem.fakesmtp.core.Configuration;
17  import com.nilhcem.fakesmtp.core.exception.UncaughtExceptionHandler;
18  import com.nilhcem.fakesmtp.gui.MainFrame;
19  import com.nilhcem.fakesmtp.server.SMTPServerHandler;
20  
21  /**
22   * Entry point of the application.
23   *
24   * @author Nilhcem
25   * @since 1.0
26   */
27  public final class FakeSMTP {
28  	private static final Logger LOGGER = LoggerFactory.getLogger(FakeSMTP.class);
29  
30  	private FakeSMTP() {
31  		throw new UnsupportedOperationException();
32  	}
33  
34  	/**
35  	 * Checks command line arguments, sets some specific properties, and runs the main window.
36  	 * <p>
37  	 * Before opening the main window, this method will:
38       * </p>
39  	 * <ul>
40  	 *   <li>check command line arguments, and possibly display an error dialog,</li>
41  	 *   <li>set a default uncaught exception handler to intercept every uncaught exception;</li>
42  	 *   <li>use a custom icon in the Mac Dock;</li>
43  	 *   <li>set a property for Mac OS X to take the menu bar off the JFrame;</li>
44  	 *   <li>set a property for Mac OS X to set the name of the application menu item;</li>
45  	 *   <li>turn off the bold font in all components for swing default theme;</li>
46  	 *   <li>use the platform look and feel.</li>
47  	 * </ul>
48  	 *
49  	 * @param args a list of command line parameters.
50  	 */
51  	public static void main(final String[] args) {
52  		try {
53  			ArgsHandler.INSTANCE.handleArgs(args);
54  		} catch (ParseException e) {
55  			ArgsHandler.INSTANCE.displayUsage();
56  			return;
57  		}
58  
59  		if (ArgsHandler.INSTANCE.shouldStartInBackground()) {
60  			try {
61  				SMTPServerHandler.INSTANCE.startServer(getPort(), getBindAddress());
62  			} catch (NumberFormatException e) {
63  				LOGGER.error("Error: Invalid port number", e);
64  			} catch (UnknownHostException e) {
65  				LOGGER.error("Error: Invalid bind address", e);
66  			} catch (Exception e) {
67  				LOGGER.error("Failed to auto-start server in background", e);
68  			}
69  		} else {
70              System.setProperty("mail.mime.decodetext.strict", "false");
71              Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler());
72  
73              EventQueue.invokeLater(new Runnable() {
74  				@Override
75  				public void run() {
76  					try {
77  						URL iconUrl = getClass().getResource(Configuration.INSTANCE.get("application.icon.path"));
78  						if (iconUrl != null && !GraphicsEnvironment.isHeadless() && Taskbar.isTaskbarSupported()) {
79  							Image img = Toolkit.getDefaultToolkit().getImage(iconUrl);
80  							Taskbar taskbar = Taskbar.getTaskbar();
81  							if (taskbar.isSupported(Taskbar.Feature.ICON_IMAGE)) {
82  								taskbar.setIconImage(img);   // works on macOS Dock, Windows taskbar, many Linux DEs
83  							}
84  						}
85  					} catch (RuntimeException e) {
86  						LOGGER.debug("Error: {} - This is probably because we run on a non-Mac platform and these components are not implemented", e.getMessage());
87  					} catch (Exception e) {
88  						LOGGER.error("", e);
89  					}
90  
91  					System.setProperty("apple.laf.useScreenMenuBar", "true");
92  					System.setProperty("com.apple.mrj.application.apple.menu.about.name", Configuration.INSTANCE.get("application.name"));
93  					UIManager.put("swing.boldMetal", Boolean.FALSE);
94  					try {
95  						UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
96  					} catch (Exception e) {
97  						LOGGER.error("", e);
98  					}
99  
100 					new MainFrame();
101 				}
102 			});
103 		}
104 	}
105 
106 	/**
107 	 * @return either the default port, or the custom port, if specified.
108 	 * @throws NumberFormatException if the specified port cannot be parsed to an integer.
109 	 */
110 	private static int getPort() throws NumberFormatException {
111 		String portStr = ArgsHandler.INSTANCE.getPort();
112 		if (portStr == null) {
113 			portStr = Configuration.INSTANCE.get("smtp.default.port");
114 		}
115 		return Integer.parseInt(portStr);
116 	}
117 
118 	/**
119 	 * @return an InetAddress representing the specified bind address, or null, if not specified
120 	 * @throws UnknownHostException if the bind address is invalid
121 	 */
122 	private static InetAddress getBindAddress() throws UnknownHostException {
123 		String bindAddressStr = ArgsHandler.INSTANCE.getBindAddress();
124 		if (bindAddressStr == null || bindAddressStr.isEmpty()) {
125 			return null;
126 		}
127 		return InetAddress.getByName(bindAddressStr);
128 	}
129 }