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 * https://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; 021import java.util.Objects; 022 023/** 024 * The NewGroupsOrNewsQuery class. This is used to issue NNTP NEWGROUPS and NEWNEWS queries, implemented by 025 * {@link org.apache.commons.net.nntp.NNTPClient#listNewNewsgroups listNewNewsGroups} and {@link org.apache.commons.net.nntp.NNTPClient#listNewNews listNewNews 026 * } respectively. It prevents you from having to format date, time, distribution, and newgroup arguments. 027 * <p> 028 * You might use the class as follows: 029 * </p> 030 * 031 * <pre> 032 * query = new NewsGroupsOrNewsQuery(new GregorianCalendar(97, 11, 15), false); 033 * query.addDistribution("comp"); 034 * NewsgroupInfo[] newsgroups = client.listNewgroups(query); 035 * </pre> 036 * 037 * This will retrieve the list of newsgroups starting with the comp. distribution prefix created since midnight 11/15/97. 038 * 039 * @see NNTPClient 040 */ 041 042public final class NewGroupsOrNewsQuery { 043 private final String date; 044 private final String time; 045 private StringBuffer distributions; 046 private StringBuffer newsgroups; 047 private final boolean isGMT; 048 049 /** 050 * Creates a new query using the given time as a reference point. 051 * 052 * @param date The date since which new groups or news have arrived. 053 * @param gmt True if the date should be considered as GMT, false if not. 054 */ 055 public NewGroupsOrNewsQuery(final Calendar date, final boolean gmt) { 056 int num; 057 String str; 058 final StringBuilder buffer; 059 060 this.distributions = null; 061 this.newsgroups = null; 062 this.isGMT = gmt; 063 064 buffer = new StringBuilder(); 065 066 // Get year 067 num = date.get(Calendar.YEAR); 068 str = Integer.toString(num); 069 num = str.length(); 070 071 if (num >= 2) { 072 buffer.append(str.substring(num - 2)); 073 } else { 074 buffer.append("00"); 075 } 076 077 // Get month 078 num = date.get(Calendar.MONTH) + 1; 079 str = Integer.toString(num); 080 num = str.length(); 081 082 if (num == 1) { 083 buffer.append('0'); 084 buffer.append(str); 085 } else if (num == 2) { 086 buffer.append(str); 087 } else { 088 buffer.append("01"); 089 } 090 091 // Get day 092 num = date.get(Calendar.DAY_OF_MONTH); 093 str = Integer.toString(num); 094 num = str.length(); 095 096 if (num == 1) { 097 buffer.append('0'); 098 buffer.append(str); 099 } 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}