/* * Copyright 2012 jMethods, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.myjavaworld.jftp; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Frame; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import java.util.TreeMap; import javax.swing.JMenuBar; import javax.swing.JTabbedPane; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.myjavaworld.ftp.FTPClient; import com.myjavaworld.ftp.FTPConstants; import com.myjavaworld.ftp.RemoteFile; import com.myjavaworld.gui.GUIUtil; import com.myjavaworld.gui.LicenseAgreementDlg; import com.myjavaworld.gui.MFrame; import com.myjavaworld.jftp.ssl.CertificateManagerDlg; import com.myjavaworld.util.Filter; import com.myjavaworld.util.ResourceLoader; /** * The main window that contains various menu items, tool bar and manages * various FTP sessions. * * @author Sai Pullabhotla, psai [at] jMethods [dot] com * @version 2.0 */ public class JFTP extends MFrame implements WindowListener, ActionListener, ChangeListener { private static ResourceBundle resources = null; public static final File USER_HOME = new File( System.getProperty("user.home")); public static final File DATA_HOME = new File(USER_HOME, ".jftp" + File.separator + "data"); private static final Map THEMES; private static final Map PARSERS; private static final Map CLIENTS; private static Map transferTypes = null; public static JFTPPreferences prefs; static { // Create Hashmap of all themes. We could actually load these // from an external file if we want to. THEMES = new TreeMap(); THEMES.put("Default", "com.myjavaworld.gui.DefaultTheme"); THEMES.put("Default - Large", "com.myjavaworld.gui.DefaultLargeTheme"); THEMES.put("Green", "com.myjavaworld.gui.GreenMetalTheme"); THEMES.put("Green - Large", "com.myjavaworld.gui.GreenMetalLargeTheme"); THEMES.put("Sandstone", "com.myjavaworld.gui.SandstoneTheme"); THEMES.put("Sandstone - Large", "com.myjavaworld.gui.SandstoneLargeTheme"); THEMES.put("High Contrast", "com.myjavaworld.gui.HighContrastTheme"); THEMES.put("High Contrast - Large", "com.myjavaworld.gui.HighContrastLargeTheme"); // Create a Hashmap of all FTP client implementations CLIENTS = new TreeMap(); CLIENTS.put("Default FTP Client", "com.myjavaworld.ftp.DefaultFTPClient"); CLIENTS.put("AS/400 FTP Client", "com.myjavaworld.ftp.AS400FTPClient"); // Create a Hashmap of all FTP list parsers PARSERS = new TreeMap(); PARSERS.put("Default List Parser (Unix)", "com.myjavaworld.ftp.DefaultListParser"); PARSERS.put("MS-DOS List Parser", "com.myjavaworld.ftp.DosListParser"); try { prefs = loadPreferences(); transferTypes = prefs.getTransferTypes(); JFTPUtil.updateProxySettings(); } catch (IOException exp) { System.err .println("Failed to load the preferences. Using Defaults. "); } } private JFTPToolBar toolBar = null; private JTabbedPane tabs = null; private boolean applet = false; /** * Creates an instance of JFTP, the main window and the central point for * the software. */ public JFTP() { this(false); } public JFTP(boolean applet) { super(JFTPConstants.PRODUCT_NAME); this.applet = applet; if (resources == null) { if (resources == null) { resources = ResourceLoader .getBundle("com.myjavaworld.jftp.JFTP"); } } setIconImage(JFTPUtil.getImage("jftp16.gif")); // showLicenseAgreement(); getContentPane().setLayout(new BorderLayout(0, 0)); setJMenuBar(prepareMenuBar()); addWindowListener(this); setBounds(getPreferredBounds()); tabs = new JTabbedPane(JTabbedPane.SCROLL_TAB_LAYOUT); tabs.addChangeListener(this); toolBar = new JFTPToolBar(this); getContentPane().add(toolBar, BorderLayout.NORTH); getContentPane().add(tabs, BorderLayout.CENTER); } /** * Creates a new FTP session */ public void newSession() { FTPSession session = new FTPSession(this); String title = resources.getString("text.notConnected"); tabs.addTab(title, session); tabs.setSelectedComponent(session); } public void windowOpened(WindowEvent evt) { if (prefs.getWindowBounds() == null) { setExtendedState(Frame.MAXIMIZED_BOTH); } if (prefs.getCheckForUpdates()) { AutoUpdater updater = new AutoUpdater(this, true, false); updater.start(); } } public void windowActivated(WindowEvent evt) { } public void windowDeactivated(WindowEvent evt) { } public void windowIconified(WindowEvent evt) { } public void windowDeiconified(WindowEvent evt) { } public void windowClosing(WindowEvent evt) { exit(); } public void windowClosed(WindowEvent evt) { } public void stateChanged(ChangeEvent evt) { updateToolBar(); } public void closeSession() { FTPSession session = (FTPSession) tabs.getSelectedComponent(); if (session != null) { session.closeSession(); tabs.remove(session); } } /** * Closes JFTP */ public void exit() { int sessionCount = tabs.getTabCount(); for (int i = 0; i < sessionCount; i++) { FTPSession session = (FTPSession) tabs.getComponentAt(i); session.closeSession(); } Rectangle windowBounds = getBounds(); prefs.setWindowBounds(windowBounds); try { savePreferences(prefs); } catch (Exception exp) { // Ignore this. } dispose(); System.gc(); if (!applet) { System.exit(0); } } public void actionPerformed(ActionEvent evt) { String command = evt.getActionCommand(); if (command.equals("cmd.closeSession")) { closeSession(); } else if (command.equals("cmd.exit")) { exit(); } else if (command.equals("cmd.refreshLocalPane")) { FTPSession session = getCurrentSession(); if (session != null) { session.refreshLocalPane(); } } else if (command.equals("cmd.refreshRemotePane")) { FTPSession session = getCurrentSession(); if (session != null) { session.refreshRemotePane(); } } else if (command.equals("cmd.manageCertificates")) { manageCertificates(); } else if (command.equals("cmd.addToFavorites")) { addToFavorites(); } else if (command.equals("cmd.preferences")) { showPreferencesDialog(); } else if (command.equals("cmd.newSession")) { newSession(); } else if (command.equals("cmd.transferType.autoDetect")) { FTPSession session = getCurrentSession(); if (session != null) { session.setAutoDetect(true); } } else if (command.equals("cmd.transferType.ascii")) { FTPSession session = getCurrentSession(); if (session != null) { session.setAutoDetect(false); session.setTransferType(FTPConstants.TYPE_ASCII); } } else if (command.equals("cmd.transferType.binary")) { FTPSession session = getCurrentSession(); if (session != null) { session.setAutoDetect(false); session.setTransferType(FTPConstants.TYPE_BINARY); } } else if (command.equals("cmd.help")) { executeCommand("HELP"); } else if (command.equals("cmd.stat")) { executeCommand("STAT"); } else if (command.equals("cmd.syst")) { executeCommand("SYST"); } else if (command.equals("cmd.noop")) { executeCommand("NOOP"); } else if (command.equals("cmd.other")) { executeCustomCommand(); } else if (command.equals("cmd.remoteFileProperties")) { showRemoteFileProperties(); } else if (command.equals("cmd.localFileProperties")) { showLocalFileProperties(); } else if (command.equals("cmd.applyLocalFileFilter")) { showLocalFileFilter(); } else if (command.equals("cmd.clearLocalFileFilter")) { clearLocalFileFilter(); } else if (command.equals("cmd.applyRemoteFileFilter")) { showRemoteFileFilter(); } else if (command.equals("cmd.clearRemoteFileFilter")) { clearRemoteFileFilter(); } else if (command.equals("cmd.localSelectAll")) { selectAllLocalFiles(); } else if (command.equals("cmd.localInvertSelection")) { invertLocalFileSelection(); } else if (command.equals("cmd.remoteSelectAll")) { selectAllRemoteFiles(); } else if (command.equals("cmd.remoteInvertSelection")) { invertRemoteFileSelection(); } } private void executeCustomCommand() { FTPSession session = getCurrentSession(); if (session == null || !session.isConnected()) { return; } ExecuteCommandDlg dlg = new ExecuteCommandDlg(this); dlg.setLocationRelativeTo(this); dlg.setVisible(true); String[] commands = dlg.getCommands(); dlg.dispose(); if (commands == null) { return; } session.executeCommands(commands); } private void executeCommand(String command) { FTPSession session = getCurrentSession(); if (session == null || !session.isConnected()) { return; } session.executeCommand(command); } private void manageCertificates() { CertificateManagerDlg dlg = new CertificateManagerDlg(this); dlg.setLocationRelativeTo(this); dlg.setVisible(true); dlg.dispose(); } private void showRemoteFileProperties() { FTPSession session = getCurrentSession(); if (session == null || !session.isConnected()) { return; } RemoteFile selectedFile = session.getSelectedRemoteFile(); if (selectedFile == null) { return; } FTPClient client = session.getFTPClient(); RemoteFilePropertiesDlg dlg = new RemoteFilePropertiesDlg(this, client, selectedFile, session.getRemoteFileFilter()); dlg.setLocationRelativeTo(this); dlg.setVisible(true); RemoteFile newFile = dlg.getFile(); dlg.dispose(); if (newFile != null) { session.changeRemoteFilePermissions(selectedFile, newFile, dlg.isRecursive()); } } private void showLocalFileProperties() { FTPSession session = getCurrentSession(); if (session == null) { return; } LocalFile selectedFile = session.getSelectedLocalFile(); if (selectedFile == null) { return; } LocalFilePropertiesDlg dlg = new LocalFilePropertiesDlg(this, selectedFile, session.getLocalFileFilter()); dlg.setLocationRelativeTo(this); dlg.setVisible(true); dlg.dispose(); } private void showLocalFileFilter() { FTPSession session = getCurrentSession(); if (session == null) { return; } LocalFileFilterDlg dlg = new LocalFileFilterDlg(this); dlg.setFilter(session.getLocalFileFilter()); dlg.setLocationRelativeTo(this); dlg.setVisible(true); Filter filter = dlg.getFilter(); dlg.dispose(); if (filter != null) { session.setLocalFileFilter(filter); } } private void clearLocalFileFilter() { FTPSession session = getCurrentSession(); if (session == null) { return; } session.setLocalFileFilter(null); } private void showRemoteFileFilter() { FTPSession session = getCurrentSession(); if (session == null) { return; } RemoteFileFilterDlg dlg = new RemoteFileFilterDlg(this); dlg.setFilter(session.getRemoteFileFilter()); dlg.setLocationRelativeTo(this); dlg.setVisible(true); Filter filter = dlg.getFilter(); dlg.dispose(); if (filter != null) { session.setRemoteFileFilter(filter); } } private void clearRemoteFileFilter() { FTPSession session = getCurrentSession(); if (session == null) { return; } session.setRemoteFileFilter(null); } private void addToFavorites() { FTPSession session = getCurrentSession(); if (session == null || !session.isConnected()) { return; } RemoteHost host = session.getRemoteHost(); Favorite favorite = new Favorite(); favorite.setName(host.getName()); favorite.setHostName(host.getHostName()); favorite.setPort(host.getPort()); favorite.setUser(host.getUser()); favorite.setPassword(host.getPassword()); favorite.setAccount(host.getAccount()); favorite.setFTPClientClassName(host.getFTPClientClassName()); favorite.setListParserClassName(host.getListParserClassName()); favorite.setInitialLocalDirectory(host.getInitialLocalDirectory()); favorite.setInitialRemoteDirectory(host.getInitialRemoteDirectory()); favorite.setPassive(host.isPassive()); favorite.setCommands(host.getCommands()); FavoritePropertiesDlg dlg = new FavoritePropertiesDlg(this, FavoritePropertiesDlg.ADD_MODE); dlg.setFavorite(favorite); dlg.setLocationRelativeTo(this); dlg.setVisible(true); favorite = dlg.getFavorite(); if (favorite != null) { try { java.util.List favorites = FavoritesManager.getFavorites(); if (favorites.contains(favorite)) { GUIUtil.showError(this, resources.getString("error.duplicateFavorite")); return; } FavoritesManager.addFavorite(favorite); } catch (Exception exp) { GUIUtil.showError(this, exp); } } } public void showPreferencesDialog() { PreferencesDlg dlg = new PreferencesDlg(this); dlg.setLocationRelativeTo(this); dlg.setVisible(true); dlg.dispose(); } private JMenuBar prepareMenuBar() { JMenuBar menuBar = new JMenuBar(); FTPMenu menuFTP = new FTPMenu(this); LocalSystemMenu menuLocalSystem = new LocalSystemMenu(this); RemoteSystemMenu menuRemoteSystem = new RemoteSystemMenu(this); TransferModeMenu menuTransferTypes = new TransferModeMenu(this); ToolsMenu menuTools = new ToolsMenu(this); HelpMenu menuHelp = new HelpMenu(this); menuBar.add(menuFTP); menuBar.add(menuLocalSystem); menuBar.add(menuRemoteSystem); menuBar.add(menuTransferTypes); menuBar.add(menuTools); menuBar.add(menuHelp); return menuBar; } private Rectangle getPreferredBounds() { Rectangle windowBounds = prefs.getWindowBounds(); if (windowBounds == null) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension preferredSize = new Dimension(screenSize.width - 100, screenSize.height - 100); windowBounds = new Rectangle( (screenSize.width - preferredSize.width) / 2, (screenSize.height - preferredSize.height) / 2, preferredSize.width, preferredSize.height); } return windowBounds; } /** * Returns the currently selected session. * * @return Currently selected session */ public FTPSession getCurrentSession() { int selectedTabIndex = tabs.getSelectedIndex(); if (selectedTabIndex >= 0) { return (FTPSession) tabs.getComponentAt(selectedTabIndex); } return null; } /** * Serializes and saves the preferences to a file in the USER_HOME * directory. * * @param prefs * Preferences * @exception IOException * if an IO error occurs */ public static synchronized void savePreferences(JFTPPreferences prefs) throws IOException { ObjectOutputStream out = null; try { File prefsFile = new File(DATA_HOME, "preferences.ser"); out = new ObjectOutputStream(new FileOutputStream(prefsFile)); out.writeObject(prefs); transferTypes = prefs.getTransferTypes(); } finally { if (out != null) { out.close(); } } } /** * Loads the preferences by reading them from the file. If the file is not * found, all preferences are set to their default values and they will be * stored in the file. * * @exception IOException * if an IO error occurs */ public static synchronized JFTPPreferences loadPreferences() throws IOException { FileInputStream fin = null; ObjectInputStream in = null; JFTPPreferences prefs = new JFTPPreferences(); try { if (!DATA_HOME.exists()) { DATA_HOME.mkdirs(); } File prefsFile = new File(DATA_HOME, "preferences.ser"); if (!prefsFile.exists()) { prefsFile.createNewFile(); savePreferences(new JFTPPreferences()); } fin = new FileInputStream(prefsFile); in = new ObjectInputStream(fin); if (fin.available() != 0) { try { prefs = (JFTPPreferences) in.readObject(); } catch (ClassNotFoundException exp) { } catch (ClassCastException exp) { } } } finally { if (in != null) { in.close(); } if (fin != null) { fin.close(); } return prefs; } } /** * Returns all the installed theme names * * @return An array of strings containing the installed theme names. */ public static String[] getInstalledThemes() { String[] themes = new String[THEMES.size()]; themes = (String[]) THEMES.keySet().toArray(themes); Arrays.sort(themes); return themes; } /** * Returns the class name implementing the given theme name * * @param themeName * Name of the theme * @return Class name of the theme */ public static String getThemeClassName(String themeName) { return (String) THEMES.get(themeName); } /** * Returns an array of installed list parsers * * @return Installed List parser names */ public static String[] getInstalledParsers() { String[] parsers = new String[PARSERS.size()]; parsers = (String[]) PARSERS.keySet().toArray(parsers); return parsers; } /** * Returns the class name of the List Parser, given the name of the parser * * @param parserName * Name of the list parser * @return Class name implementing the list parser */ public static String getParserClassName(String parserName) { return (String) PARSERS.get(parserName); } /** * Returns the parser name given the parser class name * * @param parserClassName * Class name of the list parser * @return Name of the list parser */ public static String getParserName(String parserClassName) { Set keySet = PARSERS.keySet(); Iterator iterator = keySet.iterator(); while (iterator.hasNext()) { String key = (String) iterator.next(); if (parserClassName.equals(PARSERS.get(key))) { return key; } } return null; } /** * Gets the installed FTP client implementations. * * @return Installed FTP client implementations */ public static String[] getInstalledClients() { String[] clients = new String[CLIENTS.size()]; clients = (String[]) CLIENTS.keySet().toArray(clients); return clients; } /** * Returns the client class name given the name of the client * implementation. * * @param clientName * name of the FTP client implementation * @return Class name implementing the FTP client interface */ public static String getClientClassName(String clientName) { return (String) CLIENTS.get(clientName); } /** * Returns the name of the implementation given the class name. * * @param clientClassName * Class name * @return Name of the FTP client implementation */ public static String getClientName(String clientClassName) { Set keySet = CLIENTS.keySet(); Iterator iterator = keySet.iterator(); while (iterator.hasNext()) { String key = (String) iterator.next(); if (clientClassName.equals(CLIENTS.get(key))) { return key; } } return null; } public void updateSessionTitle(FTPSession session) { int index = tabs.indexOfComponent(session); if (index < 0) { return; } String title = resources.getString("text.notConnected"); String tooltip = null; if (session.isConnected()) { title = session.getRemoteHost().getName(); tooltip = session.getRemoteHost().getHostName(); if (title == null || title.trim().length() == 0) { title = tooltip; } } tabs.setTitleAt(index, title); tabs.setToolTipTextAt(index, tooltip); } public void showAboutDialog() { AboutDlg dlg = new AboutDlg(this); dlg.setLocationRelativeTo(this); dlg.setVisible(true); } /** * Updates the state of various actions(menu items/toolbar buttons) based on * the currently selected FTP session. */ public void updateToolBar() { toolBar.updateButtons(); } private void showLicenseAgreement() { String licenseAgreedForVersion = prefs.getLicenseAgreedForVersion(); if (!JFTPConstants.PRODUCT_VERSION.equals(licenseAgreedForVersion)) { LicenseAgreementDlg dlg = new LicenseAgreementDlg(this); dlg.setURL(getClass().getResource("license.html")); dlg.setLocationRelativeTo(this); dlg.setVisible(true); boolean licenseAgreed = dlg.isLicenseAgreed(); dlg.dispose(); System.gc(); if (!licenseAgreed) { System.exit(1); } prefs.setLicenseAgreedForVersion(JFTPConstants.PRODUCT_VERSION); try { savePreferences(prefs); } catch (IOException e) { e.printStackTrace(); } } } private void selectAllLocalFiles() { FTPSession session = getCurrentSession(); if (session != null) { session.selectAllLocalFiles(); } } private void invertLocalFileSelection() { FTPSession session = getCurrentSession(); if (session != null) { session.invertLocalFileSelection(); } } private void selectAllRemoteFiles() { FTPSession session = getCurrentSession(); if (session != null && session.isConnected()) { session.selectAllRemoteFiles(); } } private void invertRemoteFileSelection() { FTPSession session = getCurrentSession(); if (session != null && session.isConnected()) { session.invertRemoteFileSelection(); } } }