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;
022
023/**
024 * A <i>domainpart</i> of an XMPP address (JID).
025 * <p>
026 * You can create instances of this class from Strings using {@link #from(String)}.
027 * </p>
028 *
029 * @see <a href="http://xmpp.org/rfcs/rfc6122.html#addressing-domain">RFC 6122 § 2.2. Domainpart</a>
030 */
031public class Domainpart extends Part {
032
033        /**
034         *
035         */
036        private static final long serialVersionUID = 1L;
037
038        private Domainpart(String domain) {
039                super(domain);
040        }
041
042        /**
043         * Get a {@link Domainpart} from a given {@link CharSequence} or {@code null} if the input is not a valid domainpart.
044         *
045         * @param cs the input CharSequence
046         * @return a Domainpart or {@code null}
047         */
048        public static Domainpart fromOrNull(CharSequence cs) {
049                try {
050                        return from(cs.toString());
051                } catch (XmppStringprepException e) {
052                        return null;
053                }
054        }
055
056        /**
057         * Like {@link #from(String)} but does throw an unchecked {@link IllegalArgumentException} instead of a
058         * {@link XmppStringprepException}.
059         *
060         * @param cs the character sequence which should be transformed to a {@link Domainpart}
061         * @return the {@link Domainpart} if no exception occurs
062         * @throws IllegalArgumentException if the given input is not a valid {@link Domainpart}
063         * @see #from(String)
064         * @since 0.6.2
065         */
066        public static Domainpart fromOrThrowUnchecked(CharSequence cs) {
067                try {
068                        return from(cs.toString());
069                } catch (XmppStringprepException e) {
070                        throw new IllegalArgumentException(e);
071                }
072        }
073
074        /**
075         * Get the {@link Domainpart} representing the input String.
076         *
077         * @param domain the input String.
078         * @return the domainpart.
079         * @throws XmppStringprepException if an error occurs.
080         */
081        public static Domainpart from(String domain) throws XmppStringprepException {
082                return from(domain, JxmppContext.getDefaultContext());
083        }
084
085        /**
086         * Get the {@link Domainpart} representing the input String.
087         *
088         * @param domain the input String.
089         * @param context the JXMPP context.
090         * @return the domainpart.
091         * @throws XmppStringprepException if an error occurs.
092         */
093        public static Domainpart from(String domain, JxmppContext context) throws XmppStringprepException {
094                if (domain == null) {
095                        throw new XmppStringprepException(domain, "Input 'domain' must not be null");
096                }
097                // TODO cache
098                // RFC 6122 § 2.2 "If the domainpart includes a final character considered to be a label
099                // separator (dot) by [IDNA2003] or [DNS], this character MUST be stripped …"
100                if (domain.length() > 0 && domain.charAt(domain.length() - 1) == '.') {
101                        domain = domain.substring(0, domain.length() - 1);
102                }
103                domain = XmppStringPrepUtil.domainprep(domain, context);
104                // First prep the String, then assure the limits of the *result*
105                assertNotLongerThan1023BytesOrEmpty(domain);
106                return new Domainpart(domain);
107        }
108}