    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 NEWNEWS queries, implemented by
    024 * {@link org.apache.commons.net.nntp.NNTPClient#listNewNewsgroups listNewNewsGroups } and {@link org.apache.commons.net.nntp.NNTPClient#listNewNews listNewNews
    025 * } respectively. It prevents you from having to format date, time, distribution, and newgroup arguments.
    026 * <p>
    027 * You might use the class as follows:
    028 *
    029 * <pre>
    030 * query = new NewsGroupsOrNewsQuery(new GregorianCalendar(97, 11, 15), false);
    031 * query.addDistribution("comp");
    032 * NewsgroupInfo[] newsgroups = client.listNewgroups(query);
    033 * </pre>
    034 *
    035 * This will retrieve the list of newsgroups starting with the comp. distribution prefix created since midnight 11/15/97.
    036 *
    037 * @see NNTPClient
    038 */
    039
    040public final class NewGroupsOrNewsQuery {
    041    private final String date, time;
    042    private StringBuffer distributions;
    043    private StringBuffer newsgroups;
    044    private final boolean isGMT;
    045
    046    /**
    047     * Creates a new query using the given time as a reference point.
    048     * <p>
    049     *
    050     * @param date The date since which new groups or news have arrived.
    051     * @param gmt  True if the date should be considered as GMT, false if not.
    052     */
    053    public NewGroupsOrNewsQuery(final Calendar date, final boolean gmt) {
    054        int num;
    055        String str;
    056        final StringBuilder buffer;
    057
    058        this.distributions = null;
    059        this.newsgroups = null;
    060        this.isGMT = gmt;
    061
    062        buffer = new StringBuilder();
    063
    064        // Get year
    065        num = date.get(Calendar.YEAR);
    066        str = Integer.toString(num);
    067        num = str.length();
    068
    069        if (num >= 2) {
    070            buffer.append(str.substring(num - 2));
    071        } else {
    072            buffer.append("00");
    073        }
    074
    075        // Get month
    076        num = date.get(Calendar.MONTH) + 1;
    077        str = Integer.toString(num);
    078        num = str.length();
    079
    080        if (num == 1) {
    081            buffer.append('0');
    082            buffer.append(str);
    083        } else if (num == 2) {
    084            buffer.append(str);
    085        } else {
    086            buffer.append("01");
    087        }
    088
    089        // Get day
    090        num = date.get(Calendar.DAY_OF_MONTH);
    091        str = Integer.toString(num);
    092        num = str.length();
    093
    094        if (num == 1) {
    095            buffer.append('0');
    096            buffer.append(str);
    097        } else if (num == 2) {
    098            buffer.append(str);
    099        } else {
    100            buffer.append("01");
    101        }
    102
    103        this.date = buffer.toString();
    104
    105        buffer.setLength(0);
    106
    107        // Get hour
    108        num = date.get(Calendar.HOUR_OF_DAY);
    109        str = Integer.toString(num);
    110        num = str.length();
    111
    112        if (num == 1) {
    113            buffer.append('0');
    114            buffer.append(str);
    115        } else if (num == 2) {
    116            buffer.append(str);
    117        } else {
    118            buffer.append("00");
    119        }
    120
    121        // Get minutes
    122        num = date.get(Calendar.MINUTE);
    123        str = Integer.toString(num);
    124        num = str.length();
    125
    126        if (num == 1) {
    127            buffer.append('0');
    128            buffer.append(str);
    129        } else if (num == 2) {
    130            buffer.append(str);
    131        } else {
    132            buffer.append("00");
    133        }
    134
    135        // Get seconds
    136        num = date.get(Calendar.SECOND);
    137        str = Integer.toString(num);
    138        num = str.length();
    139
    140        if (num == 1) {
    141            buffer.append('0');
    142            buffer.append(str);
    143        } else if (num == 2) {
    144            buffer.append(str);
    145        } else {
    146            buffer.append("00");
    147        }
    148
    149        this.time = buffer.toString();
    150    }
    151
    152    /**
    153     * 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).
    154     * 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
    155     * reported as a query result. Adding distributions is purely optional.
    156     * <p>
    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     * <p>
    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     * Return the NNTP query formatted date (year, month, day in the form YYMMDD.
    188     * <p>
    189     *
    190     * @return The NNTP query formatted date.
    191     */
    192    public String getDate() {
    193        return date;
    194    }
    195
    196    /**
    197     * Return the comma separated list of distributions. This may be null if there are no distributions.
    198     * <p>
    199     *
    200     * @return The list of distributions, which may be null if no distributions have been specified.
    201     */
    202    public String getDistributions() {
    203        return distributions == null ? null : distributions.toString();
    204    }
    205
    206    /**
    207     * Return the comma separated list of newsgroups. This may be null if there are no newsgroups
    208     * <p>
    209     *
    210     * @return The list of newsgroups, which may be null if no newsgroups have been specified.
    211     */
    212    public String getNewsgroups() {
    213        return newsgroups == null ? null : newsgroups.toString();
    214    }
    215
    216    /**
    217     * Return the NNTP query formatted time (hour, minutes, seconds in the form HHMMSS.
    218     * <p>
    219     *
    220     * @return The NNTP query formatted time.
    221     */
    222    public String getTime() {
    223        return time;
    224    }
    225
    226    /**
    227     * Return whether or not the query date should be treated as GMT.
    228     * <p>
    229     *
    230     * @return True if the query date is to be treated as GMT, false if not.
    231     */
    232    public boolean isGMT() {
    233        return isGMT;
    234    }
    235
    236    /**
    237     * 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
    238     * meaningful to the NEWNEWS command. Newsgroup names may include the <code> * </code> wildcard, as in <code>comp.lang.* </code> or
    239     * <code> comp.lang.java.* </code>.
    240     * <p>
    241     * The following would create a query that searched for new news in all comp.lang.java newsgroups except for comp.lang.java.advocacy.
    242     *
    243     * <pre>
    244     * query.addNewsgroup("comp.lang.java.*");
    245     * query.omitNewsgroup("comp.lang.java.advocacy");
    246     * </pre>
    247     * <p>
    248     *
    249     * @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..
    250     */
    251    public void omitNewsgroup(final String newsgroup) {
    252        addNewsgroup("!" + newsgroup);
    253    }
    254}