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