1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.net.nntp;
19
20 import java.util.Calendar;
21 import java.util.Objects;
22
23 /**
24 * The NewGroupsOrNewsQuery class. This is used to issue NNTP NEWGROUPS and NEWNEWS queries, implemented by
25 * {@link org.apache.commons.net.nntp.NNTPClient#listNewNewsgroups listNewNewsGroups} and {@link org.apache.commons.net.nntp.NNTPClient#listNewNews listNewNews
26 * } respectively. It prevents you from having to format date, time, distribution, and newgroup arguments.
27 * <p>
28 * You might use the class as follows:
29 * </p>
30 *
31 * <pre>
32 * query = new NewsGroupsOrNewsQuery(new GregorianCalendar(97, 11, 15), false);
33 * query.addDistribution("comp");
34 * NewsgroupInfo[] newsgroups = client.listNewgroups(query);
35 * </pre>
36 *
37 * This will retrieve the list of newsgroups starting with the comp. distribution prefix created since midnight 11/15/97.
38 *
39 * @see NNTPClient
40 */
41
42 public final class NewGroupsOrNewsQuery {
43 private final String date;
44 private final String time;
45 private StringBuffer distributions;
46 private StringBuffer newsgroups;
47 private final boolean isGMT;
48
49 /**
50 * Creates a new query using the given time as a reference point.
51 *
52 * @param date The date since which new groups or news have arrived.
53 * @param gmt True if the date should be considered as GMT, false if not.
54 */
55 public NewGroupsOrNewsQuery(final Calendar date, final boolean gmt) {
56 int num;
57 String str;
58 final StringBuilder buffer;
59
60 this.distributions = null;
61 this.newsgroups = null;
62 this.isGMT = gmt;
63
64 buffer = new StringBuilder();
65
66 // Get year
67 num = date.get(Calendar.YEAR);
68 str = Integer.toString(num);
69 num = str.length();
70
71 if (num >= 2) {
72 buffer.append(str.substring(num - 2));
73 } else {
74 buffer.append("00");
75 }
76
77 // Get month
78 num = date.get(Calendar.MONTH) + 1;
79 str = Integer.toString(num);
80 num = str.length();
81
82 if (num == 1) {
83 buffer.append('0');
84 buffer.append(str);
85 } else if (num == 2) {
86 buffer.append(str);
87 } else {
88 buffer.append("01");
89 }
90
91 // Get day
92 num = date.get(Calendar.DAY_OF_MONTH);
93 str = Integer.toString(num);
94 num = str.length();
95
96 if (num == 1) {
97 buffer.append('0');
98 buffer.append(str);
99 } else if (num == 2) {
100 buffer.append(str);
101 } else {
102 buffer.append("01");
103 }
104
105 this.date = buffer.toString();
106
107 buffer.setLength(0);
108
109 // Get hour
110 num = date.get(Calendar.HOUR_OF_DAY);
111 str = Integer.toString(num);
112 num = str.length();
113
114 if (num == 1) {
115 buffer.append('0');
116 buffer.append(str);
117 } else if (num == 2) {
118 buffer.append(str);
119 } else {
120 buffer.append("00");
121 }
122
123 // Get minutes
124 num = date.get(Calendar.MINUTE);
125 str = Integer.toString(num);
126 num = str.length();
127
128 if (num == 1) {
129 buffer.append('0');
130 buffer.append(str);
131 } else if (num == 2) {
132 buffer.append(str);
133 } else {
134 buffer.append("00");
135 }
136
137 // Get seconds
138 num = date.get(Calendar.SECOND);
139 str = Integer.toString(num);
140 num = str.length();
141
142 if (num == 1) {
143 buffer.append('0');
144 buffer.append(str);
145 } else if (num == 2) {
146 buffer.append(str);
147 } else {
148 buffer.append("00");
149 }
150
151 this.time = buffer.toString();
152 }
153
154 /**
155 * Add a distribution group to the query. The distribution part of a newsgroup is the segment of the name preceding the first dot (e.g., comp, alt, rec).
156 * Only those newsgroups matching one of the distributions or, in the case of NEWNEWS, an article in a newsgroup matching one of the distributions, will be
157 * reported as a query result. Adding distributions is purely optional.
158 *
159 * @param distribution A distribution to add to the query.
160 */
161 public void addDistribution(final String distribution) {
162 if (distributions != null) {
163 distributions.append(',');
164 } else {
165 distributions = new StringBuffer();
166 }
167 distributions.append(distribution);
168 }
169
170 /**
171 * Add a newsgroup to the list of newsgroups being queried. Newsgroups added this way are only meaningful to the NEWNEWS command. Newsgroup names may
172 * include the {@code *} wildcard, as in {@code comp.lang.*} or {@code comp.lang.java.*}. Adding at least one newsgroup is mandatory for
173 * the NEWNEWS command.
174 *
175 * @param newsgroup The newsgroup to add to the list of groups to be checked for new news.
176 */
177 public void addNewsgroup(final String newsgroup) {
178 if (newsgroups != null) {
179 newsgroups.append(',');
180 } else {
181 newsgroups = new StringBuffer();
182 }
183 newsgroups.append(newsgroup);
184 }
185
186 /**
187 * Gets the NNTP query formatted date (year, month, day in the form YYMMDD).
188 *
189 * @return The NNTP query formatted date.
190 */
191 public String getDate() {
192 return date;
193 }
194
195 /**
196 * Gets the comma separated list of distributions. This may be null if there are no distributions.
197 *
198 * @return The list of distributions, which may be null if no distributions have been specified.
199 */
200 public String getDistributions() {
201 return Objects.toString(distributions, null);
202 }
203
204 /**
205 * Gets the comma separated list of newsgroups. This may be null if there are no newsgroups
206 *
207 * @return The list of newsgroups, which may be null if no newsgroups have been specified.
208 */
209 public String getNewsgroups() {
210 return Objects.toString(newsgroups, null);
211 }
212
213 /**
214 * Gets the NNTP query formatted time (hour, minutes, seconds in the form HHMMSS).
215 *
216 * @return The NNTP query formatted time.
217 */
218 public String getTime() {
219 return time;
220 }
221
222 /**
223 * Tests whether or not the query date should be treated as GMT.
224 *
225 * @return True if the query date is to be treated as GMT, false if not.
226 */
227 public boolean isGMT() {
228 return isGMT;
229 }
230
231 /**
232 * Add a newsgroup to the list of newsgroups being queried, but indicate that group should not be checked for new news. Newsgroups added this way are only
233 * meaningful to the NEWNEWS command. Newsgroup names may include the {@code *} wildcard, as in {@code comp.lang.*} or
234 * {@code comp.lang.java.*}.
235 * <p>
236 * The following would create a query that searched for new news in all comp.lang.java newsgroups except for comp.lang.java.advocacy.
237 * </p>
238 *
239 * <pre>
240 * query.addNewsgroup("comp.lang.java.*");
241 * query.omitNewsgroup("comp.lang.java.advocacy");
242 * </pre>
243 *
244 * @param newsgroup The newsgroup to add to the list of groups to be checked for new news, but which should be omitted from the search for new news.
245 */
246 public void omitNewsgroup(final String newsgroup) {
247 addNewsgroup("!" + newsgroup);
248 }
249 }