• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.jivesoftware.smackx;
2 
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Map;
8 
9 import org.jivesoftware.smack.Connection;
10 import org.jivesoftware.smack.Roster;
11 import org.jivesoftware.smack.RosterEntry;
12 import org.jivesoftware.smack.XMPPException;
13 import org.jivesoftware.smack.util.StringUtils;
14 import org.jivesoftware.smackx.packet.DiscoverInfo;
15 import org.jivesoftware.smackx.packet.DiscoverItems;
16 import org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
17 import org.jivesoftware.smackx.packet.DiscoverItems.Item;
18 
19 /**
20  * This class is the general entry point to gateway interaction (XEP-0100).
21  * This class discovers available gateways on the users servers, and
22  * can give you also a list of gateways the you user is registered with which
23  * are not on his server. All actual interaction with a gateway is handled in the
24  * class {@see Gateway}.
25  * @author Till Klocke
26  *
27  */
28 public class GatewayManager {
29 
30 	private static Map<Connection,GatewayManager> instances =
31 		new HashMap<Connection,GatewayManager>();
32 
33 	private ServiceDiscoveryManager sdManager;
34 
35 	private Map<String,Gateway> localGateways = new HashMap<String,Gateway>();
36 
37 	private Map<String,Gateway> nonLocalGateways = new HashMap<String,Gateway>();
38 
39 	private Map<String,Gateway> gateways = new HashMap<String,Gateway>();
40 
41 	private Connection connection;
42 
43 	private Roster roster;
44 
GatewayManager()45 	private GatewayManager(){
46 
47 	}
48 
49 	/**
50 	 * Creates a new instance of GatewayManager
51 	 * @param connection
52 	 * @throws XMPPException
53 	 */
GatewayManager(Connection connection)54 	private GatewayManager(Connection connection) throws XMPPException{
55 		this.connection = connection;
56 		this.roster = connection.getRoster();
57 		sdManager = ServiceDiscoveryManager.getInstanceFor(connection);
58 	}
59 
60 	/**
61 	 * Loads all gateways the users server offers
62 	 * @throws XMPPException
63 	 */
loadLocalGateways()64 	private void loadLocalGateways() throws XMPPException{
65 		DiscoverItems items = sdManager.discoverItems(connection.getHost());
66 		Iterator<Item> iter = items.getItems();
67 		while(iter.hasNext()){
68 			String itemJID = iter.next().getEntityID();
69 			discoverGateway(itemJID);
70 		}
71 	}
72 
73 	/**
74 	 * Discovers {@link DiscoveryInfo} and {@link DiscoveryInfo.Identity} of a gateway
75 	 * and creates a {@link Gateway} object representing this gateway.
76 	 * @param itemJID
77 	 * @throws XMPPException
78 	 */
discoverGateway(String itemJID)79 	private void discoverGateway(String itemJID) throws XMPPException{
80 		DiscoverInfo info = sdManager.discoverInfo(itemJID);
81 		Iterator<Identity> i = info.getIdentities();
82 
83 		while(i.hasNext()){
84 			Identity identity = i.next();
85 			String category = identity.getCategory();
86 			if(category.toLowerCase().equals("gateway")){
87 				gateways.put(itemJID, new Gateway(connection,itemJID));
88 				if(itemJID.contains(connection.getHost())){
89 					localGateways.put(itemJID,
90 							new Gateway(connection,itemJID,info,identity));
91 				}
92 				else{
93 					nonLocalGateways.put(itemJID,
94 							new Gateway(connection,itemJID,info,identity));
95 				}
96 				break;
97 			}
98 		}
99 	}
100 
101 	/**
102 	 * Loads all getways which are in the users roster, but are not supplied by the
103 	 * users server
104 	 * @throws XMPPException
105 	 */
loadNonLocalGateways()106 	private void loadNonLocalGateways() throws XMPPException{
107 		if(roster!=null){
108 			for(RosterEntry entry : roster.getEntries()){
109 				if(entry.getUser().equalsIgnoreCase(StringUtils.parseServer(entry.getUser())) &&
110 						!entry.getUser().contains(connection.getHost())){
111 					discoverGateway(entry.getUser());
112 				}
113 			}
114 		}
115 	}
116 
117 	/**
118 	 * Returns an instance of GatewayManager for the given connection. If no instance for
119 	 * this connection exists a new one is created and stored in a Map.
120 	 * @param connection
121 	 * @return an instance of GatewayManager
122 	 * @throws XMPPException
123 	 */
getInstanceFor(Connection connection)124 	public GatewayManager getInstanceFor(Connection connection) throws XMPPException{
125 		synchronized(instances){
126 			if(instances.containsKey(connection)){
127 				return instances.get(connection);
128 			}
129 			GatewayManager instance = new GatewayManager(connection);
130 			instances.put(connection, instance);
131 			return instance;
132 		}
133 	}
134 
135 	/**
136 	 * Returns a list of gateways which are offered by the users server, wether the
137 	 * user is registered to them or not.
138 	 * @return a List of Gateways
139 	 * @throws XMPPException
140 	 */
getLocalGateways()141 	public List<Gateway> getLocalGateways() throws XMPPException{
142 		if(localGateways.size()==0){
143 			loadLocalGateways();
144 		}
145 		return new ArrayList<Gateway>(localGateways.values());
146 	}
147 
148 	/**
149 	 * Returns a list of gateways the user has in his roster, but which are offered by
150 	 * remote servers. But note that this list isn't automatically refreshed. You have to
151 	 * refresh is manually if needed.
152 	 * @return a list of gateways
153 	 * @throws XMPPException
154 	 */
getNonLocalGateways()155 	public List<Gateway> getNonLocalGateways() throws XMPPException{
156 		if(nonLocalGateways.size()==0){
157 			loadNonLocalGateways();
158 		}
159 		return new ArrayList<Gateway>(nonLocalGateways.values());
160 	}
161 
162 	/**
163 	 * Refreshes the list of gateways offered by remote servers.
164 	 * @throws XMPPException
165 	 */
refreshNonLocalGateways()166 	public void refreshNonLocalGateways() throws XMPPException{
167 		loadNonLocalGateways();
168 	}
169 
170 	/**
171 	 * Returns a Gateway object for a given JID. Please note that it is not checked if
172 	 * the JID belongs to valid gateway. If this JID doesn't belong to valid gateway
173 	 * all operations on this Gateway object should fail with a XMPPException. But there is
174 	 * no guarantee for that.
175 	 * @param entityJID
176 	 * @return a Gateway object
177 	 */
getGateway(String entityJID)178 	public Gateway getGateway(String entityJID){
179 		if(localGateways.containsKey(entityJID)){
180 			return localGateways.get(entityJID);
181 		}
182 		if(nonLocalGateways.containsKey(entityJID)){
183 			return nonLocalGateways.get(entityJID);
184 		}
185 		if(gateways.containsKey(entityJID)){
186 			return gateways.get(entityJID);
187 		}
188 		Gateway gateway = new Gateway(connection,entityJID);
189 		if(entityJID.contains(connection.getHost())){
190 			localGateways.put(entityJID, gateway);
191 		}
192 		else{
193 			nonLocalGateways.put(entityJID, gateway);
194 		}
195 		gateways.put(entityJID, gateway);
196 		return gateway;
197 	}
198 
199 }
200