All pastes #801496 Raw Edit

Miscellany

public text v1 · immutable
#801496 ·published 2007-11-29 09:47 UTC
rendered paste body
package comms.view.chat;

import java.util.Iterator;

import org.apache.wicket.Component;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;

import comms.bus.ChatService;
import comms.model.chat.Conversation;
import comms.model.chat.Event;
import comms.model.chat.MessageEvent;
import comms.model.chat.Participant;
import comms.model.chat.PublishedEvent;
import comms.view.util.OnEnterClicker;

/**
 * <p>
 * A Chat panel contains a reference to a conversation within a chat service, a timer
 * and a one field form to enter messages.</p>
 * <p>Each time the timer fires the conversation's pending events will be retrieved
 * and send as JavaScript to the page where the script will append them to the DOM
 * element that displays the conversation.</p>
 * <p>The form's submit button will publish a message event to the conversation</p>
 * 
 */
public abstract class Chat extends Panel implements IHeaderContributor {
  private String message;  
  
  public Chat( String id, final String serviceId, final String conversationId, final Participant participant ) {
    super( id );
    Conversation conversation = getConversation(serviceId, conversationId);
    conversation.resetPendingEvents(participant);

    Form form = new Form( "form", new CompoundPropertyModel( this ));
    final Component messageField = new TextField( "message" );
    form.add( messageField );
    messageField.setOutputMarkupId(true);
    
    final Component timer = new WebMarkupContainer( "timer" );
    timer.setOutputMarkupId(true);
    timer.add( new AbstractAjaxTimerBehavior( ChatService.getPollInterval()) {
      
      @Override
      protected void onTimer(AjaxRequestTarget target) {
        Conversation conversation = getConversation( serviceId, conversationId);
        Iterator<PublishedEvent>itr = conversation.getPendingEvents(participant);
        if (!itr.hasNext()) {
          return;
        }
        StringBuffer buf = new StringBuffer();
        buf.append( "var e = document.getElementById('");
        buf.append( "content");
        buf.append( "');" );
        buf.append( "e.innerHTML += '" );
        while (itr.hasNext()) {
          PublishedEvent published = itr.next();
          Event event = (Event)published.getEvent();
          Participant participant = (Participant)published.getParticipant();
          buf.append( event.getHtmlDescription(participant));
//          buf.append( ";" );
        }
        buf.append( "'" );
        buf.append( ";");
        buf.append( "e.scrollTop = e.scrollHeight" );
        target.appendJavascript( buf.toString());
        target.focusComponent(null);
      }      
    });
    add( timer );
    
    AjaxButton sendButton =
      new AjaxButton("send", form ){
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form) {
        String message = ((Chat)form.getModelObject()).getMessage();
        if (message!=null && message.trim().length()>0) {
          Conversation conversation = getConversation( serviceId, conversationId);           
          conversation.publish(participant, new MessageEvent( message ));
        }
        //clear message area add focus it
        target.appendJavascript(
            "document.getElementById('" + messageField.getMarkupId() + "').value =''");
        target.focusComponent(null);
      }
    };
    form.add( sendButton );
    messageField.add( new OnEnterClicker( sendButton ));
    add( form );
  
  }
  
  private Conversation getConversation(String serviceId, String conversationId) {
    Conversation conversation = ChatService.getInstance(serviceId).getConversation(conversationId);
    if (conversation==null) {
      conversation = createConversation( serviceId, conversationId );
      ChatService.getInstance(serviceId).putConversation( conversation );
    }
    return conversation;
  }
  
  /**
   * You can override this method to create a conversation with additional
   * functionality (like persisting itself)
   * @param serviceId
   * @param conversationId
   * @return
   */
  protected Conversation createConversation(String serviceId, String conversationId) {
    return new Conversation( conversationId );
  }

  public String getMessage() {
    return message;
  }
  
  public void setMessage( String message ) {
    this.message = message;
  }

  public void renderHead(IHeaderResponse response) {    
    response.renderCSSReference( new ResourceReference( Chat.class,  "Chat.css" ));
    response.renderJavascriptReference( new ResourceReference( Chat.class, "Chat.js" ));
  }

}