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