google-nomulus/java/google/registry/rde/RdeUploadUrl.java
mcilwain aa2f283f7c Convert entire project to strict lexicographical import sort ordering
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127234970
2016-07-13 15:59:53 -04:00

214 lines
6.3 KiB
Java

// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
//
// 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 google.registry.rde;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
* Class representing the remote destination for a deposit upload (like an SFTP server).
*
* <p>This class provides validity contracts, default values, and syntactic sugar which make it
* preferable to using a plain {@link URI}.
*
* @see java.net.URI
* @see RdeUploadAction
*/
@Immutable
final class RdeUploadUrl implements Comparable<RdeUploadUrl> {
public static final Protocol SFTP = new Protocol("sftp", 22);
private static final Map<String, Protocol> ALLOWED_PROTOCOLS = ImmutableMap.of("sftp", SFTP);
private final Protocol protocol;
private final URI uri;
/**
* Constructs and validates a new {@link RdeUploadUrl} instance.
*
* @see java.net.URI#create(String)
*/
public static RdeUploadUrl create(URI uri) {
checkArgument(!isNullOrEmpty(uri.getScheme()) && !isNullOrEmpty(uri.getHost()),
"Incomplete url: %s", uri);
Protocol protocol = ALLOWED_PROTOCOLS.get(uri.getScheme());
checkArgument(protocol != null, "Unsupported scheme: %s", uri);
return new RdeUploadUrl(protocol, uri);
}
/** @see #create(URI) */
private RdeUploadUrl(Protocol protocol, URI uri) {
this.protocol = checkNotNull(protocol, "protocol");
this.uri = checkNotNull(uri, "uri");
}
/** Returns username from URL userinfo. */
public Optional<String> getUser() {
String userInfo = uri.getUserInfo();
if (isNullOrEmpty(userInfo)) {
return Optional.absent();
}
int idx = userInfo.indexOf(':');
if (idx != -1) {
return Optional.of(userInfo.substring(0, idx));
} else {
return Optional.of(userInfo);
}
}
/** Returns password from URL userinfo (if specified). */
public Optional<String> getPass() {
String userInfo = uri.getUserInfo();
if (isNullOrEmpty(userInfo)) {
return Optional.absent();
}
int idx = userInfo.indexOf(':');
if (idx != -1) {
return Optional.of(userInfo.substring(idx + 1));
} else {
return Optional.absent();
}
}
/** Returns hostname or IP without port. */
public String getHost() {
return uri.getHost();
}
/** Returns network port or default for protocol if not specified. */
public int getPort() {
return uri.getPort() != -1 ? uri.getPort() : getProtocol().getPort();
}
/** Returns the protocol of this URL. */
public Protocol getProtocol() {
return protocol;
}
/** Returns path element of URL (if present). */
public Optional<String> getPath() {
String path = uri.getPath();
if (isNullOrEmpty(path) || path.equals("/")) {
return Optional.absent();
} else {
return Optional.of(path.substring(1));
}
}
/** Returns URL as ASCII text with password concealed (if any). */
@Override
public String toString() {
String result = getProtocol().getName() + "://";
if (getUser().isPresent()) {
result += urlencode(getUser().get());
if (getPass().isPresent()) {
result += ":****";
}
result += "@";
}
result += getHost();
if (getPort() != getProtocol().getPort()) {
result += String.format(":%d", getPort());
}
result += "/";
result += getPath().or("");
return result;
}
/**
* Simplified wrapper around Java's daft URL encoding API.
*
* @return an ASCII string that's escaped in a conservative manner for safe storage within any
* component of a URL. Non-ASCII characters are converted to UTF-8 bytes before being
* encoded. No choice of charset is provided because the W3C says we should use UTF-8.
* @see URLEncoder#encode(String, String)
*/
private static String urlencode(String str) {
try {
return URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/** @see java.net.URI#compareTo(java.net.URI) */
@Override
public int compareTo(RdeUploadUrl rhs) {
return uri.compareTo(checkNotNull(rhs).uri);
}
/** @see java.net.URI#equals(Object) */
@Override
public boolean equals(@Nullable Object object) {
return object == this
|| object instanceof RdeUploadUrl
&& Objects.equals(uri, ((RdeUploadUrl) object).uri);
}
/** @see java.net.URI#hashCode() */
@Override
public int hashCode() {
return Objects.hashCode(uri);
}
/** Used to store default settings for {@link #ALLOWED_PROTOCOLS}. */
@Immutable
public static final class Protocol {
private final String name;
private final int port;
public Protocol(String name, int port) {
checkArgument(0 < port && port < 65536, "bad port: %s", port);
this.name = checkNotNull(name, "name");
this.port = port;
}
/** Returns lowercase name of protocol. */
public String getName() {
return name;
}
/** Returns the standardized port number assigned to this protocol. */
public int getPort() {
return port;
}
/** @see Object#equals(Object) */
@Override
public boolean equals(@Nullable Object object) {
return object == this
|| object instanceof Protocol
&& port == ((Protocol) object).port
&& Objects.equals(name, ((Protocol) object).name);
}
/** @see Object#hashCode() */
@Override
public int hashCode() {
return Objects.hash(name, port);
}
}
}