package com.hokolinks.model;
import android.net.Uri;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
* URL is a wrapper around a Uri object. It provides functions to parse the query parameters,
* url scheme, component matching and route matching.
*/
public class URL {
private Uri mUri;
private String mScheme;
private HashMap<String, String> mQueryParameters;
/**
* The constructor for URL receives a url and parses it into scheme and query parameters.
*
* @param urlString A String object representing a url.
*/
public URL(String urlString) {
mUri = Uri.parse(sanitizeURL(urlString));
mScheme = mUri.getScheme();
mQueryParameters = queryParameters(mUri);
}
/**
* Retrieves the query parameters out of a Uri object.
*
* @param uri A Uri object.
* @return The query parameters in HashMap form.
*/
private static HashMap<String, String> queryParameters(Uri uri) {
HashMap<String, String> queryParameters = new HashMap<>();
Set<String> queryParameterNames = uri.getQueryParameterNames();
for (String queryParameterName : queryParameterNames) {
queryParameters.put(queryParameterName, uri.getQueryParameter(queryParameterName));
}
return queryParameters;
}
/**
* Matches path components with route components. This will result in a map between the two.
*
* @param pathComponents Path components in list form.
* @param routeComponents Route components in list form.
* @return A HashMap where the keys are route components and values are their value
* representation of path components.
*/
private static HashMap<String, String> matchComponents(List<String> pathComponents,
List<String> routeComponents) {
HashMap<String, String> routeParameters = new HashMap<>();
for (int index = 0; index < pathComponents.size(); index++) {
String pathComponent = pathComponents.get(index);
String routeComponent = routeComponents.get(index);
if (pathComponent == null || routeComponent == null) {
return null;
}
if (routeComponent.startsWith(":")) {
routeParameters.put(routeComponent.substring(1), pathComponent);
} else if (routeComponent.compareToIgnoreCase(pathComponent) != 0) {
return null;
}
}
return routeParameters;
}
/**
* Sanitizes a URL String to remove '/' characters.
*
* @param urlString A String object representing a url.
* @return A String object representing the sanitized url.
*/
public static String sanitizeURL(String urlString) {
if (urlString == null)
return null;
String sanitizedURLString = urlString.replaceAll("^/+", "");
sanitizedURLString = sanitizedURLString.replaceAll("/+$", "");
sanitizedURLString = sanitizedURLString.replaceAll("(?<!:)(/)+", "/");
return sanitizedURLString;
}
public String getScheme() {
return mScheme;
}
public HashMap<String, String> getQueryParameters() {
return mQueryParameters;
}
/**
* Tries to match a Route object to this URL instance.
* Will perform path components and route components validation and return the matched values
* in case it is a valid match.
*
* @param route A Route instance.
* @return A HashMap where the keys are route components and values are their value
* representation of path components.
*/
public HashMap<String, String> matchesWithRoute(Route route) {
List<String> pathComponents = new ArrayList<>();
pathComponents.add(mUri.getAuthority());
pathComponents.addAll(mUri.getPathSegments());
List<String> routeComponents = route.getComponents();
if (routeComponents == null || pathComponents.size() != routeComponents.size())
return null;
return matchComponents(pathComponents, routeComponents);
}
public String getURL() {
return mUri.toString();
}
}