io.vertx.up.uca.rs.config.PathResolver Maven / Gradle / Ivy
package io.vertx.up.uca.rs.config;
import io.vertx.up.log.Annal;
import io.vertx.up.eon.Strings;
import io.vertx.up.eon.Values;
import io.vertx.zero.exception.PathAnnoEmptyException;
import io.vertx.up.util.Ut;
import io.vertx.up.fn.Fn;
import javax.ws.rs.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Path resolver
* 1. Root ( Class ) + Context ( Method )
* 2. Context ( Method )
*/
class PathResolver {
private static final Annal LOGGER = Annal.get(PathResolver.class);
/**
* Parse the api endpoint for @Path ( Class Level )
*
* @param path JSR311 annotation
* @return normalized uri
*/
public static String resolve(final Path path) {
Fn.outUp(null == path, LOGGER,
PathAnnoEmptyException.class, PathResolver.class);
// Calculate single path
return resolve(path, null);
}
/**
* Parse the api endpoint for @Path ( Method Level )
*
* @param path JSR311 annotation
* @param root root folder or path
* @return normalized uri
*/
@SuppressWarnings("all")
public static String resolve(final Path path, final String root) {
Fn.outUp(null == path, LOGGER,
PathAnnoEmptyException.class, PathResolver.class);
return Fn.getSemi(Ut.isNil(root), LOGGER, () -> calculate(path(path.value())),
() -> {
final String api = calculate(root);
final String contextPath = calculate(path.value());
// If api has been calculated to
return Values.ONE == api.length() ?
path(contextPath) : path(api + contextPath);
});
}
/**
* JSR311: /query/{name}
* Named: /query/:name ( Vertx Format )
*
* @param path JSR311 annotation
* @return resolved Vert.x and JSR311
*/
@SuppressWarnings("all")
private static String path(final String path) {
final String regex = "\\{\\w+\\}";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(path);
String tempStr = path;
String result = "";
while (matcher.find()) {
result = matcher.group();
// Shift left brace and right brace
final String replaced = result.trim().substring(1, result.length() - 1);
tempStr = tempStr.replace(result, ":" + replaced);
}
return tempStr;
}
/**
* Calculate the path
* 1. Remove the last '/';
* 2. Append the '/' to first;
* 3. Replaced all duplicated '//';
*
* @param path input path no normalized.
* @return calculated uri
*/
@SuppressWarnings("all")
private static String calculate(final String path) {
String uri = path;
// 1. Shift the SLASH: Multi -> Single one.
uri = uri.replaceAll("\\/+", Strings.SLASH);
// 1. Remove the last SLASH
if (uri.endsWith(Strings.SLASH)) {
uri = uri.substring(0, uri.lastIndexOf(Strings.SLASH));
}
// Uri must begin with SLASH
final String processed = uri;
return Fn.getNull(() ->
processed.startsWith(Strings.SLASH) ?
processed : Strings.SLASH + processed,
uri);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy