001/** 002 * 003 * Copyright 2015-2017 Ishan Khanna, Fernando Ramirez 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.geoloc; 018 019import java.util.Map; 020import java.util.WeakHashMap; 021 022import org.jivesoftware.smack.ConnectionCreationListener; 023import org.jivesoftware.smack.Manager; 024import org.jivesoftware.smack.SmackException.NoResponseException; 025import org.jivesoftware.smack.SmackException.NotConnectedException; 026import org.jivesoftware.smack.XMPPConnection; 027import org.jivesoftware.smack.XMPPConnectionRegistry; 028import org.jivesoftware.smack.XMPPException.XMPPErrorException; 029import org.jivesoftware.smack.packet.Message; 030 031import org.jivesoftware.smackx.geoloc.packet.GeoLocation; 032import org.jivesoftware.smackx.pubsub.LeafNode; 033import org.jivesoftware.smackx.pubsub.PayloadItem; 034import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException; 035import org.jivesoftware.smackx.pubsub.PubSubManager; 036 037import org.jxmpp.jid.Jid; 038 039public final class GeoLocationManager extends Manager { 040 041 private static final Map<XMPPConnection, GeoLocationManager> INSTANCES = new WeakHashMap<>(); 042 043 static { 044 XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { 045 @Override 046 public void connectionCreated(XMPPConnection connection) { 047 getInstanceFor(connection); 048 } 049 }); 050 } 051 052 public GeoLocationManager(XMPPConnection connection) { 053 super(connection); 054 055 } 056 057 /** 058 * Retrieves a {@link GeoLocationManager} for the specified {@link XMPPConnection}, creating one if it doesn't 059 * already exist. 060 * 061 * @param connection The connection the manager is attached to. 062 * @return The new or existing manager. 063 */ 064 public static synchronized GeoLocationManager getInstanceFor(XMPPConnection connection) { 065 GeoLocationManager geoLocationManager = INSTANCES.get(connection); 066 if (geoLocationManager == null) { 067 geoLocationManager = new GeoLocationManager(connection); 068 INSTANCES.put(connection, geoLocationManager); 069 } 070 return geoLocationManager; 071 } 072 073 public void sendGeoLocationToJid(GeoLocation geoLocation, Jid jid) throws InterruptedException, 074 NotConnectedException { 075 076 final XMPPConnection connection = connection(); 077 078 Message geoLocationMessage = new Message(jid); 079 geoLocationMessage.addExtension(geoLocation); 080 081 connection.sendStanza(geoLocationMessage); 082 083 } 084 085 /** 086 * Returns true if the message contains a GeoLocation extension. 087 * 088 * @param message the message to check if contains a GeoLocation extension or not 089 * @return a boolean indicating whether the message is a GeoLocation message 090 */ 091 public static boolean isGeoLocationMessage(Message message) { 092 return GeoLocation.from(message) != null; 093 } 094 095 /** 096 * Send geolocation through the PubSub node. 097 * 098 * @param geoLocation 099 * @throws InterruptedException 100 * @throws NotConnectedException 101 * @throws XMPPErrorException 102 * @throws NoResponseException 103 * @throws NotALeafNodeException 104 */ 105 public void sendGeolocation(GeoLocation geoLocation) 106 throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotALeafNodeException { 107 getNode().publish(new PayloadItem<GeoLocation>(geoLocation)); 108 } 109 110 /** 111 * Send empty geolocation through the PubSub node. 112 * 113 * @throws InterruptedException 114 * @throws NotConnectedException 115 * @throws XMPPErrorException 116 * @throws NoResponseException 117 * @throws NotALeafNodeException 118 */ 119 public void stopPublishingGeolocation() 120 throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotALeafNodeException { 121 GeoLocation emptyGeolocation = new GeoLocation.Builder().build(); 122 getNode().publish(new PayloadItem<GeoLocation>(emptyGeolocation)); 123 } 124 125 private LeafNode getNode() 126 throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotALeafNodeException { 127 return PubSubManager.getInstance(connection()).getOrCreateLeafNode(GeoLocation.NAMESPACE); 128 } 129 130}