/***************************************************************************
* *
* RMIEndpoint.java *
* ------------------- *
* date : 22.02.2008, 14:10:40 *
* copyright : (C) 2008 Distributed and *
* Mobile Systems Group *
* Lehrstuhl fuer Praktische Informatik *
* Universitaet Bamberg *
* http://www.uni-bamberg.de/pi/ *
* email : sven.kaffille@uni-bamberg.de *
* *
* *
***************************************************************************/
/***************************************************************************
* *
* 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; either version 2 of the License, or *
* (at your option) any later version. *
* *
* A copy of the license can be found in the license.txt file supplied *
* with this software or at: http://www.gnu.org/copyleft/gpl.html *
* *
***************************************************************************/
package de.uniba.wiai.lspi.chord.com.rmi;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
//import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import de.uniba.wiai.lspi.chord.com.Broadcast;
import de.uniba.wiai.lspi.chord.com.CommunicationException;
import de.uniba.wiai.lspi.chord.com.Endpoint;
import de.uniba.wiai.lspi.chord.com.Entry;
import de.uniba.wiai.lspi.chord.com.Node;
import de.uniba.wiai.lspi.chord.com.RefsAndEntries;
import de.uniba.wiai.lspi.chord.data.ID;
import de.uniba.wiai.lspi.chord.data.URL;
public final class RMIEndpoint extends Endpoint implements RemoteNode {
private Registry registry = null;
private RemoteNode remoteNode = null;
static final String NAME_IN_REGISTRY = "oc_endpoint_";
public RMIEndpoint(Node node1, URL url1) {
super(node1, url1);
}
/**
* Can only be called if Endpoint is not in state STARTED!
* @return
*/
RemoteNode getRemoteNode() {
if (this.remoteNode == null) {
throw new IllegalStateException();
}
return this.remoteNode;
}
@Override
protected void closeConnections() {
try {
UnicastRemoteObject.unexportObject(this, true);
registry.unbind(NAME_IN_REGISTRY + this.url.toString());
this.setState(STARTED);
} catch (AccessException e) {
} catch (RemoteException e) {
} catch (NotBoundException e) {
}
}
@Override
protected void entriesAcceptable() {
this.setState(ACCEPT_ENTRIES);
}
@Override
protected void openConnections() {
try {
if (registry == null) {
registry = LocateRegistry.createRegistry(this.url.getPort());
}
//Remote remoteRef;
remoteNode = (RemoteNode) UnicastRemoteObject.exportObject(this);
registry.bind(NAME_IN_REGISTRY + this.url.toString(), remoteNode);
this.setState(LISTENING);
} catch (RemoteException e) {
throw new RuntimeException(e);
} catch (AlreadyBoundException e) {
throw new RuntimeException(e);
}
}
private RemoteNodeInfo createInfo(Node node) {
if (node.getNodeID().equals(this.node.getNodeID())) {
return new RemoteNodeInfo(remoteNode, this.node.getNodeID(),
this.node.getNodeURL());
} else {
return new RemoteNodeInfo(((RMIProxy) node).getRemoteNode(), node
.getNodeID(), node.getNodeURL());
}
}
public RemoteNodeInfo findSuccessor(ID key) throws CommunicationException,
RemoteException {
try {
Node node = this.node.findSuccessor(key);
return createInfo(node);
} catch (ClassCastException e) {
throw new RemoteException(
"Remote node uses unsuitable communication protocol!", e);
}
}
public ID getNodeID() throws RemoteException {
return this.node.getNodeID();
}
public void insertEntry(Entry entryToInsert) throws RemoteException,
CommunicationException {
this.node.insertEntry(entryToInsert);
}
public void insertReplicas(Set<Entry> entries) throws RemoteException,
CommunicationException {
this.node.insertReplicas(entries);
}
public void leavesNetwork(RemoteNodeInfo predecessor)
throws RemoteException, CommunicationException {
this.node.leavesNetwork(new RMIProxy(predecessor, this.getURL()));
}
public List<RemoteNodeInfo> notify(RemoteNodeInfo potentialPredecessor)
throws RemoteException, CommunicationException {
List<Node> nodes = this.node.notify(new RMIProxy(potentialPredecessor,
this.getURL()));
List<RemoteNodeInfo> result = new LinkedList<RemoteNodeInfo>();
for (Node node : nodes) {
result.add(this.createInfo(node));
}
return result;
}
public RemoteRefsAndEntries notifyAndCopyEntries(
RemoteNodeInfo potentialPredecessor) throws RemoteException,
CommunicationException {
RefsAndEntries raes = this.node.notifyAndCopyEntries(new RMIProxy(
potentialPredecessor, this.getURL()));
List<RemoteNodeInfo> rNodes = new LinkedList<RemoteNodeInfo>();
List<Node> nodes = raes.getRefs();
for (Node node : nodes) {
rNodes.add(this.createInfo(node));
}
return new RemoteRefsAndEntries(raes.getEntries(), rNodes);
}
public void ping() throws RemoteException {
}
public void removeEntry(Entry entryToRemove) throws RemoteException,
CommunicationException {
this.node.removeEntry(entryToRemove);
}
public void removeReplicas(ID sendingNode, Set<Entry> replicasToRemove)
throws RemoteException, CommunicationException {
this.node.removeReplicas(sendingNode, replicasToRemove);
}
public Set<Entry> retrieveEntries(ID id) throws RemoteException,
CommunicationException {
return this.node.retrieveEntries(id);
}
public void broadcast(Broadcast info) throws RemoteException,
CommunicationException {
this.node.broadcast(info);
}
}