/commons-net-3.1-src/src/main/java/org/apache/commons/net/nntp/Article.java

# · Java · 263 lines · 170 code · 51 blank · 42 comment · 55 complexity · f2751f8e3c3dae266eb2a2e1472acdab MD5 · raw file

  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. package org.apache.commons.net.nntp;
  18. import java.util.ArrayList;
  19. /**
  20. * This is a class that contains the basic state needed for message retrieval and threading.
  21. * With thanks to Jamie Zawinski <jwz@jwz.org>
  22. * @author rwinston <rwinston@apache.org>
  23. */
  24. public class Article implements Threadable {
  25. private long articleNumber;
  26. private String subject;
  27. private String date;
  28. private String articleId;
  29. private String simplifiedSubject;
  30. private String from;
  31. private ArrayList<String> references;
  32. private boolean isReply = false;
  33. public Article kid, next;
  34. public Article() {
  35. articleNumber = -1; // isDummy
  36. }
  37. /**
  38. * Adds a message-id to the list of messages that this message references (i.e. replies to)
  39. * @param msgId
  40. */
  41. public void addReference(String msgId) {
  42. if (msgId == null || msgId.length() == 0) {
  43. return;
  44. }
  45. if (references == null) {
  46. references = new ArrayList<String>();
  47. }
  48. isReply = true;
  49. for(String s : msgId.split(" ")) {
  50. references.add(s);
  51. }
  52. }
  53. /**
  54. * Returns the MessageId references as an array of Strings
  55. * @return an array of message-ids
  56. */
  57. public String[] getReferences() {
  58. if (references == null) {
  59. return new String[0];
  60. }
  61. return references.toArray(new String[references.size()]);
  62. }
  63. /**
  64. * Attempts to parse the subject line for some typical reply signatures, and strip them out
  65. *
  66. */
  67. private void simplifySubject() {
  68. int start = 0;
  69. String subject = getSubject();
  70. int len = subject.length();
  71. boolean done = false;
  72. while (!done) {
  73. done = true;
  74. // skip whitespace
  75. // "Re: " breaks this
  76. while (start < len && subject.charAt(start) == ' ') {
  77. start++;
  78. }
  79. if (start < (len - 2)
  80. && (subject.charAt(start) == 'r' || subject.charAt(start) == 'R')
  81. && (subject.charAt(start + 1) == 'e' || subject.charAt(start + 1) == 'E')) {
  82. if (subject.charAt(start + 2) == ':') {
  83. start += 3; // Skip "Re:"
  84. done = false;
  85. } else if (
  86. start < (len - 2)
  87. &&
  88. (subject.charAt(start + 2) == '[' || subject.charAt(start + 2) == '(')) {
  89. int i = start + 3;
  90. while (i < len && subject.charAt(i) >= '0' && subject.charAt(i) <= '9') {
  91. i++;
  92. }
  93. if (i < (len - 1)
  94. && (subject.charAt(i) == ']' || subject.charAt(i) == ')')
  95. && subject.charAt(i + 1) == ':')
  96. {
  97. start = i + 2;
  98. done = false;
  99. }
  100. }
  101. }
  102. if ("(no subject)".equals(simplifiedSubject)) {
  103. simplifiedSubject = "";
  104. }
  105. int end = len;
  106. while (end > start && subject.charAt(end - 1) < ' ') {
  107. end--;
  108. }
  109. if (start == 0 && end == len) {
  110. simplifiedSubject = subject;
  111. } else {
  112. simplifiedSubject = subject.substring(start, end);
  113. }
  114. }
  115. }
  116. /**
  117. * Recursive method that traverses a pre-threaded graph (or tree)
  118. * of connected Article objects and prints them out.
  119. * @param article the root of the article 'tree'
  120. * @param depth the current tree depth
  121. */
  122. public static void printThread(Article article, int depth) {
  123. for (int i = 0; i < depth; ++i) {
  124. System.out.print("==>");
  125. }
  126. System.out.println(article.getSubject() + "\t" + article.getFrom());
  127. if (article.kid != null) {
  128. printThread(article.kid, depth + 1);
  129. }
  130. if (article.next != null) {
  131. printThread(article.next, depth);
  132. }
  133. }
  134. public String getArticleId() {
  135. return articleId;
  136. }
  137. public long getArticleNumberLong() {
  138. return articleNumber;
  139. }
  140. public String getDate() {
  141. return date;
  142. }
  143. public String getFrom() {
  144. return from;
  145. }
  146. public String getSubject() {
  147. return subject;
  148. }
  149. public void setArticleId(String string) {
  150. articleId = string;
  151. }
  152. public void setArticleNumber(long l) {
  153. articleNumber = l;
  154. }
  155. public void setDate(String string) {
  156. date = string;
  157. }
  158. public void setFrom(String string) {
  159. from = string;
  160. }
  161. public void setSubject(String string) {
  162. subject = string;
  163. }
  164. public boolean isDummy() {
  165. return (articleNumber == -1);
  166. }
  167. public String messageThreadId() {
  168. return articleId;
  169. }
  170. public String[] messageThreadReferences() {
  171. return getReferences();
  172. }
  173. public String simplifiedSubject() {
  174. if(simplifiedSubject == null) {
  175. simplifySubject();
  176. }
  177. return simplifiedSubject;
  178. }
  179. public boolean subjectIsReply() {
  180. return isReply;
  181. }
  182. public void setChild(Threadable child) {
  183. this.kid = (Article) child;
  184. flushSubjectCache();
  185. }
  186. private void flushSubjectCache() {
  187. simplifiedSubject = null;
  188. }
  189. public void setNext(Threadable next) {
  190. this.next = (Article)next;
  191. flushSubjectCache();
  192. }
  193. public Threadable makeDummy() {
  194. return new Article();
  195. }
  196. @Override
  197. public String toString(){ // Useful for Eclipse debugging
  198. return articleNumber + " " +articleId + " " + subject;
  199. }
  200. // DEPRECATED METHODS - for API compatibility only - DO NOT USE
  201. @Deprecated
  202. public int getArticleNumber() {
  203. return (int) articleNumber;
  204. }
  205. @Deprecated
  206. public void setArticleNumber(int a) {
  207. articleNumber = a;
  208. }
  209. @Deprecated
  210. public void addHeaderField(String name, String val) {
  211. }
  212. }