Android Open Source - libgdx-chat-example Chat Messages Database






From Project

Back to project page libgdx-chat-example.

License

The source code is released under:

Apache License

If you think the Android project libgdx-chat-example listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.stofkat.chat.server;
//from  w  w  w .  j a  v  a2 s . c o m
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.stofkat.chat.common.ChatMessage;
import org.stofkat.chat.common.results.ChatResult;
import org.stofkat.chat.common.util.LowestIdFinder;

/**
 * This isn't an actual database. You probably should use a database in a real
 * server application, but since the purpose of this project is to be an example
 * that shows how you can make a client/server architecture with libgdx. I
 * didn't include a real database as it would be more complicated to set up.
 * 
 * This "Database" is a singleton. Which means that there will be only one
 * instance of this class on the entire server application. I'm following the
 * Eager Initialization example from
 * http://en.wikipedia.org/wiki/Singleton_pattern.
 * 
 * Also, I've been reading the following article:
 * http://stackoverflow.com/questions/17578299/java-concurrent-array-list-access
 * 
 * To try and get this thread safe, but I'm no expert in this area. So even
 * though my implementation is my best effort at getting it thread safe, it
 * might not be flawless. I probably should create a lot of unit tests to verify
 * if this implementation is safe to use, but you know how it goes.
 * 
 * @author Leejjon
 */
public class ChatMessagesDatabase {
  private static final ChatMessagesDatabase instance = new ChatMessagesDatabase();

  private final int capacity = 256;

  private AtomicInteger nextAvailableId;
  
  private Map<Integer, ChatMessage> chatMessages;

  /**
   * Private constructor so that it cannot be used in other classes.
   */
  private ChatMessagesDatabase() {
    chatMessages = new HashMap<Integer,ChatMessage>(capacity);
    nextAvailableId = new AtomicInteger(0);
  }
  
  /**
   * @param authorName A string that will display the name of the author of the message.
   * @param message A string containing the message. 
   */
  public void postNewMessage(String authorName, String authorSessionId, String message) {
    synchronized (chatMessages) {
      int newId = nextAvailableId.get();
      ChatMessage chatMessage = new ChatMessage(newId, authorName, authorSessionId, message, System.currentTimeMillis());
      
      // If the list is already full.
      if (newId >= capacity) {
        // We remove the oldest chat message.
        Integer oldestId = LowestIdFinder.getLowestId(chatMessages.keySet());
        chatMessages.remove(oldestId);
        
        // And add the new chat message.
        chatMessages.put(new Integer(newId), chatMessage);
      } else {
        chatMessages.put(newId, chatMessage);
      }
      
      // Only increment after the new chatMessage has been added.
      long nextId = nextAvailableId.incrementAndGet();
      
      if (nextId == Long.MAX_VALUE) {
        // In order to prevent overflowing the nextAvailableId, reset the chat.
        chatMessages.clear();
        nextAvailableId = new AtomicInteger(0);
      }
    }
  }
  
  /**
   * 
   * @param lastValueTheClientHas
   * @return
   */
  public ChatResult getLatestMessages(int lastValueTheClientHas) {
    ArrayList<ChatMessage> newMessagesForClient = new ArrayList<ChatMessage>();
    
    boolean mapHasBeenReset = false;
    synchronized (chatMessages) {
      if (chatMessages.get(new Integer(lastValueTheClientHas)) != null) {
        for (int i = lastValueTheClientHas; i < nextAvailableId.get(); i++) {
          newMessagesForClient.add(chatMessages.get(new Integer(i)));
        }
      } else {
        // If the last received value is no longer on the server, we should
        // tell the client it needs to reset it's last received id to zero.
        mapHasBeenReset = true;
        for (int i = 1; i < nextAvailableId.get(); i++) {
          newMessagesForClient.add(chatMessages.get(new Integer(i)));
        }
      }
    }
    
    return new ChatResult(newMessagesForClient, mapHasBeenReset);
  }
  
  /**
   * Use this method instead of the constructor.
   * 
   * @return The ChatMessagesDatabase instance shared by the entire server.
   */
  public static ChatMessagesDatabase getInstance() {
        return instance;
    }
}




Java Source Code List

org.stofkat.chat.android.AndroidChat.java
org.stofkat.chat.android.AndroidDispatchServiceAsync.java
org.stofkat.chat.android.ChatActivity.java
org.stofkat.chat.common.ChatMessage.java
org.stofkat.chat.common.ClientInterface.java
org.stofkat.chat.common.actions.Action.java
org.stofkat.chat.common.actions.ChatAction.java
org.stofkat.chat.common.actions.UpdateAction.java
org.stofkat.chat.common.exceptions.ActionException.java
org.stofkat.chat.common.exceptions.DispatchException.java
org.stofkat.chat.common.exceptions.ServiceException.java
org.stofkat.chat.common.exceptions.UnsupportedActionException.java
org.stofkat.chat.common.results.ChatResult.java
org.stofkat.chat.common.results.Result.java
org.stofkat.chat.common.util.HashMapToOrderedArray.java
org.stofkat.chat.common.util.LowestIdFinder.java
org.stofkat.chat.core.ChatTextField.java
org.stofkat.chat.core.Chat.java
org.stofkat.chat.core.PickNameStage.java
org.stofkat.chat.core.ServerInterface.java
org.stofkat.chat.core.UpdateTask.java
org.stofkat.chat.html.ChatHtml.java
org.stofkat.chat.html.HtmlChat.java
org.stofkat.chat.html.dispatch.GwtAsyncCallbackHandler.java
org.stofkat.chat.html.dispatch.GwtDispatchServiceAsync.java
org.stofkat.chat.html.dispatch.GwtDispatchService.java
org.stofkat.chat.http.dispatch.AsyncCallbackHandler.java
org.stofkat.chat.http.dispatch.AsyncCallback.java
org.stofkat.chat.http.dispatch.CustomCookieStore.java
org.stofkat.chat.http.dispatch.HttpDispatchServiceAsync.java
org.stofkat.chat.http.dispatch.HttpUtils.java
org.stofkat.chat.java.ChatDesktop.java
org.stofkat.chat.java.DesktopChat.java
org.stofkat.chat.java.DesktopDispatchServiceAsync.java
org.stofkat.chat.server.AbstractDispatch.java
org.stofkat.chat.server.ActionHandlerRegistry.java
org.stofkat.chat.server.ActionHandler.java
org.stofkat.chat.server.ActionResult.java
org.stofkat.chat.server.ChatMessagesDatabase.java
org.stofkat.chat.server.DefaultActionHandlerRegistry.java
org.stofkat.chat.server.Dispatch.java
org.stofkat.chat.server.InstanceActionHandlerRegistry.java
org.stofkat.chat.server.SimpleDispatch.java
org.stofkat.chat.server.actionhandlers.ChatActionHandler.java
org.stofkat.chat.server.actionhandlers.UpdateActionHandler.java
org.stofkat.chat.server.gwt.dispatch.GwtDispatchServlet.java
org.stofkat.chat.server.http.dispatch.HttpDispatchServlet.java