/* * Jeti, a Java Jabber client, Copyright (C) 2001 E.S. de Boer * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For questions, comments etc, * use the website at http://jeti.jabberstudio.org * or mail/IM me at jeti@jabber.org */ package nu.fw.jeti.backend.roster; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.SwingUtilities; import nu.fw.jeti.backend.Discovery; import nu.fw.jeti.events.*; import nu.fw.jeti.jabber.Backend; import nu.fw.jeti.jabber.JID; import nu.fw.jeti.jabber.JIDStatus; import nu.fw.jeti.jabber.elements.DiscoveryInfo; import nu.fw.jeti.jabber.elements.DiscoveryItem; import nu.fw.jeti.jabber.elements.Presence; import nu.fw.jeti.util.I18N; /** * Class that controls the transports/sever from the roster. * when a new transport is added this class wil lookup information * about the transport (with Browse) and will give every item in the roster * registered with that transport the right type. * Changes in the server roster are broadcasted using the ServerListener * @see ServerListener * @see Discovery * @see Roster * @author E.S. de Boer * @version 1.0 */ //primarys wel/niet?? what about resources? public class Server implements DiscoveryListener { private JIDStatusTree jidTree = new JIDStatusTree();//serverrostertree private Backend backend; private boolean fireReady = false;//is the server roster displayed? private Map jidStatussen;//reference to rosters jidstatus cache private Map availableTransports; public Server(Backend backend) { this.backend = backend; //backend.addListener(DiscoveryListener.class,this); availableTransports = new HashMap(5); } public void addJIDStatussen(Map jidStatussen) {//adds jidstatussen from roster this.jidStatussen = jidStatussen; //System.out.println("jidstatussen added"); } public void clear() {//reset server fireReady = false; availableTransports.clear(); if(jidTree.existGroup(I18N.gettext("main.main.roster.Servers"))) { jidTree.removeGroup(jidTree.getGroup(I18N.gettext("main.main.roster.Servers"))); } } public void fire() {//fire after complete server reset for(Iterator j = backend.getListeners(ServerListener.class);j.hasNext();) { ((RosterListener)j.next()).rosterReplaced(jidTree); } fireReady = true; } public void addServerNoFire(JIDStatus jidStatus) { JIDStatusGroup jidGroup = jidTree.getGroup(I18N.gettext("main.main.roster.Servers")); PrimaryJIDStatus primary = new PrimaryJIDStatus(jidStatus.getNick(),jidStatus); jidGroup.addPrimaryJIDStatus(primary); //primary.addJIDStatus(jidStatus); //backend.browse(JID.jidFromString(jidStatus.getJID().toStringNoResource()) ,this); backend.getInfo(JID.jidFromString(jidStatus.getJID().toStringNoResource()) ,this); } public void addServer(String nick, JIDStatus jidStatus) { addServerNoBrowse(nick,jidStatus); //backend.browse(JID.jidFromString(jidStatus.getJID().toStringNoResource()),this); backend.getInfo(JID.jidFromString(jidStatus.getJID().toStringNoResource()),this); } private void addServerNoBrowse(final String nick,final JIDStatus jidStatus) {//when nick changes after browse Runnable updateAComponent = new Runnable() { public void run() { String group = I18N.gettext("main.main.roster.Servers"); JIDStatusGroup jidGroup; if(!jidTree.existGroup(group)) { jidGroup = jidTree.getGroup(group); int index = jidTree.indexOfGroup(jidGroup); for(Iterator j = backend.getListeners(ServerListener.class);j.hasNext();) {//fire group make ((RosterListener)j.next()).groupAdded(jidGroup,index); } } else jidGroup = jidTree.getGroup(group); PrimaryJIDStatus primary = jidGroup.searchPrimaryJIDStatus(nick); //if(primary == null) {//server no primarys primary = new PrimaryJIDStatus(nick,jidStatus); jidGroup.addPrimaryJIDStatus(primary); //primary.addJIDStatus(jidStatus); //jidGroup.sort(); int index = jidGroup.indexOfPrimaryJIDStatus(primary); for(Iterator j = backend.getListeners(ServerListener.class);j.hasNext();) {//fire add ((RosterListener)j.next()).primaryAdded(jidGroup,primary,index); } } } }; if(SwingUtilities.isEventDispatchThread()) { updateAComponent.run(); } else { try { SwingUtilities.invokeAndWait(updateAComponent); } catch (InterruptedException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } public void removeServer(final String nick,final JIDStatus jidStatus) {//als primary gebruik veranderen als in roster Runnable updateAComponent = new Runnable() { public void run() { JIDStatusGroup jidGroup = jidTree.getGroup(I18N.gettext("main.main.roster.Servers")); PrimaryJIDStatus primary = jidGroup.searchPrimaryJIDStatus(nick); if(primary.removeJIDStatus(jidStatus)) //primary onzin kan weg { //if(primary.isEmpty()) { int index = jidGroup.indexOfPrimaryJIDStatus(primary); jidGroup.removePrimaryJIDStatus(primary); for(Iterator j = backend.getListeners(ServerListener.class);j.hasNext();) {//fire delete ((RosterListener)j.next()).primaryDeleted(jidGroup,primary,index); } //fire remove if(jidGroup.size() < 1) {//fire group remove int index2 = jidTree.indexOfGroup(jidGroup); jidTree.removeGroup(jidGroup); for(Iterator j = backend.getListeners(ServerListener.class);j.hasNext();) {//fire group delete ((RosterListener)j.next()).groupDeleted(jidGroup,index2); } } } // else // {//fire update // int index = jidGroup.indexOfPrimaryJIDStatus(primary); // for(Iterator j = backend.getListeners(ServerListener.class);j.hasNext();) // { // ((RosterListener)j.next()).primaryUpdated(jidGroup,primary,index); // } // } } } }; if(SwingUtilities.isEventDispatchThread()) { updateAComponent.run(); } else { try { SwingUtilities.invokeAndWait(updateAComponent); } catch (InterruptedException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } private void changeNickServer(String nick, NormalJIDStatus jidStatus) {//changes nick from server nick + oldjidstatus String group = I18N.gettext("main.main.roster.Servers"); //System.out.println("update"); JIDStatusGroup jidGroup = jidTree.getGroup(group); PrimaryJIDStatus primary = jidGroup.searchPrimaryJIDStatus(jidStatus.getNick()); if(primary.removeJIDStatus(jidStatus)) //primary onzin kan weg { //if(primary.isEmpty()) { //int index = jidGroup.indexOfPrimaryJIDStatus(primary); jidGroup.removePrimaryJIDStatus(primary); } } jidStatus.setNick(nick); // if(!jidTree.existGroup(group)) // { // jidGroup = jidTree.getGroup(group); // //int index = jidTree.indexOfGroup(jidGroup); // } // else jidGroup = jidTree.getGroup(group); //JIDPrimaryStatus primary = jidGroup.searchPrimaryJIDStatus(nick); //if(primary == null) {//server no primarys primary = new PrimaryJIDStatus(nick,jidStatus); jidGroup.addPrimaryJIDStatus(primary); //primary.addJIDStatus(jidStatus); //jidGroup.sort(); //int index = jidGroup.indexOfJIDPrimaryStatus(primary); } } //------------------------------Presence event------------------------------------\\ public void showChange(JIDStatus jidstatus) {//als primary gebruik veranderen als in roster //System.out.println("server show change"); //for(Iterator i = jidstatus.getGroups();i.hasNext();) {//new jidstatus per group? final JIDStatusGroup jidGroup = jidTree.getGroup(I18N.gettext("main.main.roster.Servers")); final PrimaryJIDStatus primary = jidGroup.searchPrimaryJIDStatus(jidstatus.getNick()); if(primary!=null) {//no status change after remove if(!jidstatus.isOnline() && !((NormalJIDStatus)jidstatus).isForcedOffline())new AutoReconnect(backend,jidstatus.getJID()); Runnable updateAComponent = new Runnable() { public void run() { int index = jidGroup.indexOfPrimaryJIDStatus(primary); for(Iterator j = backend.getListeners(ServerListener.class);j.hasNext();) { ((RosterListener)j.next()).primaryUpdated(jidGroup,primary,index); } } }; try { SwingUtilities.invokeAndWait(updateAComponent); } catch (InterruptedException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } public void discoveryItemResult(JID jid, DiscoveryItem browseItem){} public void discoveryInfoResult(JID jid, DiscoveryInfo browseItem) { //System.out.println("browse" + jid + browseItem); NormalJIDStatus jidStatus = (NormalJIDStatus) backend.getJIDStatus(jid); if(jidStatus == null) { System.out.println(jid + " is unknown jidstatus"); return; } try {//if transport has no nick/ jid as nick set nick to name of browseitem if(browseItem.getName() != null) { JID nick = JID.checkedJIDFromString(jidStatus.getNick()); if(nick == null || nick.equals(jid)) { if(fireReady) { removeServer(jidStatus.getNick(),jidStatus); jidStatus.setNick(browseItem.getName()); addServerNoBrowse(browseItem.getName(), jidStatus); } else changeNickServer(browseItem.getName(), jidStatus); } } } catch (Exception e) { //nick already correct} } String type = browseItem.getType(); if(type == null) type = "unknown"; availableTransports.put(type, jidStatus); if(jidStatus.getType().equals("jabber") && !type.equals("jabber")) {//add type to jidstatusen in roster updateTypes(jidStatus, type); } //jidStatus.setNamespaces(browseItem.getNamespaces()); } /* public void browseResult(IQBrowse browseItem) { //System.out.println("browse"); NormalJIDStatus jidStatus = (NormalJIDStatus) Backend.getJIDStatus(browseItem.getJID()); if(jidStatus == null) { System.out.println(browseItem.getJID() + " is unknown jidstatus"); return; } try {//if transport has no nick/ jid for nick set nick to name of browseitem if(browseItem.getName() != null) { JID nick = JID.checkedJIDFromString(jidStatus.getNick()); if(nick == null || nick.equals(browseItem.getJID())) { if(fireReady) { removeServer(jidStatus.getNick(),jidStatus); jidStatus.setNick(browseItem.getName()); addServerNoBrowse(browseItem.getName(), jidStatus); } else changeNickServer(browseItem.getName(), jidStatus); } } } catch (Exception e){} String type = browseItem.getType(); availableTransports.put(type, jidStatus); if(type == null) type = "unknown"; if(jidStatus.getType().equals("jabber") && !type.equals("jabber")) {//add type to jidstatusen in roster updateTypes(jidStatus, type); } jidStatus.setNamespaces(browseItem.getNamespaces()); } */ private void updateTypes(NormalJIDStatus jidStatus, String type) { jidStatus.setType(type); //System.out.println("type changed"); String server = jidStatus.getJID().getDomain(); //System.out.println(server); for(Iterator i = jidStatussen.values().iterator();i.hasNext();) { NormalJIDStatus ji =(NormalJIDStatus) i.next(); //System.out.println(ji); if(ji.getJID().getDomain().equals(server)) {//server van j == changed server ji.setType(type); /* for(Iterator i2 = ji.getGroups();i2.hasNext();) {//new jidstatus per group? JIDGroup2 jidGroup = jidTree.getGroup((String)i2.next()); JIDPrimaryStatus primary = jidGroup.searchPrimaryJIDStatus(ji.getNick()); int index = jidGroup.indexOfJIDPrimaryStatus(primary); for(Iterator j = backend.getListeners(RosterModelListener.class);j.hasNext();) { ((RosterModelListener)j.next()).primaryUpdated(jidGroup,primary,index); } } */ } } } public Map getAvailableTransports() { return availableTransports; } } class AutoReconnect extends Thread implements PresenceListener , StatusChangeListener { private Backend backend; private volatile boolean connect = true; private JID jid; public AutoReconnect(Backend backend,JID jid) { this.backend = backend; this.jid = jid; backend.addListener(PresenceListener.class, this); backend.addListener(StatusChangeListener.class, this); start(); } public void ownPresenceChanged(int show, String status) {} public void connectionChanged(boolean online) {//stop reconnecting when gone offline if(!online)exit(); } public void exit() { connect = false; interrupt(); } public void presenceChanged(Presence presence) { if(presence.getShow()!=Presence.UNAVAILABLE)exit(); } public void run() { boolean connected=false; while(connect) { backend.send(new Presence(jid,backend.getStatus(),null)); if(connected) break; try { Thread.sleep(600000); } catch (InterruptedException e){} } backend.removeListener(PresenceListener.class, this); backend.removeListener(StatusChangeListener.class, this); } } /* * Overrides for emacs * Local variables: * tab-width: 4 * End: */