ch.cyberduck.core.Host.java Source code

Java tutorial

Introduction

Here is the source code for ch.cyberduck.core.Host.java

Source

package ch.cyberduck.core;

/*
 *  Copyright (c) 2005 David Kocher. All rights reserved.
 *  http://cyberduck.ch/
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  Bug fixes, suggestions and comments should be sent to:
 *  dkocher@cyberduck.ch
 */

import ch.cyberduck.core.ftp.FTPConnectMode;
import ch.cyberduck.core.preferences.PreferencesFactory;
import ch.cyberduck.core.serializer.Serializer;

import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.TimeZone;

public class Host implements Serializable, Comparable<Host> {

    /**
     * The credentials to authenticate with for the CDN
     */
    private final Credentials cloudfront = new Credentials();
    /**
     * The protocol identifier.
     */
    private Protocol protocol;
    private String region;
    /**
     * The port number to connect to
     *
     * @see Protocol#getDefaultPort()
     */
    private Integer port = -1;
    /**
     * The fully qualified hostname
     */
    private String hostname;
    /**
     * The credentials to authenticate with
     */
    private Credentials credentials = new Credentials();
    /**
     * Unique identifier
     */
    private String uuid;

    /**
     * The given name by the user for the bookmark
     */
    private String nickname;

    /**
     * The initial working directory if any and absolute
     * path to document root of webserver for Web URL configuration
     */
    private String defaultpath;

    /**
     * Current working directory when session was interrupted
     */
    private Path workdir;

    /**
     * The character encoding to use for file listings
     */
    private String encoding;

    /**
     * The connect mode to use if FTP
     */
    private FTPConnectMode connectMode = FTPConnectMode.unknown;

    /**
     * The maximum number of concurrent sessions to this host
     */
    private TransferType transfer = TransferType.unknown;

    /**
     * The custom download folder
     */
    private Local downloadFolder;

    /**
     * The custom download folder
     */
    private Local uploadFolder;

    /**
     * The timezone the server is living in
     */
    private TimeZone timezone;

    /**
     * Arbitrary text
     */
    private String comment;

    /**
     *
     */
    private String webURL;

    /**
     * Last accessed timestamp
     */
    private Date timestamp;

    /**
     * Mount target
     */
    private Local volume;

    /**
     * Connect with readonly mode
     */
    private Boolean readonly;

    /**
     * @param protocol Scheme
     */
    public Host(final Protocol protocol) {
        this(protocol, protocol.getDefaultHostname());
    }

    /**
     * @param protocol Scheme
     * @param hostname The hostname of the server
     */
    public Host(final Protocol protocol, final String hostname) {
        this(protocol, hostname, protocol.getDefaultPort());
    }

    /**
     * @param protocol    Scheme
     * @param hostname    The hostname of the server
     * @param credentials Login credentials
     */
    public Host(final Protocol protocol, final String hostname, final Credentials credentials) {
        this(protocol, hostname, protocol.getDefaultPort(), credentials);
    }

    /**
     * @param protocol The protocol to use, must be either Session.FTP or Session.SFTP
     * @param hostname The hostname of the server
     * @param port     The port number to connect to
     */
    public Host(final Protocol protocol, final String hostname, final int port) {
        this(protocol, hostname, port, protocol.getDefaultPath());
    }

    /**
     * @param protocol    Scheme
     * @param hostname    The hostname of the server
     * @param port        Port number
     * @param defaultpath Default working directory
     */
    public Host(final Protocol protocol, final String hostname, final int port, final String defaultpath) {
        this.protocol = protocol;
        this.hostname = hostname;
        this.port = port;
        this.defaultpath = defaultpath;
    }

    /**
     * @param protocol    Scheme
     * @param hostname    The hostname of the server
     * @param port        Port number
     * @param credentials Login credentials
     */
    public Host(final Protocol protocol, final String hostname, final int port, final Credentials credentials) {
        this.protocol = protocol;
        this.hostname = hostname;
        this.port = port;
        this.credentials.setUsername(credentials.getUsername());
        this.credentials.setIdentity(credentials.getIdentity());
        if (!credentials.isAnonymousLogin()) {
            this.credentials.setPassword(credentials.getPassword());
        }
    }

    /**
     * @param protocol Scheme
     * @param hostname The hostname of the server
     * @param port     Port number
     */
    public Host(final Protocol protocol, final String hostname, final int port, final String defaultpath,
            final Credentials credentials) {
        this.protocol = protocol;
        this.hostname = hostname;
        this.port = port;
        this.defaultpath = defaultpath;
        this.credentials.setUsername(credentials.getUsername());
        this.credentials.setIdentity(credentials.getIdentity());
        if (!credentials.isAnonymousLogin()) {
            this.credentials.setPassword(credentials.getPassword());
        }
    }

    /**
     * Auto configuration
     */
    protected void configure() {
        this.configure(HostnameConfiguratorFactory.get(protocol), CredentialsConfiguratorFactory.get(protocol));
    }

    protected void configure(final HostnameConfigurator hostnameConfigurator,
            final CredentialsConfigurator credentialsConfigurator) {
        final int port = hostnameConfigurator.getPort(hostname);
        if (port != -1) {
            // External configuration found
            this.setPort(port);
        }
        credentials = credentialsConfigurator.configure(this);
    }

    @Override
    public <T> T serialize(final Serializer dict) {
        dict.setStringForKey(protocol.getIdentifier(), "Protocol");
        if (StringUtils.isNotBlank(protocol.getProvider())) {
            if (!StringUtils.equals(protocol.getProvider(), protocol.getIdentifier())) {
                dict.setStringForKey(protocol.getProvider(), "Provider");
            }
        }
        if (StringUtils.isNotBlank(nickname)) {
            dict.setStringForKey(nickname, "Nickname");
        }
        dict.setStringForKey(this.getUuid(), "UUID");
        dict.setStringForKey(hostname, "Hostname");
        dict.setStringForKey(String.valueOf(this.getPort()), "Port");
        if (StringUtils.isNotBlank(credentials.getUsername())) {
            dict.setStringForKey(credentials.getUsername(), "Username");
        }
        if (StringUtils.isNotBlank(cloudfront.getUsername())) {
            dict.setStringForKey(cloudfront.getUsername(), "CDN Credentials");
        }
        if (StringUtils.isNotBlank(defaultpath)) {
            dict.setStringForKey(defaultpath, "Path");
        }
        if (workdir != null) {
            dict.setObjectForKey(workdir, "Workdir Dictionary");
        }
        if (StringUtils.isNotBlank(encoding)) {
            dict.setStringForKey(encoding, "Encoding");
        }
        if (StringUtils.isNotBlank(credentials.getCertificate())) {
            dict.setStringForKey(credentials.getCertificate(), "Client Certificate");
        }
        if (null != credentials.getIdentity()) {
            dict.setStringForKey(credentials.getIdentity().getAbbreviatedPath(), "Private Key File");
            dict.setObjectForKey(credentials.getIdentity(), "Private Key File Dictionary");
        }
        if (protocol.getType() == Protocol.Type.ftp) {
            if (connectMode != FTPConnectMode.unknown) {
                dict.setStringForKey(connectMode.name(), "FTP Connect Mode");
            }
        }
        if (transfer != TransferType.unknown) {
            dict.setStringForKey(transfer.name(), "Transfer Connection");
        }
        if (null != downloadFolder) {
            dict.setStringForKey(downloadFolder.getAbbreviatedPath(), "Download Folder");
            dict.setObjectForKey(downloadFolder, "Download Folder Dictionary");
        }
        if (null != uploadFolder) {
            dict.setObjectForKey(uploadFolder, "Upload Folder Dictionary");
        }
        if (null != timezone) {
            dict.setStringForKey(this.getTimezone().getID(), "Timezone");
        }
        if (StringUtils.isNotBlank(comment)) {
            dict.setStringForKey(comment, "Comment");
        }
        if (!this.isDefaultWebURL()) {
            dict.setStringForKey(this.getWebURL(), "Web URL");
        }
        if (null != timestamp) {
            dict.setStringForKey(String.valueOf(timestamp.getTime()), "Access Timestamp");
        }
        if (null != volume) {
            dict.setStringForKey(String.valueOf(volume.getAbbreviatedPath()), "Volume");
        }
        if (null != readonly) {
            dict.setStringForKey(String.valueOf(readonly), "Readonly");
        }
        return dict.getSerialized();
    }

    /**
     * @return Null if no default path is set
     */
    public String getDefaultPath() {
        return defaultpath;
    }

    /**
     * @param defaultpath The path to change the working directory to upon connecting
     */
    public void setDefaultPath(final String defaultpath) {
        this.defaultpath = StringUtils.isBlank(defaultpath) ? null : StringUtils.trim(defaultpath);
    }

    public Path getWorkdir() {
        return workdir;
    }

    public void setWorkdir(final Path workdir) {
        this.workdir = workdir;
    }

    /**
     * @param username User
     * @param password Secret
     */
    public void setCredentials(final String username, final String password) {
        credentials.setUsername(username);
        credentials.setPassword(password);
    }

    public Credentials getCredentials() {
        return credentials;
    }

    public void setCredentials(final Credentials credentials) {
        this.credentials = credentials;
    }

    /**
     * @return Credentials to modify CDN configuration
     */
    public Credentials getCdnCredentials() {
        return cloudfront;
    }

    public Protocol getProtocol() {
        return protocol;
    }

    /**
     * @param protocol The protocol to use or null to use the default protocol for this port number
     */
    public void setProtocol(final Protocol protocol) {
        this.protocol = protocol;
        this.configure();
    }

    public String getUuid() {
        if (null == uuid) {
            uuid = new UUIDRandomStringService().random();
        }
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    /**
     * The given name for this bookmark
     *
     * @return The user-given name of this bookmark
     */
    public String getNickname() {
        return nickname;
    }

    /**
     * Sets a user-given name for this bookmark
     *
     * @param nickname Custom name
     */
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    /**
     * @return User readable hostname
     */
    public String getHostname() {
        return hostname;
    }

    /**
     * Sets the name for this host. Also reverts the nickname if no custom nickname is set.
     * <p>
     * Configures credentials according to new hostname.
     *
     * @param hostname Server
     */
    public void setHostname(final String hostname) {
        this.hostname = hostname.trim();
        this.configure();
    }

    /**
     * @return The port number a socket should be opened to
     */
    public int getPort() {
        return port;
    }

    /**
     * @param port The port number to connect to or -1 to use the default port for this protocol
     */
    public void setPort(final int port) {
        this.port = -1 == port ? protocol.getDefaultPort() : port;
    }

    /**
     * @return The character encoding to be used when connecting to this server or null
     * if the default encoding should be used
     */
    public String getEncoding() {
        if (null == encoding) {
            return PreferencesFactory.get().getProperty("browser.charset.encoding");
        }
        return encoding;
    }

    /**
     * The character encoding to be used with this host
     *
     * @param encoding Control connection encoding
     */
    public void setEncoding(final String encoding) {
        this.encoding = encoding;
    }

    /**
     * @return The connect mode to be used when connecting
     * to this server or null if the default connect mode should be used
     */
    public FTPConnectMode getFTPConnectMode() {
        return connectMode;
    }

    public void setFTPConnectMode(final FTPConnectMode connectMode) {
        this.connectMode = connectMode;
    }

    /**
     * @return The number of concurrent sessions allowed. -1 if unlimited or null
     * if the default should be used
     */
    public TransferType getTransferType() {
        switch (transfer) {
        case unknown:
            return Host.TransferType.valueOf(PreferencesFactory.get().getProperty("queue.transfer.type"));
        }
        return transfer;
    }

    /**
     * Set a custom number of concurrent sessions allowed for this host
     * If not set, connection.pool.max is used.
     *
     * @param transfer null to use the default value or -1 if no limit
     */
    public void setTransfer(final TransferType transfer) {
        this.transfer = transfer;
    }

    /**
     * The custom folder if any or the default download location
     *
     * @return Absolute path
     */
    public Local getDownloadFolder() {
        return downloadFolder;
    }

    /**
     * Set a custom download folder instead of queue.download.folder
     *
     * @param folder Absolute path
     */
    public void setDownloadFolder(final Local folder) {
        downloadFolder = folder;
    }

    public Local getUploadFolder() {
        return uploadFolder;
    }

    public void setUploadFolder(final Local folder) {
        this.uploadFolder = folder;
    }

    /**
     * @return The custom timezone or null if not set
     */
    public TimeZone getTimezone() {
        return timezone;
    }

    /**
     * Set a timezone for the remote server different from the local default timezone
     * May be useful to display modification dates of remote files correctly using the local timezone
     *
     * @param timezone Timezone of server
     */
    public void setTimezone(final TimeZone timezone) {
        this.timezone = timezone;
    }

    public String getRegion() {
        if (StringUtils.isBlank(region)) {
            return protocol.getRegion();
        }
        return region;
    }

    public void setRegion(final String region) {
        this.region = region;
    }

    /**
     * @return Notice
     */
    public String getComment() {
        return comment;
    }

    /**
     * @param comment Notice
     */
    public void setComment(final String comment) {
        this.comment = comment;
    }

    /**
     * @return HTTP accessible URL
     */
    public String getWebURL() {
        if (StringUtils.isBlank(webURL)) {
            return this.getDefaultWebURL();
        }
        final String regex = "^http(s)?://.*$";
        if (!webURL.matches(regex)) {
            webURL = String.format("http://%s", webURL);
        }
        return webURL;
    }

    public void setWebURL(final String url) {
        if (this.getDefaultWebURL().equals(url)) {
            webURL = null;
        } else {
            webURL = url;
        }
    }

    /**
     * @return True if no custom web URL has been set
     */
    public boolean isDefaultWebURL() {
        return this.getWebURL().equals(this.getDefaultWebURL());
    }

    /**
     * @return HTTP accessible URL with the same hostname as the server
     */
    public String getDefaultWebURL() {
        return String.format("http://%s", StringUtils.strip(hostname));
    }

    /**
     * @return The date this bookmark was last accessed.
     */
    public Date getTimestamp() {
        return timestamp;
    }

    /**
     * Update the time this bookmark was last accessed.
     *
     * @param timestamp Date and time
     */
    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }

    public Local getVolume() {
        return volume;
    }

    public void setVolume(final Local volume) {
        this.volume = volume;
    }

    public Boolean getReadonly() {
        return readonly;
    }

    public void setReadonly(final Boolean readonly) {
        this.readonly = readonly;
    }

    @Override
    public boolean equals(Object other) {
        if (null == other) {
            return false;
        }
        if (other instanceof Host) {
            return this.getUuid().equals(((Host) other).getUuid());
        }
        return false;
    }

    @Override
    public int hashCode() {
        return this.getUuid().hashCode();
    }

    @Override
    public int compareTo(final Host o) {
        if (protocol.compareTo(o.protocol) < 0) {
            return -1;
        } else if (protocol.compareTo(o.protocol) > 0) {
            return 1;
        }
        if (port.compareTo(o.port) < 0) {
            return -1;
        } else if (port.compareTo(o.port) > 0) {
            return 1;
        }
        if (hostname.compareTo(o.hostname) < 0) {
            return -1;
        } else if (hostname.compareTo(o.hostname) > 0) {
            return 1;
        }
        if (credentials.compareTo(o.credentials) < 0) {
            return -1;
        } else if (credentials.compareTo(o.credentials) > 0) {
            return 1;
        }
        return 0;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Host{");
        sb.append("credentials=").append(credentials);
        sb.append(", hostname='").append(hostname).append('\'');
        sb.append(", defaultpath='").append(defaultpath).append('\'');
        sb.append(", port=").append(port);
        sb.append(", protocol=").append(protocol);
        sb.append('}');
        return sb.toString();
    }

    public enum TransferType {
        unknown {
            @Override
            public String toString() {
                return LocaleFactory.localizedString("Default");
            }
        },
        browser {
            @Override
            public String toString() {
                return LocaleFactory.localizedString("Use browser connection", "Transfer");
            }
        },
        /**
         * Single connnection in Transfer window
         */
        newconnection {
            @Override
            public String toString() {
                return LocaleFactory.localizedString("Open single connection", "Transfer");
            }
        },
        concurrent {
            @Override
            public String toString() {
                return LocaleFactory.localizedString("Open multiple connections", "Transfer");
            }
        },
        udt {
            @Override
            public String toString() {
                return LocaleFactory.localizedString("Qloudsonic (UDP-based Data Transfer Protocol)", "Transfer");
            }
        }
    }
}