Initial import.
2 * StarOffice News Server
3 * see AUTHORS for the list of contributors
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 package com.so.news.storage;
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23 import java.util.Date;
24 import java.util.HashMap;
26 import java.util.Map.Entry;
27 import java.util.UUID;
29 import com.so.news.Config;
30 import com.so.news.Debug;
33 * Represents a newsgroup article.
34 * @author Christian Lins
35 * @author Denis Schwerdel
40 * Loads the Article identified by the given ID from the Database.
42 * @return null if Article is not found or if an error occurred.
44 public static Article getByMessageID(String messageID)
48 return Database.getInstance().getArticle(messageID);
50 catch(SQLException ex)
52 ex.printStackTrace(Debug.getInstance().getStream());
57 public static Article getByNumberInGroup(Group group, int number)
60 long gid = group.getID();
61 return Database.getInstance().getArticle(gid, number); // Is number her correct?
64 private String body = "";
65 private long groupID = -1;
66 private Map<String, String> header = new HashMap<String, String>();
67 private int numberInGroup = -1;
68 private String msgID = null;
71 * Default constructor.
78 * Creates a new Article object using the date from the given
79 * ResultSet. It is expected that ResultSet.next() was already
80 * called by the Database class.
81 * This construction has only package visibility.
87 this.body = rs.getString("body");
88 this.msgID = rs.getString("message_id");
91 parseHeader(rs.getString("header"));
95 * Parses the header fields and puts them into a map for faster access.
96 * TODO: There could be fields that go over more than one line, some
97 * bad clients do create them.
100 private void parseHeader(String hsrc)
102 String[] lines = hsrc.split("\n");
104 for(String line : lines)
106 String[] kv = line.split(":");
109 Debug.getInstance().log("Invalid header field: " + line);
114 // Set value in the header hash map
115 String value = kv[1];
116 for(int n = 2; n < kv.length; n++)
117 value += ":" + kv[n];
118 this.header.put(kv[0], value);
124 * Returnes the next Article in the group of this Article.
127 public Article nextArticleInGroup()
133 * Returns the previous Article in the group of this Article.
136 public Article prevArticleInGroup()
142 * Generates a message id for this article and sets it into
143 * the header HashMap.
145 private String generateMessageID()
147 this.msgID = "<" + UUID.randomUUID() + "@"
148 + Config.getInstance().get("n3tpd.hostname", "localhost") + ">";
150 this.header.put("Message-ID", msgID);
156 * Tries to delete this article.
157 * @return false if the article could not be deleted, otherwise true
159 public boolean delete()
165 * Checks if all necessary header fields are within this header.
167 private void validateHeader()
169 // Forces a MessageID creation if not existing
172 // Check if the references are correct...
173 String rep = header.get("In-Reply-To");
174 if(rep == null) // Some clients use only references instead of In-Reply-To
175 return; //rep = header.get("References");
177 String ref = getMessageID();
179 if(rep != null && !rep.equals(""))
181 Article art = null; //TODO // getByMessageID(rep, articleDir);
184 ref = art.header.get("References") + " " + rep;
187 header.put("References", ref);
191 * Returns the body string.
193 public String getBody()
199 * @return Numerical ID of the associated Group.
203 if(groupID == -1) // If the GroupID was not determined yet
205 // Determining GroupID
206 String newsgroups = this.header.get("Newsgroups");
207 if(newsgroups != null)
209 String[] newsgroup = newsgroups.split(",");
210 // Crossposting is not supported
214 if(newsgroup.length > 0)
215 group = Database.getInstance().getGroup(newsgroup[0].trim());
217 group = Database.getInstance().getGroup(newsgroups.trim());
218 // TODO: What to do if Group does not exist?
219 this.groupID = group.getID();
221 catch(SQLException ex)
223 ex.printStackTrace(Debug.getInstance().getStream());
224 System.err.println(ex.getLocalizedMessage());
228 System.err.println("Should never happen: Article::getGroupID");
233 public void setBody(String body)
238 public int getNumberInGroup()
240 return this.numberInGroup;
243 public void setHeader(HashMap<String, String> header)
245 this.header = header;
248 public void setNumberInGroup(int id)
250 this.numberInGroup = id;
253 public String getMessageID()
256 msgID = generateMessageID();
261 * @return Header source code of this Article.
263 public String getHeaderSource()
265 StringBuffer buf = new StringBuffer();
267 for(Entry<String, String> entry : this.header.entrySet())
269 buf.append(entry.getKey());
271 buf.append(entry.getValue());
275 return buf.toString();
278 public Map<String, String> getHeader()
283 public Date getDate()
287 String date = this.header.get("Date");
288 return new Date(Date.parse(date));
292 e.printStackTrace(Debug.getInstance().getStream());
297 public void setDate(Date date)
299 this.header.put("Date", date.toString());
303 public String toString()
305 return getMessageID();