package org.beanfuse.struts2.route; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.CompareToBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 路由调转配置 * * @author chaostone <br> * /:controller:ext =>:method=index||get("method") * /:controller/:method:ext */ public class Profile implements Comparable { private static final Logger logger = LoggerFactory.getLogger(Profile.class); // 配置名 private String name; // action所在的包,匹配action的唯一条件 private String packageName; private String[] packageSegs; // action前缀 private String pattern = ""; private String[] patternSegs = new String[0]; // action类名后缀 private String actionSuffix = ""; // 路径前缀 private String viewPath = ""; // 路径后缀 private String viewExtension = ""; // 缺省的action中的方法 private String defaultMethod = "index"; private String uriStyle = "simple"; private String pathStyle = "simple"; /** URI的后缀 */ private String uriExtension; // 匹配缓存[className,matchInfo] private Map<String, MatchInfo> cache = new HashMap(); /** * 得到控制器的起始位置 * * @param className * @return */ public MatchInfo getCtlMatchInfo(final String className) { MatchInfo match = cache.get(className); if (null == match) { match = getMatchInfo(patternSegs, className); if (-1 != match.startIndex) { synchronized (cache) { cache.put(className, match); } logger.debug("get match info {}", match); } } return match; } /** * 给定action是否符合该配置文件 * * @param className * @return */ public boolean isMatch(final String className) { return -1 != getMatchInfo(packageSegs, className).startIndex; } public int matchedIndex(final String className) { return getMatchInfo(packageSegs, className).startIndex; } public MatchInfo getMatchInfo(final String[] pattens, final String className) { String sub = className; int index = 0; MatchInfo match = new MatchInfo(-1); for (int i = 0; i < pattens.length; i++) { int subIndex = sub.indexOf(pattens[i]); if (-1 == subIndex) { return match; } // 串接所有匹配项保留部分 if (0 != subIndex) { if (match.reserved.length() > 0) { match.reserved.append('.'); } match.reserved.append(sub.substring(0, subIndex)); } index += (subIndex + pattens[i].length()); if (i != pattens.length - 1) { sub = sub.substring(subIndex + pattens[i].length()); if (StringUtils.isEmpty(sub)) { match.startIndex = className.length() - 1; return match; } } } match.startIndex = index - 1; return match; } /** * 子包优先 */ public int compareTo(Object object) { Profile myClass = (Profile) object; return new CompareToBuilder().append(myClass.packageName, this.packageName).toComparison(); } public String getSimpleName(String className) { String postfix = getActionSuffix(); String simpleName = className.substring(className.lastIndexOf('.') + 1); if (StringUtils.contains(simpleName, postfix)) { simpleName = StringUtils.uncapitalize(simpleName.substring(0, simpleName.length() - postfix.length())); } else { simpleName = StringUtils.uncapitalize(simpleName); } StringBuilder infix = new StringBuilder(); infix.append(StringUtils.substringBeforeLast(className, ".")); if (infix.length() == 0) return simpleName; infix.append('.'); infix.append(simpleName); // 将.替换成/ for (int i = 0; i < infix.length(); i++) { if (infix.charAt(i) == '.') { infix.setCharAt(i, '/'); } } return infix.toString(); } /** * 将前后缀去除后,中间的.替换为/<br> * 不以/开始。 * * @param clazz * @param profile * @return */ public String getInfix(String className) { String postfix = getActionSuffix(); String simpleName = className.substring(className.lastIndexOf('.') + 1); if (StringUtils.contains(simpleName, postfix)) { simpleName = StringUtils.uncapitalize(simpleName.substring(0, simpleName.length() - postfix.length())); } else { simpleName = StringUtils.uncapitalize(simpleName); } MatchInfo match = getCtlMatchInfo(className); StringBuilder infix = new StringBuilder(match.getReserved().toString()); if (infix.length() > 0) { infix.append('.'); } String remainder = StringUtils.substring(StringUtils.substringBeforeLast(className, "."), match.getStartIndex() + 1); if (remainder.length() > 0) { infix.append(remainder).append('.'); } if (infix.length() == 0) return simpleName; infix.append(simpleName); // 将.替换成/ for (int i = 0; i < infix.length(); i++) { if (infix.charAt(i) == '.') { infix.setCharAt(i, '/'); } } return infix.toString(); } /** * @see java.lang.Object#toString() */ public String toString() { return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).append("name", this.name) .append("packageName", this.packageName).append("pattern", this.pattern).append( "actionSuffix", this.actionSuffix).append("viewPath", this.viewPath) .append("viewExtension", this.viewExtension).append("defaultMethod", this.defaultMethod).append("uriStyle", this.uriStyle).append("pathStyle", this.pathStyle).toString(); } public String getPattern() { return pattern; } public void setPattern(String pattern) { this.pattern = pattern; this.patternSegs = StringUtils.split(pattern, '*'); } public String getViewPath() { return viewPath; } public void setViewPath(String pagePath) { this.viewPath = pagePath; } public String getActionSuffix() { return actionSuffix; } public void setActionSuffix(String ctlPostfix) { this.actionSuffix = ctlPostfix; } public String getViewExtension() { return viewExtension; } public void setViewExtension(String pagePostfix) { this.viewExtension = pagePostfix; } public String getDefaultMethod() { return defaultMethod; } public void setDefaultMethod(String defaultMethod) { this.defaultMethod = defaultMethod; } public String getUriStyle() { return uriStyle; } public void setUriStyle(String uriStyle) { this.uriStyle = uriStyle; } public String getPackageName() { return new String(packageName); } public void setPackageName(String packageName) { this.packageName = packageName; this.packageSegs = StringUtils.split(packageName, '*'); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUriExtension() { return uriExtension; } public void setUriExtension(String uriExtension) { this.uriExtension = uriExtension; } public String getPathStyle() { return pathStyle; } public void setPathStyle(String pathStyle) { this.pathStyle = pathStyle; } }