package com.sissi.context.impl; import com.sissi.context.JID; import com.sissi.context.JIDBuilder; /** * @author kim 2013年12月23日 */ public class LengthLimitJIDBuilder implements JIDBuilder { private final String connectAt = "@"; private final String connectResource = "/"; private final int limit; private final String group; private final String domain; /** * @param limit JID长度限制 * @param group MUC域 * @param domain 服务器域 */ public LengthLimitJIDBuilder(int limit, String group, String domain) { super(); this.limit = limit; this.group = group; this.domain = domain; } @Override public JID build(String jid) { String trim = (jid != null ? jid.trim() : null); // 如果无法解析则使用OFFLINE return (trim != null && !trim.isEmpty()) ? new User(trim) : OfflineJID.OFFLINE; } public JID build(String username, String resource) { return new User(username, resource); } private class User implements JID { private boolean valid = Boolean.TRUE; private String user; private String domain; private String resource; private String stringWithBare; private User(String jid) { super(); try { if (jid.length() > LengthLimitJIDBuilder.this.limit) { this.valid = false; return; } StringBuffer buffer = new StringBuffer(jid); int startMain = buffer.indexOf(LengthLimitJIDBuilder.this.connectAt); this.user = startMain == -1 ? null : buffer.substring(0, startMain); int startResource = buffer.indexOf(LengthLimitJIDBuilder.this.connectResource); this.domain = (startResource == -1 ? buffer.substring(startMain != -1 ? startMain + 1 : 0) : buffer.substring(startMain + 1, startResource)); this.resource = startResource == -1 ? null : buffer.substring(startResource + 1); } catch (Exception e) { this.valid = false; } } private User(String user, String resource) { super(); this.user = user; this.resource = resource; } private User copy4Bare() { return new User(this.user, null).domain(this.domain()); } public String user() { return this.user; } public String domain() { return this.domain != null ? this.domain : LengthLimitJIDBuilder.this.domain; } public User domain(String domain) { this.domain = domain; return this; } /* * Not allowed null and empty * * @see com.sissi.context.JID#resource() */ public String resource() { return this.resource != null && !this.resource.isEmpty() ? this.resource : null; } @Override public JID resource(String resource) { this.resource = resource; return this; } public JID bare() { return this.copy4Bare(); } public JID clone() { return this.copy4Bare().resource(this.resource()); } public boolean isBare() { return this.resource() == null; } public boolean isGroup() { return LengthLimitJIDBuilder.this.group.equals(this.domain()); } public boolean same(JID jid) { return this.same(jid.asString()); } public boolean same(String jid) { return this.asString().equals(jid); } public boolean like(JID jid) { return this.like(jid.asStringWithBare()); } public boolean like(String jid) { return this.asStringWithBare().equals(jid); } public boolean valid() { return this.valid(true); } /* * 解析正确,长度正确,指定部分不含错误关键字 * * @see com.sissi.context.JID#valid(boolean) */ public boolean valid(boolean excludeDomain) { return this.valid && this.validKeyword(this.user(), true) && this.validKeyword(this.domain(), excludeDomain); } private boolean validKeyword(String part, boolean allowNull) { return (part != null && !part.isEmpty()) ? !part.contains(LengthLimitJIDBuilder.this.connectAt) && !part.contains(LengthLimitJIDBuilder.this.connectResource) : (false || allowNull); } public String asString() { return this.asStringWithBare() + (this.isBare() ? "" : LengthLimitJIDBuilder.this.connectResource + this.resource()); } public String asStringWithBare() { return this.stringWithBare != null ? this.stringWithBare : (this.domain() != null ? this.stringWithBare(true) : this.stringWithBare(false)); } /** * 是否缓存JID * * @param cached * @return */ private String stringWithBare(boolean cached) { String stringWithBare = (this.user() != null ? this.user() + LengthLimitJIDBuilder.this.connectAt : "") + this.domain(); return cached ? (this.stringWithBare = stringWithBare) : stringWithBare; } public String asString(boolean bare) { return bare ? this.asStringWithBare() : this.asString(); } } }