// ex:sw=3 package lava.net.psyc.packages; import java.util.Enumeration; import java.util.Hashtable; import lava.net.common.UNL; import lava.net.common.Value; import lava.net.common.VariableModifier; import lava.net.psyc.PSYCMessageCenter; import lava.net.psyc.PSYCDeliveryException; import lava.net.psyc.UNI; /** * * Conferencing also handles content and even private messages - * That's wrong! It should only manage the local representation * of the room, but pass the messages transparently. -lynx * * Maybe we should seperate real conferencing from the issues * of handling a text chat window. * **/ public class Conferencing extends Skeleton { /** * **/ public final static String PackageName = "Conferencing"; /** * **/ public final static String conversationTag = "_message"; private final static String[] conversationAliases = { "m" }; /** * **/ public final static String conversationEchoTag = "_message_echo"; private final static String[] conversationEchoAliases = { "me" }; /** * **/ public final static String conversationPagerTag = "_message_private_page"; private final static String[] conversationPagerAliases = { "mp_page" }; /** * **/ public final static String structGroupTag = "_struct_group"; private final static String[] structGroupAliases = {}; /** * **/ public final static String propertiesGroupTag = "_list_props_group"; private final static String[] propertiesGroupAliases = {}; /** * **/ public final static String speakTag = "_speak"; private final static String[] speakAliases = {}; /** * **/ public final static String listenTag = "_listen"; private final static String[] listenAliases = {}; /** * **/ public final static String authorityTag = "_authority"; private final static String[] authorityAliases = {}; /** * **/ public final static String allowExternalsTag = "_allow_externals"; private final static String[] allowExternalsAliases = {}; /** * **/ public final static String speakersAddSpeakersTag = "_add_members"; private final static String[] speakersAddSpeakersAliases = {}; /** * **/ public final static String speakersAddListenersTag = "_add_listeners"; private final static String[] speakersAddListenersAliases = {}; /** * **/ public final static String listenersAddListenersTag = "_add_listeners_too"; private final static String[] listenersAddListenersAliases = {}; /** * **/ public final static String speakersRemoveSpeakersTag = "_remove_members"; private final static String[] speakersRemoveSpeakersAliases = {}; /** * **/ public final static String speakersRemoveListenersTag = "_remove_listeners"; private final static String[] speakersRemoveListenersAliases = {}; /** * **/ public final static String topicTag = "_topic"; private final static String[] topicAliases = {}; class Member { /** * **/ public UNI identification = null; /** * **/ public UNL multicaster = null; /** * **/ public Hashtable locations = new Hashtable(); /** * **/ public UNL lastSender = null; /** * **/ public boolean speak = true; /** * **/ public boolean listen = true; /** * **/ public boolean authority = false; } class Place { /** * members ... (UNI, Member) ... all members * memberLocations ... (UNL, UNI) ... all locations of all members **/ public final Hashtable members = new Hashtable(); /** * **/ public final Hashtable memberLocations = new Hashtable(); /** * **/ public boolean allowExternals = false; /** * **/ public boolean speakersAddSpeakers = false; /** * **/ public boolean speakersAddListeners = false; /** * **/ public boolean listenersAddListeners = false; /** * **/ public boolean speakersRemoveSpeakers = false; /** * **/ public boolean speakersRemoveListeners = false; } class DummyListener implements ConferencingListener { /** * **/ public void contextIntroduced(UNL server, String context) { } /** * **/ public void placeEntered(String context, UNI user) { } /** * **/ public void placeLeft(String context, UNI user) { } /** * **/ public void placeDeleted(String context) { } /** * **/ public void memberChanged(String context, UNI user, UNL multicaster, // Hashtable locations, // boolean speak, boolean listen, boolean authority) { } /** * **/ public void placePropertiesChanged(String context, // boolean allowExternals, // boolean speakersAddSpeakers, boolean speakersAddListeners, // boolean listenersAddListeners, // boolean speakersRemoveSpeakers, boolean speakersRemoveListeners) { } /** * **/ public void conversationPager(UNL user, String message) { } /** * **/ public void conversationPrivate(UNL user, String message) { } /** * **/ public void conversationPublic(String context, UNI user, // String message) { } /** * **/ public void conversationEcho(String message) { } } /** * **/ private UNL me = null; /** * **/ private ConferencingListener listener = new DummyListener(); /** * **/ private Hashtable places = new Hashtable(); /** * **/ private Hashtable acceptPlaces = new Hashtable(); /** * **/ private StringBuffer buf = new StringBuffer(); /** * **/ private final static Hashtable optionShortcuts = new Hashtable(); /** * **/ private final static Hashtable propertyShortcuts = new Hashtable(); { int i; optionShortcuts.put(speakTag,speakTag); for(i = 0;i < speakAliases.length;++i) optionShortcuts.put(speakTag,speakAliases[i]); optionShortcuts.put(listenTag,listenTag); for(i = 0;i < listenAliases.length;++i) optionShortcuts.put(listenTag,listenAliases[i]); optionShortcuts.put(authorityTag,authorityTag); for(i = 0;i < authorityAliases.length;++i) optionShortcuts.put(authorityTag,authorityAliases[i]); propertyShortcuts.put(allowExternalsTag,allowExternalsTag); for(i = 0;i < allowExternalsAliases.length;++i) propertyShortcuts.put(allowExternalsTag,allowExternalsAliases[i]); propertyShortcuts.put(speakersAddSpeakersTag,speakersAddSpeakersTag); for(i = 0;i < speakersAddSpeakersAliases.length;++i) propertyShortcuts.put(speakersAddSpeakersTag,// speakersAddSpeakersAliases[i]); propertyShortcuts.put(speakersAddListenersTag,speakersAddListenersTag); for(i = 0;i < speakersAddListenersAliases.length;++i) propertyShortcuts.put(speakersAddListenersTag,// speakersAddListenersAliases[i]); propertyShortcuts.put(listenersAddListenersTag,// listenersAddListenersTag); for(i = 0;i < listenersAddListenersAliases.length;++i) propertyShortcuts.put(listenersAddListenersTag,// listenersAddListenersAliases[i]); propertyShortcuts.put(speakersRemoveSpeakersTag,// speakersRemoveSpeakersTag); for(i = 0;i < speakersRemoveSpeakersAliases.length;++i) propertyShortcuts.put(speakersRemoveSpeakersTag,// speakersRemoveSpeakersAliases[i]); propertyShortcuts.put(speakersRemoveListenersTag,// speakersRemoveListenersTag); for(i = 0;i < speakersRemoveListenersAliases.length;++i) propertyShortcuts.put(speakersRemoveListenersTag,// speakersRemoveListenersAliases[i]); } /** * **/ public Conferencing(ConferencingListener listener) { super(); setPackageName(PackageName); addPackageMethod(conversationTag,conversationAliases,true); addPackageMethod(conversationEchoTag,conversationEchoAliases,false); addPackageMethod(conversationPagerTag,conversationPagerAliases,false); addPackageVariable(structGroupTag,structGroupAliases,true); addPackageVariable(propertiesGroupTag,propertiesGroupAliases,true); addPackageVariable(topicTag,topicAliases,false); if(listener != null) this.listener = listener; } /** * **/ public boolean understands() { return !(listener instanceof DummyListener); } /** * **/ public void registerCenter(PSYCMessageCenter center) { super.registerCenter(center); me = center.getObjectName(null); } /** * **/ public void received(UNL source, String method, String body) { String context = source.getContext(); Place place = null; Member member = null; UNI user = null; if(context != null) { place = (Place)places.get(context); if(place == null) { if(acceptPlaces.remove(source.withoutContext()) != null) { places.put(context,place = new Place()); Hashtable locations = new Hashtable(); locations.put(source,source); user = center.getIdentification(source); if(user == null) user = new UNI(source); listener.contextIntroduced(source,context); assignMember(context,user,null,locations,// false,false,true,false); } else // ignore messages to unknown places return; } user = (UNI)place.memberLocations.get(source); if(user == null) // ignore everything from non-members return; member = (Member)place.members.get(user); if(member == null) // ignore everything from non-members return; member.lastSender = source; if(!member.speak && !place.allowExternals) // ignore everything from non-speakers return; } if(conversationTag.equals(method)) { String full_method = center.getActualMethod(source); if(conversationEchoTag.regionMatches(0,full_method,0,// conversationEchoTag.length())) listener.conversationEcho(body); else if(conversationPagerTag.regionMatches(0,full_method,0,// conversationPagerTag.length())) listener.conversationPager(source,body); else if(member == null) listener.conversationPrivate(source,body); else listener.conversationPublic(context,// member.identification,body); } } /** * **/ public synchronized void variableChanged(// UNL source, VariableModifier modifier) { char glyph = modifier.getGlyph(); if(VariableModifier.isTemporary(glyph)) // ignore temporary group settings return; String context = source.getContext(); if(context == null) // ignore group settings if there is no group given return; Place place = (Place)places.get(context); if(place == null) { if(acceptPlaces.remove(source.withoutContext()) != null) { places.put(context,place = new Place()); Hashtable locations = new Hashtable(); locations.put(source,source); UNI user = center.getIdentification(source); if(user == null) user = new UNI(source); listener.contextIntroduced(source,context); assignMember(context,user,null,locations,// false,false,true,false); } else // ignore group settings to unknown places return; } UNI user = (UNI)place.memberLocations.get(source); if(user == null) // ignore everything from non-members return; Member member = (Member)place.members.get(user); if(member == null) // ignore everything from non-members return; member.lastSender = source; String name = modifier.getName(); if(propertiesGroupTag.equals(name)) { if(!member.authority) // group properties only permitted for authorities return; place.allowExternals = false; place.speakersAddSpeakers = false; place.speakersAddListeners = false; place.listenersAddListeners = false; place.speakersRemoveSpeakers = false; place.speakersRemoveListeners = false; Value v = center.getValue(source,propertiesGroupTag); if(v != null) { String[] list = v.toList(); for(int i = 0;i < list.length;++i) { String property = (String)propertyShortcuts.get(list[i]); if(allowExternalsTag.equals(property)) { place.allowExternals = true; continue; } if(speakersAddSpeakersTag.equals(property)) { place.speakersAddSpeakers = true; continue; } if(speakersAddListenersTag.equals(property)) { place.speakersAddListeners = true; continue; } if(listenersAddListenersTag.equals(property)) { place.listenersAddListeners = true; continue; } if(speakersRemoveSpeakersTag.equals(property)) { place.speakersRemoveSpeakers = true; continue; } if(speakersRemoveListenersTag.equals(property)) { place.speakersRemoveListeners = true; continue; } } } listener.placePropertiesChanged(context,place.allowExternals,// place.speakersAddSpeakers,place.speakersAddListeners,// place.listenersAddListeners,// place.speakersRemoveSpeakers,place.speakersRemoveListeners); } else if(structGroupTag.equals(name)) { center.removeVariable(source,structGroupTag); Value v = modifier.getValue(); if(glyph == VariableModifier.GLYPH_ASSIGN) if(!member.authority) // assign is only permitted for authorities return; // TODO: here we are else glyph = VariableModifier.GLYPH_AUGMENT; if(glyph == VariableModifier.GLYPH_DIMINISH && // (v == null || v.toString().length() <= 0)) { // special case: remove all members... destroy place if(!member.authority) // destroy place is only permitted for authorities return; else { places.remove(context); listener.placeDeleted(context); return; } } String value = v == null ? "" : v.toString(); UNL multicaster; int begin = 0; int end; do { multicaster = null; end = value.indexOf(' ',begin); if(end == -1) end = value.length(); // check if we have a multicaster structure int end1 = value.indexOf('(',begin); if(end1 > begin && end1 < end) { // we have a multicaster multicaster = (new UNL(value.substring(begin,end1))).// addContext(context); begin = ++end1; // redefine the end end = value.indexOf(')',begin); if(end == -1) end = value.length(); } // parse through members do { end1 = value.indexOf(' ',begin); if(end1 == -1 || end1 > end) end1 = end; parseMember(context,place,member,glyph,multicaster,// value,begin,end1); begin = ++end1; } while(end1 < end); if(multicaster != null) ++end; begin = ++end; } while(end < value.length()); } } /** * **/ private void parseMember(String context, Place place, // Member sender, char glyph, UNL multicaster, String value, // int bIndex, int eIndex) { UNI identification = null; Hashtable locations = new Hashtable(); boolean speak = true; boolean listen = true; boolean authority = false; boolean somethingSet = false; boolean speakSet = false; boolean listenSet = false; boolean authoritySet = false; int begin = bIndex; int end = value.indexOf(';',begin); int iEnd; if(end == -1 || end > eIndex) end = eIndex; if(end > begin) { // identification set identification = new UNI(value.substring(begin,end)); begin = ++end; } end = value.indexOf(';',begin); if(end == -1 || end > eIndex) end = eIndex; if(end > begin) { // location(s) set do { iEnd = value.indexOf(',',begin); if(iEnd == -1 || iEnd > end) iEnd = end; if(iEnd > begin) { UNL location = (new UNL(value.substring(begin,iEnd))).// addContext(context); locations.put(location,location); begin = ++iEnd; } } while(iEnd < end); begin = ++end; } end = value.indexOf(';',begin); if(end == -1 || end > eIndex) end = eIndex; if(end > begin) { do { iEnd = value.indexOf(',',begin); if(iEnd == -1 || iEnd > end) iEnd = end; if(iEnd > begin) { somethingSet = true; String option = (String)optionShortcuts.get(// value.substring(begin,iEnd)); begin = ++iEnd; if(speakTag.equals(option)) { speakSet = true; continue; } if(listenTag.equals(option)) { listenSet = true; continue; } if(authorityTag.equals(option)) { authoritySet = true; continue; } } } while(iEnd < end); begin = ++end; } if(somethingSet) { speak = speakSet; listen = listenSet; authority = authoritySet; } // ignore additional comma separated UNLs /* end = value.indexOf(';', begin); if(end == -1 || end > eIndex) end = eIndex; if(end > begin) { do { iEnd = value.indexOf(',', begin); if(iEnd == -1 || iEnd > eIndex) iEnd = end; if(iEnd > begin) { UNL additional = (new UNL(value.substring(begin, iEnd))). // addContext(context); } } while(iEnd < end); begin = ++end; } */ // check access rights if(!sender.authority && // !sender.identification.equals(identification)) { // uh, it's no authority and it wants to modify another one // than itself if(multicaster != null && identification == null) // operation on a complete multicaster - only by authorities return; if(sender.speak) { // it's a speaker boolean speakers = place.speakersAddSpeakers; boolean listeners = place.speakersAddListeners; if(glyph == VariableModifier.GLYPH_DIMINISH) { speakers = place.speakersRemoveSpeakers; listeners = place.speakersRemoveListeners; } listeners = listeners || speakers; if(authority) authority = false; if(speak && !speakers) speak = false; if(listen && !listeners) listen = false; } else { // it's a listener if(authority) authority = false; if(speak) speak = false; if(listen && !place.listenersAddListeners) listen = false; } } if(identification == null) { if(multicaster != null) { // operation on a complete multicaster if(glyph == VariableModifier.GLYPH_AUGMENT) { // augment an empty multicaster center.addToContext(multicaster); } else { // diminish a multicaster center.removeFromContext(multicaster); // add all members within the multicaster to outgoing context for(Enumeration e = place.members.elements();// e.hasMoreElements();) { Member m = (Member)e.nextElement(); if(multicaster.equals(m.multicaster)) { m.multicaster = null; for(Enumeration en = m.locations.keys();// en.hasMoreElements();) { UNL location = (UNL)en.nextElement(); center.addToContext(location); } } } } } return; } switch(glyph) { case VariableModifier.GLYPH_ASSIGN: assignMember(context,identification,multicaster,locations,// speak,listen,authority,false); break; case VariableModifier.GLYPH_AUGMENT: augmentMember(context,identification,multicaster,locations,// speak,listen,authority,false); break; case VariableModifier.GLYPH_DIMINISH: diminishMember(context,identification,multicaster,locations,// speak,listen,authority,false); break; default: break; } } /** * **/ private String createMemberString(UNI identification, UNL multicaster, // Hashtable locations, boolean speak, boolean listen, boolean authority) { synchronized(buf) { if(!speak && !listen && !authority) { speak = true; listen = true; } buf.setLength(0); if(multicaster != null) { buf.append(multicaster.toString()); buf.append('('); } buf.append(identification.toString()); if(locations.size() > 0 || !speak || !listen || authority) buf.append(';'); for(Enumeration e = locations.keys();e.hasMoreElements();) { buf.append(e.nextElement()); if(e.hasMoreElements()) buf.append(','); } if(!speak || !listen || authority) { buf.append(';'); if(speak) { buf.append(speakTag); if(listen || authority) buf.append(','); } if(listen) { buf.append(listenTag); if(authority) buf.append(','); } if(authority) buf.append(authorityTag); } return buf.toString(); } } /** * **/ private Value createMemberValue(UNI identification, UNL multicaster, // Hashtable locations, boolean speak, boolean listen, boolean authority) { return new Value(createMemberString(identification,multicaster,// locations,speak,listen,authority)); } /** * **/ private Value createMemberValue(Member member) { return createMemberValue(member.identification,member.multicaster,// member.locations,member.speak,member.listen,member.authority); } /** * **/ public Value getMemberValue(String context, UNI identification) { if(context == null || identification == null) return null; Place place = (Place)places.get(context); if(place == null) return null; Member member = (Member)place.members.get(identification); if(member == null) return null; return createMemberValue(member); } /** * **/ public Value getGroupValue(String context) { if(context == null) return null; Place place = (Place)places.get(context); if(place == null) return null; // (UNL -> StringBuffer) Hashtable multicasters = new Hashtable(); StringBuffer standalones = new StringBuffer(); for(Enumeration e = place.members.elements();e.hasMoreElements();) { Member member = (Member)e.nextElement(); UNL multicaster = member.multicaster; StringBuffer buf = standalones; if(multicaster != null) { buf = (StringBuffer)multicasters.get(multicaster); if(buf == null) { buf = new StringBuffer(); multicasters.put(multicaster,buf); } } buf.append(createMemberString(member.identification,null,// member.locations,member.speak,member.listen,member.authority)); buf.append(' '); } StringBuffer buf = new StringBuffer(); for(Enumeration e = multicasters.keys();e.hasMoreElements();) { UNL multicaster = (UNL)e.nextElement(); buf.append(multicaster.toString()); buf.append('('); StringBuffer buf1 = (StringBuffer)multicasters.get(multicaster); buf1.setCharAt(buf1.length() - 1,')'); buf.append(buf1); buf.append(' '); } buf.append(standalones); int l = buf.length(); if(l > 0) buf.setLength(l - 1); return new Value(buf.toString()); } /** * **/ public Value getGroupProperties(boolean allowExternals, // boolean speakersAddSpeakers, boolean speakersAddListeners, // boolean listenersAddListeners, // boolean speakersRemoveSpeakers, boolean speakersRemoveListeners) { Value v = new Value(); if(allowExternals) v.augment(allowExternalsTag); if(speakersAddSpeakers) v.augment(speakersAddSpeakersTag); if(speakersAddListeners) v.augment(speakersAddListenersTag); if(listenersAddListeners) v.augment(listenersAddListenersTag); if(speakersRemoveSpeakers) v.augment(speakersRemoveSpeakersTag); if(speakersRemoveListeners) v.augment(speakersRemoveListenersTag); return v; } /** * **/ public void assignMember(String context, UNI identification, // UNL multicaster, Hashtable locations, // boolean speak, boolean listen, boolean authority) { if(context == null || identification == null) return; if(multicaster != null) multicaster = multicaster.addContext(context); if(locations == null) locations = new Hashtable(); Hashtable locs = new Hashtable(); for(Enumeration e = locations.keys();e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); location = location.addContext(context); locs.put(location,location); } locations = locs; assignMember(context,identification,multicaster,locations,// speak,listen,authority,true); } /** * **/ private void assignMember(String context, UNI identification, // UNL multicaster, Hashtable locations, // boolean speak, boolean listen, boolean authority, boolean send) { if(send) { center.assignVariable(context,structGroupTag,// createMemberValue(identification,multicaster,locations,// speak,listen,authority),true); center.removeVariable(context,structGroupTag); } diminishMember(context,identification,null,null,// true,true,false,false); augmentMember(context,identification,multicaster,locations,// speak,listen,authority,false); } /** * **/ public void augmentMember(String context, UNI identification, // UNL multicaster, Hashtable locations, // boolean speak, boolean listen, boolean authority) { if(context == null || identification == null) return; if(multicaster != null) multicaster = multicaster.addContext(context); if(locations == null) locations = new Hashtable(); Hashtable locs = new Hashtable(); for(Enumeration e = locations.keys();e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); location = location.addContext(context); locs.put(location,location); } locations = locs; augmentMember(context,identification,multicaster,locations,// speak,listen,authority,true); } /** * **/ private void augmentMember(String context, UNI identification, // UNL multicaster, Hashtable locations, // boolean speak, boolean listen, boolean authority, boolean send) { Place place = (Place)places.get(context); if(place == null) return; if(locations == null) locations = new Hashtable(); if(send) { center.augmentVariable(context,structGroupTag,// createMemberValue(identification,multicaster,locations,// speak,listen,authority),true); center.removeVariable(context,structGroupTag); } Member member = (Member)place.members.get(identification); if(member == null) { member = new Member(); member.identification = identification; member.multicaster = multicaster; member.locations = locations; member.speak = speak; member.listen = listen; member.authority = authority; if(multicaster != null) { center.addToContext(multicaster); } for(Enumeration e = locations.keys();e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); if(multicaster == null) center.addToContext(location); place.memberLocations.put(location,identification); } place.members.put(member.identification,member); listener.placeEntered(context,identification); } else { if(multicaster != null) { // we got a multicaster for this member if(member.multicaster == null) { // we had no multicaster before // remove all its locations from the outgoing context for(Enumeration e = member.locations.keys();// e.hasMoreElements();) center.removeFromContext((UNL)e.nextElement()); } center.addToContext(multicaster); member.multicaster = multicaster; } if(locations.size() > 0) { // locations added for(Enumeration e = locations.keys();e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); member.locations.put(location,location); place.memberLocations.put(location,identification); if(member.multicaster == null) center.addToContext(location); } } if(speak) member.speak = true; if(listen) member.listen = true; if(authority) member.authority = true; } center.removeFromContext(context,me); listener.memberChanged(context,member.identification,// member.multicaster,member.locations,// member.speak,member.listen,member.authority); } /** * **/ public void diminishMember(String context, UNI identification, // UNL multicaster, Hashtable locations, // boolean speak, boolean listen, boolean authority) { if(context == null || identification == null) return; if(multicaster != null) multicaster = multicaster.addContext(context); if(locations == null) locations = new Hashtable(); Hashtable locs = new Hashtable(); for(Enumeration e = locations.keys();e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); location = location.addContext(context); locs.put(location,location); } locations = locs; if(!speak && !listen && !authority) { speak = true; listen = true; } diminishMember(context,identification,multicaster,locations,// speak,listen,authority,true); } /** * **/ private void diminishMember(String context, UNI identification, // UNL multicaster, Hashtable locations, // boolean speak, boolean listen, boolean authority, boolean send) { Place place = (Place)places.get(context); if(place == null) return; if(locations == null) locations = new Hashtable(); if(send) { center.diminishVariable(context,structGroupTag,// createMemberValue(identification,multicaster,locations,// speak,listen,authority),true); center.removeVariable(context,structGroupTag); } Member member = (Member)place.members.get(identification); if(member != null) { if(multicaster == null && locations.size() <= 0 && // speak && listen && !authority) { // remove the complete member listener.placeLeft(context,identification); place.members.remove(identification); for(Enumeration e = member.locations.keys();// e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); place.memberLocations.remove(location); center.removeFromContext(location); } } else { // remove parts of the member if(multicaster != null && // member.multicaster != null && // member.multicaster.equals(multicaster)) { // remove its multicaster member.multicaster = null; for(Enumeration e = member.locations.keys();// e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); center.addToContext(location); } } for(Enumeration e = locations.keys();e.hasMoreElements();) { UNL location = (UNL)e.nextElement(); member.locations.remove(location); place.memberLocations.remove(location); center.removeFromContext(location); } if(speak) member.speak = false; if(listen) member.listen = false; if(authority) member.authority = false; listener.memberChanged(context,member.identification,// member.multicaster,member.locations,// member.speak,member.listen,member.authority); } } } /** * **/ public Enumeration getMembers(String context) { if(context == null) return null; Place place = (Place)places.get(context); if(place == null) return null; return place.members.keys(); } /** * **/ public UNL getMulticaster(String context, UNI identification) { if(context == null || identification == null) return null; Place place = (Place)places.get(context); if(place == null) return null; Member member = (Member)place.members.get(identification); if(member == null) return null; return member.multicaster; } /** * **/ public Enumeration getLocations(String context, UNI identification) { if(context == null || identification == null) return null; Place place = (Place)places.get(context); if(place == null) return null; Member member = (Member)place.members.get(identification); if(member == null) return null; return member.locations.keys(); } /** * **/ public UNL getLastSender(String context, UNI identification) { if(context == null || identification == null) return null; Place place = (Place)places.get(context); if(place == null) return null; Member member = (Member)place.members.get(identification); if(member == null) return null; return member.lastSender; } /** * **/ public boolean isAuthority(String context, UNI identification) { if(context == null || identification == null) return false; Place place = (Place)places.get(context); if(place == null) return false; Member member = (Member)place.members.get(identification); if(member == null) return false; return member.authority; } /** * **/ public boolean speaks(String context, UNI identification) { if(context == null || identification == null) return false; Place place = (Place)places.get(context); if(place == null) return false; Member member = (Member)place.members.get(identification); if(member == null) return false; return member.speak; } /** * **/ public boolean listens(String context, UNI identification) { if(context == null || identification == null) return false; Place place = (Place)places.get(context); if(place == null) return false; Member member = (Member)place.members.get(identification); if(member == null) return false; return member.listen; } /** * **/ public void acceptPlace(UNL introducer) { if(introducer == null) return; introducer = introducer.withoutContext(); acceptPlaces.put(introducer,introducer); } /** * **/ public String createPlace(String context, boolean allowExternals, // boolean speakersAddSpeakers, boolean speakersAddListeners, // boolean listenersAddListeners, // boolean speakersRemoveSpeakers, boolean speakersRemoveListeners) { if(context == null) context = me.toString(); Place place = (Place)places.get(context); if(place != null) return context; center.createContext(context); place = new Place(); if(allowExternals || speakersAddSpeakers || speakersAddListeners || // listenersAddListeners || // speakersRemoveSpeakers || speakersRemoveListeners) { place.allowExternals = allowExternals; place.speakersAddSpeakers = speakersAddSpeakers; place.speakersAddListeners = speakersAddListeners; place.listenersAddListeners = listenersAddListeners; place.speakersRemoveSpeakers = speakersRemoveSpeakers; place.speakersRemoveListeners = speakersRemoveListeners; center.assignVariable(context,propertiesGroupTag,// getGroupProperties(allowExternals,// speakersAddSpeakers,speakersAddListeners,// listenersAddListeners,// speakersRemoveSpeakers,speakersRemoveListeners),true); } places.put(context,place); Hashtable locations = new Hashtable(); locations.put(me,me); assignMember(context,new UNI(me),null,locations,// false,false,true,false); return context; } /** * **/ public void setPlaceProperties(String context, boolean allowExternals, // boolean speakersAddSpeakers, boolean speakersAddListeners, // boolean listenersAddListeners, // boolean speakersRemoveSpeakers, boolean speakersRemoveListeners) { if(context == null) return; Place place = (Place)places.get(context); if(place == null) return; place.allowExternals = allowExternals; place.speakersAddSpeakers = speakersAddSpeakers; place.speakersAddListeners = speakersAddListeners; place.listenersAddListeners = listenersAddListeners; place.speakersRemoveSpeakers = speakersRemoveSpeakers; place.speakersRemoveListeners = speakersRemoveListeners; center.assignVariable(context,propertiesGroupTag,// getGroupProperties(allowExternals,// speakersAddSpeakers,speakersAddListeners,// listenersAddListeners,// speakersRemoveSpeakers,speakersRemoveListeners),true); } /** * **/ public void send(String context, String message) { center.send(context,conversationTag,message); } /** * **/ public void send(UNL target, String message) { UNL[] user = center.getLocations(target); if(user == null || user.length <= 0) { user = new UNL[1]; user[0] = target; } for(int i = 0;i < user.length;++i) try { center.send(user[i],conversationTag,message); } catch(PSYCDeliveryException e) { } } /** * **/ public void sendPager(UNL target, String message) { UNL[] user = center.getLocations(target); if(user == null || user.length <= 0) { user = new UNL[1]; user[0] = target; } for(int i = 0;i < user.length;++i) try { center.send(user[i],conversationPagerTag,message); } catch(PSYCDeliveryException e) { } } }