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 }