package lava.net.mmp; import java.util.Enumeration; import java.util.Hashtable; import lava.net.common.UNA; import lava.net.common.Value; /** * **/ public class MMPMultiplexer extends MMPCenter implements MMPPacketManager { /** * mapping UNA remote -> UNA local **/ private final Hashtable locals = new Hashtable(); /** * **/ private String name = "/"; /** * **/ private MMPPacketManager manager = null; /** * **/ private final Hashtable slaves = new Hashtable(); /** * **/ private MMPCenter center = null; public class DummyManager implements MMPPacketManager { /** * **/ public String getGreetingBody(UNA remote, UNA local) { return null; } /** * **/ public void manage(MMPPacket packet) { } /** * **/ public void error(MMPException e, UNA remote, UNA local, // MMPPacket packet) { } } /** * **/ public MMPMultiplexer(String name, MMPPacketManager manager, // MMPCenter center) { this.name = normalize(name); setManager(manager); this.center = center; } /** * **/ private String normalize(String name) { if(name == null || name.length() <= 0) name = this.name; if(name.charAt(0) != '/') name = this.name + name; int l = name.length(); if(l > 1 && name.charAt(l - 1) != '/') name = name + "/"; return name; } /** * **/ public Value usingProtocols() { return center.usingProtocols(); } /** * **/ public UNA[] getListenLocations() { UNA[] listen = center.getListenLocations(); if(listen == null) return null; for(int i = 0;i < listen.length;++i) listen[i] = new UNA(listen[i],name); return listen; } /** * **/ public void setManager(MMPPacketManager manager) { if(manager == null) manager = new DummyManager(); this.manager = manager; setManager(null,manager); } /** * TODO: security problem? **/ public void setManager(String name, MMPPacketManager manager) { name = normalize(name); if(manager == null) manager = new DummyManager(); slaves.put(name,manager); } /** * **/ public String[] getVars(UNA remote) { return center.getVars(remote,getLocal(remote)); } /** * **/ protected String[] getVars(UNA remote, UNA local) { return center.getVars(remote,local); } /** * **/ public Value getValue(UNA remote, String name) { return center.getValue(remote,getLocal(remote),name); } /** * **/ protected Value getValue(UNA remote, UNA local, String name) { return center.getValue(remote,local,name); } /** * **/ public Value removeValue(UNA remote, String name) { return center.removeValue(remote,getLocal(remote),name); } /** * **/ protected Value removeValue(UNA remote, UNA local, String name) { return center.removeValue(remote,local,name); } /** * **/ public void close() { for(Enumeration e = locals.keys();e.hasMoreElements();) { UNA remote = (UNA)e.nextElement(); UNA local = (UNA)locals.get(remote); center.close(remote,local); } } /** * **/ protected void close(UNA remote, UNA local) { center.close(remote,local); } /** * **/ public void close(UNA remote) { center.close(remote,getLocal(remote)); } /** * **/ private String getName(String resource) { resource = normalize(resource); try { if(!resource.regionMatches(0,name,0,name.length())) return null; int end = resource.indexOf('/',name.length()); if(end++ == -1) end = resource.length(); return resource.substring(0,end); } catch(StringIndexOutOfBoundsException e) { return null; } } /** * **/ public String getGreetingBody(UNA remote, UNA local) { if(remote == null) return null; // get the right local, deliver it String name = this.name; if(local != null) name = local.getResource(); name = getName(name); if(name == null) // whoups, this was not for us return null; MMPPacketManager m = (MMPPacketManager)slaves.get(name); if(m == null) { manager.error(new MMPReceiverException(// MMPReceiverException.UNKNOWN_LOCAL),remote,local,null); m = (MMPPacketManager)slaves.get(name); if(m == null) return null; } return m.getGreetingBody(remote,local); } /** * **/ public void error(MMPException e, UNA remote, UNA local, MMPPacket packet) { if(e == null) return; // get the right local, deliver it String name = this.name; if(local != null) name = local.getResource(); name = getName(name); if(name == null) // whoups, this was not for us return; MMPPacketManager m = (MMPPacketManager)slaves.get(name); if(m == null) { manager.error(new MMPReceiverException(// MMPReceiverException.UNKNOWN_LOCAL),remote,local,packet); m = (MMPPacketManager)slaves.get(name); if(m == null) return; } m.error(e,remote,local,packet); if(e instanceof MMPReceiverException && // e.getErrorCode() == MMPReceiverException.CLOSED && remote != null) locals.remove(remote); if(e instanceof MMPDeliveryException && // e.getErrorCode() == MMPDeliveryException.CANNOT_DELIVER && // remote != null) locals.remove(remote); } /** * **/ public void manage(MMPPacket packet) { UNA remote = packet.getRemote(); if(remote == null) return; UNA local = packet.getLocal(); if(local != null) locals.put(remote,local); else locals.put(remote,new UNA(null,name)); // get the right local, deliver it String name = this.name; if(local != null) name = local.getResource(); name = getName(name); if(name == null) // whoups, this was not for us return; MMPPacketManager m = (MMPPacketManager)slaves.get(name); if(m == null) { manager.error(new MMPReceiverException(// MMPReceiverException.UNKNOWN_LOCAL),remote,local,packet); m = (MMPPacketManager)slaves.get(name); if(m == null) return; } m.manage(packet); } /** * **/ public UNA getLocal(UNA remote) { if(remote == null) return new UNA(null,name); UNA local = (UNA)locals.get(remote); if(local == null) { local = center.getLocal(remote); local = new UNA(local,name); locals.put(remote,local); } return local; } /** * **/ public void assignVariable(UNA remote, String name, Value value) { center.assignVariable(remote,getLocal(remote),name,value); } /** * **/ protected void assignVariable(UNA remote, UNA local, // String name, Value value) { center.assignVariable(remote,local,name,value); } /** * **/ public void augmentVariable(UNA remote, String name, Value value) { center.augmentVariable(remote,getLocal(remote),name,value); } /** * **/ protected void augmentVariable(UNA remote, UNA local, // String name, Value value) { center.augmentVariable(remote,local,name,value); } /** * **/ public void diminishVariable(UNA remote, String name, Value value) { center.diminishVariable(remote,getLocal(remote),name,value); } /** * **/ protected void diminishVariable(UNA remote, UNA local, // String name, Value value) { center.diminishVariable(remote,local,name,value); } /** * **/ public void send(UNA remote, MMPPacket packet) { center.send(remote,getLocal(remote),packet); } /** * **/ protected void send(UNA remote, UNA local, MMPPacket packet) { center.send(remote,local,packet); } /** * **/ public Enumeration getAllRemotes() { return locals.keys(); } /** * **/ protected Enumeration getAllRemotes(UNA local) { return center.getAllRemotes(local); } /** * **/ public void broadcast(MMPPacket packet) { for(Enumeration e = locals.keys();e.hasMoreElements();) { UNA remote = (UNA)e.nextElement(); UNA local = (UNA)locals.get(remote); center.send(remote,local,packet); } } /** * **/ protected void broadcast(UNA local, MMPPacket packet) { center.broadcast(local,packet); } }