001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2.provider;
018
019import org.apache.commons.lang3.StringUtils;
020import org.apache.commons.vfs2.FileName;
021import org.apache.commons.vfs2.FileType;
022
023/**
024 * A file name that represents a 'generic' URI, as per RFC 2396. Consists of a scheme, userinfo (typically username and
025 * password), hostname, port, and path.
026 */
027public class GenericFileName extends AbstractFileName {
028
029    private final String userName;
030    private final String hostName;
031    private final int defaultPort;
032    private final String password;
033    private final int port;
034
035    /**
036     * Constructs a new instance.
037     *
038     * @param scheme the scheme.
039     * @param hostName the host name.
040     * @param port the port.
041     * @param defaultPort the default port.
042     * @param userName the user name.
043     * @param password the password.
044     * @param path the absolute path, maybe empty or null.
045     * @param type the file type.
046     */
047    protected GenericFileName(final String scheme, final String hostName, final int port, final int defaultPort,
048        final String userName, final String password, final String path, final FileType type) {
049        super(scheme, path, type);
050        this.hostName = hostName;
051        this.defaultPort = defaultPort;
052        this.password = password;
053        this.userName = userName;
054        this.port = port > 0 ? port : defaultPort;
055    }
056
057    /**
058     * Append the user credentials.
059     * <p>
060     * If anything was added, it will be '@' terminated.
061     * </p>
062     *
063     * @param buffer the string buffer to modify.
064     * @param addPassword flag if password should be added or replaced with placeholder (false).
065     */
066    protected void appendCredentials(final StringBuilder buffer, final boolean addPassword) {
067        if (!StringUtils.isEmpty(userName)) {
068            UriParser.appendEncodedRfc2396(buffer, userName, RFC2396.USERINFO_UNESCAPED);
069            if (password != null && !password.isEmpty()) {
070                buffer.append(':');
071                if (addPassword) {
072                    UriParser.appendEncodedRfc2396(buffer, password, RFC2396.USERINFO_UNESCAPED);
073                } else {
074                    buffer.append("***");
075                }
076            }
077            buffer.append('@');
078        }
079    }
080
081    /**
082     * Builds the root URI for this file name.
083     */
084    @Override
085    protected void appendRootUri(final StringBuilder buffer, final boolean addPassword) {
086        buffer.append(getScheme());
087        buffer.append("://");
088        appendCredentials(buffer, addPassword);
089        buffer.append(hostName);
090        if (port != getDefaultPort()) {
091            buffer.append(':');
092            buffer.append(port);
093        }
094    }
095
096    /**
097     * Create a FileName.
098     *
099     * @param absPath The absolute path.
100     * @param type The FileType.
101     * @return The created FileName.
102     */
103    @Override
104    public FileName createName(final String absPath, final FileType type) {
105        return new GenericFileName(getScheme(), hostName, port, defaultPort, userName, password, absPath, type);
106    }
107
108    /**
109     * Returns the default port for this file name.
110     *
111     * @return The default port number.
112     */
113    public int getDefaultPort() {
114        return defaultPort;
115    }
116
117    /**
118     * Returns the host name part of this name.
119     *
120     * @return The host name.
121     */
122    public String getHostName() {
123        return hostName;
124    }
125
126    /**
127     * Returns the password part of this name.
128     *
129     * @return The password.
130     */
131    public String getPassword() {
132        return password;
133    }
134
135    /**
136     * Returns the port part of this name.
137     *
138     * @return The port number.
139     */
140    public int getPort() {
141        return port;
142    }
143
144    /**
145     * Returns the user name part of this name.
146     *
147     * @return The user name.
148     */
149    public String getUserName() {
150        return userName;
151    }
152}