diff options
Diffstat (limited to 'src/org/jivesoftware/smackx/GatewayManager.java')
-rw-r--r-- | src/org/jivesoftware/smackx/GatewayManager.java | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/org/jivesoftware/smackx/GatewayManager.java b/src/org/jivesoftware/smackx/GatewayManager.java new file mode 100644 index 0000000..eee9cfc --- /dev/null +++ b/src/org/jivesoftware/smackx/GatewayManager.java @@ -0,0 +1,199 @@ +package org.jivesoftware.smackx; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.jivesoftware.smack.Connection; +import org.jivesoftware.smack.Roster; +import org.jivesoftware.smack.RosterEntry; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.packet.DiscoverInfo; +import org.jivesoftware.smackx.packet.DiscoverItems; +import org.jivesoftware.smackx.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.packet.DiscoverItems.Item; + +/** + * This class is the general entry point to gateway interaction (XEP-0100). + * This class discovers available gateways on the users servers, and + * can give you also a list of gateways the you user is registered with which + * are not on his server. All actual interaction with a gateway is handled in the + * class {@see Gateway}. + * @author Till Klocke + * + */ +public class GatewayManager { + + private static Map<Connection,GatewayManager> instances = + new HashMap<Connection,GatewayManager>(); + + private ServiceDiscoveryManager sdManager; + + private Map<String,Gateway> localGateways = new HashMap<String,Gateway>(); + + private Map<String,Gateway> nonLocalGateways = new HashMap<String,Gateway>(); + + private Map<String,Gateway> gateways = new HashMap<String,Gateway>(); + + private Connection connection; + + private Roster roster; + + private GatewayManager(){ + + } + + /** + * Creates a new instance of GatewayManager + * @param connection + * @throws XMPPException + */ + private GatewayManager(Connection connection) throws XMPPException{ + this.connection = connection; + this.roster = connection.getRoster(); + sdManager = ServiceDiscoveryManager.getInstanceFor(connection); + } + + /** + * Loads all gateways the users server offers + * @throws XMPPException + */ + private void loadLocalGateways() throws XMPPException{ + DiscoverItems items = sdManager.discoverItems(connection.getHost()); + Iterator<Item> iter = items.getItems(); + while(iter.hasNext()){ + String itemJID = iter.next().getEntityID(); + discoverGateway(itemJID); + } + } + + /** + * Discovers {@link DiscoveryInfo} and {@link DiscoveryInfo.Identity} of a gateway + * and creates a {@link Gateway} object representing this gateway. + * @param itemJID + * @throws XMPPException + */ + private void discoverGateway(String itemJID) throws XMPPException{ + DiscoverInfo info = sdManager.discoverInfo(itemJID); + Iterator<Identity> i = info.getIdentities(); + + while(i.hasNext()){ + Identity identity = i.next(); + String category = identity.getCategory(); + if(category.toLowerCase().equals("gateway")){ + gateways.put(itemJID, new Gateway(connection,itemJID)); + if(itemJID.contains(connection.getHost())){ + localGateways.put(itemJID, + new Gateway(connection,itemJID,info,identity)); + } + else{ + nonLocalGateways.put(itemJID, + new Gateway(connection,itemJID,info,identity)); + } + break; + } + } + } + + /** + * Loads all getways which are in the users roster, but are not supplied by the + * users server + * @throws XMPPException + */ + private void loadNonLocalGateways() throws XMPPException{ + if(roster!=null){ + for(RosterEntry entry : roster.getEntries()){ + if(entry.getUser().equalsIgnoreCase(StringUtils.parseServer(entry.getUser())) && + !entry.getUser().contains(connection.getHost())){ + discoverGateway(entry.getUser()); + } + } + } + } + + /** + * Returns an instance of GatewayManager for the given connection. If no instance for + * this connection exists a new one is created and stored in a Map. + * @param connection + * @return an instance of GatewayManager + * @throws XMPPException + */ + public GatewayManager getInstanceFor(Connection connection) throws XMPPException{ + synchronized(instances){ + if(instances.containsKey(connection)){ + return instances.get(connection); + } + GatewayManager instance = new GatewayManager(connection); + instances.put(connection, instance); + return instance; + } + } + + /** + * Returns a list of gateways which are offered by the users server, wether the + * user is registered to them or not. + * @return a List of Gateways + * @throws XMPPException + */ + public List<Gateway> getLocalGateways() throws XMPPException{ + if(localGateways.size()==0){ + loadLocalGateways(); + } + return new ArrayList<Gateway>(localGateways.values()); + } + + /** + * Returns a list of gateways the user has in his roster, but which are offered by + * remote servers. But note that this list isn't automatically refreshed. You have to + * refresh is manually if needed. + * @return a list of gateways + * @throws XMPPException + */ + public List<Gateway> getNonLocalGateways() throws XMPPException{ + if(nonLocalGateways.size()==0){ + loadNonLocalGateways(); + } + return new ArrayList<Gateway>(nonLocalGateways.values()); + } + + /** + * Refreshes the list of gateways offered by remote servers. + * @throws XMPPException + */ + public void refreshNonLocalGateways() throws XMPPException{ + loadNonLocalGateways(); + } + + /** + * Returns a Gateway object for a given JID. Please note that it is not checked if + * the JID belongs to valid gateway. If this JID doesn't belong to valid gateway + * all operations on this Gateway object should fail with a XMPPException. But there is + * no guarantee for that. + * @param entityJID + * @return a Gateway object + */ + public Gateway getGateway(String entityJID){ + if(localGateways.containsKey(entityJID)){ + return localGateways.get(entityJID); + } + if(nonLocalGateways.containsKey(entityJID)){ + return nonLocalGateways.get(entityJID); + } + if(gateways.containsKey(entityJID)){ + return gateways.get(entityJID); + } + Gateway gateway = new Gateway(connection,entityJID); + if(entityJID.contains(connection.getHost())){ + localGateways.put(entityJID, gateway); + } + else{ + nonLocalGateways.put(entityJID, gateway); + } + gateways.put(entityJID, gateway); + return gateway; + } + +} |