/** * $RCSfile: ,v $ * $Revision: $ * $Date: $ * * Copyright (C) 2004-2011 Jive Software. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.sparkimpl.plugin.gateways.transports; import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.SmackConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.Registration; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.PrivateDataManager; import org.jivesoftware.smackx.ServiceDiscoveryManager; import org.jivesoftware.smackx.packet.DiscoverInfo; import org.jivesoftware.spark.SparkManager; import org.jivesoftware.spark.util.TaskEngine; import org.jivesoftware.spark.util.log.Log; import org.jivesoftware.sparkimpl.plugin.gateways.GatewayPrivateData; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * Handles some basic handling of */ public class TransportUtils { private static Map<String, Transport> transports = new HashMap<String, Transport>(); private static GatewayPrivateData gatewayPreferences; private TransportUtils() { } static { PrivateDataManager.addPrivateDataProvider(GatewayPrivateData.ELEMENT, GatewayPrivateData.NAMESPACE, new GatewayPrivateData.ConferencePrivateDataProvider()); final Runnable loadGateways = new Runnable() { public void run() { PrivateDataManager pdm = SparkManager.getSessionManager().getPersonalDataManager(); gatewayPreferences = null; //Re: SPARK-1483 comment the loop as it causes Out Of Memory (infinite loop) if preferences not found //If really necessary to try more times, a Thread Pool may be used: java ScheduledThreadPoolExecutor for example //while (gatewayPreferences == null){ try { gatewayPreferences = (GatewayPrivateData)pdm.getPrivateData(GatewayPrivateData.ELEMENT, GatewayPrivateData.NAMESPACE); } catch (XMPPException e) { Log.error("Unable to load private data for Gateways", e); } //} } }; TaskEngine.getInstance().submit(loadGateways); } public static boolean autoJoinService(String serviceName) { if (gatewayPreferences != null) { return gatewayPreferences.autoLogin(serviceName); }else{ return false; } } public static void setAutoJoin(String serviceName, boolean autoJoin) { if (gatewayPreferences != null) { gatewayPreferences.addService(serviceName, autoJoin); PrivateDataManager pdm = SparkManager.getSessionManager().getPersonalDataManager(); try { pdm.setPrivateData(gatewayPreferences); } catch (XMPPException e) { Log.error(e); } } else { Log.warning("Cannot set privacy data as gatewayPreferences is NULL"); } } public static Transport getTransport(String serviceName) { // Return transport. if (transports.containsKey(serviceName)) { return transports.get(serviceName); } return null; } /** * Returns true if the jid is from a gateway. * @param jid the jid. * @return true if the jid is from a gateway. */ public static boolean isFromGateway(String jid) { jid = StringUtils.parseBareAddress(jid); String serviceName = StringUtils.parseServer(jid); return transports.containsKey(serviceName); } public static void addTransport(String serviceName, Transport transport) { transports.put(serviceName, transport); } public static Collection<Transport> getTransports() { return transports.values(); } /** * Checks if the user is registered with a gateway. * * @param con the XMPPConnection. * @param transport the transport. * @return true if the user is registered with the transport. */ public static boolean isRegistered(XMPPConnection con, Transport transport) { if (!con.isConnected()) { return false; } ServiceDiscoveryManager discoveryManager = ServiceDiscoveryManager.getInstanceFor(con); try { DiscoverInfo info = discoveryManager.discoverInfo(transport.getServiceName()); return info.containsFeature("jabber:iq:registered"); } catch (XMPPException e) { Log.error(e); } return false; } /** * Registers a user with a gateway. * * @param con the XMPPConnection. * @param gatewayDomain the domain of the gateway (service name) * @param username the username. * @param password the password. * @param nickname the nickname. * @throws XMPPException thrown if there was an issue registering with the gateway. */ public static void registerUser(XMPPConnection con, String gatewayDomain, String username, String password, String nickname) throws XMPPException { Registration registration = new Registration(); registration.setType(IQ.Type.SET); registration.setTo(gatewayDomain); registration.addExtension(new GatewayRegisterExtension()); Map<String, String> attributes = new HashMap<String, String>(); if (username != null) { attributes.put("username", username); } if (password != null) { attributes.put("password", password); } if (nickname != null) { attributes.put("nick", nickname); } registration.setAttributes(attributes); PacketCollector collector = con.createPacketCollector(new PacketIDFilter(registration.getPacketID())); con.sendPacket(registration); IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("Server timed out"); } if (response.getType() == IQ.Type.ERROR) { throw new XMPPException("Error registering user", response.getError()); } } /** * @param con the XMPPConnection. * @param gatewayDomain the domain of the gateway (service name) * @throws XMPPException thrown if there was an issue unregistering with the gateway. */ public static void unregister(XMPPConnection con, String gatewayDomain) throws XMPPException { Registration registration = new Registration(); registration.setType(IQ.Type.SET); registration.setTo(gatewayDomain); Map<String,String> map = new HashMap<String,String>(); map.put("remove", ""); registration.setAttributes(map); PacketCollector collector = con.createPacketCollector(new PacketIDFilter(registration.getPacketID())); con.sendPacket(registration); IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("Server timed out"); } if (response.getType() == IQ.Type.ERROR) { throw new XMPPException("Error registering user", response.getError()); } } static class GatewayRegisterExtension implements PacketExtension { public String getElementName() { return "x"; } public String getNamespace() { return "jabber:iq:gateway:register"; } public String toXML() { StringBuilder builder = new StringBuilder(); builder.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append( "\"/>"); return builder.toString(); } } }