alluxio.uri.URI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alluxio-core-common Show documentation
Show all versions of alluxio-core-common Show documentation
Common utilities shared in Alluxio core modules
/*
* The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
* (the "License"). You may not use this work except in compliance with the License, which is
* available at www.apache.org/licenses/LICENSE-2.0
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied, as more fully set forth in the License.
*
* See the NOTICE file distributed with this work for information regarding copyright ownership.
*/
package alluxio.uri;
import alluxio.AlluxioURI;
import alluxio.collections.Pair;
import com.google.common.base.Preconditions;
import java.io.Serializable;
import java.net.URISyntaxException;
/**
* This interface represents a URI. This {@link URI} supports more than just strict
* {@link java.net.URI}. Some examples:
* * Windows paths
* * C:\
* * D:\path\to\file
* * E:\path\to\skip\..\file
* * URI with multiple scheme components
* * scheme://host:123/path
* * scheme:part2//host:123/path
* * scheme:part2://host:123/path
* * scheme:part2:part3//host:123/path
* * scheme:part2:part3://host:123/path
*
* Currently, does not support fragment in the URI.
*/
public interface URI extends Comparable, Serializable {
/**
* Factory for {@link URI}.
*/
class Factory {
private Factory() {} // prevent instantiation
/**
* Creates a {@link URI} from a string.
*
* @param uriStr URI string to create the {@link URI} from
* @return the created {@link URI}
*/
public static URI create(String uriStr) {
Preconditions.checkArgument(uriStr != null, "Can not create a uri with a null path.");
// add a slash in front of paths with Windows drive letters
if (AlluxioURI.hasWindowsDrive(uriStr, false)) {
uriStr = "/" + uriStr;
}
// parse uri components
String scheme = null;
String authority = null;
String query = null;
int start = 0;
// parse uri scheme, if any
int colon = uriStr.indexOf(':');
int slash = uriStr.indexOf('/');
if ((colon != -1) && ((slash == -1) || (colon < slash))) { // has a scheme
if (slash != -1) {
// There is a slash. The scheme may have multiple parts, so the scheme is everything
// before the slash.
start = slash;
// Ignore any trailing colons from the scheme.
while (slash > 0 && uriStr.charAt(slash - 1) == ':') {
slash--;
}
scheme = uriStr.substring(0, slash);
} else {
// There is no slash. The scheme is the component before the first colon.
scheme = uriStr.substring(0, colon);
start = colon + 1;
}
}
// parse uri authority, if any
if (uriStr.startsWith("//", start) && (uriStr.length() - start > 2)) { // has authority
int nextSlash = uriStr.indexOf('/', start + 2);
int authEnd = nextSlash > 0 ? nextSlash : uriStr.length();
authority = uriStr.substring(start + 2, authEnd);
start = authEnd;
}
// uri path is the rest of the string -- fragment not supported
String path = uriStr.substring(start, uriStr.length());
// Parse the query part.
int question = path.indexOf('?');
if (question != -1) {
// There is a query.
query = path.substring(question + 1);
path = path.substring(0, question);
}
return create(scheme, Authority.fromString(authority), path, query);
}
/**
* Creates a {@link URI} from components.
*
* @param scheme the scheme string of the URI
* @param authority the authority of the URI
* @param path the path component of the URI
* @param query the query component of the URI
* @return the created {@link URI}
*/
public static URI create(String scheme, Authority authority, String path, String query) {
Preconditions.checkArgument(path != null, "Can not create a uri with a null path.");
// Handle schemes with two components.
Pair schemeComponents = getSchemeComponents(scheme);
String schemePrefix = schemeComponents.getFirst();
scheme = schemeComponents.getSecond();
if (scheme == null || schemePrefix.isEmpty()) {
return new StandardURI(scheme, authority, path, query);
} else {
return new MultiPartSchemeURI(schemePrefix, scheme, authority, path, query);
}
}
/**
* Resolves a child {@link URI} against a parent {@link URI}.
*
* @param parent the parent
* @param child the child
* @return the created {@link URI}
*/
public static URI create(URI parent, URI child) {
// Add a slash to parent's path so resolution is compatible with URI's
String parentPath = parent.getPath();
if (!parentPath.endsWith(AlluxioURI.SEPARATOR) && parentPath.length() > 0) {
parentPath += AlluxioURI.SEPARATOR;
}
java.net.URI parentUri;
java.net.URI childUri;
Authority authority = child.getAuthority() instanceof NoAuthority
? parent.getAuthority() : child.getAuthority();
try {
// To be compatible with URI, must use the last component of the scheme.
parentUri = new java.net.URI(getSchemeComponents(parent.getScheme()).getSecond(),
null, parentPath, parent.getQuery(), null);
childUri = new java.net.URI(getSchemeComponents(child.getScheme()).getSecond(),
null, child.getPath(), child.getQuery(), null);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
java.net.URI resolved = parentUri.resolve(childUri);
String resolvedScheme;
// Determine which scheme prefix to take.
if (child.getPath() == null || parent.getPath() == null || child.getScheme() != null) {
// With these conditions, the resolved URI uses the child's scheme.
resolvedScheme = child.getScheme();
} else {
// Otherwise, the parent scheme is used in the resolved URI.
resolvedScheme = parent.getScheme();
}
return create(resolvedScheme, authority, resolved.getPath(), resolved.getQuery());
}
/**
* @param baseUri the base URI
* @param newPath the new path component
* @param checkNormalization if true, will check if the path requires normalization
* @return a new URI based off a URI and a new path component
*/
public static URI create(URI baseUri, String newPath, boolean checkNormalization) {
Preconditions.checkArgument(newPath != null, "Can not create a uri with a null newPath.");
return baseUri.createNewPath(newPath, checkNormalization);
}
/**
* Returns a {@link Pair} of components of the given scheme. A given scheme may have have two
* components if it has the ':' character to specify a sub-protocol of the scheme. If the
* scheme does not have multiple components, the first component will be the empty string, and
* the second component will be the given scheme. If the given scheme is null, both components
* in the {@link Pair} will be null.
*
* @param scheme the scheme string
* @return a {@link Pair} with the scheme components
*/
public static Pair getSchemeComponents(String scheme) {
if (scheme == null) {
return new Pair<>(null, null);
}
int colon = scheme.lastIndexOf(':');
if (colon == -1) {
return new Pair<>("", scheme);
}
return new Pair<>(scheme.substring(0, colon), scheme.substring(colon + 1));
}
}
/**
* @param newPath the new path component
* @param checkNormalization if true, will check if the path requires normalization
* @return a new URI based off of this URI, but with a new path component
*/
URI createNewPath(String newPath, boolean checkNormalization);
/**
* @return the authority of the {@link URI}, null if it does not have one
*/
Authority getAuthority();
/**
* @return the path of the {@link URI}
*/
String getPath();
/**
* @return the query component of the {@link URI}
*/
String getQuery();
/**
* @return the scheme of the {@link URI}, null if there is no scheme
*/
String getScheme();
/**
* @return the scheme specific part of the {@link URI}, null if there is no scheme
*/
String getSchemeSpecificPart();
/**
* Tells whether or not the {@link URI} is absolute.
*
*
* An {@link URI} is absolute if, and only if, it has a scheme component.
*
*
* @return true if, and only if, this {@link URI} is absolute
*/
boolean isAbsolute();
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy