1.1 --- a/org/sonews/storage/Article.java Sun Aug 29 17:04:25 2010 +0200
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,253 +0,0 @@
1.4 -/*
1.5 - * SONEWS News Server
1.6 - * see AUTHORS for the list of contributors
1.7 - *
1.8 - * This program is free software: you can redistribute it and/or modify
1.9 - * it under the terms of the GNU General Public License as published by
1.10 - * the Free Software Foundation, either version 3 of the License, or
1.11 - * (at your option) any later version.
1.12 - *
1.13 - * This program is distributed in the hope that it will be useful,
1.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.16 - * GNU General Public License for more details.
1.17 - *
1.18 - * You should have received a copy of the GNU General Public License
1.19 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
1.20 - */
1.21 -
1.22 -package org.sonews.storage;
1.23 -
1.24 -import java.io.ByteArrayInputStream;
1.25 -import java.io.ByteArrayOutputStream;
1.26 -import java.io.IOException;
1.27 -import java.security.MessageDigest;
1.28 -import java.security.NoSuchAlgorithmException;
1.29 -import java.util.UUID;
1.30 -import java.util.ArrayList;
1.31 -import java.util.Enumeration;
1.32 -import java.util.List;
1.33 -import javax.mail.Header;
1.34 -import javax.mail.Message;
1.35 -import javax.mail.MessagingException;
1.36 -import javax.mail.internet.InternetHeaders;
1.37 -import org.sonews.config.Config;
1.38 -
1.39 -/**
1.40 - * Represents a newsgroup article.
1.41 - * @author Christian Lins
1.42 - * @author Denis Schwerdel
1.43 - * @since n3tpd/0.1
1.44 - */
1.45 -public class Article extends ArticleHead
1.46 -{
1.47 -
1.48 - /**
1.49 - * Loads the Article identified by the given ID from the JDBCDatabase.
1.50 - * @param messageID
1.51 - * @return null if Article is not found or if an error occurred.
1.52 - */
1.53 - public static Article getByMessageID(final String messageID)
1.54 - {
1.55 - try
1.56 - {
1.57 - return StorageManager.current().getArticle(messageID);
1.58 - }
1.59 - catch(StorageBackendException ex)
1.60 - {
1.61 - ex.printStackTrace();
1.62 - return null;
1.63 - }
1.64 - }
1.65 -
1.66 - private byte[] body = new byte[0];
1.67 -
1.68 - /**
1.69 - * Default constructor.
1.70 - */
1.71 - public Article()
1.72 - {
1.73 - }
1.74 -
1.75 - /**
1.76 - * Creates a new Article object using the date from the given
1.77 - * raw data.
1.78 - */
1.79 - public Article(String headers, byte[] body)
1.80 - {
1.81 - try
1.82 - {
1.83 - this.body = body;
1.84 -
1.85 - // Parse the header
1.86 - this.headers = new InternetHeaders(
1.87 - new ByteArrayInputStream(headers.getBytes()));
1.88 -
1.89 - this.headerSrc = headers;
1.90 - }
1.91 - catch(MessagingException ex)
1.92 - {
1.93 - ex.printStackTrace();
1.94 - }
1.95 - }
1.96 -
1.97 - /**
1.98 - * Creates an Article instance using the data from the javax.mail.Message
1.99 - * object. This constructor is called by the Mailinglist gateway.
1.100 - * @see javax.mail.Message
1.101 - * @param msg
1.102 - * @throws IOException
1.103 - * @throws MessagingException
1.104 - */
1.105 - public Article(final Message msg)
1.106 - throws IOException, MessagingException
1.107 - {
1.108 - this.headers = new InternetHeaders();
1.109 -
1.110 - for(Enumeration e = msg.getAllHeaders() ; e.hasMoreElements();)
1.111 - {
1.112 - final Header header = (Header)e.nextElement();
1.113 - this.headers.addHeader(header.getName(), header.getValue());
1.114 - }
1.115 -
1.116 - // Reads the raw byte body using Message.writeTo(OutputStream out)
1.117 - this.body = readContent(msg);
1.118 -
1.119 - // Validate headers
1.120 - validateHeaders();
1.121 - }
1.122 -
1.123 - /**
1.124 - * Reads from the given Message into a byte array.
1.125 - * @param in
1.126 - * @return
1.127 - * @throws IOException
1.128 - */
1.129 - private byte[] readContent(Message in)
1.130 - throws IOException, MessagingException
1.131 - {
1.132 - ByteArrayOutputStream out = new ByteArrayOutputStream();
1.133 - in.writeTo(out);
1.134 - return out.toByteArray();
1.135 - }
1.136 -
1.137 - /**
1.138 - * Removes the header identified by the given key.
1.139 - * @param headerKey
1.140 - */
1.141 - public void removeHeader(final String headerKey)
1.142 - {
1.143 - this.headers.removeHeader(headerKey);
1.144 - this.headerSrc = null;
1.145 - }
1.146 -
1.147 - /**
1.148 - * Generates a message id for this article and sets it into
1.149 - * the header object. You have to update the JDBCDatabase manually to make this
1.150 - * change persistent.
1.151 - * Note: a Message-ID should never be changed and only generated once.
1.152 - */
1.153 - private String generateMessageID()
1.154 - {
1.155 - String randomString;
1.156 - MessageDigest md5;
1.157 - try
1.158 - {
1.159 - md5 = MessageDigest.getInstance("MD5");
1.160 - md5.reset();
1.161 - md5.update(getBody());
1.162 - md5.update(getHeader(Headers.SUBJECT)[0].getBytes());
1.163 - md5.update(getHeader(Headers.FROM)[0].getBytes());
1.164 - byte[] result = md5.digest();
1.165 - StringBuffer hexString = new StringBuffer();
1.166 - for (int i = 0; i < result.length; i++)
1.167 - {
1.168 - hexString.append(Integer.toHexString(0xFF & result[i]));
1.169 - }
1.170 - randomString = hexString.toString();
1.171 - }
1.172 - catch (NoSuchAlgorithmException e)
1.173 - {
1.174 - e.printStackTrace();
1.175 - randomString = UUID.randomUUID().toString();
1.176 - }
1.177 - String msgID = "<" + randomString + "@"
1.178 - + Config.inst().get(Config.HOSTNAME, "localhost") + ">";
1.179 -
1.180 - this.headers.setHeader(Headers.MESSAGE_ID, msgID);
1.181 -
1.182 - return msgID;
1.183 - }
1.184 -
1.185 - /**
1.186 - * Returns the body string.
1.187 - */
1.188 - public byte[] getBody()
1.189 - {
1.190 - return body;
1.191 - }
1.192 -
1.193 - /**
1.194 - * @return Numerical IDs of the newsgroups this Article belongs to.
1.195 - */
1.196 - public List<Group> getGroups()
1.197 - {
1.198 - String[] groupnames = getHeader(Headers.NEWSGROUPS)[0].split(",");
1.199 - ArrayList<Group> groups = new ArrayList<Group>();
1.200 -
1.201 - try
1.202 - {
1.203 - for(String newsgroup : groupnames)
1.204 - {
1.205 - newsgroup = newsgroup.trim();
1.206 - Group group = StorageManager.current().getGroup(newsgroup);
1.207 - if(group != null && // If the server does not provide the group, ignore it
1.208 - !groups.contains(group)) // Yes, there may be duplicates
1.209 - {
1.210 - groups.add(group);
1.211 - }
1.212 - }
1.213 - }
1.214 - catch(StorageBackendException ex)
1.215 - {
1.216 - ex.printStackTrace();
1.217 - return null;
1.218 - }
1.219 - return groups;
1.220 - }
1.221 -
1.222 - public void setBody(byte[] body)
1.223 - {
1.224 - this.body = body;
1.225 - }
1.226 -
1.227 - /**
1.228 - *
1.229 - * @param groupname Name(s) of newsgroups
1.230 - */
1.231 - public void setGroup(String groupname)
1.232 - {
1.233 - this.headers.setHeader(Headers.NEWSGROUPS, groupname);
1.234 - }
1.235 -
1.236 - /**
1.237 - * Returns the Message-ID of this Article. If the appropriate header
1.238 - * is empty, a new Message-ID is created.
1.239 - * @return Message-ID of this Article.
1.240 - */
1.241 - public String getMessageID()
1.242 - {
1.243 - String[] msgID = getHeader(Headers.MESSAGE_ID);
1.244 - return msgID[0].equals("") ? generateMessageID() : msgID[0];
1.245 - }
1.246 -
1.247 - /**
1.248 - * @return String containing the Message-ID.
1.249 - */
1.250 - @Override
1.251 - public String toString()
1.252 - {
1.253 - return getMessageID();
1.254 - }
1.255 -
1.256 -}