aboutsummaryrefslogtreecommitdiff
path: root/src/org/jivesoftware/smackx/GatewayManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jivesoftware/smackx/GatewayManager.java')
-rw-r--r--src/org/jivesoftware/smackx/GatewayManager.java199
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;
+ }
+
+}