/*
* MailClientMessage.java
*
* Created on den 27 september 2001, 12:33
*/
package ip1.u9;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.*;
import javax.swing.event.*;
import ip1.u7.b.*;
import java.awt.*;
import java.util.*;
/** Wrapperklass för Javamail Message-objekt. MailClientMessage är en
* visuell komponent som visar upp sig som ett JTextField som innehåller det underliggande
* Message-objektets ämnesrad, om man klickar på denna produceras ett MessageChosenEvent.
* En annan finess som gör wrappandet nödvändigt är möjligheten att spara meddelanden lokalt.
* Javamails Message-klass är inte serialiserbart detär däremot MailClientMessage.
*
* @author Henrik Johansson, DS80
*@version ht2001
*/
public class MailClientMessage extends javax.swing.JPanel implements Serializable, Comparable {
/** Visar att ett meddelande valts åtminstonne en gång*/
protected boolean visited = false;
/** Meddelandets ämnesrad*/
protected String subject;
/** Meddelandets message-id*/
protected String messageID;
/** Meddelandet som byte-matris.
* Första gången ett meddelande väljs skrivs det som en byte-matris som till skilnad
* från ett Javamail Message kan sparas på hårddisken.
*/
protected byte[] bMessage = null;
/** Javamail Message, sparas inte utan återskapas vid varje inläsning via bMessage
*/
transient protected Message message = null;
/** vilka lyssnar på MessageChosenEvents*/
protected EventListenerList messageChosenListeners;
/** Har ett meddelande hämtats*/
protected boolean notFetched = true;
private long timestamp;
/** Skapar ett ntt MailClientMessage
*
*@param message Meddelandet som skall wrappas
*/
public MailClientMessage(Message message) {
try {
initComponents();
this.message = message;
subjectField.setFont(new Font(subjectField.getFont().getName(), Font.BOLD, subjectField.getFont().getSize()));
subject = message.getSubject();
messageID = ((MimeMessage) message).getMessageID();
if(messageID == null) {
messageID = Long.toString((new Date()).getTime());
((MimeMessage) message).setHeader("Message-ID", messageID);
}
this.subjectField.setText(subject);
messageChosenListeners = new EventListenerList();
} catch(MessagingException e) {
System.out.println(e.getMessage());
}
}
public long getTimestamp() {
return timestamp;
}
/** Sätter chosen, om true blir bakgrunden grisaskär, annars ljusgrå
*/
public void setChosen(boolean chosen) {
if(chosen)
subjectField.setBackground(Color.pink);
else
subjectField.setBackground(Color.lightGray);
this.subjectField.validate();
}
protected void setMessage(Message message) {
this.message = message;
}
public String getMessageID() {
return messageID;
}
/** Gämför detta MailClientMessage-objekt, med ett annat meddelande, antingen ett Javamail Message
* eller ett annat MailClientMessage.
*
*@param message Meddelande att gämföra med.
*@return true om meddelandena motsvarar varandra annars false.
*/
public boolean equals(Object message) {
String tmp = "";
try {
if(message instanceof MimeMessage)
tmp = ((MimeMessage) message).getMessageID();
else if(message instanceof MailClientMessage)
tmp = ((MailClientMessage) message).getMessageID();
} catch(MessagingException e) {
System.out.println(e.getMessage());
}
boolean ret = getMessageID().equals(tmp);
return getMessageID().equals(tmp);
}
public int hashCode() {
return messageID.hashCode();
}
private class FireEvent implements Runnable {
private MailClientMessage mcm;
private Thread thread;
private FireEvent(MailClientMessage mcm) {
this.mcm = mcm;
(thread = new Thread(this)).start();
}
/* Implementerar Runnable. Skickar MessageChosenEvent, funkar så här:
* 1: om det finns bMessage men inget Message-objekt, skapar Message från bMessage, MessageChosenEvent skickas
* 2: om både bMessage och Message objekt finns, MessageChosenEvent skickas
* 3: om inget bMessage finns, men ett Message, bMessage skapas från Message, MessageChosenEvent skickas
* 4: om inget bMessage finns, och inget Messsage, vänta en stund, sedan
*/
public void run() {
try {
while(notFetched) {
timestamp = (new Date()).getTime();
if(bMessage != null) {
// lokal kopia finns, inte visad tidigare under denna session
if(message == null) {
message = new MimeMessage(null, new ByteArrayInputStream(bMessage));
}
// lokal kopia finns, som tidigare visats under denna session.
else {
notFetched = false;
}
}
else {
showFetchMessage(true);
// Det finns ingen lokal kopia men ett message (meddelandet är nytt på servern)
if(message != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
message.writeTo(baos);
bMessage = baos.toByteArray();
message.setFlag(Flags.Flag.DELETED, true);
visited = true;
notFetched = false;
showFetchMessage(false);
}
// Det finns ingenlokal kopia och inget message (meddelandet fanns på servern
// under förra sessionen, men laddades aldrig hem för läsning)
else {
thread.sleep(50);
}
}
}
fireMessageChosen(new MessageChosenEvent(message, mcm));
notFetched = true;
} catch(MessagingException e) {
System.out.println(e.getMessage());
} catch(IOException e) {
System.out.println(e.getMessage());
} catch(InterruptedException e) {
System.out.println(e.getMessage());
}
}
//Lägger om sfm = true, in ett meddelande om att meddelande hämtas.
private void showFetchMessage(boolean sfm) {
if(sfm) {
subjectField.setText("Hämtar från servern: " + subject);
subjectField.setForeground(Color.red);
} else {
subjectField.setFont(new Font(subjectField.getFont().getName(), Font.PLAIN, subjectField.getFont().getSize()));
subjectField.setText(subject);
subjectField.setForeground(Color.black);
}
}
}
// Vi återskapandet efeter serialisering måste man återskapa lyssnarfunktionaliteten
private void readObject(ObjectInputStream in) throws IOException {
try {
in.defaultReadObject();
subjectField.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
subjectFieldMousePressed(evt);
}
});
this.setChosen(false);
} catch(ClassNotFoundException e) {
System.err.println(e.getMessage());
}
}
/** Implementerar interfacet Comparable.
*
*@param obj Objektet att gämföra med
*/
public int compareTo(java.lang.Object obj) {
if(obj instanceof MailClientMessage) {
MailClientMessage msg = (MailClientMessage) obj;
if(msg.timestamp > timestamp)
return -1;
else if(msg.getMessageID().equals(getMessageID()))
return 0;
else
return 1;
}
return 1;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {//GEN-BEGIN:initComponents
subjectField = new javax.swing.JTextField();
setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints1;
setBackground(java.awt.Color.white);
subjectField.setEditable(false);
subjectField.setDisabledTextColor(java.awt.Color.white);
subjectField.setDoubleBuffered(true);
subjectField.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
subjectFieldMousePressed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(1, 5, 1, 5);
gridBagConstraints1.weightx = 1.0;
add(subjectField, gridBagConstraints1);
}//GEN-END:initComponents
private void subjectFieldMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_subjectFieldMousePressed
new FireEvent(this);
}//GEN-LAST:event_subjectFieldMousePressed
/** Låter andra prenumerera på MessageChosenEvents från MailClientMessage-objekten i samlingen.
* @param listener prenumerant
*/
public void addMessageChosenListener(MessageChosenListener listener) {
messageChosenListeners.add(MessageChosenListener.class, listener);
}
/** Låter andra avlägsna prenumeration på MessageChosenEvents från MailClientMessage-objekten i samlingen.
* @param listener prenumerant
*/
public void removeMessageChosenListener(MessageChosenListener listener) {
messageChosenListeners.remove(MessageChosenListener.class, listener);
}
/** Vidaresänder MessageChosenEvents till eventuella prenumeranter
* @param evt det Event som skall skickas vidare till prenumeranterna
*/
protected void fireMessageChosen(MessageChosenEvent evt) {
Object[] listeners = messageChosenListeners.getListenerList();
// loop through each listener and pass on the event if needed
for(int i = 0; i < listeners.length; i++) {
if (listeners[i] == MessageChosenListener.class) {
// pass the event to the listeners event dispatch method
((MessageChosenListener)listeners[i + 1]).dispatchMessageChosen(evt);
}
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTextField subjectField;
// End of variables declaration//GEN-END:variables
}