001/** 002 * 003 * Copyright © 2014 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.parts; 018 019import java.io.Serializable; 020 021import org.jxmpp.stringprep.XmppStringprepException; 022 023public abstract class Part implements CharSequence, Serializable { 024 025 /** 026 * 027 */ 028 private static final long serialVersionUID = 1L; 029 030 private final String part; 031 032 protected Part(String part) { 033 this.part = part; 034 } 035 036 @Override 037 public final int length() { 038 return part.length(); 039 } 040 041 @Override 042 public final char charAt(int index) { 043 return part.charAt(index); 044 } 045 046 @Override 047 public final CharSequence subSequence(int start, int end) { 048 return part.subSequence(start, end); 049 } 050 051 @Override 052 public final String toString() { 053 return part; 054 } 055 056 @Override 057 public final boolean equals(Object other) { 058 if (this == other) { 059 return true; 060 } 061 if (other == null) { 062 return false; 063 } 064 return part.equals(other.toString()); 065 } 066 067 @Override 068 public final int hashCode() { 069 return part.hashCode(); 070 } 071 072 protected static void assertNotLongerThan1023BytesOrEmpty(String string) throws XmppStringprepException { 073 char[] bytes = string.toCharArray(); 074 075 // Better throw XmppStringprepException instead of IllegalArgumentException here, because users don't expect an 076 // IAE and it also makes the error handling for users easier. 077 if (bytes.length > 1023) { 078 throw new XmppStringprepException(string, "Given string is longer then 1023 bytes"); 079 } else if (bytes.length == 0) { 080 throw new XmppStringprepException(string, "Argument can't be the empty string"); 081 } 082 } 083 084 /** 085 * The cache holding the internalized value of this part. This needs to be transient so that the 086 * cache is recreated once the data was de-serialized. 087 */ 088 private transient String internalizedCache; 089 090 /** 091 * Returns the canonical String representation of this Part. See {@link String#intern} for details. 092 * 093 * @return the canonical String representation. 094 */ 095 public final String intern() { 096 if (internalizedCache == null) { 097 internalizedCache = toString().intern(); 098 } 099 return internalizedCache; 100 } 101}