一、前言
关于camel-core源码包中org.apache.camel.util.URISupport链接常用处理支持类,主要抽取指定路径入参extractRemainderPath、转换参数为Map的处理parseQuery、解析url的参数为Map的方法parseParameters等对于同一资源地址URL的相关操作支持。
二、源码说明
package org.apache.camel.util;@b@@b@import java.io.UnsupportedEncodingException;@b@import java.net.URI;@b@import java.net.URISyntaxException;@b@import java.net.URLDecoder;@b@import java.net.URLEncoder;@b@import java.util.ArrayList;@b@import java.util.Iterator;@b@import java.util.LinkedHashMap;@b@import java.util.List;@b@import java.util.Map;@b@import java.util.Map.Entry;@b@import java.util.Set;@b@import java.util.regex.Matcher;@b@import java.util.regex.Pattern;@b@@b@public final class URISupport@b@{@b@ public static final String RAW_TOKEN_START = "RAW(";@b@ public static final String RAW_TOKEN_END = ")";@b@ private static final Pattern SECRETS = Pattern.compile("([?&][^=]*(?:passphrase|password|secretKey)[^=]*)=(RAW\\(.*\\)|[^&]*)", 2);@b@ private static final Pattern USERINFO_PASSWORD = Pattern.compile("(.*://.*:)(.*)(@)");@b@ private static final Pattern PATH_USERINFO_PASSWORD = Pattern.compile("(.*:)(.*)(@)");@b@ private static final String CHARSET = "UTF-8";@b@@b@ public static String sanitizeUri(String uri)@b@ {@b@ String sanitized = uri;@b@ if (uri != null) {@b@ sanitized = SECRETS.matcher(sanitized).replaceAll("$1=xxxxxx");@b@ sanitized = USERINFO_PASSWORD.matcher(sanitized).replaceFirst("$1xxxxxx$3");@b@ }@b@ return sanitized;@b@ }@b@@b@ public static String sanitizePath(String path)@b@ {@b@ String sanitized = path;@b@ if (path != null)@b@ sanitized = PATH_USERINFO_PASSWORD.matcher(sanitized).replaceFirst("$1xxxxxx$3");@b@@b@ return sanitized;@b@ }@b@@b@ public static String extractRemainderPath(URI u, boolean useRaw)@b@ {@b@ String path = (useRaw) ? u.getRawSchemeSpecificPart() : u.getSchemeSpecificPart();@b@@b@ if (path.startsWith("//"))@b@ path = path.substring(2);@b@@b@ int idx = path.indexOf(63);@b@ if (idx > -1) {@b@ path = path.substring(0, idx);@b@ }@b@@b@ return path;@b@ }@b@@b@ public static Map<String, Object> parseQuery(String uri)@b@ throws URISyntaxException@b@ {@b@ return parseQuery(uri, false);@b@ }@b@@b@ public static Map<String, Object> parseQuery(String uri, boolean useRaw)@b@ throws URISyntaxException@b@ {@b@ return parseQuery(uri, useRaw, false);@b@ }@b@@b@ public static Map<String, Object> parseQuery(String uri, boolean useRaw, boolean lenient)@b@ throws URISyntaxException@b@ {@b@ if ((!(lenient)) && @b@ (uri != null) && (uri.endsWith("&"))) {@b@ throw new URISyntaxException(uri, "Invalid uri syntax: Trailing & marker found. Check the uri and remove the trailing & marker.");@b@ }@b@@b@ if ((uri == null) || (ObjectHelper.isEmpty(uri)))@b@ {@b@ return new LinkedHashMap(0);@b@ }@b@@b@ try@b@ {@b@ Map rc = new LinkedHashMap();@b@@b@ boolean isKey = true;@b@ boolean isValue = false;@b@ boolean isRaw = false;@b@ StringBuilder key = new StringBuilder();@b@ StringBuilder value = new StringBuilder();@b@@b@ for (int i = 0; i < uri.length(); ++i)@b@ {@b@ char next;@b@ char ch = uri.charAt(i);@b@@b@ if (i <= uri.length() - 2)@b@ next = uri.charAt(i + 1);@b@ else {@b@ next = ';@b@ }@b@@b@ isRaw = value.toString().startsWith("RAW(");@b@@b@ if (isRaw) {@b@ if (isKey)@b@ key.append(ch);@b@ else if (isValue) {@b@ value.append(ch);@b@ }@b@@b@ boolean end = (ch == ")".charAt(0)) && (((next == '&') || (next == 0)));@b@ if (end)@b@ {@b@ addParameter(key.toString(), value.toString(), rc, (useRaw) || (isRaw));@b@ key.setLength(0);@b@ value.setLength(0);@b@ isKey = true;@b@ isValue = false;@b@ isRaw = false;@b@@b@ ++i;@b@ }@b@@b@ }@b@ else if ((isKey) && (ch == '=')) {@b@ isKey = false;@b@ isValue = true;@b@ isRaw = false;@b@ }@b@ else if (ch == '&')@b@ {@b@ addParameter(key.toString(), value.toString(), rc, (useRaw) || (isRaw));@b@ key.setLength(0);@b@ value.setLength(0);@b@ isKey = true;@b@ isValue = false;@b@ isRaw = false;@b@ }@b@ else if (isKey) {@b@ key.append(ch);@b@ } else if (isValue) {@b@ value.append(ch);@b@ }@b@@b@ }@b@@b@ if (key.length() > 0) {@b@ addParameter(key.toString(), value.toString(), rc, (useRaw) || (isRaw));@b@ }@b@@b@ return rc;@b@ }@b@ catch (UnsupportedEncodingException e) {@b@ URISyntaxException se = new URISyntaxException(e.toString(), "Invalid encoding");@b@ se.initCause(e);@b@ throw se;@b@ }@b@ }@b@@b@ private static void addParameter(String name, String value, Map<String, Object> map, boolean isRaw) throws UnsupportedEncodingException {@b@ name = URLDecoder.decode(name, "UTF-8");@b@ if (!(isRaw))@b@ {@b@ String s = StringHelper.replaceAll(value, "%", "%25");@b@ value = URLDecoder.decode(s, "UTF-8");@b@ }@b@@b@ if (map.containsKey(name))@b@ {@b@ List list;@b@ Object existing = map.get(name);@b@@b@ if (existing instanceof List) {@b@ list = CastUtils.cast((List)existing);@b@ }@b@ else {@b@ list = new ArrayList();@b@ String s = (existing != null) ? existing.toString() : null;@b@ if (s != null)@b@ list.add(s);@b@ }@b@@b@ list.add(value);@b@ map.put(name, list);@b@ } else {@b@ map.put(name, value);@b@ }@b@ }@b@@b@ public static Map<String, Object> parseParameters(URI uri)@b@ throws URISyntaxException@b@ {@b@ String query = uri.getQuery();@b@ if (query == null) {@b@ String schemeSpecificPart = uri.getSchemeSpecificPart();@b@ int idx = schemeSpecificPart.indexOf(63);@b@ if (idx < 0)@b@ {@b@ return new LinkedHashMap(0);@b@ }@b@ query = schemeSpecificPart.substring(idx + 1);@b@ }@b@ else {@b@ query = stripPrefix(query, "?");@b@ }@b@ return parseQuery(query);@b@ }@b@@b@ public static void resolveRawParameterValues(Map<String, Object> parameters)@b@ {@b@ for (Map.Entry entry : parameters.entrySet())@b@ if (entry.getValue() != null)@b@ {@b@ List list;@b@ int i;@b@ Object value = entry.getValue();@b@ if (value instanceof List) {@b@ list = (List)value;@b@ for (i = 0; i < list.size(); ++i) {@b@ Object obj = list.get(i);@b@ if (obj != null) {@b@ String str = obj.toString();@b@ if ((str.startsWith("RAW(")) && (str.endsWith(")"))) {@b@ str = str.substring(4, str.length() - 1);@b@@b@ list.set(i, str);@b@ }@b@ }@b@ }@b@ } else {@b@ String str = entry.getValue().toString();@b@ if ((str.startsWith("RAW(")) && (str.endsWith(")"))) {@b@ str = str.substring(4, str.length() - 1);@b@ entry.setValue(str);@b@ }@b@ }@b@ }@b@ }@b@@b@ public static URI createURIWithQuery(URI uri, String query)@b@ throws URISyntaxException@b@ {@b@ ObjectHelper.notNull(uri, "uri");@b@@b@ String s = uri.toString();@b@ String before = ObjectHelper.before(s, "?");@b@ if (before == null)@b@ before = ObjectHelper.before(s, "#");@b@@b@ if (before != null)@b@ s = before;@b@@b@ if (query != null)@b@ s = s + "?" + query;@b@@b@ if ((!(s.contains("#"))) && (uri.getFragment() != null)) {@b@ s = s + "#" + uri.getFragment();@b@ }@b@@b@ return new URI(s);@b@ }@b@@b@ public static String stripPrefix(String value, String prefix)@b@ {@b@ if ((value != null) && (value.startsWith(prefix)))@b@ return value.substring(prefix.length());@b@@b@ return value;@b@ }@b@@b@ public static String createQueryString(Map<String, Object> options)@b@ throws URISyntaxException@b@ {@b@ try@b@ {@b@ if (options.size() > 0) {@b@ StringBuilder rc = new StringBuilder();@b@ boolean first = true;@b@ for (Iterator localIterator1 = options.keySet().iterator(); localIterator1.hasNext(); ) { Iterator it;@b@ Object o = localIterator1.next();@b@ if (first)@b@ first = false;@b@ else {@b@ rc.append("&");@b@ }@b@@b@ String key = (String)o;@b@ Object value = options.get(key);@b@@b@ if (value instanceof List) {@b@ List list = (List)value;@b@ for (it = list.iterator(); it.hasNext(); ) {@b@ String s = (String)it.next();@b@ appendQueryStringParameter(key, s, rc);@b@@b@ if (it.hasNext())@b@ rc.append("&");@b@ }@b@ }@b@ else@b@ {@b@ String s = (value != null) ? value.toString() : null;@b@ appendQueryStringParameter(key, s, rc);@b@ }@b@ }@b@ return rc.toString();@b@ }@b@ return "";@b@ }@b@ catch (UnsupportedEncodingException e) {@b@ URISyntaxException se = new URISyntaxException(e.toString(), "Invalid encoding");@b@ se.initCause(e);@b@ throw se;@b@ }@b@ }@b@@b@ private static void appendQueryStringParameter(String key, String value, StringBuilder rc) throws UnsupportedEncodingException {@b@ rc.append(URLEncoder.encode(key, "UTF-8"));@b@@b@ if (value != null) {@b@ rc.append("=");@b@ if ((value.startsWith("RAW(")) && (value.endsWith(")")))@b@ {@b@ String s = StringHelper.replaceAll(value, "%", "%25");@b@ rc.append(s);@b@ } else {@b@ rc.append(URLEncoder.encode(value, "UTF-8"));@b@ }@b@ }@b@ }@b@@b@ public static URI createRemainingURI(URI originalURI, Map<String, Object> params)@b@ throws URISyntaxException@b@ {@b@ String s = createQueryString(params);@b@ if (s.length() == 0)@b@ s = null;@b@@b@ return createURIWithQuery(originalURI, s);@b@ }@b@@b@ public static String appendParametersToURI(String originalURI, Map<String, Object> newParameters)@b@ throws URISyntaxException, UnsupportedEncodingException@b@ {@b@ URI uri = new URI(normalizeUri(originalURI));@b@ Map parameters = parseParameters(uri);@b@ parameters.putAll(newParameters);@b@ return createRemainingURI(uri, parameters).toString();@b@ }@b@@b@ public static String normalizeUri(String uri)@b@ throws URISyntaxException, UnsupportedEncodingException@b@ {@b@ URI u = new URI(UnsafeUriCharactersEncoder.encode(uri, true));@b@ String path = u.getSchemeSpecificPart();@b@ String scheme = u.getScheme();@b@@b@ if ((scheme == null) || (path == null)) {@b@ return uri;@b@ }@b@@b@ if (path.startsWith("//"))@b@ path = path.substring(2);@b@@b@ int idx = path.indexOf(63);@b@@b@ if (idx != -1) {@b@ path = path.substring(0, idx);@b@ }@b@@b@ if (u.getScheme().startsWith("http"))@b@ path = UnsafeUriCharactersEncoder.encodeHttpURI(path);@b@ else {@b@ path = UnsafeUriCharactersEncoder.encode(path);@b@ }@b@@b@ String userInfoPath = path;@b@ if (userInfoPath.contains("/"))@b@ userInfoPath = userInfoPath.substring(0, userInfoPath.indexOf("/"));@b@@b@ if (StringHelper.countChar(userInfoPath, '@') > 1) {@b@ int max = userInfoPath.lastIndexOf(64);@b@ String before = userInfoPath.substring(0, max);@b@@b@ String after = path.substring(max);@b@@b@ before = StringHelper.replaceAll(before, "@", "%40");@b@ path = before + after;@b@ }@b@@b@ Map parameters = parseParameters(u);@b@ if (parameters.isEmpty())@b@ {@b@ return buildUri(scheme, path, null);@b@ }@b@@b@ List keys = new ArrayList(parameters.keySet());@b@ keys.sort(null);@b@@b@ Map sorted = new LinkedHashMap(parameters.size());@b@ for (String key : keys) {@b@ sorted.put(key, parameters.get(key));@b@ }@b@@b@ String query = createQueryString(sorted);@b@ return buildUri(scheme, path, query);@b@ }@b@@b@ private static String buildUri(String scheme, String path, String query)@b@ {@b@ return scheme + "://" + path + ((query != null) ? "?" + query : "");@b@ }@b@@b@ public static Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix) {@b@ Map rc = new LinkedHashMap(properties.size());@b@@b@ for (Iterator it = properties.entrySet().iterator(); it.hasNext(); ) {@b@ Map.Entry entry = (Map.Entry)it.next();@b@ String name = (String)entry.getKey();@b@ if (name.startsWith(optionPrefix)) {@b@ Object value = properties.get(name);@b@ name = name.substring(optionPrefix.length());@b@ rc.put(name, value);@b@ it.remove();@b@ }@b@ }@b@@b@ return rc;@b@ }@b@@b@ public static String pathAndQueryOf(URI uri) {@b@ String path = uri.getPath();@b@@b@ String pathAndQuery = path;@b@ if (ObjectHelper.isEmpty(path)) {@b@ pathAndQuery = "/";@b@ }@b@@b@ String query = uri.getQuery();@b@ if (ObjectHelper.isNotEmpty(query)) {@b@ pathAndQuery = pathAndQuery + "?" + query;@b@ }@b@@b@ return pathAndQuery;@b@ }@b@}