001/*
002 * Copyright 2015-2018 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 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    public static Builder builder() {
038        return new Builder();
039    }
040
041    public static class Builder {
042        private DnsName name;
043        private TYPE type;
044        private CLASS clazz;
045        Set<Record<? extends Data>> records = new LinkedHashSet<>(8);
046
047        private Builder() {
048        }
049
050        public Builder addRecord(Record<? extends Data> record) {
051            if (name == null) {
052                name = record.name;
053                type = record.type;
054                clazz = record.clazz;
055            } else if (!couldContain(record)) {
056                throw new IllegalArgumentException(
057                        "Can not add " + record + " to RRSet " + name + ' ' + type + ' ' + clazz);
058            }
059
060            boolean didNotExist = records.add(record);
061            assert (didNotExist);
062
063            return this;
064        }
065
066        public boolean couldContain(Record<? extends Data> record) {
067            if (name == null) {
068                return true;
069            }
070            return name.equals(record.name) && type == record.type && clazz == record.clazz;
071        }
072
073        public boolean addIfPossible(Record<? extends Data> record) {
074            if (!couldContain(record)) {
075                return false;
076            }
077            addRecord(record);
078            return true;
079        }
080
081        public RrSet build() {
082            if (name == null) {
083                // There is no RR added to this builder.
084                throw new IllegalStateException();
085            }
086            return new RrSet(name, type, clazz, records);
087        }
088    }
089}