| 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; |
| } |
| |
| } |