Package org.mitre.sipchat

Source Code of org.mitre.sipchat.BasicMessageAppend

// $Id: BasicMessageAppend.java,v 1.18 2001/10/19 12:28:32 ramsdell Exp $

// Copyright (c) 2000. The MITRE Corporation (http://www.mitre.org/).
// All rights reserved.
// The SIMP Service comes with ABSOLUTELY NO WARRANTY.
// See the SIMP Service License Agreement for details.

package org.mitre.sipchat;

import java.awt.Color;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.awt.event.*;
import java.util.*;
import java.text.DateFormat;

//import org.mitre.simp.util.IMA;
import org.mitre.sipchat.model.presence.Presentity;

//import org.mitre.simp.security.SimpSigner;

/**
* A text pane for displaying conversation messages.  Allows the
* messages to be displayed with optional sender identification and
* time stamps.  BUG: the message in the pane are never purged so that
* it is possible to run out of memory.
* @version March 2000
* @author Galen B. Williamson
* @author John D. Ramsdell (adapted from TextAppend)
*/
public class BasicMessageAppend
    extends JTextPane
    implements MessageAppend
{
    public static final String CVS_VERSION = "$Id: BasicMessageAppend.java,v 1.18 2001/10/19 12:28:32 ramsdell Exp $";

    protected final static int DEFAULT_MAX_MESSAGES = 1000;

    private final StyleContext sc = new StyleContext();
    private final Style normal =
  sc.addStyle("normal", sc.getStyle(StyleContext.DEFAULT_STYLE));

    private final LinkedList messages = new LinkedList();

    private DefaultStyledDocument doc;
    private boolean showDate = false;
    private boolean longUser = false;
    private boolean showSignatureStatus = false;

    private SimpleAttributeSet me_headerStyle = new SimpleAttributeSet();
    private SimpleAttributeSet you_headerStyle = new SimpleAttributeSet();
    private SimpleAttributeSet signatureStatus_headerStyle = new SimpleAttributeSet(normal);
    private SimpleAttributeSet truncatedMsg_style = new SimpleAttributeSet(normal);

    //    private IMA me = null;
    private Presentity me = null;
    private MessageScroller messageScroller = null;

    private int maxMessages = DEFAULT_MAX_MESSAGES;

    public JComponent getJComponent() {
  return this;
    }

    /**
     * Create a MessageAppend text pane.
     */
    public BasicMessageAppend() {
  this(null);
    }

    public BasicMessageAppend(int maxMessages) {
  this(null, maxMessages);
    }

    //    public BasicMessageAppend(IMA me, int maxMessages) {
    public BasicMessageAppend( Presentity me, int maxMessage ) {
  this(me);
  this.maxMessages = maxMessages;
    }

    //    public BasicMessageAppend(IMA me) {
    public BasicMessageAppend( Presentity me ) {
  this.me = me;
  doc = createNewDocument();
  setStyledDocument(doc);
  setEditable(false);

  StyleConstants.setForeground(me_headerStyle, meColor);
  StyleConstants.setBold(me_headerStyle, false);
  StyleConstants.setFontFamily(me_headerStyle,
             StyleConstants.getFontFamily(normal));

  StyleConstants.setForeground(you_headerStyle, youColor);
  StyleConstants.setBold(you_headerStyle, false);
  StyleConstants.setFontFamily(you_headerStyle,
             StyleConstants.getFontFamily(normal));

  StyleConstants.setForeground(signatureStatus_headerStyle, signedForegroundColor);
  StyleConstants.setBackground(signatureStatus_headerStyle, signedBackgroundColor);
   StyleConstants.setBold(signatureStatus_headerStyle, true);
//    StyleConstants.setFontFamily(signatureStatus_headerStyle,
//               StyleConstants.getFontFamily(normal));
  StyleConstants.setFontSize(signatureStatus_headerStyle,
           StyleConstants.getFontSize(normal) - 2);

  StyleConstants.setForeground(truncatedMsg_style, truncatedMsgColor);
  StyleConstants.setBold(truncatedMsg_style, true);
    }

    /**
     * @return <code>false</code>
     */
    public boolean isFocusTraversable() {
  return false;
    }

    /**
     * Indicate whether messages should be shown with the full
     * Instant Messaging Address, or just the username, i.e.,
     * "user" versus "user@host".
     */
    public boolean getShowLongUser() {
  return longUser;
    }

    /**
     * Indicate whether messages should be shown with time stamps.
     * Note: time stamps indicate the time the message was added,
     * since messages do not carry time stamps.
     */
    public boolean getShowDate() {
  return showDate;
    }

    /**
     * Indicate whether messages should be shown with signature status messages.
     */
    public boolean getShowSignatureStatus() {
  return showSignatureStatus;
    }

    /**
     * Indicate whether messages should be shown with the full
     * Instant Messaging Address, or just the username, i.e.,
     * "user" versus "user@host".
     */
    public void setShowLongUser(boolean show) {
  if (longUser != show) {
      longUser = show;
      refresh();
  }
    }

    /**
     * Indicate whether messages should be shown with time stamps.
     * Note: time stamps indicate the time the message was added,
     * since messages do not carry time stamps.
     */
    public void setShowDate(boolean show) {
  if (showDate != show) {
      showDate = show;
      refresh();
  }
    }

    /**
     * Indicate whether messages should be shown with signature status messages.
     */
    public void setShowSignatureStatus(boolean show) {
  if (showSignatureStatus != show) {
      showSignatureStatus = show;
      refresh();
  }
    }

    /**
     * Set the maximum message count.
     */
    public void setMaximumMessageCount(int maxMessages) {
  this.maxMessages = maxMessages;
    }

    /**
     * Get the maximum message count.
     */
    public int getMaximumMessageCount() {
  return maxMessages;
    }

    /**
     * Add a message to the text pane with the indicated sender and
     * signature status.
     */
    //    public void addMessage(IMA from, String body, int signatureStatus) {
    public void addMessage( Presentity from, String body, int signatureStatus ) {
  addMessage(new Message(from, body, signatureStatus));
    }

    /**
     * Add a message to the text pane with the indicated sender.
     */
    //    public void addMessage(IMA from, String body) {
    public void addMessage( Presentity from, String body ) {
  addMessage(new Message(from, body));
    }

    /**
     * Add a message to the text pane with no sender.
     */
    public void addMessage(String body) {
  addMessage(new Message(body));
    }

    /**
     * Add a <code>Message</code> object to the text pane.
     */
    public void addMessage(Message msg) {
  reallyAddMessage(msg);
    }

    /**
     * Add a message to the text pane with no sender.
     */
    public void addLine(String line) {
  addLines(new String[] { line });
    }

    /**
     * Add a message to the text pane with no sender, but follow each
     * element of the argument array with a newline.
     */
    public void addLines(String[] lines) {
  addMessage(new Message(lines));
    }

    /**
     * Set the date format used to print messages' time stamps.
     */
    public void setDateFormat(DateFormat df) {
  this.df = df;
    }

    /**
     * Get the MessageScroller for the containing component.
     */
    public MessageScroller getMessageScroller() {
  return messageScroller;
    }

    /**
     * Set the MessageScroller for the containing component.
     */
    public void setMessageScroller(MessageScroller scroller) {
  messageScroller = scroller;
    }

    /**
     * Get an iterator over the stored Message objects.
     */
    public Iterator getMessageIterator() {
  synchronized(messages) {
      LinkedList m = (LinkedList) messages.clone();
      return m.listIterator();
  }
    }

    private void scrollToBottom() {
  /* This doesn't always work very well: sometimes it doesn't
   * quite scroll to the bottom, but one or two lines up from
   * the bottom, thus rendering the last line of conversation
   * unreadable.  So we go back to the original code, which
   * works just fine, but doesn't generalize well.  Oh well.
   if (messageScroller != null) {
       messageScroller.scrollToBottom();
   }
  */
   if (getStyledDocument() == doc)
       setCaretPosition(doc.getLength());
    }

    private DefaultStyledDocument createNewDocument() {
  return new DefaultStyledDocument(sc);
    }

    int lastTruncMsgSize = 0;
    int lastMaxMessages = -2;

    private void reallyAddMessage(final Message m) {
  new Thread() {
    public void run() {
        synchronized(messages) {
      Message rm = null;
      int deleteLength = 0;
      int ms = messages.size();
      while (maxMessages >= 0 && ms >= maxMessages && ms > 0) {
          if (ms > 0) {
        rm = (Message) messages.removeFirst();
        deleteLength += sizeOfMessageHeader(rm) + sizeOfMessageBody(rm);
          }
          ms = messages.size();
      }
      if (rm != null || maxMessages != lastMaxMessages) {
          if (getStyledDocument() == doc) {
        try {
            String truncMsg = null;
            if (maxMessages != lastMaxMessages && rm != null) {
          doc.remove(0, lastTruncMsgSize + deleteLength);
          if (maxMessages >= 0) {
              truncMsg = "<Old messages truncated: limit set to "+maxMessages+">\n";
          }
          else {
              lastTruncMsgSize = 0;
          }
            }
            else if (rm != null) {
          doc.remove(lastTruncMsgSize, deleteLength);
            }
            if (truncMsg != null && maxMessages >= 0) { // && rm != null) {
           lastTruncMsgSize = truncMsg.length();
          doc.insertString(0, truncMsg, truncatedMsg_style);
            }
        } catch (BadLocationException ble) { /* shouldn't happen */
            ble.printStackTrace();
        }
          }
          lastMaxMessages = maxMessages;

      }
      messages.addLast(m);
      showMessage(m);
        }
    }}.start();
    }

    private void showMessage(final Message m) {
  if (SwingUtilities.isEventDispatchThread()) {
      new Thread() {
        public void run() {
      showMessage(m);
        }}.start();
  }
  else {
      reallyShowMessage(m);
  }
    }

    protected Style getBodyStyle() {
  return normal;
    }

    private void reallyShowMessage(final Message m) {
  synchronized(messages) {
      String[] body = m.getBody();
      //      IMA from = m.getFrom();
      Presentity from = m.getFrom();
      SimpleAttributeSet style = (from != null && !from.equals(me)) ? you_headerStyle : me_headerStyle;
      try {
    insertHeader(doc, m, style);
      } catch (BadLocationException ble1) { /* can't happen */ }
      for (int i = 0; i < body.length; i++) {
    if (body[i] == null)
        body[i] = "";
    try {
        doc.insertString(doc.getLength(), body[i], getBodyStyle());
    } catch (BadLocationException ble2) { /* can't happen */ }
    doc.setLogicalStyle(doc.getLength() - 1, normal);
    try {
        doc.insertString(doc.getLength(), "\n", null);
    } catch (BadLocationException ble3) { /* can't happen */ }
      }
      scrollToBottom();
  }
    }

    private void refresh() {
  new Thread() {
      public void run () {
    synchronized(messages) {
        doc = createNewDocument();
        if (lastTruncMsgSize > 0) {
      try {
          String truncMsg = getStyledDocument().getText(0, lastTruncMsgSize);
          doc.insertString(0, truncMsg, truncatedMsg_style);
      }
      catch (BadLocationException ble) { /* shouldn't happen */
          ble.printStackTrace();
      }
        }
        Iterator i = messages.listIterator();
        while (i.hasNext())
      reallyShowMessage((Message)i.next());
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
        setStyledDocument(doc);
        scrollToBottom();
          }});
    }
      }}.start();
    }

    private DateFormat df = DateFormat.getTimeInstance();

    protected void insertHeader(Document doc, Message msg, SimpleAttributeSet style)
  throws BadLocationException
    {
  String s = "";
  String status = msg.getSignatureStatus();
  //  IMA from = msg.getFrom();
  Presentity from = msg.getFrom();
  if (from != null) {
      /** SRJ check the next line */
      String s1 = longUser ? from.nameAddr() : from.getFullname();
      if ((getShowSignatureStatus() && status != null) || getShowDate()) {
    s1 += " ";
      }
      doc.insertString(doc.getLength(), s1, style);
  }
  if (getShowSignatureStatus() && status != null) {
      doc.insertString(doc.getLength(), status, signatureStatus_headerStyle);
  }
  if (getShowDate()) {
      s += "["+df.format(msg.getDate())+"]";
  }
  if (from != null || getShowDate()) {
      s += ": ";
      doc.insertString(doc.getLength(), s, style);
  }
    }

    protected int sizeOfMessageHeader(Message msg) {
  StringBuffer sb = new StringBuffer();
  String s = "";
  String status = msg.getSignatureStatus();
  //  IMA from = msg.getFrom();
  Presentity from = msg.getFrom();
  if (from != null) {
      /** SRJ check next line */
      String s1 = longUser ? from.toString() : from.uri();
      if ((getShowSignatureStatus() && status != null) || getShowDate()) {
    s1 += " ";
      }
      sb.append(s1);
  }
  if (getShowSignatureStatus() && status != null) {
      sb.append(status);
  }
  if (getShowDate()) {
      s += "["+df.format(msg.getDate())+"]";
  }
  if (from != null || getShowDate()) {
      s += ": ";
      sb.append(s);
  }
  return sb.length();
    }

    protected int sizeOfMessageBody(Message msg) {
  int len = 0;
  int newLineLen = "\n".length();
  String[] s = msg.getBody();
  for (int i = 0; i < s.length; i++) {
      String ss = s[i];
      if (ss == null) ss = "";
      len += ss.length()+newLineLen;
  }
  return len;
    }
}
TOP

Related Classes of org.mitre.sipchat.BasicMessageAppend

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.