/*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tm.tcf.core;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.tm.internal.tcf.core.RemotePeer;
import org.eclipse.tm.internal.tcf.services.local.LocatorService;
import org.eclipse.tm.tcf.protocol.IPeer;
import org.eclipse.tm.tcf.protocol.JSON;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.ILocator;
import org.eclipse.tm.tcf.services.ILocator.LocatorListener;
/**
* Abstract implementation of IPeer interface.
* Objects of this class are stored in Locator service peer table.
* The class implements sending notification events to Locator listeners.
* See TransientPeer for IPeer objects that are not stored in the Locator table.
*/
public class AbstractPeer extends TransientPeer {
private long last_heart_beat_time;
public AbstractPeer(Map<String,String> attrs) {
super(attrs);
assert Protocol.isDispatchThread();
String id = getID();
assert id != null;
Map<String,IPeer> peers = LocatorService.getLocator().getPeers();
if (peers.get(id) instanceof RemotePeer) {
((RemotePeer)peers.get(id)).dispose();
}
//assert peers.get(id) == null;
peers.put(id, this);
sendPeerAddedEvent();
}
public void dispose() {
assert Protocol.isDispatchThread();
String id = getID();
assert id != null;
Map<String,IPeer> peers = LocatorService.getLocator().getPeers();
//assert peers.get(id) == this;
peers.remove(id);
sendPeerRemovedEvent();
}
void onChannelTerminated() {
// A channel to this peer was terminated:
// not delaying next heart beat helps client to recover much faster.
last_heart_beat_time = 0;
}
public void updateAttributes(Map<String,String> attrs) {
boolean equ = true;
assert attrs.get(ATTR_ID).equals(rw_attrs.get(ATTR_ID));
for (Iterator<String> i = rw_attrs.keySet().iterator(); i.hasNext();) {
String key = i.next();
if (!rw_attrs.get(key).equals(attrs.get(key))) {
equ = false;
break;
}
}
for (Iterator<String> i = attrs.keySet().iterator(); i.hasNext();) {
String key = i.next();
if (!attrs.get(key).equals(rw_attrs.get(key))) {
equ = false;
break;
}
}
long time = System.currentTimeMillis();
if (!equ) {
rw_attrs.clear();
rw_attrs.putAll(attrs);
for (LocatorListener l : LocatorService.getListeners()) {
try {
l.peerChanged(this);
}
catch (Throwable x) {
Protocol.log("Unhandled exception in Locator listener", x);
}
}
try {
Object[] args = { rw_attrs };
Protocol.sendEvent(ILocator.NAME, "peerChanged", JSON.toJSONSequence(args));
}
catch (IOException x) {
Protocol.log("Locator: failed to send 'peerChanged' event", x);
}
last_heart_beat_time = time;
}
else if (last_heart_beat_time + ILocator.DATA_RETENTION_PERIOD / 4 < time) {
for (LocatorListener l : LocatorService.getListeners()) {
try {
l.peerHeartBeat(attrs.get(ATTR_ID));
}
catch (Throwable x) {
Protocol.log("Unhandled exception in Locator listener", x);
}
}
try {
Object[] args = { rw_attrs.get(ATTR_ID) };
Protocol.sendEvent(ILocator.NAME, "peerHeartBeat", JSON.toJSONSequence(args));
}
catch (IOException x) {
Protocol.log("Locator: failed to send 'peerHeartBeat' event", x);
}
last_heart_beat_time = time;
}
}
private void sendPeerAddedEvent() {
for (LocatorListener l : LocatorService.getListeners()) {
try {
l.peerAdded(this);
}
catch (Throwable x) {
Protocol.log("Unhandled exception in Locator listener", x);
}
}
try {
Object[] args = { rw_attrs };
Protocol.sendEvent(ILocator.NAME, "peerAdded", JSON.toJSONSequence(args));
}
catch (IOException x) {
Protocol.log("Locator: failed to send 'peerAdded' event", x);
}
last_heart_beat_time = System.currentTimeMillis();
}
private void sendPeerRemovedEvent() {
for (LocatorListener l : LocatorService.getListeners()) {
try {
l.peerRemoved(rw_attrs.get(ATTR_ID));
}
catch (Throwable x) {
Protocol.log("Unhandled exception in Locator listener", x);
}
}
try {
Object[] args = { rw_attrs.get(ATTR_ID) };
Protocol.sendEvent(ILocator.NAME, "peerRemoved", JSON.toJSONSequence(args));
}
catch (IOException x) {
Protocol.log("Locator: failed to send 'peerRemoved' event", x);
}
}
}