com.xebialabs.overthere.cifs.PathEncoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of overthere Show documentation
Show all versions of overthere Show documentation
Remote file manipulation and process execution framework for Java
/**
* Copyright (c) 2008-2016, XebiaLabs B.V., All rights reserved.
*
*
* Overthere is licensed under the terms of the GPLv2
* , like most XebiaLabs Libraries.
* There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
* this software, see the FLOSS License Exception
* .
*
* 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; version 2
* of the License.
*
* 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.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
package com.xebialabs.overthere.cifs;
import com.xebialabs.overthere.RuntimeIOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.xebialabs.overthere.cifs.CifsConnectionBuilder.CIFS_PORT_DEFAULT;
import static java.lang.String.format;
import static java.util.regex.Pattern.quote;
/**
* Conversions to/from UNC, SMB and Windows file paths
*/
class PathEncoder {
// "\\host-name\share" or "\\host-name\share\" or "\\host-name\share\path"
private static final Pattern UNC_PATH_PATTERN = Pattern.compile("\\\\\\\\[^\\\\]+\\\\([^\\\\]+(?:\\\\.*)?)");
private static final char WINDOWS_SEPARATOR = '\\';
private static final char SMB_URL_SEPARATOR = '/';
private final String smbUrlPrefix;
private final PathMapper pathMapper;
PathEncoder(String username, String password, String address, int cifsPort, Map pathMappings) {
StringBuilder urlPrefix = new StringBuilder();
urlPrefix.append("smb://");
// this is *not* the Windows file separator ;-)
if (username != null) {
urlPrefix.append(urlEncode(username.replaceFirst(quote("\\"), ";")));
urlPrefix.append(":");
urlPrefix.append(urlEncode(password));
urlPrefix.append("@");
}
urlPrefix.append(urlEncode(address));
if (cifsPort != CIFS_PORT_DEFAULT) {
urlPrefix.append(":");
urlPrefix.append(cifsPort);
}
urlPrefix.append(SMB_URL_SEPARATOR);
this.smbUrlPrefix = urlPrefix.toString();
this.pathMapper = new PathMapper(pathMappings);
}
private static String urlEncode(String value) {
try {
return URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeIOException("Unable to construct SMB URL", e);
}
}
String toSmbUrl(String hostPath) {
if (hostPath.length() < 2) {
throw new IllegalArgumentException(format("Host path '%s' is too short", hostPath));
}
if (hostPath.charAt(1) != ':') {
throw new IllegalArgumentException(format("Host path '%s' does not have a colon (:) as its second character", hostPath));
}
// This '/' is *not* the Unix or the SMB URL separator. It's something that can appear when people use
// Java-style Windows paths.
hostPath = hostPath.replace('/', WINDOWS_SEPARATOR);
if (hostPath.length() >= 3 && hostPath.charAt(2) != WINDOWS_SEPARATOR) {
throw new IllegalArgumentException(format("Host path '%s' does not have a backslash (\\) as its third character", hostPath));
}
StringBuilder smbUrl = new StringBuilder(smbUrlPrefix);
smbUrl.append(pathMapper.toSharedPath(hostPath).replace(WINDOWS_SEPARATOR, SMB_URL_SEPARATOR));
return smbUrl.toString();
}
/**
* @param uncPath the UNC path to convert to a Windows file path
* @return the Windows file path representing the UNC path
*/
final String fromUncPath(String uncPath) {
Matcher matcher = UNC_PATH_PATTERN.matcher(uncPath);
if (!matcher.matches()) {
throw new IllegalArgumentException(format("UNC path '%s' did not match expected expression '%s'", uncPath, UNC_PATH_PATTERN));
}
return pathMapper.toLocalPath(matcher.group(1));
}
/**
* Check whether the UNC path is valid.
* @param uncPath the UNC path to check.
* @return true if it is a valid UNC path.
*/
final boolean isValidUncPath(String uncPath) {
return UNC_PATH_PATTERN.matcher(uncPath).matches();
}
}