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