001/** 002 * 003 * Copyright © 2014-2017 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jxmpp.jid.impl; 018 019import org.jxmpp.jid.EntityBareJid; 020import org.jxmpp.jid.DomainBareJid; 021import org.jxmpp.jid.DomainFullJid; 022import org.jxmpp.jid.EntityFullJid; 023import org.jxmpp.jid.Jid; 024import org.jxmpp.jid.EntityJid; 025import org.jxmpp.jid.FullJid; 026import org.jxmpp.jid.parts.Localpart; 027import org.jxmpp.jid.parts.Resourcepart; 028 029public abstract class AbstractJid implements Jid { 030 031 /** 032 * 033 */ 034 private static final long serialVersionUID = 1L; 035 036 /** 037 * Cache for the String representation of this JID. 038 */ 039 protected String cache; 040 041 @Override 042 public final boolean isEntityJid() { 043 return isEntityBareJid() || isEntityFullJid(); 044 } 045 046 @Override 047 public final boolean isEntityBareJid() { 048 return this instanceof EntityBareJid; 049 } 050 051 @Override 052 public final boolean isEntityFullJid() { 053 return this instanceof EntityFullJid; 054 } 055 056 @Override 057 public final boolean isDomainBareJid() { 058 return this instanceof DomainBareJid; 059 } 060 061 @Override 062 public final boolean isDomainFullJid() { 063 return this instanceof DomainFullJid; 064 } 065 066 @Override 067 public abstract boolean hasNoResource(); 068 069 @Override 070 public final boolean hasResource() { 071 return this instanceof FullJid; 072 } 073 074 @Override 075 public final boolean hasLocalpart() { 076 return this instanceof EntityJid; 077 } 078 079 @Override 080 public final <T extends Jid> T downcast(Class<T> jidClass) { 081 return jidClass.cast(this); 082 } 083 084 @Override 085 public int length() { 086 return toString().length(); 087 } 088 089 @Override 090 public char charAt(int index) { 091 return toString().charAt(index); 092 } 093 094 @Override 095 public CharSequence subSequence(int start, int end) { 096 return toString().subSequence(start, end); 097 } 098 099 @Override 100 public final EntityBareJid asEntityBareJidOrThrow() { 101 EntityBareJid entityBareJid = asEntityBareJidIfPossible(); 102 if (entityBareJid == null) throwIse("can not be converted to EntityBareJid"); 103 return entityBareJid; 104 } 105 106 @Override 107 public EntityFullJid asEntityFullJidOrThrow() { 108 EntityFullJid entityFullJid = asEntityFullJidIfPossible(); 109 if (entityFullJid == null) throwIse("can not be converted to EntityFullJid"); 110 return entityFullJid; 111 } 112 113 @Override 114 public EntityJid asEntityJidOrThrow() { 115 EntityJid entityJid = asEntityJidIfPossible(); 116 if (entityJid == null) throwIse("can not be converted to EntityJid"); 117 return entityJid; 118 } 119 120 @Override 121 public EntityFullJid asFullJidOrThrow() { 122 EntityFullJid entityFullJid = asEntityFullJidIfPossible(); 123 if (entityFullJid == null) throwIse("can not be converted to EntityBareJid"); 124 return entityFullJid; 125 } 126 127 @Override 128 public DomainFullJid asDomainFullJidOrThrow() { 129 DomainFullJid domainFullJid = asDomainFullJidIfPossible(); 130 if (domainFullJid == null) throwIse("can not be converted to DomainFullJid"); 131 return domainFullJid; 132 } 133 134 @Override 135 public abstract Resourcepart getResourceOrNull(); 136 137 @Override 138 public final Resourcepart getResourceOrEmpty() { 139 Resourcepart resourcepart = getResourceOrNull(); 140 if (resourcepart == null) return Resourcepart.EMPTY; 141 return resourcepart; 142 } 143 144 @Override 145 public final Resourcepart getResourceOrThrow() { 146 Resourcepart resourcepart = getResourceOrNull(); 147 if (resourcepart == null) throwIse("has no resourcepart"); 148 return resourcepart; 149 } 150 151 @Override 152 public abstract Localpart getLocalpartOrNull(); 153 154 @Override 155 public final Localpart getLocalpartOrThrow() { 156 Localpart localpart = getLocalpartOrNull(); 157 if (localpart == null) throwIse("has no localpart"); 158 return localpart; 159 } 160 161 @Override 162 public final boolean isParentOf(Jid jid) { 163 EntityFullJid fullJid = jid.asEntityFullJidIfPossible(); 164 if (fullJid != null) { 165 return isParentOf(fullJid); 166 } 167 EntityBareJid bareJid = jid.asEntityBareJidIfPossible(); 168 if (bareJid != null) { 169 return isParentOf(bareJid); 170 } 171 DomainFullJid domainFullJid = jid.asDomainFullJidIfPossible(); 172 if (domainFullJid != null) { 173 return isParentOf(domainFullJid); 174 } 175 176 return isParentOf(jid.asDomainBareJid()); 177 } 178 179 @Override 180 public final int hashCode() { 181 return toString().hashCode(); 182 } 183 184 @Override 185 public final boolean equals(Object other) { 186 if (other == null) { 187 return false; 188 } 189 if (this == other) { 190 return true; 191 } 192 if (other instanceof CharSequence) { 193 return equals((CharSequence) other); 194 } 195 return false; 196 } 197 198 @SuppressWarnings("NonOverridingEquals") 199 @Override 200 public final boolean equals(CharSequence charSequence) { 201 if (charSequence == null) { 202 return false; 203 } 204 return equals(charSequence.toString()); 205 } 206 207 @SuppressWarnings("NonOverridingEquals") 208 @Override 209 public final boolean equals(String string) { 210 return toString().equals(string); 211 } 212 213 @Override 214 public final int compareTo(Jid other) { 215 String otherString = other.toString(); 216 String myString = toString(); 217 return myString.compareTo(otherString); 218 } 219 220 /** 221 * The cache holding the internalized value of this part. This needs to be transient so that the 222 * cache is recreated once the data was de-serialized. 223 */ 224 private transient String internalizedCache; 225 226 @Override 227 public final String intern() { 228 if (internalizedCache == null) { 229 cache = internalizedCache = toString().intern(); 230 } 231 return internalizedCache; 232 } 233 234 private void throwIse(String message) { 235 String exceptionMessage = "The JID '" + this + "' " + message; 236 throw new IllegalStateException(exceptionMessage); 237 } 238 239 static <O extends Object> O requireNonNull(O object, String message) { 240 if (object != null) { 241 return object; 242 } 243 throw new IllegalArgumentException(message); 244 } 245}