package com.hundsun.jresplus.web.url; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author LeoHu copy by sagahl copy by fish * */ public class RestUrlBroker extends URLBroker { private static final Pattern NAMES_PATTERN = Pattern .compile("\\{([^/]+?)\\}"); private Map<String, UrlTemplate> name2Template; public void setUrlTemplates(Map<String, String> templates) { if (templates == null || templates.isEmpty()) { throw new IllegalArgumentException("templates can't empty."); } this.name2Template = new HashMap<String, UrlTemplate>(templates.size()); for (Entry<String, String> entry : templates.entrySet()) { UrlTemplate temp = new UrlTemplate(entry.getValue()); this.name2Template.put(entry.getKey(), temp); } if (logger.isDebugEnabled()) { logger.debug("init RestUrlBroker whih Templates:" + this.name2Template); } } @Override public QueryData setTarget(String target) { UrlTemplate t = this.name2Template.get(target); if (t == null) { return super.setTarget(target); } return new RestQueryData(t); } public class RestQueryData extends QueryData { private UrlTemplate template; private Map<String, String> restVariables = new HashMap<String, String>( 2); public RestQueryData(UrlTemplate template) { this.template = template; } @Override public QueryData addQueryData(String id, String value) { if (this.template.isVariable(id)) { restVariables.put(id, value); } else { if (this.query == null) { query = new StringBuilder("?"); } super.addQueryData(id, value); } return this; } @Override public QueryData addNullQueryData(String id) { if (this.template.isVariable(id)) { restVariables.put(id, ""); } else { if (this.query == null) { query = new StringBuilder("?"); } super.addNullQueryData(id); } return this; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(RestUrlBroker.this.server); sb.append(this.template.merge(restVariables)); if (this.query != null) { sb.append(query); } char last = sb.charAt(sb.length() - 1); if (last == '&') { sb.deleteCharAt(sb.length() - 1); } return sb.toString(); } } private static class UrlTemplate { private String pathTemplate; /** */ private String[] pathSplits; /** */ private String[] variables; private UrlTemplate(String pathTemplate) { if (!pathTemplate.startsWith("/")) { pathTemplate = "/" + pathTemplate; } this.pathTemplate = pathTemplate; this.pathSplits = NAMES_PATTERN.split(pathTemplate); if (pathSplits == null || pathSplits.length == 0) { throw new IllegalArgumentException(pathTemplate + " is not a vaild url path."); } if (pathSplits.length == 1) { throw new IllegalArgumentException(pathTemplate + " is not a vaild rest url path."); } List<String> variableNames = new ArrayList<String>(); Matcher m = NAMES_PATTERN.matcher(pathTemplate); while (m.find()) { variableNames.add(m.group(1)); } this.variables = variableNames.toArray(new String[variableNames .size()]); } private boolean isVariable(String v) { for (String var : this.variables) { if (var.equals(v)) { return true; } } return false; } private String merge(Map<String, String> vmap) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < this.pathSplits.length; i++) { sb.append(pathSplits[i]); if (i < variables.length) { String v = vmap.get(variables[i]); if (v == null) { sb.append(""); } else { sb.append(v); } } } return sb.toString(); } @Override public String toString() { return pathTemplate; } } }