View Javadoc
1   /*
2    * Copyright 2013 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.dns;
17  
18  import io.netty.util.AbstractReferenceCounted;
19  import io.netty.util.ReferenceCountUtil;
20  
21  import java.util.Collections;
22  import java.util.LinkedList;
23  import java.util.List;
24  
25  /**
26   * The message super-class which contains core information concerning DNS
27   * packets, both outgoing and incoming.
28   */
29  public abstract class DnsMessage extends AbstractReferenceCounted {
30  
31      private List<DnsQuestion> questions;
32      private List<DnsResource> answers;
33      private List<DnsResource> authority;
34      private List<DnsResource> additional;
35  
36      private final DnsHeader header;
37  
38      // Only allow to extend from same package
39      DnsMessage(int id) {
40          header = newHeader(id);
41      }
42  
43      /**
44       * Returns the header belonging to this message.
45       */
46      public DnsHeader header() {
47          return header;
48      }
49  
50      /**
51       * Returns a list of all the questions in this message.
52       */
53      public List<DnsQuestion> questions() {
54          if (questions == null) {
55              return Collections.emptyList();
56          }
57          return Collections.unmodifiableList(questions);
58      }
59  
60      /**
61       * Returns a list of all the answer resource records in this message.
62       */
63      public List<DnsResource> answers() {
64          if (answers == null) {
65              return Collections.emptyList();
66          }
67          return Collections.unmodifiableList(answers);
68      }
69  
70      /**
71       * Returns a list of all the authority resource records in this message.
72       */
73      public List<DnsResource> authorityResources() {
74          if (authority == null) {
75              return Collections.emptyList();
76          }
77          return Collections.unmodifiableList(authority);
78      }
79  
80      /**
81       * Returns a list of all the additional resource records in this message.
82       */
83      public List<DnsResource> additionalResources() {
84          if (additional == null) {
85              return Collections.emptyList();
86          }
87          return Collections.unmodifiableList(additional);
88      }
89  
90      /**
91       * Adds an answer resource record to this message.
92       *
93       * @param answer
94       *            the answer resource record to be added
95       * @return the message to allow method chaining
96       */
97      public DnsMessage addAnswer(DnsResource answer) {
98          if (answers == null) {
99              answers = new LinkedList<DnsResource>();
100         }
101         answers.add(answer);
102         return this;
103     }
104 
105     /**
106      * Adds a question to this message.
107      *
108      * @param question
109      *            the question to be added
110      * @return the message to allow method chaining
111      */
112     public DnsMessage addQuestion(DnsQuestion question) {
113         if (questions == null) {
114             questions = new LinkedList<DnsQuestion>();
115         }
116         questions.add(question);
117         return this;
118     }
119 
120     /**
121      * Adds an authority resource record to this message.
122      *
123      * @param resource
124      *            the authority resource record to be added
125      * @return the message to allow method chaining
126      */
127     public DnsMessage addAuthorityResource(DnsResource resource) {
128         if (authority == null) {
129             authority = new LinkedList<DnsResource>();
130         }
131         authority.add(resource);
132         return this;
133     }
134 
135     /**
136      * Adds an additional resource record to this message.
137      *
138      * @param resource
139      *            the additional resource record to be added
140      * @return the message to allow method chaining
141      */
142     public DnsMessage addAdditionalResource(DnsResource resource) {
143         if (additional == null) {
144             additional = new LinkedList<DnsResource>();
145         }
146         additional.add(resource);
147         return this;
148     }
149 
150     @Override
151     protected void deallocate() {
152         // NOOP
153     }
154 
155     @Override
156     public boolean release() {
157         release(questions());
158         release(answers());
159         release(additionalResources());
160         release(authorityResources());
161         return super.release();
162     }
163 
164     private static void release(List<?> resources) {
165         for (Object resource: resources) {
166             ReferenceCountUtil.release(resource);
167         }
168     }
169 
170     @Override
171     public boolean release(int decrement) {
172         release(questions(), decrement);
173         release(answers(), decrement);
174         release(additionalResources(), decrement);
175         release(authorityResources(), decrement);
176         return super.release(decrement);
177     }
178 
179     private static void release(List<?> resources, int decrement) {
180         for (Object resource: resources) {
181             ReferenceCountUtil.release(resource, decrement);
182         }
183     }
184 
185     @Override
186     public DnsMessage touch(Object hint) {
187         touch(questions(), hint);
188         touch(answers(), hint);
189         touch(additionalResources(), hint);
190         touch(authorityResources(), hint);
191         return this;
192     }
193 
194     private static void touch(List<?> resources, Object hint) {
195         for (Object resource: resources) {
196             ReferenceCountUtil.touch(resource, hint);
197         }
198     }
199 
200     @Override
201     public DnsMessage retain() {
202         retain(questions());
203         retain(answers());
204         retain(additionalResources());
205         retain(authorityResources());
206         super.retain();
207         return this;
208     }
209 
210     private static void retain(List<?> resources) {
211         for (Object resource: resources) {
212             ReferenceCountUtil.retain(resource);
213         }
214     }
215 
216     @Override
217     public DnsMessage retain(int increment) {
218         retain(questions(), increment);
219         retain(answers(), increment);
220         retain(additionalResources(), increment);
221         retain(authorityResources(), increment);
222         super.retain(increment);
223         return this;
224     }
225 
226     private static void retain(List<?> resources, int increment) {
227         for (Object resource: resources) {
228             ReferenceCountUtil.retain(resource, increment);
229         }
230     }
231 
232     @Override
233     public DnsMessage touch() {
234         super.touch();
235         return this;
236     }
237 
238     protected abstract DnsHeader newHeader(int id);
239 }