001/*
002 * Copyright 2015-2020 the original author or authors
003 *
004 * This software is licensed under the Apache License, Version 2.0,
005 * the GNU Lesser General Public License version 2 or later ("LGPL")
006 * and the WTFPL.
007 * You may choose either license to govern your use of this software only
008 * upon the condition that you accept all of the terms of either
009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL.
010 */
011package org.minidns.dnslabel;
012
013/**
014 * A LDH (<b>L</b>etters, <b>D</b>igits, <b>H</b>yphen) label, which is the classical label form.
015 * 
016 * @see <a href="https://tools.ietf.org/html/rfc5890#section-2.3.1">RFC 5890 ยง 2.3.1. LDH Label</a>
017 *
018 */
019public abstract class LdhLabel extends DnsLabel {
020
021    protected LdhLabel(String label) {
022        super(label);
023    }
024
025    public static boolean isLdhLabel(String label) {
026        if (label.isEmpty()) {
027            return false;
028        }
029
030        if (LeadingOrTrailingHyphenLabel.isLeadingOrTrailingHypenLabelInternal(label)) {
031            return false;
032        }
033
034        for (int i = 0; i < label.length(); i++) {
035            char c = label.charAt(i);
036            if ((c >= 'a' && c <= 'z')
037                    || (c >= 'A' && c <= 'Z')
038                    || (c >= '0' && c <= '9')
039                    || c == '-') {
040                continue;
041            }
042            return false;
043        }
044        return true;
045    }
046
047    protected static LdhLabel fromInternal(String label) {
048        assert isLdhLabel(label);
049
050        if (ReservedLdhLabel.isReservedLdhLabel(label)) {
051            // Label starts with '??--'. Now let us see if it is a XN-Label, starting with 'xn--', but be aware that the
052            // 'xn' part is case insensitive. The XnLabel.isXnLabelInternal(String) method takes care of this.
053            if (XnLabel.isXnLabelInternal(label)) {
054                return XnLabel.fromInternal(label);
055            } else {
056                return new ReservedLdhLabel(label);
057            }
058        }
059        return new NonReservedLdhLabel(label);
060    }
061}