diff --git a/src/java/davmail/AbstractConnection.java b/src/java/davmail/AbstractConnection.java index 3c0ba6ea..05fc16c0 100644 --- a/src/java/davmail/AbstractConnection.java +++ b/src/java/davmail/AbstractConnection.java @@ -12,8 +12,8 @@ import java.net.Socket; * Generic connection common to pop3 and smtp implementations */ public class AbstractConnection extends Thread { - protected Socket client; + protected BufferedReader in; protected OutputStream os; // user name and password initialized through connection @@ -26,7 +26,7 @@ public class AbstractConnection extends Thread { // Initialize the streams and start the thread public AbstractConnection(Socket clientSocket) { - client = clientSocket; + this.client = clientSocket; try { in = new BufferedReader(new InputStreamReader(client.getInputStream())); os = client.getOutputStream(); @@ -34,7 +34,7 @@ public class AbstractConnection extends Thread { try { client.close(); } catch (IOException e2) { - DavGatewayTray.error("Exception while getting socket streams", e2); + DavGatewayTray.warn("Exception closing client socket", e2); } DavGatewayTray.error("Exception while getting socket streams", e); return; diff --git a/src/java/davmail/AbstractServer.java b/src/java/davmail/AbstractServer.java index 138bb0c3..abdddb84 100644 --- a/src/java/davmail/AbstractServer.java +++ b/src/java/davmail/AbstractServer.java @@ -15,8 +15,12 @@ public abstract class AbstractServer extends Thread { * Create a ServerSocket to listen for connections. * Start the thread. */ - public AbstractServer(int port) { - this.port = port; + public AbstractServer(int port, int defaultPort) { + if (port == 0) { + this.port = defaultPort; + } else { + this.port = port; + } try { //noinspection SocketOpenedButNotSafelyClosed serverSocket = new ServerSocket(port); @@ -56,7 +60,7 @@ public abstract class AbstractServer extends Thread { clientSocket.close(); } } catch (IOException e) { - // ignore + DavGatewayTray.warn("Exception closing client socket", e); } } } diff --git a/src/java/davmail/DavGateway.java b/src/java/davmail/DavGateway.java index 49e85184..383f306c 100644 --- a/src/java/davmail/DavGateway.java +++ b/src/java/davmail/DavGateway.java @@ -7,11 +7,15 @@ import davmail.smtp.SmtpServer; * DavGateway main class */ public class DavGateway { - protected static SmtpServer smtpServer; - protected static PopServer popServer; + protected DavGateway() { + } + + private static SmtpServer smtpServer; + private static PopServer popServer; /** * Start the gateway, listen on spécified smtp and pop3 ports + * * @param args command line parameter config file path */ public static void main(String[] args) { diff --git a/src/java/davmail/DavGatewayTray.java b/src/java/davmail/DavGatewayTray.java index 19633022..be6de551 100644 --- a/src/java/davmail/DavGatewayTray.java +++ b/src/java/davmail/DavGatewayTray.java @@ -1,191 +1,193 @@ -package davmail; - -import org.apache.log4j.Logger; -import org.apache.log4j.Priority; -import org.apache.log4j.lf5.LF5Appender; -import org.apache.log4j.lf5.LogLevel; -import org.apache.log4j.lf5.viewer.LogBrokerMonitor; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.net.URL; - -/** - * Tray icon handler - */ -public class DavGatewayTray { - protected static final Logger logger = Logger.getLogger("davmail"); - - // lock for synchronized block - protected static final Object lock = new Object(); - - protected static TrayIcon trayIcon = null; - protected static Image image = null; - protected static Image image2 = null; - - public static void switchIcon() { - try { - synchronized (lock) { - if (trayIcon.getImage() == image) { - trayIcon.setImage(image2); - } else { - trayIcon.setImage(image); - } - } - } catch (NoClassDefFoundError e) { - // ignore, jdk <= 1.6 - } - - } - - public static void resetIcon() { - try { - synchronized (lock) { - trayIcon.setImage(image); - } - } catch (NoClassDefFoundError e) { - // ignore, jdk <= 1.6 - } - } - - protected static void displayMessage(String message, Priority priority) { - synchronized (lock) { - if (trayIcon != null) { - TrayIcon.MessageType messageType = null; - if (priority == Priority.INFO) { - messageType = TrayIcon.MessageType.INFO; - } else if (priority == Priority.WARN) { - messageType = TrayIcon.MessageType.WARNING; - } else if (priority == Priority.ERROR) { - messageType = TrayIcon.MessageType.ERROR; - } - if (messageType != null) { - trayIcon.displayMessage("DavMail gateway", message, messageType); - } - trayIcon.setToolTip("DavMail gateway \n" + message); - } - logger.log(priority, message); - } - - } - - public static void debug(String message) { - displayMessage(message, Priority.DEBUG); - } - - public static void info(String message) { - displayMessage(message, Priority.INFO); - } - - public static void warn(String message) { - displayMessage(message, Priority.WARN); - } - - public static void error(String message) { - displayMessage(message, Priority.ERROR); - } - - public static void debug(String message, Exception e) { - debug(message + " " + e + " " + e.getMessage()); - } - - public static void info(String message, Exception e) { - info(message + " " + e + " " + e.getMessage()); - } - - public static void warn(String message, Exception e) { - warn(message + " " + e + " " + e.getMessage()); - } - - public static void error(String message, Exception e) { - error(message + " " + e + " " + e.getMessage()); - } - - public static void init() { - try { - if (SystemTray.isSupported()) { - // set native look and feel - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } - catch (Exception e) { - // ignore - } - - // get the SystemTray instance - SystemTray tray = SystemTray.getSystemTray(); - // load an image - ClassLoader classloader = DavGatewayTray.class.getClassLoader(); - URL imageUrl = classloader.getResource("tray.png"); - image = Toolkit.getDefaultToolkit().getImage(imageUrl); - URL imageUrl2 = classloader.getResource("tray2.png"); - image2 = Toolkit.getDefaultToolkit().getImage(imageUrl2); - // create a popup menu - PopupMenu popup = new PopupMenu(); - final SettingsFrame settingsFrame = new SettingsFrame(); - settingsFrame.setIconImage(image); - // create an action settingsListener to listen for settings action executed on the tray icon - ActionListener settingsListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - settingsFrame.setVisible(true); - } - }; - // create menu item for the default action - MenuItem defaultItem = new MenuItem("Settings..."); - defaultItem.addActionListener(settingsListener); - popup.add(defaultItem); - - MenuItem logItem = new MenuItem("Show logs..."); - logItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - Logger rootLogger = Logger.getRootLogger(); - LF5Appender lf5Appender = (LF5Appender) rootLogger.getAppender("LF5Appender"); - if (lf5Appender == null) { - lf5Appender = new LF5Appender(new LogBrokerMonitor(LogLevel.getLog4JLevels()) { - protected void closeAfterConfirm() { - hide(); - } - }); - lf5Appender.setName("LF5Appender"); - rootLogger.addAppender(lf5Appender); - } - lf5Appender.getLogBrokerMonitor().show(); - } - }); - popup.add(logItem); - - // create an action exitListener to listen for exit action executed on the tray icon - ActionListener exitListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - SystemTray.getSystemTray().remove(trayIcon); - //noinspection CallToSystemExit - System.exit(0); - } - }; - // create menu item for the exit action - MenuItem exitItem = new MenuItem("Exit"); - exitItem.addActionListener(exitListener); - popup.add(exitItem); - - /// ... add other items - // construct a TrayIcon - trayIcon = new TrayIcon(image, "DavMail Gateway", popup); - // set the TrayIcon properties - trayIcon.addActionListener(settingsListener); - // ... - // add the tray image - try { - tray.add(trayIcon); - } catch (AWTException e) { - System.err.println(e); - } - } - - } catch (NoClassDefFoundError e) { - DavGatewayTray.warn("JDK 1.6 needed for system tray support"); - } - - } -} +package davmail; + +import org.apache.log4j.Logger; +import org.apache.log4j.Priority; +import org.apache.log4j.lf5.LF5Appender; +import org.apache.log4j.lf5.LogLevel; +import org.apache.log4j.lf5.viewer.LogBrokerMonitor; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.net.URL; + +/** + * Tray icon handler + */ +public class DavGatewayTray { + protected DavGatewayTray() { + } + + protected static final Logger LOGGER = Logger.getLogger("davmail"); + + // LOCK for synchronized block + protected static final Object LOCK = new Object(); + + private static TrayIcon trayIcon = null; + private static Image image = null; + private static Image image2 = null; + + public static void switchIcon() { + try { + synchronized (LOCK) { + if (trayIcon.getImage() == image) { + trayIcon.setImage(image2); + } else { + trayIcon.setImage(image); + } + } + } catch (NoClassDefFoundError e) { + LOGGER.debug("JDK not at least 1.6, tray not supported"); + } + + } + + public static void resetIcon() { + try { + synchronized (LOCK) { + trayIcon.setImage(image); + } + } catch (NoClassDefFoundError e) { + LOGGER.debug("JDK not at least 1.6, tray not supported"); + } + } + + protected static void displayMessage(String message, Priority priority) { + synchronized (LOCK) { + if (trayIcon != null) { + TrayIcon.MessageType messageType = null; + if (priority == Priority.INFO) { + messageType = TrayIcon.MessageType.INFO; + } else if (priority == Priority.WARN) { + messageType = TrayIcon.MessageType.WARNING; + } else if (priority == Priority.ERROR) { + messageType = TrayIcon.MessageType.ERROR; + } + if (messageType != null) { + trayIcon.displayMessage("DavMail gateway", message, messageType); + } + trayIcon.setToolTip("DavMail gateway \n" + message); + } + LOGGER.log(priority, message); + } + + } + + public static void debug(String message) { + displayMessage(message, Priority.DEBUG); + } + + public static void info(String message) { + displayMessage(message, Priority.INFO); + } + + public static void warn(String message) { + displayMessage(message, Priority.WARN); + } + + public static void error(String message) { + displayMessage(message, Priority.ERROR); + } + + public static void debug(String message, Exception e) { + debug(message + " " + e + " " + e.getMessage()); + } + + public static void info(String message, Exception e) { + info(message + " " + e + " " + e.getMessage()); + } + + public static void warn(String message, Exception e) { + warn(message + " " + e + " " + e.getMessage()); + } + + public static void error(String message, Exception e) { + error(message + " " + e + " " + e.getMessage()); + } + + public static void init() { + try { + if (SystemTray.isSupported()) { + // set native look and feel + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + LOGGER.warn("Unable to set system look and feel"); + } + + // get the SystemTray instance + SystemTray tray = SystemTray.getSystemTray(); + // load an image + ClassLoader classloader = DavGatewayTray.class.getClassLoader(); + URL imageUrl = classloader.getResource("tray.png"); + image = Toolkit.getDefaultToolkit().getImage(imageUrl); + URL imageUrl2 = classloader.getResource("tray2.png"); + image2 = Toolkit.getDefaultToolkit().getImage(imageUrl2); + // create a popup menu + PopupMenu popup = new PopupMenu(); + final SettingsFrame settingsFrame = new SettingsFrame(); + settingsFrame.setIconImage(image); + // create an action settingsListener to listen for settings action executed on the tray icon + ActionListener settingsListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + settingsFrame.setVisible(true); + } + }; + // create menu item for the default action + MenuItem defaultItem = new MenuItem("Settings..."); + defaultItem.addActionListener(settingsListener); + popup.add(defaultItem); + + MenuItem logItem = new MenuItem("Show logs..."); + logItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Logger rootLogger = Logger.getRootLogger(); + LF5Appender lf5Appender = (LF5Appender) rootLogger.getAppender("LF5Appender"); + if (lf5Appender == null) { + lf5Appender = new LF5Appender(new LogBrokerMonitor(LogLevel.getLog4JLevels()) { + protected void closeAfterConfirm() { + hide(); + } + }); + lf5Appender.setName("LF5Appender"); + rootLogger.addAppender(lf5Appender); + } + lf5Appender.getLogBrokerMonitor().show(); + } + }); + popup.add(logItem); + + // create an action exitListener to listen for exit action executed on the tray icon + ActionListener exitListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + SystemTray.getSystemTray().remove(trayIcon); + //noinspection CallToSystemExit + System.exit(0); + } + }; + // create menu item for the exit action + MenuItem exitItem = new MenuItem("Exit"); + exitItem.addActionListener(exitListener); + popup.add(exitItem); + + /// ... add other items + // construct a TrayIcon + trayIcon = new TrayIcon(image, "DavMail Gateway", popup); + // set the TrayIcon properties + trayIcon.addActionListener(settingsListener); + // ... + // add the tray image + try { + tray.add(trayIcon); + } catch (AWTException e) { + System.err.println(e); + } + } + + } catch (NoClassDefFoundError e) { + DavGatewayTray.warn("JDK 1.6 needed for system tray support"); + } + + } +} diff --git a/src/java/davmail/Settings.java b/src/java/davmail/Settings.java index 8c1057c0..390a8452 100644 --- a/src/java/davmail/Settings.java +++ b/src/java/davmail/Settings.java @@ -10,59 +10,83 @@ import java.io.IOException; * Settings facade */ public class Settings { - protected static final Properties settings = new Properties(); - protected static String configFilePath; + protected Settings() { + } + + private static final Properties SETTINGS = new Properties(); + private static String configFilePath; public static synchronized void setConfigFilePath(String value) { configFilePath = value; } public static synchronized void load() { + FileReader fileReader = null; try { if (configFilePath == null) { + //noinspection AccessOfSystemProperties configFilePath = System.getProperty("user.home") + "/.davmail.properties"; } File configFile = new File(configFilePath); if (configFile.exists()) { - settings.load(new FileReader(configFile)); + fileReader = new FileReader(configFile); + SETTINGS.load(fileReader); } else { - settings.put("davmail.url", "http://exchangeServer/exchange/"); - settings.put("davmail.popPort", "110"); - settings.put("davmail.smtpPort", "25"); - settings.put("davmail.keepDelay", "30"); - settings.put("davmail.enableProxy", "false"); - settings.put("davmail.proxyHost", ""); - settings.put("davmail.proxyPort", ""); - settings.put("davmail.proxyUser", ""); - settings.put("davmail.proxyPassword", ""); + SETTINGS.put("davmail.url", "http://exchangeServer/exchange/"); + SETTINGS.put("davmail.popPort", "110"); + SETTINGS.put("davmail.smtpPort", "25"); + SETTINGS.put("davmail.keepDelay", "30"); + SETTINGS.put("davmail.enableProxy", "false"); + SETTINGS.put("davmail.proxyHost", ""); + SETTINGS.put("davmail.proxyPort", ""); + SETTINGS.put("davmail.proxyUser", ""); + SETTINGS.put("davmail.proxyPassword", ""); save(); } } catch (IOException e) { DavGatewayTray.error("Unable to load settings: ", e); + } finally { + if (fileReader != null) { + try { + fileReader.close(); + } catch (IOException e) { + DavGatewayTray.debug("Error closing configuration file: ", e); + } + } } } public static synchronized void save() { + FileWriter fileWriter = null; try { - settings.store(new FileWriter(configFilePath), "DavMail settings"); + fileWriter = new FileWriter(configFilePath); + SETTINGS.store(fileWriter, "DavMail settings"); } catch (IOException e) { DavGatewayTray.error("Unable to store settings: ", e); + } finally { + if (fileWriter != null) { + try { + fileWriter.close(); + } catch (IOException e) { + DavGatewayTray.debug("Error closing configuration file: ", e); + } + } } } public static synchronized String getProperty(String property) { - return settings.getProperty(property); + return SETTINGS.getProperty(property); } public static synchronized void setProperty(String property, String value) { - settings.setProperty(property, value); + SETTINGS.setProperty(property, value); } public static synchronized int getIntProperty(String property) { int value = 0; try { - String propertyValue = settings.getProperty(property); + String propertyValue = SETTINGS.getProperty(property); if (propertyValue != null && propertyValue.length() > 0) { value = Integer.valueOf(propertyValue); } diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 8b81c7a3..616a6ca3 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -776,7 +776,11 @@ public class ExchangeSession { int parsedAttachmentIndex = 0; try { parsedAttachmentIndex = Integer.parseInt(attachmentName); - } catch (Exception e) {/* ignore */} + } catch (Exception e) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Current attachment name " + attachmentName + " is not an index", e); + } + } if (parsedAttachmentIndex == 0) { Attachment attachment = attachmentsMap.get(attachmentName); String attachmentContentType = getAttachmentContentType(attachment.href); @@ -819,7 +823,7 @@ public class ExchangeSession { try { reader.close(); } catch (IOException e) { - // ignore + LOGGER.warn("Error closing header reader", e); } } } @@ -856,7 +860,7 @@ public class ExchangeSession { try { reader.close(); } catch (IOException e) { - // ignore + LOGGER.warn("Error closing header reader", e); } } } @@ -887,9 +891,8 @@ public class ExchangeSession { && partHeader.contentType.startsWith("multipart") && partHeader.boundary != null) { writeMimeMessage(reader, os, partHeader); - } - // body part - else if (attachmentIndex <= 0) { + } else if (attachmentIndex <= 0) { + // body part attachmentIndex++; writeBody(os, partHeader); } else { @@ -990,7 +993,7 @@ public class ExchangeSession { try { bis.close(); } catch (IOException e) { - // ignore + LOGGER.warn("Error closing message input stream", e); } } } @@ -1086,10 +1089,10 @@ public class ExchangeSession { } */ wdr.moveMethod(messageUrl, destination); - if (wdr.getStatusCode() == 412) { + if (wdr.getStatusCode() == HttpURLConnection.HTTP_PRECON_FAILED) { int count = 2; // name conflict, try another name - while (wdr.getStatusCode() == 412) { + while (wdr.getStatusCode() == HttpURLConnection.HTTP_PRECON_FAILED) { wdr.moveMethod(messageUrl, destination.substring(0, destination.lastIndexOf('.')) + "-" + count++ + ".eml"); } } @@ -1117,7 +1120,7 @@ public class ExchangeSession { try { reader.close(); } catch (IOException e) { - // ignore + LOGGER.warn("Error closing header reader", e); } } } @@ -1133,7 +1136,7 @@ public class ExchangeSession { public boolean isConnectionCloseForced() { // force connection if attachment not found - return getStatusCode() == 404; + return getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND; } } @@ -1146,7 +1149,7 @@ public class ExchangeSession { ConnectionCloseHeadMethod method = new ConnectionCloseHeadMethod(URIUtil.encodePathQuery(decodedPath)); wdr.retrieveSessionInstance().executeMethod(method); - if (method.getStatusCode() == 404) { + if (method.getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { method.releaseConnection(); System.err.println("Unable to retrieve attachment"); } @@ -1203,7 +1206,7 @@ public class ExchangeSession { GetMethod getMethod = new GetMethod(URIUtil.encodePathQuery(messageUrl + "?Cmd=Open&unfiltered=1")); wdr.retrieveSessionInstance().executeMethod(getMethod); - if (getMethod.getStatusCode() != 200) { + if (getMethod.getStatusCode() != HttpURLConnection.HTTP_OK) { throw new IOException("Unable to get attachments: " + getMethod.getStatusCode() + " " + getMethod.getStatusLine()); } diff --git a/src/java/davmail/imap/ImapServer.java b/src/java/davmail/imap/ImapServer.java index f7075bda..30c1edcb 100644 --- a/src/java/davmail/imap/ImapServer.java +++ b/src/java/davmail/imap/ImapServer.java @@ -9,14 +9,14 @@ import davmail.AbstractServer; * Pop3 server */ public class ImapServer extends AbstractServer { - public final static int DEFAULT_PORT = 143; + public static final int DEFAULT_PORT = 143; /** * Create a ServerSocket to listen for connections. * Start the thread. */ public ImapServer(int port) { - super((port == 0) ? ImapServer.DEFAULT_PORT : port); + super(port, ImapServer.DEFAULT_PORT); } public void createConnectionHandler(Socket clientSocket) { diff --git a/src/java/davmail/pop/PopServer.java b/src/java/davmail/pop/PopServer.java index b2588c1e..003c5199 100644 --- a/src/java/davmail/pop/PopServer.java +++ b/src/java/davmail/pop/PopServer.java @@ -17,7 +17,7 @@ public class PopServer extends AbstractServer { * @param port pop listen port, 110 if not defined (0) */ public PopServer(int port) { - super((port == 0) ? PopServer.DEFAULT_PORT : port); + super(port, PopServer.DEFAULT_PORT); } public void createConnectionHandler(Socket clientSocket) { diff --git a/src/java/davmail/smtp/SmtpServer.java b/src/java/davmail/smtp/SmtpServer.java index f7433182..12632bb1 100644 --- a/src/java/davmail/smtp/SmtpServer.java +++ b/src/java/davmail/smtp/SmtpServer.java @@ -12,7 +12,7 @@ public class SmtpServer extends AbstractServer { * Start the thread. */ public SmtpServer(int port) { - super((port == 0) ? SmtpServer.DEFAULT_PORT : port); + super(port, SmtpServer.DEFAULT_PORT); } public void createConnectionHandler(Socket clientSocket) { diff --git a/src/test/davmail/exchange/TestExchangeSession.java b/src/test/davmail/exchange/TestExchangeSession.java index 626bc47e..6593b4c1 100644 --- a/src/test/davmail/exchange/TestExchangeSession.java +++ b/src/test/davmail/exchange/TestExchangeSession.java @@ -7,25 +7,30 @@ import org.apache.commons.httpclient.util.URIUtil; * */ public class TestExchangeSession { + + protected TestExchangeSession() { + } + public static void main(String[] argv) { - Settings.setConfigFilePath(argv[0]); + int currentArg = 0; + Settings.setConfigFilePath(argv[currentArg++]); Settings.load(); ExchangeSession session = new ExchangeSession(); // test auth try { ExchangeSession.checkConfig(); - session.login(argv[1], argv[2]); + session.login(argv[currentArg++], argv[currentArg++]); - ExchangeSession.Folder folder = session.selectFolder(argv[3]); + ExchangeSession.Folder folder = session.selectFolder(argv[currentArg++]); String messageName; - messageName = URIUtil.decode(argv[4]); + messageName = URIUtil.decode(argv[currentArg]); long startTime = System.currentTimeMillis(); - ExchangeSession.Message messageTest = session.getMessage(folder.folderUrl+"/"+messageName); + ExchangeSession.Message messageTest = session.getMessage(folder.folderUrl + "/" + messageName); System.out.println("******"); messageTest.write(System.out); - System.out.println("Elapsed time " + (System.currentTimeMillis()-startTime) + " ms"); + System.out.println("Elapsed time " + (System.currentTimeMillis() - startTime) + " ms"); session.purgeOldestTrashMessages();