View Javadoc
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 }