package by.istin.android.xcore.utils; import java.util.ArrayList; import java.util.List; public class UrlBuilder { public static final String SCHEME_END = "://"; public static final String HTTP = "http" + SCHEME_END; public static final String HTTPS = "https" + SCHEME_END; public static final String AMP = "&"; public static final String Q = "?"; private class ParamValue { private ParamValue(String param, String value, boolean autoEncode) { this.param = param; this.value = value; this.autoEncode = autoEncode; } private final String param; private final String value; private boolean autoEncode = true; } private final Object mLock = new Object(); private final StringBuffer mUrlStringBuilder; private String mPath; private final List<ParamValue> mListParams = new ArrayList<ParamValue>(); private final List<ParamValue> mListParamsUnknown = new ArrayList<ParamValue>(); private UrlBuilder(String path) { mPath = path; mUrlStringBuilder = new StringBuffer(mPath); } public static UrlBuilder http(String host) { return scheme(HTTP, host); } public static UrlBuilder https(String host) { return scheme(HTTPS, host); } public static UrlBuilder scheme(String scheme, String host) { return new UrlBuilder(scheme + host); } public static UrlBuilder parent(UrlBuilder urlBuilder) { UrlBuilder builder = new UrlBuilder(urlBuilder.mPath); builder.mListParams.addAll(urlBuilder.mListParams); builder.mListParamsUnknown.addAll(urlBuilder.mListParamsUnknown); return builder; } public UrlBuilder path(String path) { mPath+=path; synchronized (mLock) { mUrlStringBuilder.append(path); } return this; } public UrlBuilder s(String value) { path("/" + value); return this; } public UrlBuilder param(String param) { mListParamsUnknown.add(new ParamValue(param, StringUtil.EMPTY, false)); return this; } public UrlBuilder param(String param, String value) { return param(param, value, true); } private String format(String ... params){ String result = mUrlStringBuilder.toString(); try { if (params == null) { return result; } return StringUtil.format(result, params); } finally { mUrlStringBuilder.setLength(0); mUrlStringBuilder.append(mPath); } } public UrlBuilder param(String param, String value, boolean autoEncode) { mListParams.add(new ParamValue(param, value, autoEncode)); return this; } private static String[] join(String[] args1, String[] args2) { if (args1 == null) { return args2; } if (args2 == null) { return args1; } String[] argsAll = new String[args1.length + args2.length]; System.arraycopy(args1, 0, argsAll, 0, args1.length); System.arraycopy(args2, 0, argsAll, args1.length, args2.length); return argsAll; } public String build(String ... args) { synchronized (mLock) { String[] resultArgs = null; if (!mListParams.isEmpty() || !mListParamsUnknown.isEmpty()) { String[] argsKnown = new String[mListParams.size()]; int i = 0; for (ParamValue paramValue : mListParams) { appendPrefix(); mUrlStringBuilder.append(paramValue.param).append("=%s"); argsKnown[i] = (paramValue.autoEncode ? StringUtil.encode(paramValue.value) : paramValue.value); i++; } for (ParamValue paramValue : mListParamsUnknown) { appendPrefix(); mUrlStringBuilder.append(paramValue.param).append("=%s"); } resultArgs = join(argsKnown, args); } return format(resultArgs); } } @Override public String toString() { return build(); } private void appendPrefix() { if (mUrlStringBuilder.indexOf(Q) > 0) { mUrlStringBuilder.append(AMP); } else { mUrlStringBuilder.append(Q); } } }