/interpreter/branches/multinetwork/src/edu/vub/at/actors/net/NATNetworks.java
Java | 250 lines | 151 code | 24 blank | 75 comment | 22 complexity | fe3d7672517fbf34cf15d65dc5d2ea74 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.0, LGPL-2.1
- /**
- * AmbientTalk/2 Project
- * OBJSystem.java created on 21-sep-2006 at 17:18:32
- * (c) Programming Technology Lab, 2006 - 2007
- * Authors: Tom Van Cutsem & Stijn Mostinckx
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
- package edu.vub.at.actors.net;
- import edu.vub.at.actors.eventloops.Event;
- import edu.vub.at.actors.natives.ELActor;
- import edu.vub.at.actors.natives.ELVirtualMachine;
- import edu.vub.at.actors.natives.NATFarReference;
- import edu.vub.at.actors.net.comm.Address;
- import edu.vub.at.eval.Evaluator;
- import edu.vub.at.exceptions.InterpreterException;
- import edu.vub.at.exceptions.XIOProblem;
- import edu.vub.at.exceptions.XIllegalArgument;
- import edu.vub.at.exceptions.XNetworkError;
- import edu.vub.at.objects.ATClosure;
- import edu.vub.at.objects.ATNil;
- import edu.vub.at.objects.ATObject;
- import edu.vub.at.objects.ATTable;
- import edu.vub.at.objects.natives.NATByCopy;
- import edu.vub.at.objects.natives.NATTable;
- import edu.vub.at.objects.natives.NATText;
- import edu.vub.at.util.logging.Logging;
- import java.io.IOException;
- import java.net.InetAddress;
- import java.net.InterfaceAddress;
- import java.net.NetworkInterface;
- import java.net.SocketException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Set;
- /**
- * Instances of this class represent the 'networks' object,
- * that configures network port objects in an actor
- * No more than one threads access this object
- *
- * The interface of the networks object is as follows:
- *
- * def system := object: {
- * def getAll() { returns all port objects in this actor}
- * def createPort(name) { creates virtual port object }
- * def getByFarRef(farRef) { return port object that is related to the far reference }
- * }
- *
- * @author suztomo
- */
- public final class NATNetworks extends NATByCopy {
- private NATNetworkPort[] ports_;
- private NATNetworkPort defaultPort;
- private HashMap nameToPort;
- private HashMap virtualNameToPort;
- public NATNetworks() {
- virtualNameToPort = new HashMap();
- nameToPort = new HashMap();
- }
-
- public NATText meta_print() throws InterpreterException {
- return NATText.atValue("<native object: netoworks>");
- }
-
-
- /**
- * Returns all NATNetworkPort objects available in this actor
- * This includes virutual ports that have been created in this actor
- */
- public NATTable base_getAll() {
- NATNetworkPort[] ports = getAllNetworks();
- return NATTable.atValue(ports);
- }
-
- @SuppressWarnings("unchecked")
- public NATNetworkPort[] getAllNetworks() {
- /*
- * ifnameToAddress instance is read only after its initialization,
- * so actors can share the Address instances
- */
- HashMap ifnameToAddress = ELVirtualMachine.currentVM().getIfnameToAddress();
- Set keys;
- int len;
- int c = 0;
- NATNetworkPort[] ret;
- synchronized(ifnameToAddress) {
- len = ifnameToAddress.size() + virtualNameToPort.size();
- ret = new NATNetworkPort[len];
- keys = ifnameToAddress.keySet();
- for (Iterator i = keys.iterator(); i.hasNext();) {
- String name = (String)i.next();
- NATNetworkPort p = (NATNetworkPort)nameToPort.get(name);
- if (p == null) {
- Address a = (Address) ifnameToAddress.get(name);
- p = new NATNetworkPort(name, a);
- nameToPort.put(name, p);
- }
- ret[c] = p;
- c++;
- }
- }
-
- // The latter is actor specific. No need to lock
- keys = virtualNameToPort.keySet();
- for (Iterator i = keys.iterator(); i.hasNext();) {
- ret[c] = (NATNetworkPort) virtualNameToPort.get(i.next());
- c++;
- }
- return ret;
- }
-
- /**
- * Returns a port object that represents the network of the given far reference
- * @param obj a far reference
- * @return object that represents a network.
- */
- public ATObject base_getByFarRef(ATObject obj) throws InterpreterException {
- if (!obj.isFarReference()) {
- throw new XIllegalArgument("Parameter is not far reference: " + obj);
- }
-
- NATFarReference ref = (NATFarReference)obj;
-
- Address target = ELVirtualMachine.currentVM().vmAddressBook_.getAddressOf(ref.getObjectId().getVirtualMachineId());
- if (target == null) { // local far reference
- throw new XIllegalArgument("Parameter is local far reference: " + obj);
- }
- if (target.isVirtualNetwork()) { // ?
- return createVirtualPortOf(target.virtualNetworkName_);
- }
- for (int i=0; i<ports_.length; i++) {
- NATNetworkPort port = ports_[i];
- if (target.equals(port.address)) {
- return port;
- }
- }
- return Evaluator.getNil();
- }
-
- @SuppressWarnings("unchecked")
- private NATNetworkPort createVirtualPortOf(String virtualPortName) {
- NATNetworkPort port = (NATNetworkPort)virtualNameToPort.get(virtualPortName);
- if (port == null) {
- port = new NATNetworkPort(virtualPortName);
- virtualNameToPort.put(virtualPortName, port);
- }
- return port;
-
- }
-
- /**
- * Creates a object that represents a virtual network, which can be used
- * as communication among several VMs in one computer
- * @param name of the network
- * @return the object representing network
- */
- public ATObject base_createPort(ATObject name) throws InterpreterException {
- if (!name.isNativeText()) {
- throw new XIllegalArgument("Parameter is not text");
- }
- String portName = ((NATText)name).javaValue;
-
- // port is unique in an actor, thus, in a NATNetwork object
- NATNetworkPort port = createVirtualPortOf(portName);
- return port;
- }
-
- public ATObject base_setDefault(ATObject obj) throws InterpreterException {
- if (! (obj instanceof NATNetworkPort)) {
- throw new XIllegalArgument("Parameter is not a port object");
- }
- defaultPort = (NATNetworkPort)obj;
- return Evaluator.getNil();
- }
-
- public ATObject base_getDefault() throws InterpreterException {
- if (defaultPort != null) {
- return defaultPort;
- }
-
- /*
- * Default port object is the first port object
- * unless it is not set before this function is called
- */
- NATNetworkPort[] ports = getAllNetworks();
- if (ports.length == 0) {
- return Evaluator.getNil();
- }
- defaultPort = ports[0];
- return defaultPort;
- }
-
- /**
- * Connects the interpreter to the network
- * this method can be called by a default actor
- */
- public ATObject base_online() throws InterpreterException {
- ELActor actor = ELActor.currentActor();
- if (actor.isDefault) {
- ELVirtualMachine.currentVM().event_goOnline();
- } else {
- throw new XNetworkError("Only default actor can change the interpreter's status");
- }
- return Evaluator.getNil();
- }
- /**
- * Disonnects the interpreter to the network
- * this method can be called by a default actor
- */
- public ATObject base_offline() throws InterpreterException {
- ELActor actor = ELActor.currentActor();
- if (actor.isDefault) {
- ELVirtualMachine.currentVM().event_goOffline();
- } else {
- throw new XNetworkError("Only default actor can change the interpreter's status");
- }
- return Evaluator.getNil();
- }
- }