package lava.net.psyc.packages; import java.util.Hashtable; import lava.net.common.UNL; import lava.net.common.Value; import lava.net.common.VariableModifier; import lava.net.psyc.PSYCDeliveryException; import lava.net.psyc.PSYCMessageCenter; /** * **/ public class IdentificationChecker extends Skeleton { /** * The maximum time in milliseconds to wait for an answer for * a query about locations. **/ public long queryTimeout = 60000; class TimeoutGuard extends Thread { /** * **/ private UNL identification = null; /** * **/ private UNL location = null; /** * **/ public TimeoutGuard(UNL identification, UNL location) { super(); this.identification = identification; this.location = location; start(); } /** * **/ public void run() { synchronized(this) { try { sleep(queryTimeout); } catch(InterruptedException e) { } } queried.remove(identification); timeouts.remove(identification); if(!check(identification,center.getLocations(identification))) listener.wrongIdentification(location); } } class DummyListener implements IdentificationCheckerListener { /** * **/ public void wrongIdentification(UNL source) { center.removeVariable(source,center.identificationTag); } /** * **/ public void temporarilyIdentification(UNL source) { center.removeVariable(source,center.identificationTag); } } /** * **/ private IdentificationCheckerListener listener = new DummyListener(); /** * **/ private Hashtable queried = new Hashtable(); /** * **/ private Hashtable timeouts = new Hashtable(); /** * **/ public IdentificationChecker() { this (null); } /** * **/ public IdentificationChecker(IdentificationCheckerListener listener) { super(); addPackageVariable(center.locationTag,null,true); addPackageVariable(center.identificationTag,null,true); if(listener != null) this.listener = listener; } /** * **/ public boolean understands() { return !(listener instanceof DummyListener); } /** * **/ public void variableChanged(UNL source, VariableModifier modifier) { String name = modifier.getName(); if(center.identificationTag.equals(name)) { char glyph = modifier.getGlyph(); if(glyph == VariableModifier.GLYPH_SET) listener.temporarilyIdentification(source); else if(glyph == VariableModifier.GLYPH_ASSIGN) { Value value = modifier.getValue(); if(value == null) return; UNL identification = new UNL(value.toString()); if(!check(identification,center.getLocations(identification))) { queried.put(identification,source); try { center.queryVariable(identification,center.locationTag); timeouts.put(identification,// new TimeoutGuard(identification,source)); } catch(PSYCDeliveryException e) { queried.remove(identification); listener.wrongIdentification(source); } } } } else if(center.locationTag.equals(name)) { TimeoutGuard guard = (TimeoutGuard)timeouts.get(source); if(guard != null) guard.interrupt(); } } /** * **/ private boolean check(UNL identification, UNL[] locations) { if(locations == null) return false; for(int i = 0;i < locations.length;++i) if(identification.equals(locations[i])) return true; return false; } }