/** 渲染URI query string。 */ @Override protected final void renderQuery(StringBuilder buf) { if (!getQuery().isEmpty()) { buf.append("?"); for (Iterator<Map.Entry<String, Object>> i = getQuery().entrySet().iterator(); i.hasNext(); ) { Map.Entry<String, Object> entry = i.next(); String id = escapeURL(entry.getKey()); Object value = entry.getValue(); if (value instanceof String[]) { int length = ((String[]) value).length; for (int j = 0; j < length; j++) { buf.append(id).append("=").append(escapeURL(((String[]) value)[j])); if (j + 1 < length) { buf.append("&"); } } } else { buf.append(id).append("=").append(escapeURL(String.valueOf(value))); } if (i.hasNext()) { buf.append("&"); } } } }
/** 取得不包含query和reference的serverURI。 */ public String getServerURI() { processInterceptors(); StringBuilder buf = new StringBuilder(); render(buf, true); return buf.toString(); }
/** 将path转换成相对于base的相对路径。 */ private String getRelativePath(String base, String path) { // 去除base中最后一段路径,例如: // /sub/dir/index.html -> /sub/dir // /sub/dir/ -> /sub/dir int index = base.lastIndexOf("/"); if (index >= 0) { base = base.substring(0, index); } // 特殊情况:base为空,直接返回path,但除去开头的/ if (isEmpty(base)) { if (path.startsWith("/")) { return path.replaceFirst("^/+", EMPTY_STRING); } else { return path; } } Matcher baseMatcher = pathPattern.matcher(base); Matcher pathMatcher = pathPattern.matcher(path); boolean baseFound; boolean pathFound; // 去除base和path中相同的部分,例如: // /this/is/base/dir -> /base/dir // /this/is/my/path -> /my/path do { baseFound = baseMatcher.find(); pathFound = pathMatcher.find(); } while (baseFound && pathFound && isEquals(baseMatcher.group(2), pathMatcher.group(2))); StringBuilder relativePath = new StringBuilder(); // 将base中剩余的部分,分别转换成../ for (; baseFound; baseFound = baseMatcher.find()) { relativePath.append("../"); } // 将path中剩余的部分,追加到末尾 while (pathFound) { relativePath.append(pathMatcher.group(2)); pathFound = pathMatcher.find(); if (pathFound) { relativePath.append("/"); } } return relativePath.toString(); }
private String getSubPathAsString(int segment, boolean multi) { assertSegment(segment); StringBuilder buf = new StringBuilder(); int endIndex = multi ? path.size() : pathSegmentIndexes[segment]; int beginIndex = segment > 0 ? pathSegmentIndexes[segment - 1] : 0; for (int i = beginIndex; i < endIndex; i++) { buf.append("/").append(path.get(i)); } return buf.toString(); }
/** 渲染URI服务器信息。 */ @Override protected final void renderServer(StringBuilder buf) { // scheme:// String serverScheme = getEffectiveServerScheme(getServerScheme()); buf.append(serverScheme); buf.append("://"); // user:password@ String loginUser = getLoginUser(); String loginPassword = getLoginPassword(); if (!isEmpty(loginUser)) { buf.append(loginUser); if (!isEmpty(loginPassword)) { buf.append(":").append(loginPassword); } buf.append("@"); } // hostname:port String serverName = getServerName(); if (!isEmpty(serverName)) { buf.append(serverName); if (!isDefaultPort(serverScheme)) { buf.append(":"); buf.append(getServerPort()); } } }
/** 取得指定在enum中所标注的、指定locale的消息串,并格式化之。 */ public String format(T key, Locale locale, Object... args) { ResourceBundle bundle = getBundle(locale); String strKey = String.valueOf(key); String message; try { message = format(bundle.getString(strKey), args); } catch (MissingResourceException e) { StringBuilder buffer = new StringBuilder(); buffer.append(strKey).append(": "); if (args != null && args.length > 0) { for (Object arg : args) { buffer.append(arg).append(", "); } } buffer.setLength(buffer.length() - 2); message = buffer.toString(); } return message; }
/** 渲染URI path。 */ @Override protected final void renderPath(StringBuilder buf) { for (String path : URIBroker.this.path) { buf.append("/").append(escapeURL(path)); } }
private void render(StringBuilder buf, boolean renderServerURIOnly) { URIType type = renderServerURIOnly || getURIType() == null ? URIType.full : getURIType(); BaseURI baseURI = null; boolean renderServer = true; switch (type) { case auto: case absolute: case relative: baseURI = createBaseURI(); if (baseURI != null) { // 当且仅当baseURI中的server信息和broker中的一致,才不渲染server String scheme = getEffectiveServerScheme(getServerScheme()); int port = getEffectiveServerPort(scheme, getServerPort()); if (isEquals(scheme, baseURI.serverScheme) && isEquals(getServerName(), baseURI.serverName) && port == baseURI.serverPort) { renderServer = false; } } break; case full: } // server info if (renderServer) { if (renderer.isServerRendered()) { buf.append(renderer.serverBuffer); } else { renderServer(buf); } } // path info String path = EMPTY_STRING; if (!URIBroker.this.path.isEmpty()) { StringBuilder pathBuf = new StringBuilder(); if (renderer.isPathRendered()) { pathBuf.append(renderer.pathBuffer); } else { renderPath(pathBuf); } path = pathBuf.toString(); } path = trimToEmpty(processPathInterceptors(path)); // 将path转换成相对路径(前提:server未渲染) if (!renderServer) { switch (type) { case relative: path = getRelativePath(baseURI.path, path); break; case auto: String relativePath = getRelativePath(baseURI.path, path); if (!relativePath.startsWith("../")) { path = relativePath; } break; case full: case absolute: } } if (renderServer && !path.startsWith("/")) { buf.append("/"); } buf.append(path); if (!renderServerURIOnly) { // query info if (renderer.isQueryRendered()) { buf.append(renderer.queryBuffer); } else { renderQuery(buf); } // #reference String reference = getReference(); if (!isEmpty(reference)) { buf.append("#"); buf.append(reference); } } }
private Object preprocessMethodOrConstructor( int mod, Class<?> returnType, Class<?> declaringClass, String methodName, Class<?>[] paramTypes, Class<?>[] exceptionTypes) { StringBuilder sb = new StringBuilder(); // return type if (returnType != null) { sb.append(getSimpleClassName(returnType)).append(" "); } // declaring class sb.append(getSimpleClassName(declaringClass)); // method name if (methodName != null) { sb.append(".").append(methodName); } sb.append("("); // params for (int i = 0; i < paramTypes.length; i++) { sb.append(getSimpleClassName(paramTypes[i])); if (i < paramTypes.length - 1) { sb.append(", "); } } sb.append(")"); // exceptions if (exceptionTypes.length > 0) { sb.append(" throws "); for (int i = 0; i < exceptionTypes.length; i++) { sb.append(getSimpleClassName(exceptionTypes[i])); if (i < exceptionTypes.length - 1) { sb.append(","); } } } return sb.toString(); }