com.scalagent.appli.client.RPCServiceCacheClient.java Source code

Java tutorial

Introduction

Here is the source code for com.scalagent.appli.client.RPCServiceCacheClient.java

Source

/*
 * JORAM: Java(TM) Open Reliable Asynchronous Messaging
 * Copyright (C) 2010 - 2011 ScalAgent Distributed Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA.
 *
 * Initial developer(s): ScalAgent Distributed Technologies
 * Contributor(s): 
 */
package com.scalagent.appli.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Timer;
import com.scalagent.appli.client.command.info.LoadServerInfoAction;
import com.scalagent.appli.client.command.info.LoadServerInfoResponse;
import com.scalagent.appli.client.command.message.LoadMessageAction;
import com.scalagent.appli.client.command.message.LoadMessageResponse;
import com.scalagent.appli.client.command.queue.LoadQueueAction;
import com.scalagent.appli.client.command.queue.LoadQueueResponse;
import com.scalagent.appli.client.command.subscription.LoadSubscriptionAction;
import com.scalagent.appli.client.command.subscription.LoadSubscriptionResponse;
import com.scalagent.appli.client.command.topic.LoadTopicAction;
import com.scalagent.appli.client.command.topic.LoadTopicResponse;
import com.scalagent.appli.client.command.user.LoadUserAction;
import com.scalagent.appli.client.command.user.LoadUserResponse;
import com.scalagent.appli.client.event.common.UpdateCompleteEvent;
import com.scalagent.appli.client.event.message.DeletedMessageEvent;
import com.scalagent.appli.client.event.message.NewMessageEvent;
import com.scalagent.appli.client.event.message.QueueNotFoundEvent;
import com.scalagent.appli.client.event.message.UpdatedMessageEvent;
import com.scalagent.appli.client.event.queue.DeletedQueueEvent;
import com.scalagent.appli.client.event.queue.NewQueueEvent;
import com.scalagent.appli.client.event.queue.UpdatedQueueEvent;
import com.scalagent.appli.client.event.subscription.DeletedSubscriptionEvent;
import com.scalagent.appli.client.event.subscription.NewSubscriptionEvent;
import com.scalagent.appli.client.event.subscription.UpdatedSubscriptionEvent;
import com.scalagent.appli.client.event.topic.DeletedTopicEvent;
import com.scalagent.appli.client.event.topic.NewTopicEvent;
import com.scalagent.appli.client.event.topic.UpdatedTopicEvent;
import com.scalagent.appli.client.event.user.DeletedUserEvent;
import com.scalagent.appli.client.event.user.NewUserEvent;
import com.scalagent.appli.client.event.user.UpdatedUserEvent;
import com.scalagent.appli.client.presenter.SubscriptionDetailPresenter;
import com.scalagent.appli.shared.MessageWTO;
import com.scalagent.appli.shared.QueueWTO;
import com.scalagent.appli.shared.SubscriptionWTO;
import com.scalagent.appli.shared.TopicWTO;
import com.scalagent.appli.shared.UserWTO;
import com.scalagent.engine.client.BaseRPCServiceAsync;
import com.scalagent.engine.client.BaseRPCServiceCacheClient;
import com.scalagent.engine.client.command.Handler;
import com.scalagent.engine.shared.BaseWTO;

/**
 * This class is used as a cache.
 * Periodically, it retrieves data from the server, compares it
 * with its stored data and fires corresponding events on the EventBus.
 * It handles:
 * - queues
 * - topics
 * - users
 * - subscriptions
 * - messages
 * 
 * @author Yohann CINTRE
 */
public class RPCServiceCacheClient implements BaseRPCServiceCacheClient {

    public static class HistoryData {
        public Date time;
        public int[] data;

        public HistoryData(Date time, int[] data) {
            super();
            this.time = time;
            this.data = data;
        }
    }

    public static class FloatHistoryData {
        public Date time;
        public float[] data;

        public FloatHistoryData(Date time, float[] data) {
            super();
            this.time = time;
            this.data = data;
        }
    }

    private static final String logCategory = SubscriptionDetailPresenter.class.getName();

    /** Devices available in the cache */
    private Map<String, TopicWTO> topics = new HashMap<String, TopicWTO>();
    private Map<String, QueueWTO> queues = new HashMap<String, QueueWTO>();
    private Map<String, MessageWTO> messages = new HashMap<String, MessageWTO>();
    private Map<String, UserWTO> users = new HashMap<String, UserWTO>();
    private Map<String, SubscriptionWTO> subs = new HashMap<String, SubscriptionWTO>();

    private List<HistoryData> countHistory = new ArrayList<HistoryData>();
    private Map<String, List<HistoryData>> globalHistory = new HashMap<String, List<HistoryData>>();
    private List<FloatHistoryData> serverHistory = new ArrayList<FloatHistoryData>();

    private BaseRPCServiceAsync RPCService;
    private SimpleEventBus eventBus;

    private boolean topicRequest = true;
    private boolean queueRequest = true;
    private boolean userRequest = true;
    private boolean subRequest = true;
    private boolean servRequest = true;

    public RPCServiceCacheClient(BaseRPCServiceAsync RPCService, SimpleEventBus eventBus, int updatePeriod) {

        Log.debug("RPCServiceCacheClient start.");

        this.RPCService = RPCService;
        this.eventBus = eventBus;

        // start the timer, to update periodically the cache
        if (updatePeriod != -1) {
            Timer timer = new RPCServiceCacheTimer(this);
            timer.scheduleRepeating(updatePeriod);
        }
    }

    public Map<String, TopicWTO> getTopics() {
        return topics;
    }

    public Map<String, QueueWTO> getQueues() {
        return queues;
    }

    public Map<String, MessageWTO> getMessages() {
        return messages;
    }

    public Map<String, UserWTO> getUsers() {
        return users;
    }

    public Map<String, SubscriptionWTO> getSubscriptions() {
        return subs;
    }

    public List<HistoryData> getCountHistory() {
        return countHistory;
    }

    public List<HistoryData> getSpecificHistory(String name) {
        return globalHistory.get(name);
    }

    public List<FloatHistoryData> getServerHistory() {
        return serverHistory;
    }

    public void addToCountHistory(int... value) {
        Date nowSec = new Date(System.currentTimeMillis() / 1000 * 1000);
        if (countHistory.size() == 0 || !countHistory.get(countHistory.size() - 1).time.equals(nowSec)) {
            countHistory.add(new HistoryData(nowSec, value));
        }
    }

    public void addToHistory(float... value) {
        Date nowSec = new Date(System.currentTimeMillis() / 1000 * 1000);
        if (serverHistory.size() == 0 || !serverHistory.get(serverHistory.size() - 1).time.equals(nowSec)) {
            serverHistory.add(new FloatHistoryData(nowSec, value));
        }
    }

    public void addToSpecificHistory(String name, int... value) {
        Date nowSec = new Date(System.currentTimeMillis() / 1000 * 1000);

        if (!globalHistory.containsKey(name)) {
            globalHistory.put(name, new ArrayList<HistoryData>());
        }

        List<HistoryData> history = globalHistory.get(name);
        if (history.size() == 0 || !history.get(history.size() - 1).time.equals(nowSec)) {
            history.add(new HistoryData(nowSec, value));
        }
    }

    public void setPeriod(int updatePeriod) {
        if (updatePeriod != -1) {
            Timer timer = new RPCServiceCacheTimer(this);
            timer.run();
            timer.scheduleRepeating(updatePeriod);
        }
    }

    /**
     * Called periodically by the RPCServiceCacheTimer
     * in order to update data.
     * Depending on the type of objects:
     * - events are fired on the event bus,
     * - lists devices and ecwSpecifications are updated.
     */

    public void retrieveTopic(boolean forceUpdate) {
        if (topicRequest) {
            topicRequest = false;
            LoadTopicAction action = new LoadTopicAction((topics.isEmpty()), forceUpdate);
            RPCService.execute(action, new Handler<LoadTopicResponse>(eventBus) {
                @Override
                public void onSuccess(LoadTopicResponse response) {
                    if (response != null) {
                        processTopics(response.getTopics());
                        topicRequest = true;
                    }
                    fireBusEvent(new UpdateCompleteEvent(UpdateCompleteEvent.TOPIC_UPDATE));
                }
            });
        }
    }

    public void retrieveQueue(boolean forceUpdate) {
        if (queueRequest) {
            queueRequest = false;
            LoadQueueAction action = new LoadQueueAction(queues.isEmpty(), forceUpdate);
            RPCService.execute(action, new Handler<LoadQueueResponse>(eventBus) {
                @Override
                public void onSuccess(LoadQueueResponse response) {
                    if (response != null) {
                        processQueues(response.getQueues());
                        queueRequest = true;
                    }
                    fireBusEvent(new UpdateCompleteEvent(UpdateCompleteEvent.QUEUE_UPDATE));
                }
            });
        }
    }

    public void retrieveMessageQueue(QueueWTO queue, boolean retrieveAll) {
        RPCService.execute(new LoadMessageAction(queue.getId(), retrieveAll, true),
                new Handler<LoadMessageResponse>(eventBus) {
                    @Override
                    public void onSuccess(LoadMessageResponse response) {
                        if (response.isSuccess()) {
                            processMessages(response.getMessages(), response.getQueueName());
                            fireBusEvent(new UpdateCompleteEvent(UpdateCompleteEvent.GENERIC_UPDATE,
                                    response.getQueueName()));
                        } else {
                            fireBusEvent(new QueueNotFoundEvent(response.getQueueName()));
                        }
                    }
                });
    }

    public void retrieveMessageSub(SubscriptionWTO sub, boolean retrieveAll) {
        RPCService.execute(new LoadMessageAction(sub.getId(), retrieveAll, false),
                new Handler<LoadMessageResponse>(eventBus) {
                    @Override
                    public void onSuccess(LoadMessageResponse response) {
                        if (response.isSuccess()) {
                            processSubMessages(response.getMessages(), response.getQueueName());
                            fireBusEvent(new UpdateCompleteEvent(UpdateCompleteEvent.GENERIC_UPDATE,
                                    response.getQueueName()));
                        } else {
                            fireBusEvent(new QueueNotFoundEvent(response.getQueueName()));
                        }
                    }
                });
    }

    public void retrieveUser(boolean forceUpdate) {
        if (userRequest) {
            userRequest = false;
            LoadUserAction action = new LoadUserAction((users.isEmpty()), forceUpdate);
            RPCService.execute(action, new Handler<LoadUserResponse>(eventBus) {
                @Override
                public void onSuccess(LoadUserResponse response) {
                    if (response != null) {
                        processUsers(response.getUsers());
                        userRequest = true;
                    }
                    fireBusEvent(new UpdateCompleteEvent(UpdateCompleteEvent.USER_UPDATE));
                }
            });
        }
    }

    public void retrieveSubscription(boolean forceUpdate) {
        if (subRequest) {
            subRequest = false;
            LoadSubscriptionAction action = new LoadSubscriptionAction((subs.isEmpty()), forceUpdate);
            RPCService.execute(action, new Handler<LoadSubscriptionResponse>(eventBus) {
                @Override
                public void onSuccess(LoadSubscriptionResponse response) {
                    if (response != null) {
                        processSubscriptions(response.getSubscriptions());
                        subRequest = true;
                    }
                    fireBusEvent(new UpdateCompleteEvent(UpdateCompleteEvent.SUBSCRIPTION_UPDATE));
                }
            });
        }
    }

    public void retrieveServerInfo(boolean forceUpdate) {
        if (servRequest) {
            servRequest = false;
            LoadServerInfoAction action = new LoadServerInfoAction(forceUpdate);
            RPCService.execute(action, new Handler<LoadServerInfoResponse>(eventBus) {
                @Override
                public void onSuccess(LoadServerInfoResponse response) {
                    if (response != null) {
                        processInfos(response.getInfos());
                        servRequest = true;
                    }
                    fireBusEvent(new UpdateCompleteEvent(UpdateCompleteEvent.SERVER_INFO_UPDATE));
                }
            });
        }
    }

    /**
     * Using dbChangeStatus attribute, update the list of cached devices.
     * It also fires event regarding action performed on devices.
     * 
     * @param newDevices list of devices retrieved from the server
     */
    private void processTopics(List<TopicWTO> newTopics) {

        if (newTopics != null) {

            for (int i = 0; i < newTopics.size(); i++) {

                TopicWTO topic = newTopics.get(i);

                // new topic
                if (topic.getDbChangeStatus() == BaseWTO.NEW) {
                    topics.put(topic.getId(), topic);
                    fireBusEvent(new NewTopicEvent(topic));
                    continue;
                }

                // updated topic
                if (topic.getDbChangeStatus() == BaseWTO.UPDATED) {
                    topics.put(topic.getId(), topic);
                    fireBusEvent(new UpdatedTopicEvent(topic));
                    continue;
                }

                // deleted topic
                if (topic.getDbChangeStatus() == BaseWTO.DELETED) {
                    topics.remove(topic.getId());
                    fireBusEvent(new DeletedTopicEvent(topic));
                    continue;
                }
            }
        }
    }

    private void processQueues(List<QueueWTO> newQueues) {

        if (newQueues != null) {

            for (int i = 0; i < newQueues.size(); i++) {

                QueueWTO queue = newQueues.get(i);

                // new queue
                if (queue.getDbChangeStatus() == BaseWTO.NEW) {
                    queues.put(queue.getId(), queue);
                    fireBusEvent(new NewQueueEvent(queue));
                    continue;
                }

                // updated queue
                if (queue.getDbChangeStatus() == BaseWTO.UPDATED) {
                    queues.put(queue.getId(), queue);
                    fireBusEvent(new UpdatedQueueEvent(queue));
                    continue;
                }

                // deleted queue
                if (queue.getDbChangeStatus() == BaseWTO.DELETED) {
                    queues.remove(queue.getId());
                    fireBusEvent(new DeletedQueueEvent(queue));
                    continue;
                }
            }
        }
    }

    private void processMessages(List<MessageWTO> newMessages, String queueName) {

        if (newMessages != null) {

            for (int i = 0; i < newMessages.size(); i++) {

                MessageWTO message = newMessages.get(i);

                queues.get(queueName).addMessageToList(message.getId());

                // new queue message
                if (message.getDbChangeStatus() == BaseWTO.NEW) {
                    messages.put(message.getId(), message);
                    fireBusEvent(new NewMessageEvent(message, queueName));
                    continue;
                }

                // updated queue message
                if (message.getDbChangeStatus() == BaseWTO.UPDATED) {
                    messages.put(message.getId(), message);
                    fireBusEvent(new UpdatedMessageEvent(message, queueName));
                    continue;
                }

                // deleted queue message
                if (message.getDbChangeStatus() == BaseWTO.DELETED) {
                    messages.remove(message.getId());
                    fireBusEvent(new DeletedMessageEvent(message, queueName));
                    continue;
                }
            }
        }
    }

    private void processSubMessages(List<MessageWTO> newMessages, String subName) {

        if (newMessages != null) {

            for (int i = 0; i < newMessages.size(); i++) {

                MessageWTO message = newMessages.get(i);

                // new sub message
                if (message.getDbChangeStatus() == BaseWTO.NEW) {
                    subs.get(subName).addMessageToList(message.getId());
                    messages.put(message.getId(), message);
                    fireBusEvent(new NewMessageEvent(message, subName));
                    continue;
                }

                // updated sub message
                if (message.getDbChangeStatus() == BaseWTO.UPDATED) {
                    messages.put(message.getId(), message);
                    fireBusEvent(new UpdatedMessageEvent(message, subName));
                    continue;
                }

                // deleted sub message
                if (message.getDbChangeStatus() == BaseWTO.DELETED) {
                    subs.get(subName).removeMessageFromList(message.getId());
                    messages.remove(message.getId());
                    fireBusEvent(new DeletedMessageEvent(message, subName));
                    continue;
                }
            }
        }
    }

    private void processUsers(List<UserWTO> newUsers) {

        if (newUsers != null) {

            for (int i = 0; i < newUsers.size(); i++) {

                UserWTO user = newUsers.get(i);

                // new user
                if (user.getDbChangeStatus() == BaseWTO.NEW) {
                    users.put(user.getId(), user);
                    fireBusEvent(new NewUserEvent(user));
                    continue;
                }

                // updated user
                if (user.getDbChangeStatus() == BaseWTO.UPDATED) {
                    users.put(user.getId(), user);
                    fireBusEvent(new UpdatedUserEvent(user));
                    continue;
                }

                // deleted user
                if (user.getDbChangeStatus() == BaseWTO.DELETED) {
                    users.remove(user.getId());
                    fireBusEvent(new DeletedUserEvent(user));
                }
            }
        }
    }

    private void processSubscriptions(List<SubscriptionWTO> newSubs) {

        if (newSubs != null) {

            for (int i = 0; i < newSubs.size(); i++) {

                SubscriptionWTO sub = newSubs.get(i);

                // new subscription
                if (sub.getDbChangeStatus() == BaseWTO.NEW) {
                    subs.put(sub.getId(), sub);
                    fireBusEvent(new NewSubscriptionEvent(sub));
                    continue;
                }

                // updated subscription
                if (sub.getDbChangeStatus() == BaseWTO.UPDATED) {
                    subs.put(sub.getId(), sub);
                    fireBusEvent(new UpdatedSubscriptionEvent(sub));
                    continue;
                }

                // deleted subscription
                if (sub.getDbChangeStatus() == BaseWTO.DELETED) {
                    subs.remove(sub.getId());
                    fireBusEvent(new DeletedSubscriptionEvent(sub));
                    continue;
                }
            }
        }
    }

    private void fireBusEvent(GwtEvent<?> event) {
        Log.debug(logCategory, " fire BUS event : " + event.getClass().getName());
        eventBus.fireEvent(event);
    }

    private void processInfos(float[] infos) {
        if (infos != null) {
            addToHistory(infos);
        }
    }
}