Ja, Rosi hat ein Telefon
Spider Murphy Gang
Auch ich hab ihre Nummer schon
Unter zwounddreißig, sechzehn, acht
Herrscht Konjunktur die ganze Nacht
Die deutsche Bundesnetzagentur stellt eine Reihe Drama Numbers für Medienproduktionen bereit. Diese Telefonnummern sind für die Nutzung in Fernsehen, Radio, Broschüren und anderen Medien gedacht, in denen keine tatsächlich genutzten Telefonnummern auftauchen sollten. Der Spider Murphy Gang mag man die Wahl der Telefonnummer +40 69 32168 verzeihen, denn die bestehenden Drama Numbers passen alle nicht in das Versmaß.
Eine Drama Number in einem Beispiel zu nutzen ist eine freundliche Geste um niemanden Anrufe durch Witzbolde aufzubürden, andererseits sollte niemand eine Drama Number in ein Pflichtfeld der eigenen Web-Anwendung eingeben können. Daher sollte eine Validierung der Telefonnummer auch die deutschen Drama Numbers erkennen können. Die Telephone Bibliothek bietet solch eine Validierung über die @GermanDramaNumber
Annotation.
@GermanDramaNumber InternationalPhoneNumber international; @GermanDramaNumber NationalPhoneNumber national;
Bei beiden Telefonnummern wird gegen eine Liste der deutschen Drama Numbers getestet. Bei der InternationalPhoneNumber
wird zusätzlich
die internationale Vorwahl geprüft. Bei der NationalPhoneNumber
existiert keine internationale Vorwahl und der Anwendungsfall muss sicherstellen, dass nur deutsche Telefonnummern verarbeitet werden.
In dieser Form wird aber nur positiv validiert, dass eine Telefonnummer eine Drama Number ist. der übliche Anwendungsfall sieht aber anders aus.
@GermanDestinationCode @GermanDramaNumber(allowed=false) InternationalPhoneNumber international; @GermanDramaNumber(allowed=false) NationalPhoneNumber national;
In diesem Beispiel sind die Drama Numbers über das Attribut allowed
verboten. Damit aber bei der InternationalPhoneNumber
nur deutsche Telefonnummern betrachtet werden, wurde noch die Annotation @GermanDestinationCode
hinzugefügt.
Die Validatoren für die Drama Numbers verwenden alle die statische Methode GermanDramaNumbers#isValid
, die anhand einer InternationalPhoneNumber
bestimmt, ob diese zu den Drama Numbers gehört.
public class NationalPhoneNumberGermanDramaValidator extends AbstractGermanDramaValidator<NationalPhoneNumber> { @Override public boolean isValid(NationalPhoneNumber phoneNumber, ConstraintValidatorContext constraintValidatorContext) { if (phoneNumber == null) { return true; } return allowed == GermanDramaNumbers.isValid(InternationalPhoneNumber.of("49", phoneNumber)); } }
Der NationalPhoneNumberGermanDramaValidator
validiert eine NationalPhoneNumber
, indem er eine InternationalPhoneNumber
mit der internationalen Vorwahl für Deutschland erzeugt. Dies ist keine teure Operation, weil eine InternationalPhoneNumber
nur eine NationalPhoneNumber
mit internationaler Vorwahl ist.
Die Methode GermanDramaNumbers#isValid
greift auf eine Map
zurück, in der für jede Vorwahl eine Liste von PhoneNumberAccessor
Instanzen hinterlegt sind. Implementierungen von PhoneNumberAccessor
sind die Klassen NationalPhoneNumber
, InternationalPhoneNumber
und PhoneNumberBlock
. Zweck des PhoneNumberAccessor an dieser Stelle ist die Verwendung seiner Methode matches
. Bei einer NationalPhoneNumber
, InternationalPhoneNumber
wird damit die Gleichheit geprüft und bei PhoneNumberBlock
, ob die Telefonnummer innerhalb der Rufnummernblocks zu finden ist.
public final class GermanDramaNumbers { private static final Map<String, List<PhoneNumberAccessor>> numbers = Map.ofEntries( Map.entry("30", List.of(trunk("30", "23125", "000", "999"))), Map.entry("69", List.of(trunk("69", "90009", "000", "999"))), Map.entry("40", List.of(trunk("40", "66969", "000", "999"))), Map.entry("221", List.of(trunk("221", "4710", "000", "999"))), Map.entry("89", List.of(trunk("89", "99998", "000", "999"))), Map.entry("152", numbers("152", "28817386", "28895456", "54599371")), Map.entry("171", List.of(trunk("171", "39200", "00", "99"))), Map.entry("176", List.of(trunk("176", "040690", "00", "99"))), Map.entry("172", numbers("172", "9925904", "9968532", "9973185", "9973186", "9980752")), Map.entry("174", numbers("174", "9091317", "9464308")) ); public static boolean isValid(InternationalPhoneNumber phoneNumber) { return Stream.of(numbers.get(phoneNumber.getNationalDestinationCode())).filter(Objects::nonNull).flatMap(List::stream).anyMatch(x -> x.matches(phoneNumber)); } private static PhoneNumberAccessor trunk(String nationalDestinationCode, String subscriberNumber, String blockStart, String blockEnd) { return PhoneNumberBlock.of(InternationalPhoneNumber.of("49", "0", nationalDestinationCode, subscriberNumber), blockStart, blockEnd); } private static List<PhoneNumberAccessor> numbers(String nationalDestinationCode, String... subscriberNumbers) { return Stream.of(subscriberNumbers).map(sn -> InternationalPhoneNumber.of("49", "0", nationalDestinationCode, sn)) .map(PhoneNumberAccessor.class::cast).toList(); } }
Mit Hilfe der PhoneNumberBlock
Instanzen kann die Map
mit ihren 5210 Telefonnummern kompakt repräsentiert werden.
Die Unit Tests der Bibliothek haben auch durch die Drama Numbers gewonnen. Bislang wurde häufig die Telefonnummer +49 521 112233 verwendet, die unvorsichtige Zeitgenossen vielleicht an den falschen Adressaten durchgestellt hätte.