Dawno nic technicznego nie było… zatem wracamy do tematyki związanej z Guavą. Na dziś krótko o narzędziu, które ułatwia pracę z domenami, czyli o klasie InternetDomainName.

Chwila teorii

Jak zapewne wiecie po sieci poruszamy się z pomocą adresów internetowych, czyli domen. Domena z jednej strony mapuje się na odpowiedni IP serwera (to robi za nas system DNS), a z drugiej siedzi w „drzewie domen” nad którym nadzór sprawuje ICANN. Ale nie o tym chciałem.

Konkretne domeny, które są „własnością” firm, instytucji czy osób prywatnych, są w rzeczywistości pod-domenami albo dziećmi, jeżeli używamy drzewiastej nomenklatury, domen wyższego poziomu. Domeny wyższego poziomu dzielimy na dwie grupy. Pierwsza to Top Level Domain (TLD), czyli korzenie drzewa domen. Należą do nich na przykład .com, czy .net. Druga grupa to Top Public Domain (TPD) zwana też Public Suffix. Domeny te pozwalają na rejestrowanie domen dzieci w swoim drzewie każdemu kto ma na to ochotę. Przykładem takiej domeny jest co.uk.
Kilka regułek:

  • TLD może być TPD np. .com
  • TPD nie zawsze jest TLD np. .co.uk
  • Są domeny, które pomimo, że są korzeniem drzewa domen nie są TLD ani TPD.

Ta ostatnia grupa czasami jest nazywana prywatnymi TLD. Koszt takiej domeny to około 1000USD. Jest tylko jeden drobny problem… Otóż ICANN nie oferuje tego typu wynalazków, a do alternatywnych dostawców usług DNS zazwyczaj nie podpinają się ISPki. Zatem taka domena to dość drogi mało skuteczny substytut viagry.

Do tego dochodzą zasady związane z umieszczaniem plików cookie na poziomie poszczególnych domen… znaczy na domenach publicznych tego nie zrobimy i tyle.

Ok… wiemy, że TLD są dostarczane przez ICANN to co z TPD? Otóż jest sobie taka stronka http://publicsuffix.org, która zawiera listę większości publicznych sufiksów dla domen. Klasa InternetDomainName pozwala ogarnąć ten burdel 😀

Klasa InternetDomainName

Jest to jedna biedna klasa jedynaczka. Ma zarówno metody fabrykujące jak i narzędziowe. Na listingu 1. zamieściłem przegląd możliwości tej klasy.

Listing 1. Klasa InternetDomainName i jej metody

public class InternetDomainNamesBasics {

	public static final String KOZIOLEKWEB_PL = "koziolekweb.pl";
	public static final InternetDomainName KOZIOLEKWEB_PL_IDN = from(KOZIOLEKWEB_PL);

	public static final String APPSPOT_COM = "appspot.com";
	public static final InternetDomainName APPSPOT_COM_IDN = from(APPSPOT_COM);

	public static final String TYRSOFT_PL = "tyrsoft.com";
	public static final InternetDomainName TYRSOFT_PL_IDN = from(TYRSOFT_PL);

	public static final String ETH = "8thcolour";
	public static final String ETH_TYRSOFT_PL = "8thcolour.tyrsoft.com";
	public static final InternetDomainName ETH_TYRSOFT_PL_IDN = from(ETH_TYRSOFT_PL);


	public static void main(String[] args) {
		isValidExample();
		childExample();
		parentExample();
		hasParentExample();
		hasPublicSuffixExample();
		isPublicSuffixExample();
		isTopPrivateExample();
		isUnderPublicSuffixExample();
		partsExample();
		publicSuffixExample();
		topPrivateDomainExample();
	}

	public static void isValidExample() {
		System.out.printf("Domain %s is %s\n", KOZIOLEKWEB_PL, validInvalid(isValid(KOZIOLEKWEB_PL)));
		System.out.printf("Domain %s is %s\n", "Koziołekłeb.pl", validInvalid(isValid("Koziołekłeb.pl")));
		System.out.printf("Domain %s is %s\n", "$#%$##.com", validInvalid(isValid("$#%$##.com")));

	}

	public static void childExample() {
		InternetDomainName child = TYRSOFT_PL_IDN.child(ETH);
		System.out.printf("Domain %s has child %s and it is %s to %s\n", TYRSOFT_PL, child,
				equalNotEqual(child.equals(ETH_TYRSOFT_PL_IDN)),
				ETH_TYRSOFT_PL);

	}

	public static void parentExample() {
		InternetDomainName parent = ETH_TYRSOFT_PL_IDN.parent();
		System.out.printf("Parent of %s is %s and is %s to %s\n", ETH_TYRSOFT_PL, parent
				, equalNotEqual(parent.equals(TYRSOFT_PL_IDN)), TYRSOFT_PL);

		System.out.printf("Parent of %s is %s\n", TYRSOFT_PL, TYRSOFT_PL_IDN.parent());

	}

	public static void hasParentExample() {
		System.out.printf("Is domain %s has parent? %s\n", TYRSOFT_PL, yesNo(TYRSOFT_PL_IDN.hasParent()));
	}

	public static void hasPublicSuffixExample() {
		System.out.printf("Has domain %s public suffix? %s\n", TYRSOFT_PL, yesNo(TYRSOFT_PL_IDN.hasPublicSuffix()));
		System.out.printf("Has domain %s public suffix? %s\n", ETH_TYRSOFT_PL, yesNo(ETH_TYRSOFT_PL_IDN.hasPublicSuffix()));
	}

	public static void isPublicSuffixExample() {
		System.out.printf("Is domain %s public suffix? %s\n", TYRSOFT_PL, yesNo(TYRSOFT_PL_IDN.isPublicSuffix()));
		System.out.printf("Is domain %s public suffix? %s\n", APPSPOT_COM, yesNo(APPSPOT_COM_IDN.isPublicSuffix()));
	}

	public static void isTopPrivateExample() {
		System.out.printf("Is domain %s TPD? %s\n", TYRSOFT_PL, yesNo(TYRSOFT_PL_IDN.isTopPrivateDomain()));
		System.out.printf("Is domain %s TPD? %s\n", ETH_TYRSOFT_PL, yesNo(ETH_TYRSOFT_PL_IDN.isTopPrivateDomain()));
		System.out.printf("Is domain %s TPD? %s\n", APPSPOT_COM, yesNo(APPSPOT_COM_IDN.isTopPrivateDomain()));
	}

	public static void isUnderPublicSuffixExample() {
		System.out.printf("Is domain %s under public suffix? %s\n", ETH_TYRSOFT_PL, yesNo(ETH_TYRSOFT_PL_IDN.isUnderPublicSuffix()));
		System.out.printf("Is domain %s under public suffix? %s\n", APPSPOT_COM, yesNo(APPSPOT_COM_IDN.isUnderPublicSuffix()));
	}

	public static void partsExample() {
		System.out.printf("Domain %s parts: %s\n", ETH_TYRSOFT_PL, on(", ").join(ETH_TYRSOFT_PL_IDN.parts()));
	}
	public static void publicSuffixExample() {
		System.out.printf("Domain %s public suffix is %s\n", ETH_TYRSOFT_PL, ETH_TYRSOFT_PL_IDN.publicSuffix());
	}
	public static void topPrivateDomainExample() {
		System.out.printf("TPD of %s is %s\n", ETH_TYRSOFT_PL, ETH_TYRSOFT_PL_IDN.topPrivateDomain());
	}

}

Po kolei.

Metoda from

Statyczna metoda fabrykująca. Tworzy nowy obiekt na podstawie przekazanego String-a (NIE IP). Jeżeli przekazany String nie pozwala na stworzenie prawidłowej domeny… no cóż…

Metoda isValid

Żadnej magii. Metoda sprawdza poprawność String-a pod kątem RFC3490. Znaki diakrytyczne w nazwach są poprawne… choć nie wszystkie przeglądarki się z tym lubią.

Metoda child

Niestatyczna metoda fabrykująca, która na podstawie przekazanego parametru tworzy nowy obiekt reprezentujący pod-domenę dla obiektu na rzecz którego jest wołana. Oczywiście wywali się gdy podamy null oraz gdy nowy twór będzie nieprawidłowy.

Metoda parent

Odwrotnie do poprzedniej. Zwraca obiekt reprezentujący nad-domenę dla tej reprezentowanej przez obiekt, na rzecz którego ją wywołano.

Metoda hasParent

Metoda weryfikuje czy dana domena (reprezentowana przez obiekt.. ble, ble, ble…) ma rodzica czy też jest korzeniem.

Metoda hasPublicSuffix

Podobna do poprzedniej, ale dodatkowo sprawdza czy rodzic jest publicznym sufiksem.

Metoda isPublicSuffix

Sprawdza czy mamy do czynienia z publicznym sufiksem. Przydatna gdy chcemy ustawić ciastko „na rodzicu” i nie wiemy czy wywołanie jest z poziomu naszej domeny czy też z którejś z pod-domen.

Metoda isTopPrivate

Podobna do poprzedniej. Sprawdza jednak czy nasza domena jest prywatna i jej rodzić przez przypadek nie jest prywatny.

Metoda isUnderPublicSuffix

Sprawdza czy domena znajduje się w drzewie publicznego sufiksu, ale nim nie jest.

Metoda parts

Metoda działa jak split po kropkach.

Metoda publicSuffix

Metoda zwraca publiczny sufiks domeny. Albo null jak taki nie istnieje.

Metoda topPrivateDomain

Podobnie jak poprzednia, ale tym razem zwraca nam najwyższa domenę prywatną w naszym drzewie.

Podsumowanie

Po co? Ponieważ czasami musimy popracować z nazwami domen w ramach naszych serwletów (spraw ciastków) i przydało by się mieć jakieś ogarnięcie w tym temacie. Klasa dostarcza tak naprawdę jedną ważną funkcjonalność – walidację w ramach RFC 3490 wraz ze sprawdzaniem listy publicznych sufiksów. Po prostu nie musimy robić tego sami.