package cloudone.cumulonimbus.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; /** * Utility methods for the path. * * @author Martin Mares (martin.mares at oracle.com) */ public class PathUtil { private static final Logger LOGGER = LoggerFactory.getLogger(PathUtil.class); private static final Pattern MULTISLASHES_PATTERN = Pattern.compile("/{2,}"); public static String normalizePath(String path) { if (path == null || path.length() == 0) { path = "/"; } else if (!path.startsWith("/")) { path = "/" + path.trim(); } else { path = path.trim(); } if (path.length() > 1 && path.endsWith("/")) { path = path.substring(0, path.length() - 1); } return path; } /** * Devides path into ints segments. * * @param path to be parsed. * @param toRegexp if {@code true} then it will parse path parameter definition into regexp. */ public static List<String> parsePath(String path, final boolean toRegexp) { if (path == null) { return Collections.emptyList(); } path = path.trim(); if (path.length() == 0 || "/".equals(path)) { return Collections.emptyList(); } List<String> result = new ArrayList<>(); boolean first = true; StringBuilder standard = new StringBuilder(); StringBuilder parameter = null; boolean inParameter = false; for (char c : path.toCharArray()) { if (first) { first = false; if (c == '/') { continue; //Must skip first slash } } switch (c) { case '/': if (inParameter) { parameter.append(c); } else { result.add(standard.toString()); standard.setLength(0); } break; case '{': if (inParameter) { parameter.append(c); } else if (toRegexp) { inParameter = true; parameter = new StringBuilder(); } else { standard.append(c); } break; case '}': if (inParameter) { standard.append(deriveRegexpFromPathParam(parameter.toString())); parameter = null; inParameter = false; } else if (toRegexp) { if (escapeInRegexp(c)) { standard.append('\\'); } standard.append(c); } else { standard.append(c); } break; default: if (inParameter) { parameter.append(c); } else { if (toRegexp && escapeInRegexp(c)) { standard.append('\\'); } standard.append(c); } } } if (standard.length() > 0) { result.add(standard.toString()); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("parsePath(" + path + ", " + toRegexp + ") -> " + result); } return result; } private static boolean escapeInRegexp(char c) { return ".^$*+?()[{\\|}".indexOf(c) > -1; } private static String deriveRegexpFromPathParam(String pathParam) { if (pathParam == null) { return ""; } if (pathParam.endsWith("}")) { pathParam = pathParam.substring(pathParam.length() - 1); } int ind = pathParam.indexOf(':'); if (ind >= 0) { return "(" + pathParam.substring(ind + 1) + ")"; } else { return "(.*)"; } } }