📄 jid.java
字号:
*/
JID(String jid, Object fake) {
fake = null; // Workaround IDE warnings for unused param.
if (jid == null) {
throw new NullPointerException("JID cannot be null");
}
int atIndex = jid.indexOf("@");
int slashIndex = jid.indexOf("/");
// Node
if (atIndex > 0) {
node = jid.substring(0, atIndex);
}
// Domain
if (atIndex + 1 > jid.length()) {
throw new IllegalArgumentException("JID with empty domain not valid");
}
if (atIndex < 0) {
if (slashIndex > 0) {
domain = jid.substring(0, slashIndex);
}
else {
domain = jid;
}
}
else {
if (slashIndex > 0) {
domain = jid.substring(atIndex + 1, slashIndex);
}
else {
domain = jid.substring(atIndex + 1);
}
}
// Resource
if (slashIndex + 1 > jid.length() || slashIndex < 0) {
resource = null;
}
else {
resource = jid.substring(slashIndex + 1);
}
// Cache the bare and full JID String representation
updateCache();
}
/**
* Transforms the JID parts using the appropriate Stringprep profiles, then
* validates them. If they are fully valid, the field values are saved, otherwise
* an IllegalArgumentException is thrown.
*
* @param node the node.
* @param domain the domain.
* @param resource the resource.
*/
private void init(String node, String domain, String resource) {
// Set node and resource to null if they are the empty string.
if (node != null && node.equals("")) {
node = null;
}
if (resource != null && resource.equals("")) {
resource = null;
}
// Stringprep (node prep, resourceprep, etc).
try {
if (!stringprepCache.containsKey(node)) {
this.node = Stringprep.nodeprep(node);
// Validate field is not greater than 1023 bytes. UTF-8 characters use two bytes.
if (node != null && node.length()*2 > 1023) {
throw new IllegalArgumentException("Node cannot be larger than 1023 bytes. " +
"Size is " + (node.length() * 2) + " bytes.");
}
stringprepCache.put(this.node, null);
}
else {
this.node = node;
}
// XMPP specifies that domains should be run through IDNA and
// that they should be run through nameprep before doing any
// comparisons. We always run the domain through nameprep to
// make comparisons easier later.
if (!stringprepCache.containsKey(domain)) {
this.domain = Stringprep.nameprep(IDNA.toASCII(domain), false);
// Validate field is not greater than 1023 bytes. UTF-8 characters use two bytes.
if (domain.length()*2 > 1023) {
throw new IllegalArgumentException("Domain cannot be larger than 1023 bytes. " +
"Size is " + (domain.length() * 2) + " bytes.");
}
stringprepCache.put(this.domain, null);
}
else {
this.domain = domain;
}
if (!stringprepCache.containsKey(resource)) {
this.resource = Stringprep.resourceprep(resource);
// Validate field is not greater than 1023 bytes. UTF-8 characters use two bytes.
if (resource != null && resource.length()*2 > 1023) {
throw new IllegalArgumentException("Resource cannot be larger than 1023 bytes. " +
"Size is " + (resource.length() * 2) + " bytes.");
}
stringprepCache.put(this.resource, null);
}
else {
this.resource = resource;
}
// Cache the bare and full JID String representation
updateCache();
}
catch (Exception e) {
StringBuilder buf = new StringBuilder();
if (node != null) {
buf.append(node).append("@");
}
buf.append(domain);
if (resource != null) {
buf.append("/").append(resource);
}
throw new IllegalArgumentException("Illegal JID: " + buf.toString(), e);
}
}
private void updateCache() {
// Cache the bare JID
StringBuilder buf = new StringBuilder(40);
if (node != null) {
buf.append(node).append("@");
}
buf.append(domain);
cachedBareJID = buf.toString();
// Cache the full JID
if (resource != null) {
buf.append("/").append(resource);
cachedFullJID = buf.toString();
}
else {
cachedFullJID = cachedBareJID;
}
}
/**
* Returns the node, or <tt>null</tt> if this JID does not contain node information.
*
* @return the node.
*/
public String getNode() {
return node;
}
/**
* Returns the domain.
*
* @return the domain.
*/
public String getDomain() {
return domain;
}
/**
* Returns the resource, or <tt>null</tt> if this JID does not contain resource information.
*
* @return the resource.
*/
public String getResource() {
return resource;
}
/**
* Returns the String representation of the bare JID, which is the JID with
* resource information removed.
*
* @return the bare JID.
*/
public String toBareJID() {
return cachedBareJID;
}
/**
* Returns a String representation of the JID.
*
* @return a String representation of the JID.
*/
public String toString() {
return cachedFullJID;
}
public int hashCode() {
return toString().hashCode();
}
public boolean equals(Object object) {
if (!(object instanceof JID)) {
return false;
}
if (this == object) {
return true;
}
JID jid = (JID)object;
// Node. If node isn't null, compare.
if (node != null) {
if (!node.equals(jid.node)) {
return false;
}
}
// Otherwise, jid.node must be null.
else if (jid.node != null) {
return false;
}
// Compare domain, which must be null.
if (!domain.equals(jid.domain)) {
return false;
}
// Resource. If resource isn't null, compare.
if (resource != null) {
if (!resource.equals(jid.resource)) {
return false;
}
}
// Otherwise, jid.resource must be null.
else if (jid.resource != null) {
return false;
}
// Passed all checks, so equal.
return true;
}
public int compareTo(Object o) {
if (!(o instanceof JID)) {
throw new ClassCastException("Ojbect not instanceof JID: " + o);
}
JID jid = (JID)o;
// Comparison order is domain, node, resource.
int compare = domain.compareTo(jid.domain);
if (compare == 0 && node != null && jid.node != null) {
compare = node.compareTo(jid.node);
}
if (compare == 0 && resource != null && jid.resource != null) {
compare = resource.compareTo(jid.resource);
}
return compare;
}
/**
* Returns true if two JID's are equivalent. The JID components are compared using
* the following rules:<ul>
* <li>Nodes are normalized using nodeprep (case insensitive).
* <li>Domains are normalized using IDNA and then nameprep (case insensitive).
* <li>Resources are normalized using resourceprep (case sensitive).</ul>
*
* These normalization rules ensure, for example, that
* <tt>User@EXAMPLE.com/home</tt> is considered equal to <tt>user@example.com/home</tt>.
*
* @param jid1 a JID.
* @param jid2 a JID.
* @return true if the JIDs are equivalent; false otherwise.
* @throws IllegalArgumentException if either JID is not valid.
*/
public static boolean equals(String jid1, String jid2) {
return new JID(jid1).equals(new JID(jid2));
}
/**
* A simple cache class that extends LinkedHashMap. It uses an LRU policy to
* keep the cache at a maximum size.
*/
private static class Cache extends LinkedHashMap {
private int maxSize;
public Cache(int maxSize) {
super(64, .75f, true);
this.maxSize = maxSize;
}
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > maxSize;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -