001/** 002 * 003 * Copyright © 2014-2018 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 org.jxmpp.JxmppContext; 020import org.jxmpp.stringprep.XmppStringPrepUtil; 021import org.jxmpp.stringprep.XmppStringprepException; 022import org.jxmpp.util.XmppStringUtils; 023 024/** 025 * A <i>localpart</i> of an XMPP address (JID). The localpart is the part before the 026 * first @ sign in an XMPP address and usually identifies the user (or the XMPP 027 * entity) within an XMPP service. It is also often referred to as "username", 028 * but note that the actual username used to login may be different from the 029 * resulting localpart of the user's JID. 030 * <p> 031 * You can create instances of this class from Strings using {@link #from(String)}. 032 * </p> 033 * 034 * @see <a href="http://xmpp.org/rfcs/rfc6122.html#addressing-localpart">RFC 035 * 6122 § 2.3. Localpart</a> 036 */ 037public class Localpart extends Part { 038 039 /** 040 * 041 */ 042 private static final long serialVersionUID = 1L; 043 044 private transient String unescapedCache; 045 046 private Localpart(String localpart) { 047 super(localpart); 048 } 049 050 /** 051 * Return the <b>unescaped</b> String representation of this Localpart. 052 * <p> 053 * Since certain Unicode code points are disallowed in the localpart of a JID by the required stringprep profile, 054 * those need to get escaped when used in a real JID. The unescaped representation of the JID is only for 055 * presentation to a human user or for gatewaying to a non-XMPP system. 056 * </p> 057 * 058 * @return the unescaped String representation of this JID. 059 * @see org.jxmpp.jid.Jid#asUnescapedString() 060 * @since 0.6.1 061 */ 062 public String asUnescapedString() { 063 if (unescapedCache != null) { 064 return unescapedCache; 065 } 066 unescapedCache = XmppStringUtils.unescapeLocalpart(toString()); 067 return unescapedCache; 068 } 069 070 /** 071 * Like {@link #from(String)} but does throw an unchecked {@link IllegalArgumentException} instead of a 072 * {@link XmppStringprepException}. 073 * 074 * @param cs the character sequence which should be transformed to a {@link Localpart} 075 * @return the {@link Localpart} if no exception occurs 076 * @throws IllegalArgumentException if the given input is not a valid {@link Localpart} 077 * @see #from(String) 078 * @since 0.6.2 079 */ 080 public static Localpart fromOrThrowUnchecked(CharSequence cs) { 081 try { 082 return from(cs.toString()); 083 } catch (XmppStringprepException e) { 084 throw new IllegalArgumentException(e); 085 } 086 } 087 088 /** 089 * Like {@link #fromUnescaped(String)} but does throw an unchecked {@link IllegalArgumentException} instead of a 090 * {@link XmppStringprepException}. 091 * 092 * @param cs the character sequence which should be transformed to a {@link Localpart} 093 * @return the {@link Localpart} if no exception occurs 094 * @see #from(String) 095 * @since 0.6.2 096 */ 097 public static Localpart fromUnescapedOrThrowUnchecked(CharSequence cs) { 098 try { 099 return fromUnescaped(cs.toString()); 100 } catch (XmppStringprepException e) { 101 throw new IllegalArgumentException(e); 102 } 103 } 104 105 /** 106 * Get a {@link Localpart} from a given {@link CharSequence} or {@code null} if the input is not a valid localpart. 107 * 108 * @param cs the input CharSequence 109 * @return a Localpart or {@code null} 110 */ 111 public static Localpart formUnescapedOrNull(CharSequence cs) { 112 try { 113 return fromUnescaped(cs); 114 } catch (XmppStringprepException e) { 115 return null; 116 } 117 } 118 119 /** 120 * Get a {@link Localpart} from an unescaped String. 121 * 122 * @param unescapedLocalpart an unescaped String representing a Localpart. 123 * @return a Localpart 124 * @throws XmppStringprepException if an error occurs. 125 * @since 0.6.2 126 */ 127 public static Localpart fromUnescaped(String unescapedLocalpart) throws XmppStringprepException { 128 String escapedLocalpartString = XmppStringUtils.escapeLocalpart(unescapedLocalpart); 129 return from(escapedLocalpartString); 130 } 131 132 /** 133 * Get a {@link Localpart} from an unescaped CharSequence. 134 * 135 * @param unescapedLocalpart an unescaped CharSequence representing a Localpart. 136 * @return a Localpart 137 * @throws XmppStringprepException if an error occurs. 138 * @since 0.6.2 139 */ 140 public static Localpart fromUnescaped(CharSequence unescapedLocalpart) throws XmppStringprepException { 141 return fromUnescaped(unescapedLocalpart.toString()); 142 } 143 144 /** 145 * Get a {@link Localpart} from a given {@link CharSequence} or {@code null} if the input is not a valid localpart. 146 * 147 * @param cs the input CharSequence 148 * @return a Localpart or {@code null} 149 */ 150 public static Localpart fromOrNull(CharSequence cs) { 151 try { 152 return from(cs.toString()); 153 } catch (XmppStringprepException e) { 154 return null; 155 } 156 } 157 158 /** 159 * Get the {@link Localpart} representing the input String. 160 * 161 * @param localpart the input String. 162 * @return the localpart. 163 * @throws XmppStringprepException if an error occurs. 164 */ 165 public static Localpart from(String localpart) throws XmppStringprepException { 166 return from(localpart, JxmppContext.getDefaultContext()); 167 } 168 169 /** 170 * Get the {@link Localpart} representing the input String. 171 * 172 * @param localpart the input String. 173 * @param context the JXMPP context. 174 * @return the localpart. 175 * @throws XmppStringprepException if an error occurs. 176 */ 177 public static Localpart from(String localpart, JxmppContext context) throws XmppStringprepException { 178 localpart = XmppStringPrepUtil.localprep(localpart, context); 179 // First prep the String, then assure the limits of the *result* 180 assertNotLongerThan1023BytesOrEmpty(localpart); 181 return new Localpart(localpart); 182 } 183}