/* * 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 }