001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net.nntp;
019
020import java.util.Calendar;
021
022/**
023 * The NewGroupsOrNewsQuery class.  This is used to issue NNTP NEWGROUPS and
024 * NEWNEWS queries, implemented by
025 * {@link org.apache.commons.net.nntp.NNTPClient#listNewNewsgroups listNewNewsGroups }
026 *  and
027 * {@link org.apache.commons.net.nntp.NNTPClient#listNewNews listNewNews }
028 *  respectively.  It prevents you from having to format
029 * date, time, distribution, and newgroup arguments.
030 * <p>
031 * You might use the class as follows:
032 * <pre>
033 * query = new NewsGroupsOrNewsQuery(new GregorianCalendar(97, 11, 15), false);
034 * query.addDistribution("comp");
035 * NewsgroupInfo[] newsgroups = client.listNewgroups(query);
036 * </pre>
037 * This will retrieve the list of newsgroups starting with the comp.
038 * distribution prefix created since midnight 11/15/97.
039 *
040 * @see NNTPClient
041 */
042
043public final class NewGroupsOrNewsQuery
044{
045    private final String date, time;
046    private StringBuffer distributions;
047    private StringBuffer newsgroups;
048    private final boolean isGMT;
049
050
051    /**
052     * Creates a new query using the given time as a reference point.
053     * <p>
054     * @param date  The date since which new groups or news have arrived.
055     * @param gmt   True if the date should be considered as GMT, false if not.
056     */
057    public NewGroupsOrNewsQuery(final Calendar date, final boolean gmt)
058    {
059        int num;
060        String str;
061        final StringBuilder buffer;
062
063        this.distributions = null;
064        this.newsgroups = null;
065        this.isGMT = gmt;
066
067        buffer = new StringBuilder();
068
069        // Get year
070        num = date.get(Calendar.YEAR);
071        str = Integer.toString(num);
072        num = str.length();
073
074        if (num >= 2) {
075            buffer.append(str.substring(num - 2));
076        } else {
077            buffer.append("00");
078        }
079
080        // Get month
081        num = date.get(Calendar.MONTH) + 1;
082        str = Integer.toString(num);
083        num = str.length();
084
085        if (num == 1) {
086            buffer.append('0');
087            buffer.append(str);
088        } else if (num == 2) {
089            buffer.append(str);
090        } else {
091            buffer.append("01");
092        }
093
094        // Get day
095        num = date.get(Calendar.DAY_OF_MONTH);
096        str = Integer.toString(num);
097        num = str.length();
098
099        if (num == 1) {
100            buffer.append('0');
101            buffer.append(str);
102        } else if (num == 2) {
103            buffer.append(str);
104        } else {
105            buffer.append("01");
106        }
107
108        this.date = buffer.toString();
109
110        buffer.setLength(0);
111
112        // Get hour
113        num = date.get(Calendar.HOUR_OF_DAY);
114        str = Integer.toString(num);
115        num = str.length();
116
117        if (num == 1) {
118            buffer.append('0');
119            buffer.append(str);
120        } else if (num == 2) {
121            buffer.append(str);
122        } else {
123            buffer.append("00");
124        }
125
126        // Get minutes
127        num = date.get(Calendar.MINUTE);
128        str = Integer.toString(num);
129        num = str.length();
130
131        if (num == 1) {
132            buffer.append('0');
133            buffer.append(str);
134        } else if (num == 2) {
135            buffer.append(str);
136        } else {
137            buffer.append("00");
138        }
139
140
141        // Get seconds
142        num = date.get(Calendar.SECOND);
143        str = Integer.toString(num);
144        num = str.length();
145
146        if (num == 1) {
147            buffer.append('0');
148            buffer.append(str);
149        } else if (num == 2) {
150            buffer.append(str);
151        } else {
152            buffer.append("00");
153        }
154
155        this.time = buffer.toString();
156    }
157
158
159    /**
160     * Add a newsgroup to the list of newsgroups being queried.  Newsgroups
161     * added this way are only meaningful to the NEWNEWS command.  Newsgroup
162     * names may include the <code> * </code> wildcard, as in
163     * <code>comp.lang.* </code> or <code> comp.lang.java.* </code>.  Adding
164     * at least one newsgroup is mandatory for the NEWNEWS command.
165     * <p>
166     * @param newsgroup  The newsgroup to add to the list of groups to be
167     *                   checked for new news.
168     */
169    public void addNewsgroup(final String newsgroup)
170    {
171        if (newsgroups != null) {
172            newsgroups.append(',');
173        } else {
174            newsgroups = new StringBuffer();
175        }
176        newsgroups.append(newsgroup);
177    }
178
179
180    /**
181     * Add a newsgroup to the list of newsgroups being queried, but indicate
182     * that group should not be checked for new news.  Newsgroups
183     * added this way are only meaningful to the NEWNEWS command.
184     * Newsgroup names may include the <code> * </code> wildcard, as in
185     * <code>comp.lang.* </code> or <code> comp.lang.java.* </code>.
186     * <p>
187     * The following would create a query that searched for new news in
188     * all comp.lang.java newsgroups except for comp.lang.java.advocacy.
189     * <pre>
190     * query.addNewsgroup("comp.lang.java.*");
191     * query.omitNewsgroup("comp.lang.java.advocacy");
192     * </pre>
193     * <p>
194     * @param newsgroup  The newsgroup to add to the list of groups to be
195     *                   checked for new news, but which should be omitted from
196     *                   the search for new news..
197     */
198    public void omitNewsgroup(final String newsgroup)
199    {
200        addNewsgroup("!" + newsgroup);
201    }
202
203
204    /**
205     * Add a distribution group to the query.  The distribution part of a
206     * newsgroup is the segment of the name preceding the first dot (e.g.,
207     * comp, alt, rec).  Only those newsgroups matching one of the
208     * distributions or, in the case of NEWNEWS, an article in a newsgroup
209     * matching one of the distributions, will be reported as a query result.
210     * Adding distributions is purely optional.
211     * <p>
212     * @param distribution A distribution to add to the query.
213     */
214    public void addDistribution(final String distribution)
215    {
216        if (distributions != null) {
217            distributions.append(',');
218        } else {
219            distributions = new StringBuffer();
220        }
221        distributions.append(distribution);
222    }
223
224    /**
225     * Return the NNTP query formatted date (year, month, day in the form
226     * YYMMDD.
227     * <p>
228     * @return The NNTP query formatted date.
229     */
230    public String getDate()
231    {
232        return date;
233    }
234
235    /**
236     * Return the NNTP query formatted time (hour, minutes, seconds in the form
237     * HHMMSS.
238     * <p>
239     * @return The NNTP query formatted time.
240     */
241    public String getTime()
242    {
243        return time;
244    }
245
246    /**
247     * Return whether or not the query date should be treated as GMT.
248     * <p>
249     * @return True if the query date is to be treated as GMT, false if not.
250     */
251    public boolean isGMT()
252    {
253        return isGMT;
254    }
255
256    /**
257     * Return the comma separated list of distributions.  This may be null
258     * if there are no distributions.
259     * <p>
260     * @return The list of distributions, which may be null if no distributions
261     *         have been specified.
262     */
263    public String getDistributions()
264    {
265        return distributions == null ? null : distributions.toString();
266    }
267
268    /**
269     * Return the comma separated list of newsgroups.  This may be null
270     * if there are no newsgroups
271     * <p>
272     * @return The list of newsgroups, which may be null if no newsgroups
273     *         have been specified.
274     */
275    public String getNewsgroups()
276    {
277        return newsgroups == null ? null : newsgroups.toString();
278    }
279}