savant.agp.HTTPBrowser.java Source code

Java tutorial

Introduction

Here is the source code for savant.agp.HTTPBrowser.java

Source

/**
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package savant.agp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.filechooser.FileSystemView;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;

import net.htmlparser.jericho.Source;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import savant.api.util.DialogUtils;
import savant.api.util.TrackUtils;
import savant.controller.BookmarkController;
import savant.settings.DirectorySettings;
import savant.util.swing.DocumentViewer;
import savant.view.dialog.DownloadDialog;
import savant.view.icon.SavantIconFactory;

/**
 * HTTP browser for AGP project.
 *
 * @author tarkvara
 */
public class HTTPBrowser extends JPanel {

    private static final Log LOG = LogFactory.getLog(HTTPBrowser.class);
    private JLabel addressLabel;
    private JTable table;
    private FTPClient ftp;
    String user = "anonymous";
    String password = "";
    private static String host;
    int port;
    private File curDir;
    private File rootDir;

    public HTTPBrowser(URL rootURL) throws IOException {
        host = rootURL.getHost();
        int p = rootURL.getPort();
        port = p != -1 ? p : rootURL.getDefaultPort();
        rootDir = new File(rootURL.getPath());
        curDir = rootDir;

        setLayout(new BorderLayout());

        addressLabel = new JLabel();
        add(addressLabel, BorderLayout.NORTH);
        add(getToolBar(), BorderLayout.SOUTH);

        table = new JTable();

        updateDirectory();

        table.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent evt) {
                if (evt.getClickCount() == 2) {
                    String f = ((HTTPTableModel) table.getModel()).getEntry(table.rowAtPoint(evt.getPoint()));

                    if (f.equals("..")) {
                        // Going up a directory.
                        curDir = curDir.getParentFile();
                        updateDirectory();
                    } else if (!f.contains(".")) {
                        if (f.startsWith("/")) {
                            curDir = new File(f);
                        } else {
                            curDir = new File(curDir, f);
                        }
                        updateDirectory();
                    } else {
                        openIndexAs(table.rowAtPoint(evt.getPoint()), OpenAsOption.TRACK);
                    }
                }
            }
        });

        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.getViewport().setBackground(Color.WHITE);
        scrollPane.setPreferredSize(new Dimension(800, 500));
        add(scrollPane, BorderLayout.CENTER);

        this.setPreferredSize(new Dimension(800, 500));
    }

    private void openSelectedIndexAs(OpenAsOption opt) {
        openIndexAs(table.getSelectedRow(), opt);
    }

    private static DocumentViewer v = new DocumentViewer();

    private void openIndexAs(int row, OpenAsOption opt) {
        try {
            String shortpath = ((HTTPTableModel) table.getModel()).getEntry(row);
            URI fullpath = new URI(getPath() + "/" + shortpath.replace("\\", "/"));

            File outputDir;
            String fileSeparator;
            String filename;

            switch (opt) {
            case TRACK:
                TrackUtils.createTrack(fullpath);
                break;
            case BOOKMARK:
                outputDir = DirectorySettings.getTmpDirectory();
                fileSeparator = System.getProperty("file.separator");
                filename = outputDir + fileSeparator + shortpath;
                if (!(new File(filename)).exists()) {
                    // FIXME A Window is needed, I'm not sure that we can
                    // actually get one this way
                    DownloadDialog dd = new DownloadDialog(SwingUtilities.getWindowAncestor(this), true);
                    dd.downloadFile(fullpath.toURL(), outputDir, null);
                    setVisible(false);
                }
                BookmarkController.getInstance().addBookmarksFromFile(new File(filename), false);
                break;
            case DOCUMENT:
                outputDir = DirectorySettings.getTmpDirectory();
                fileSeparator = System.getProperty("file.separator");
                filename = outputDir + fileSeparator + shortpath;
                if (!(new File(filename)).exists()) {
                    // FIXME A Window is needed, I'm not sure that we can
                    // actually get one this way
                    DownloadDialog dd = new DownloadDialog(SwingUtilities.getWindowAncestor(this), true);
                    dd.downloadFile(fullpath.toURL(), outputDir, null);
                    setVisible(false);
                }
                v.addDocument(filename);
                v.setExtendedState(v.getExtendedState() | DocumentViewer.MAXIMIZED_BOTH);
                v.setVisible(true);
                break;
            default:
                break;
            }
        } catch (Throwable x) {
            DialogUtils.displayException("AGP Plugin Error", "Unable to process request.", x);
        }
    }

    private enum OpenAsOption {

        TRACK, BOOKMARK, DOCUMENT
    };

    private void updateDirectory() {
        try {
            List<String> files = listFiles();
            addressLabel.setText("Current directory: http://" + host + curDir.getPath().replace("\\", "/"));
            table.setModel(new HTTPTableModel(files, !curDir.equals(rootDir)));
            TableColumnModel columns = table.getColumnModel();
            columns.getColumn(0).setMaxWidth(40); // icon
            columns.getColumn(1).setPreferredWidth(400); // name
            //columns.getColumn(2).setPreferredWidth(60);     // size
        } catch (IOException ex) {
            Logger.getLogger(HTTPBrowser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public String getPath() {
        return "http://" + host + curDir.toString().replace("\\", "/");
    }

    private List<String> listFiles() throws IOException {

        String rtparent = rootDir.getParent().replace("\\", "/") + "/";

        boolean atRoot = false;
        List<String> files = new ArrayList<String>();
        Source source = new Source(new URL(getPath()));
        List<net.htmlparser.jericho.Element> elementList = source.getAllElements();
        for (net.htmlparser.jericho.Element element : elementList) {
            if (element.getName().equals("a")) {
                String href = element.getAttributeValue("href");
                if (!href.equals(rtparent)) {
                    if (!href.startsWith("/")) {
                        files.add(href);
                    } else {
                        // System.out.println("not adding " + href);
                    }
                } else {
                    atRoot = true;
                }
            }
        }

        if (!atRoot) {
            files.add(0, "..");
        }

        return files;
    }

    public void openConnection() throws IOException {
        updateDirectory();
    }

    public void closeConnection() throws IOException {
        if (ftp != null) {
            ftp.disconnect();
        }
    }

    private Component getToolBar() {
        JToolBar bar = new JToolBar();
        bar.setFloatable(false);
        JButton butt_track = new JButton("Open as track");
        butt_track.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                openSelectedIndexAs(OpenAsOption.TRACK);
            }
        });
        butt_track.setBorder(new LineBorder(Color.gray, 1));
        JButton butt_bkmks = new JButton("Open as bookmarks");
        butt_bkmks.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                openSelectedIndexAs(OpenAsOption.BOOKMARK);
            }
        });
        butt_bkmks.setBorder(new LineBorder(Color.gray, 1));
        JButton butt_doc = new JButton("Open as document");
        butt_doc.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                openSelectedIndexAs(OpenAsOption.DOCUMENT);
            }
        });
        butt_doc.setBorder(new LineBorder(Color.gray, 1));
        bar.add(butt_track);
        bar.addSeparator(new Dimension(5, 5));
        bar.add(butt_bkmks);
        bar.addSeparator(new Dimension(5, 5));
        bar.add(butt_doc);

        return bar;
    }
}

/*
class HTTPFile {
public HTTPFile(String url, String name)
}
 * 
 */
class HTTPTableModel extends AbstractTableModel {

    private List<String> files = new ArrayList<String>();

    HTTPTableModel(List<String> files, boolean hasParent) {
        // We can't use the FTPFile array directly, because it contains some items
        // we want to suppress.  We may also want to insert a fake entry for the parent directory.
        for (String f : files) {
            if (f != null && !f.contains("?")) {
                this.files.add(f);
            }
        }
    }

    @Override
    public Class getColumnClass(int col) {
        switch (col) {
        case 0:
            return Icon.class;
        default:
            return String.class;
        }
    }

    @Override
    public int getColumnCount() {
        //return 3;
        return 2;
    }

    @Override
    public String getColumnName(int col) {
        switch (col) {
        case 1:
            return "Name";
        //case 2:
        //    return "Size";
        default:
            return null;
        }
    }

    @Override
    public int getRowCount() {
        return files.size();
    }

    @Override
    public Object getValueAt(int row, int col) {
        String f = files.get(row);
        switch (col) {
        case 0:
            return getIcon(f);
        case 1:
            return f;
        /*
        case 2:
        if (f.equals("..") || !f.contains(".")) {
        return "";
        } else {
        try {
        //HttpURLConnection httpConn = (HttpURLConnection) (new URL(HTTPBrowser.getPath() + "/" + f)).openConnection();
        //httpConn.get
        //long totalsize = httpConn.getContentLength();
        //System.out.println(f + " " + totalsize);
        //return MiscUtils.getSophisticatedByteString(totalsize);
        return "";
        } catch (Exception ex) {
        return "?" + ex.getMessage();
        }
        }
         *
         */
        }
        return null;
    }

    String getEntry(int row) {
        return files.get(row);
    }

    /**
     * Get a nicely formatted string describing the file's size.
     * 
     * @param f the FTP entry whose size we're displaying
     * @return a string describing the size, or null if f is a directory
     */
    private static String getSizeString(FTPFile f) {
        if (f != null && f.isFile()) {
            long size = f.getSize();
            if (size < 1E6) {
                return String.format("%.2f kB", size / 1.0E3);
            } else if (size < 1E9) {
                return String.format("%.2f MB", size / 1.0E6);
            } else {
                return String.format("%.2f GB", size / 1.0E9);
            }
        }
        return null;
    }

    /**
     * Use the Swing FileSystemView to get a system icon corresponding to the given
     * file.
     *
     * @param f the remote file-name whose icon we want to retrieve
     * @return a system icon representing f
     */
    private static Icon getIcon(String f) {
        try {
            if (f.contains("..") || f.contains("/")) {
                return FileSystemView.getFileSystemView().getSystemIcon(new File("."));
            } else {
                Icon i;
                if (isLikelyFormattedTrack(f)) {
                    i = SavantIconFactory.getInstance().getIcon(SavantIconFactory.StandardIcon.TRACK);
                } else {
                    File tmp = File.createTempFile("temp_icon.", "." + "txt");
                    i = FileSystemView.getFileSystemView().getSystemIcon(tmp);
                    tmp.delete();
                }
                return i;
            }
        } catch (IOException ex) {
            return null;
        }
    }

    private static boolean isLikelyFormattedTrack(String name) {
        return name.endsWith(".savant") || name.endsWith(".gz") || name.endsWith(".bam") || name.endsWith(".bw");
    }
}