/** * Derived from Harmony Resolves a given url relative to this url. Resolution rules are the same * as for {@code java.net.URI.resolve(URI)} */ public Uri resolve(Uri relative) { if (relative == null) { return null; } if (relative.isAbsolute()) { return relative; } UriBuilder result; if (StringUtils.isEmpty(relative.path) && relative.scheme == null && relative.authority == null && relative.query == null && relative.fragment != null) { // if the relative URI only consists of fragment, // the resolved URI is very similar to this URI, // except that it has the fragement from the relative URI. result = new UriBuilder(this); result.setFragment(relative.fragment); } else if (relative.scheme != null) { result = new UriBuilder(relative); } else if (relative.authority != null) { // if the relative URI has authority, // the resolved URI is almost the same as the relative URI, // except that it has the scheme of this URI. result = new UriBuilder(relative); result.setScheme(scheme); } else { // since relative URI has no authority, // the resolved URI is very similar to this URI, // except that it has the query and fragment of the relative URI, // and the path is different. result = new UriBuilder(this); result.setFragment(relative.fragment); result.setQuery(relative.query); String relativePath = (relative.path == null) ? "" : relative.path; if (relativePath.startsWith("/")) { // $NON-NLS-1$ result.setPath(relativePath); } else { // resolve a relative reference int endindex = path.lastIndexOf('/') + 1; result.setPath(normalizePath(path.substring(0, endindex) + relativePath)); } } Uri resolved = result.toUri(); validate(resolved); return resolved; }