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    *      http://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, time;
44      private StringBuffer distributions;
45      private StringBuffer newsgroups;
46      private final boolean isGMT;
47  
48      /**
49       * Creates a new query using the given time as a reference point.
50       *
51       * @param date The date since which new groups or news have arrived.
52       * @param gmt  True if the date should be considered as GMT, false if not.
53       */
54      public NewGroupsOrNewsQuery(final Calendar date, final boolean gmt) {
55          int num;
56          String str;
57          final StringBuilder buffer;
58  
59          this.distributions = null;
60          this.newsgroups = null;
61          this.isGMT = gmt;
62  
63          buffer = new StringBuilder();
64  
65          // Get year
66          num = date.get(Calendar.YEAR);
67          str = Integer.toString(num);
68          num = str.length();
69  
70          if (num >= 2) {
71              buffer.append(str.substring(num - 2));
72          } else {
73              buffer.append("00");
74          }
75  
76          // Get month
77          num = date.get(Calendar.MONTH) + 1;
78          str = Integer.toString(num);
79          num = str.length();
80  
81          if (num == 1) {
82              buffer.append('0');
83              buffer.append(str);
84          } else if (num == 2) {
85              buffer.append(str);
86          } else {
87              buffer.append("01");
88          }
89  
90          // Get day
91          num = date.get(Calendar.DAY_OF_MONTH);
92          str = Integer.toString(num);
93          num = str.length();
94  
95          if (num == 1) {
96              buffer.append('0');
97              buffer.append(str);
98          } else if (num == 2) {
99              buffer.append(str);
100         } else {
101             buffer.append("01");
102         }
103 
104         this.date = buffer.toString();
105 
106         buffer.setLength(0);
107 
108         // Get hour
109         num = date.get(Calendar.HOUR_OF_DAY);
110         str = Integer.toString(num);
111         num = str.length();
112 
113         if (num == 1) {
114             buffer.append('0');
115             buffer.append(str);
116         } else if (num == 2) {
117             buffer.append(str);
118         } else {
119             buffer.append("00");
120         }
121 
122         // Get minutes
123         num = date.get(Calendar.MINUTE);
124         str = Integer.toString(num);
125         num = str.length();
126 
127         if (num == 1) {
128             buffer.append('0');
129             buffer.append(str);
130         } else if (num == 2) {
131             buffer.append(str);
132         } else {
133             buffer.append("00");
134         }
135 
136         // Get seconds
137         num = date.get(Calendar.SECOND);
138         str = Integer.toString(num);
139         num = str.length();
140 
141         if (num == 1) {
142             buffer.append('0');
143             buffer.append(str);
144         } else if (num == 2) {
145             buffer.append(str);
146         } else {
147             buffer.append("00");
148         }
149 
150         this.time = buffer.toString();
151     }
152 
153     /**
154      * 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).
155      * 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
156      * reported as a query result. Adding distributions is purely optional.
157      *
158      * @param distribution A distribution to add to the query.
159      */
160     public void addDistribution(final String distribution) {
161         if (distributions != null) {
162             distributions.append(',');
163         } else {
164             distributions = new StringBuffer();
165         }
166         distributions.append(distribution);
167     }
168 
169     /**
170      * Add a newsgroup to the list of newsgroups being queried. Newsgroups added this way are only meaningful to the NEWNEWS command. Newsgroup names may
171      * include the <code> * </code> wildcard, as in <code>comp.lang.* </code> or <code> comp.lang.java.* </code>. Adding at least one newsgroup is mandatory for
172      * the NEWNEWS command.
173      *
174      * @param newsgroup The newsgroup to add to the list of groups to be checked for new news.
175      */
176     public void addNewsgroup(final String newsgroup) {
177         if (newsgroups != null) {
178             newsgroups.append(',');
179         } else {
180             newsgroups = new StringBuffer();
181         }
182         newsgroups.append(newsgroup);
183     }
184 
185     /**
186      * Return the NNTP query formatted date (year, month, day in the form YYMMDD).
187      *
188      * @return The NNTP query formatted date.
189      */
190     public String getDate() {
191         return date;
192     }
193 
194     /**
195      * Return the comma separated list of distributions. This may be null if there are no distributions.
196      *
197      * @return The list of distributions, which may be null if no distributions have been specified.
198      */
199     public String getDistributions() {
200         return Objects.toString(distributions, null);
201     }
202 
203     /**
204      * Return the comma separated list of newsgroups. This may be null if there are no newsgroups
205      *
206      * @return The list of newsgroups, which may be null if no newsgroups have been specified.
207      */
208     public String getNewsgroups() {
209         return Objects.toString(newsgroups, null);
210     }
211 
212     /**
213      * Return the NNTP query formatted time (hour, minutes, seconds in the form HHMMSS).
214      *
215      * @return The NNTP query formatted time.
216      */
217     public String getTime() {
218         return time;
219     }
220 
221     /**
222      * Return whether or not the query date should be treated as GMT.
223      *
224      * @return True if the query date is to be treated as GMT, false if not.
225      */
226     public boolean isGMT() {
227         return isGMT;
228     }
229 
230     /**
231      * 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
232      * meaningful to the NEWNEWS command. Newsgroup names may include the <code> * </code> wildcard, as in <code>comp.lang.* </code> or
233      * <code> comp.lang.java.* </code>.
234      * <p>
235      * The following would create a query that searched for new news in all comp.lang.java newsgroups except for comp.lang.java.advocacy.
236      * </p>
237      *
238      * <pre>
239      * query.addNewsgroup("comp.lang.java.*");
240      * query.omitNewsgroup("comp.lang.java.advocacy");
241      * </pre>
242      *
243      * @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.
244      */
245     public void omitNewsgroup(final String newsgroup) {
246         addNewsgroup("!" + newsgroup);
247     }
248 }