/* license-start
*
* Copyright (C) 2008 - 2013 Crispico, <http://www.crispico.com/>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 3.
*
* This program 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 General Public License for more details, at <http://www.gnu.org/licenses/>.
*
* Contributors:
* Crispico - Initial API and implementation
*
* license-end
*/
package org.flowerplatform.communication.stateful_service;
import java.util.Map;
import org.flowerplatform.communication.channel.CommunicationChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Cristi
*
* @param <DT>
*
*/
public abstract class RegularStatefulService<CT extends CommunicationChannel, DT> extends StatefulService {
protected Logger logger;
protected Map<CT, DT> clients;
public RegularStatefulService() {
super();
logger = LoggerFactory.getLogger(this.getClass());
}
///////////////////////////////////////////////////////////////
// JMX Methods
///////////////////////////////////////////////////////////////
public String printStatefulDataPerCommunicationChannel(String communicationChannelIdFilter, String linePrefix) {
// clean parameters
if ("".equals(communicationChannelIdFilter) || "String".equals(communicationChannelIdFilter)) {
communicationChannelIdFilter = null;
}
if ("String".equals(linePrefix)) {
linePrefix = "";
}
StringBuffer sb = new StringBuffer();
for (Map.Entry<CT, DT> entry : clients.entrySet()) {
if (communicationChannelIdFilter == null || communicationChannelIdFilter.equals(entry.getKey().getId())) {
printStatefulDataForClient(sb, linePrefix, entry.getKey(), entry.getValue());
}
}
return sb.toString();
}
protected void printStatefulDataForClient(StringBuffer stringBuffer, String linePrefix, CT client, DT data) {
stringBuffer.append(linePrefix).append(client).append("\n");
}
///////////////////////////////////////////////////////////////
// Normal methods
///////////////////////////////////////////////////////////////
protected DT getDataFromStatefulClientLocalState(StatefulServiceInvocationContext context, IStatefulClientLocalState statefulClientLocalState) {
return null;
}
protected abstract String getStatefulServiceId();
///////////////////////////////////////////////////////////////
//@RemoteInvocation methods
///////////////////////////////////////////////////////////////
@RemoteInvocation
@SuppressWarnings("unchecked")
public void subscribe(StatefulServiceInvocationContext context, IStatefulClientLocalState statefulClientLocalState) {
DT dt = getDataFromStatefulClientLocalState(context, statefulClientLocalState);
logger.info("Subscribing to {} with client data {}", getStatefulServiceId(), dt);
clients.put((CT) context.getCommunicationChannel(), dt);
}
@RemoteInvocation
public void unsubscribe(StatefulServiceInvocationContext context, IStatefulClientLocalState statefulClientLocalState) {
DT dt = getDataFromStatefulClientLocalState(context, statefulClientLocalState);
if (clients.containsKey(context.getCommunicationChannel())) {
// we check this, because we don't want to pollute the log and
// actually this is not correct: unsubscribe makes sense only after a subscribe; someone
// reading the log would be misleaded, thinking that the element was subscribed
logger.info("Unsubscribing from {} with client data {}", getStatefulServiceId(), dt);
clients.remove(context.getCommunicationChannel());
}
}
}