src/org/sonews/storage/Article.java
changeset 37 74139325d305
parent 35 ed84c8bdd87b
child 51 be419cf170d6
     1.1 --- a/src/org/sonews/storage/Article.java	Sun Aug 29 17:28:58 2010 +0200
     1.2 +++ b/src/org/sonews/storage/Article.java	Sun Aug 29 18:17:37 2010 +0200
     1.3 @@ -41,213 +41,196 @@
     1.4   */
     1.5  public class Article extends ArticleHead
     1.6  {
     1.7 -  
     1.8 -  /**
     1.9 -   * Loads the Article identified by the given ID from the JDBCDatabase.
    1.10 -   * @param messageID
    1.11 -   * @return null if Article is not found or if an error occurred.
    1.12 -   */
    1.13 -  public static Article getByMessageID(final String messageID)
    1.14 -  {
    1.15 -    try
    1.16 -    {
    1.17 -      return StorageManager.current().getArticle(messageID);
    1.18 -    }
    1.19 -    catch(StorageBackendException ex)
    1.20 -    {
    1.21 -      ex.printStackTrace();
    1.22 -      return null;
    1.23 -    }
    1.24 -  }
    1.25 -  
    1.26 -  private byte[] body       = new byte[0];
    1.27 -  
    1.28 -  /**
    1.29 -   * Default constructor.
    1.30 -   */
    1.31 -  public Article()
    1.32 -  {
    1.33 -  }
    1.34 -  
    1.35 -  /**
    1.36 -   * Creates a new Article object using the date from the given
    1.37 -   * raw data.
    1.38 -   */
    1.39 -  public Article(String headers, byte[] body)
    1.40 -  {
    1.41 -    try
    1.42 -    {
    1.43 -      this.body  = body;
    1.44  
    1.45 -      // Parse the header
    1.46 -      this.headers = new InternetHeaders(
    1.47 -        new ByteArrayInputStream(headers.getBytes()));
    1.48 -      
    1.49 -      this.headerSrc = headers;
    1.50 -    }
    1.51 -    catch(MessagingException ex)
    1.52 -    {
    1.53 -      ex.printStackTrace();
    1.54 -    }
    1.55 -  }
    1.56 +	/**
    1.57 +	 * Loads the Article identified by the given ID from the JDBCDatabase.
    1.58 +	 * @param messageID
    1.59 +	 * @return null if Article is not found or if an error occurred.
    1.60 +	 */
    1.61 +	public static Article getByMessageID(final String messageID)
    1.62 +	{
    1.63 +		try {
    1.64 +			return StorageManager.current().getArticle(messageID);
    1.65 +		} catch (StorageBackendException ex) {
    1.66 +			ex.printStackTrace();
    1.67 +			return null;
    1.68 +		}
    1.69 +	}
    1.70 +	private byte[] body = new byte[0];
    1.71  
    1.72 -  /**
    1.73 -   * Creates an Article instance using the data from the javax.mail.Message
    1.74 -   * object. This constructor is called by the Mailinglist gateway.
    1.75 -   * @see javax.mail.Message
    1.76 -   * @param msg
    1.77 -   * @throws IOException
    1.78 -   * @throws MessagingException
    1.79 -   */
    1.80 -  public Article(final Message msg)
    1.81 -    throws IOException, MessagingException
    1.82 -  {
    1.83 -    this.headers = new InternetHeaders();
    1.84 +	/**
    1.85 +	 * Default constructor.
    1.86 +	 */
    1.87 +	public Article()
    1.88 +	{
    1.89 +	}
    1.90  
    1.91 -    for(Enumeration e = msg.getAllHeaders() ; e.hasMoreElements();) 
    1.92 -    {
    1.93 -      final Header header = (Header)e.nextElement();
    1.94 -      this.headers.addHeader(header.getName(), header.getValue());
    1.95 -    }
    1.96 +	/**
    1.97 +	 * Creates a new Article object using the date from the given
    1.98 +	 * raw data.
    1.99 +	 */
   1.100 +	public Article(String headers, byte[] body)
   1.101 +	{
   1.102 +		try {
   1.103 +			this.body = body;
   1.104  
   1.105 -	// Reads the raw byte body using Message.writeTo(OutputStream out)
   1.106 -	this.body = readContent(msg);
   1.107 -    
   1.108 -    // Validate headers
   1.109 -    validateHeaders();
   1.110 -  }
   1.111 +			// Parse the header
   1.112 +			this.headers = new InternetHeaders(
   1.113 +				new ByteArrayInputStream(headers.getBytes()));
   1.114  
   1.115 -  /**
   1.116 -   * Reads from the given Message into a byte array.
   1.117 -   * @param in
   1.118 -   * @return
   1.119 -   * @throws IOException
   1.120 -   */
   1.121 -  private byte[] readContent(Message in)
   1.122 -    throws IOException, MessagingException
   1.123 -  {
   1.124 -    ByteArrayOutputStream out = new ByteArrayOutputStream();
   1.125 -    in.writeTo(out);
   1.126 -    return out.toByteArray();
   1.127 -  }
   1.128 +			this.headerSrc = headers;
   1.129 +		} catch (MessagingException ex) {
   1.130 +			ex.printStackTrace();
   1.131 +		}
   1.132 +	}
   1.133  
   1.134 -  /**
   1.135 -   * Removes the header identified by the given key.
   1.136 -   * @param headerKey
   1.137 -   */
   1.138 -  public void removeHeader(final String headerKey)
   1.139 -  {
   1.140 -    this.headers.removeHeader(headerKey);
   1.141 -    this.headerSrc = null;
   1.142 -  }
   1.143 +	/**
   1.144 +	 * Creates an Article instance using the data from the javax.mail.Message
   1.145 +	 * object. This constructor is called by the Mailinglist gateway.
   1.146 +	 * @see javax.mail.Message
   1.147 +	 * @param msg
   1.148 +	 * @throws IOException
   1.149 +	 * @throws MessagingException
   1.150 +	 */
   1.151 +	public Article(final Message msg)
   1.152 +		throws IOException, MessagingException
   1.153 +	{
   1.154 +		this.headers = new InternetHeaders();
   1.155  
   1.156 -  /**
   1.157 -   * Generates a message id for this article and sets it into
   1.158 -   * the header object. You have to update the JDBCDatabase manually to make this
   1.159 -   * change persistent.
   1.160 -   * Note: a Message-ID should never be changed and only generated once.
   1.161 -   */
   1.162 -  private String generateMessageID()
   1.163 -  {
   1.164 -    String randomString;
   1.165 -    MessageDigest md5;
   1.166 -    try
   1.167 -    {
   1.168 -      md5 = MessageDigest.getInstance("MD5");
   1.169 -      md5.reset();
   1.170 -      md5.update(getBody());
   1.171 -      md5.update(getHeader(Headers.SUBJECT)[0].getBytes());
   1.172 -      md5.update(getHeader(Headers.FROM)[0].getBytes());
   1.173 -      byte[] result = md5.digest();
   1.174 -      StringBuffer hexString = new StringBuffer();
   1.175 -      for (int i = 0; i < result.length; i++)
   1.176 -      {
   1.177 -        hexString.append(Integer.toHexString(0xFF & result[i]));
   1.178 -      }
   1.179 -      randomString = hexString.toString();
   1.180 -    }
   1.181 -    catch (NoSuchAlgorithmException e)
   1.182 -    {
   1.183 -      e.printStackTrace();
   1.184 -      randomString = UUID.randomUUID().toString();
   1.185 -    }
   1.186 -    String msgID = "<" + randomString + "@"
   1.187 -        + Config.inst().get(Config.HOSTNAME, "localhost") + ">";
   1.188 -    
   1.189 -    this.headers.setHeader(Headers.MESSAGE_ID, msgID);
   1.190 -    
   1.191 -    return msgID;
   1.192 -  }
   1.193 +		for (Enumeration e = msg.getAllHeaders(); e.hasMoreElements();) {
   1.194 +			final Header header = (Header) e.nextElement();
   1.195 +			this.headers.addHeader(header.getName(), header.getValue());
   1.196 +		}
   1.197  
   1.198 -  /**
   1.199 -   * Returns the body string.
   1.200 -   */
   1.201 -  public byte[] getBody()
   1.202 -  {
   1.203 -    return body;
   1.204 -  }
   1.205 -  
   1.206 -  /**
   1.207 -   * @return Numerical IDs of the newsgroups this Article belongs to.
   1.208 -   */
   1.209 -  public List<Group> getGroups()
   1.210 -  {
   1.211 -    String[]         groupnames = getHeader(Headers.NEWSGROUPS)[0].split(",");
   1.212 -    ArrayList<Group> groups     = new ArrayList<Group>();
   1.213 +		// Reads the raw byte body using Message.writeTo(OutputStream out)
   1.214 +		this.body = readContent(msg);
   1.215  
   1.216 -    try
   1.217 -    {
   1.218 -      for(String newsgroup : groupnames)
   1.219 -      {
   1.220 -        newsgroup = newsgroup.trim();
   1.221 -        Group group = StorageManager.current().getGroup(newsgroup);
   1.222 -        if(group != null &&         // If the server does not provide the group, ignore it
   1.223 -          !groups.contains(group))  // Yes, there may be duplicates
   1.224 -        {
   1.225 -          groups.add(group);
   1.226 -        }
   1.227 -      }
   1.228 -    }
   1.229 -    catch(StorageBackendException ex)
   1.230 -    {
   1.231 -      ex.printStackTrace();
   1.232 -      return null;
   1.233 -    }
   1.234 -    return groups;
   1.235 -  }
   1.236 +		// Validate headers
   1.237 +		validateHeaders();
   1.238 +	}
   1.239  
   1.240 -  public void setBody(byte[] body)
   1.241 -  {
   1.242 -    this.body = body;
   1.243 -  }
   1.244 -  
   1.245 -  /**
   1.246 -   * 
   1.247 -   * @param groupname Name(s) of newsgroups
   1.248 -   */
   1.249 -  public void setGroup(String groupname)
   1.250 -  {
   1.251 -    this.headers.setHeader(Headers.NEWSGROUPS, groupname);
   1.252 -  }
   1.253 +	/**
   1.254 +	 * Reads from the given Message into a byte array.
   1.255 +	 * @param in
   1.256 +	 * @return
   1.257 +	 * @throws IOException
   1.258 +	 */
   1.259 +	private byte[] readContent(Message in)
   1.260 +		throws IOException, MessagingException
   1.261 +	{
   1.262 +		ByteArrayOutputStream out = new ByteArrayOutputStream();
   1.263 +		in.writeTo(out);
   1.264 +		return out.toByteArray();
   1.265 +	}
   1.266  
   1.267 -  /**
   1.268 -   * Returns the Message-ID of this Article. If the appropriate header
   1.269 -   * is empty, a new Message-ID is created.
   1.270 -   * @return Message-ID of this Article.
   1.271 -   */
   1.272 -  public String getMessageID()
   1.273 -  {
   1.274 -    String[] msgID = getHeader(Headers.MESSAGE_ID);
   1.275 -    return msgID[0].equals("") ? generateMessageID() : msgID[0];
   1.276 -  }
   1.277 -  
   1.278 -  /**
   1.279 -   * @return String containing the Message-ID.
   1.280 -   */
   1.281 -  @Override
   1.282 -  public String toString()
   1.283 -  {
   1.284 -    return getMessageID();
   1.285 -  }
   1.286 +	/**
   1.287 +	 * Removes the header identified by the given key.
   1.288 +	 * @param headerKey
   1.289 +	 */
   1.290 +	public void removeHeader(final String headerKey)
   1.291 +	{
   1.292 +		this.headers.removeHeader(headerKey);
   1.293 +		this.headerSrc = null;
   1.294 +	}
   1.295  
   1.296 +	/**
   1.297 +	 * Generates a message id for this article and sets it into
   1.298 +	 * the header object. You have to update the JDBCDatabase manually to make this
   1.299 +	 * change persistent.
   1.300 +	 * Note: a Message-ID should never be changed and only generated once.
   1.301 +	 */
   1.302 +	private String generateMessageID()
   1.303 +	{
   1.304 +		String randomString;
   1.305 +		MessageDigest md5;
   1.306 +		try {
   1.307 +			md5 = MessageDigest.getInstance("MD5");
   1.308 +			md5.reset();
   1.309 +			md5.update(getBody());
   1.310 +			md5.update(getHeader(Headers.SUBJECT)[0].getBytes());
   1.311 +			md5.update(getHeader(Headers.FROM)[0].getBytes());
   1.312 +			byte[] result = md5.digest();
   1.313 +			StringBuffer hexString = new StringBuffer();
   1.314 +			for (int i = 0; i < result.length; i++) {
   1.315 +				hexString.append(Integer.toHexString(0xFF & result[i]));
   1.316 +			}
   1.317 +			randomString = hexString.toString();
   1.318 +		} catch (NoSuchAlgorithmException e) {
   1.319 +			e.printStackTrace();
   1.320 +			randomString = UUID.randomUUID().toString();
   1.321 +		}
   1.322 +		String msgID = "<" + randomString + "@"
   1.323 +			+ Config.inst().get(Config.HOSTNAME, "localhost") + ">";
   1.324 +
   1.325 +		this.headers.setHeader(Headers.MESSAGE_ID, msgID);
   1.326 +
   1.327 +		return msgID;
   1.328 +	}
   1.329 +
   1.330 +	/**
   1.331 +	 * Returns the body string.
   1.332 +	 */
   1.333 +	public byte[] getBody()
   1.334 +	{
   1.335 +		return body;
   1.336 +	}
   1.337 +
   1.338 +	/**
   1.339 +	 * @return Numerical IDs of the newsgroups this Article belongs to.
   1.340 +	 */
   1.341 +	public List<Group> getGroups()
   1.342 +	{
   1.343 +		String[] groupnames = getHeader(Headers.NEWSGROUPS)[0].split(",");
   1.344 +		ArrayList<Group> groups = new ArrayList<Group>();
   1.345 +
   1.346 +		try {
   1.347 +			for (String newsgroup : groupnames) {
   1.348 +				newsgroup = newsgroup.trim();
   1.349 +				Group group = StorageManager.current().getGroup(newsgroup);
   1.350 +				if (group != null && // If the server does not provide the group, ignore it
   1.351 +					!groups.contains(group)) // Yes, there may be duplicates
   1.352 +				{
   1.353 +					groups.add(group);
   1.354 +				}
   1.355 +			}
   1.356 +		} catch (StorageBackendException ex) {
   1.357 +			ex.printStackTrace();
   1.358 +			return null;
   1.359 +		}
   1.360 +		return groups;
   1.361 +	}
   1.362 +
   1.363 +	public void setBody(byte[] body)
   1.364 +	{
   1.365 +		this.body = body;
   1.366 +	}
   1.367 +
   1.368 +	/**
   1.369 +	 *
   1.370 +	 * @param groupname Name(s) of newsgroups
   1.371 +	 */
   1.372 +	public void setGroup(String groupname)
   1.373 +	{
   1.374 +		this.headers.setHeader(Headers.NEWSGROUPS, groupname);
   1.375 +	}
   1.376 +
   1.377 +	/**
   1.378 +	 * Returns the Message-ID of this Article. If the appropriate header
   1.379 +	 * is empty, a new Message-ID is created.
   1.380 +	 * @return Message-ID of this Article.
   1.381 +	 */
   1.382 +	public String getMessageID()
   1.383 +	{
   1.384 +		String[] msgID = getHeader(Headers.MESSAGE_ID);
   1.385 +		return msgID[0].equals("") ? generateMessageID() : msgID[0];
   1.386 +	}
   1.387 +
   1.388 +	/**
   1.389 +	 * @return String containing the Message-ID.
   1.390 +	 */
   1.391 +	@Override
   1.392 +	public String toString()
   1.393 +	{
   1.394 +		return getMessageID();
   1.395 +	}
   1.396  }