001/* 002 * Copyright 2015-2024 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; 012 013import java.util.Collections; 014import java.util.LinkedHashSet; 015import java.util.Set; 016 017import org.minidns.dnsname.DnsName; 018import org.minidns.record.Data; 019import org.minidns.record.Record; 020import org.minidns.record.Record.CLASS; 021import org.minidns.record.Record.TYPE; 022 023public final class RrSet { 024 025 public final DnsName name; 026 public final TYPE type; 027 public final CLASS clazz; 028 public final Set<Record<? extends Data>> records; 029 030 private RrSet(DnsName name, TYPE type, CLASS clazz, Set<Record<? extends Data>> records) { 031 this.name = name; 032 this.type = type; 033 this.clazz = clazz; 034 this.records = Collections.unmodifiableSet(records); 035 } 036 037 @Override 038 public String toString() { 039 StringBuilder sb = new StringBuilder(); 040 sb.append(name).append('\t').append(clazz).append('\t').append(type).append('\n'); 041 for (Record<?> record : records) { 042 sb.append(record).append('\n'); 043 } 044 return sb.toString(); 045 } 046 047 public static Builder builder() { 048 return new Builder(); 049 } 050 051 public static final class Builder { 052 private DnsName name; 053 private TYPE type; 054 private CLASS clazz; 055 Set<Record<? extends Data>> records = new LinkedHashSet<>(8); 056 057 private Builder() { 058 } 059 060 public Builder addRecord(Record<? extends Data> record) { 061 if (name == null) { 062 name = record.name; 063 type = record.type; 064 clazz = record.clazz; 065 } else if (!couldContain(record)) { 066 throw new IllegalArgumentException( 067 "Can not add " + record + " to RRSet " + name + ' ' + type + ' ' + clazz); 068 } 069 070 boolean didNotExist = records.add(record); 071 assert didNotExist; 072 073 return this; 074 } 075 076 public boolean couldContain(Record<? extends Data> record) { 077 if (name == null) { 078 return true; 079 } 080 return name.equals(record.name) && type == record.type && clazz == record.clazz; 081 } 082 083 public boolean addIfPossible(Record<? extends Data> record) { 084 if (!couldContain(record)) { 085 return false; 086 } 087 addRecord(record); 088 return true; 089 } 090 091 public RrSet build() { 092 if (name == null) { 093 // There is no RR added to this builder. 094 throw new IllegalStateException(); 095 } 096 return new RrSet(name, type, clazz, records); 097 } 098 } 099}