001/**
002 *
003 * Copyright 2014 Georg Lukas.
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 */
017
018package org.jivesoftware.smackx.iqversion;
019
020import java.util.Collections;
021import java.util.Map;
022import java.util.WeakHashMap;
023
024import org.jivesoftware.smack.SmackException.NotConnectedException;
025import org.jivesoftware.smack.XMPPConnection;
026import org.jivesoftware.smack.Manager;
027import org.jivesoftware.smack.PacketListener;
028import org.jivesoftware.smack.filter.AndFilter;
029import org.jivesoftware.smack.filter.IQTypeFilter;
030import org.jivesoftware.smack.filter.PacketTypeFilter;
031import org.jivesoftware.smack.packet.IQ.Type;
032import org.jivesoftware.smack.packet.Packet;
033import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
034import org.jivesoftware.smackx.iqversion.packet.Version;
035
036/**
037 * A Version Manager that automatically responds to version IQs with a predetermined reply.
038 *
039 * <p>
040 * The VersionManager takes care of handling incoming version request IQs, according to
041 * XEP-0092 (Software Version). You can configure the version reply for a given connection
042 * by running the following code:
043 * </p>
044 *
045 * <pre>
046 * Version MY_VERSION = new Version("My Little XMPP Application", "v1.23", "OS/2 32-bit");
047 * VersionManager.getInstanceFor(mConnection).setVersion(MY_VERSION);
048 * </pre>
049 *
050 * @author Georg Lukas
051 */
052public class VersionManager extends Manager {
053    private static final Map<XMPPConnection, VersionManager> instances =
054            Collections.synchronizedMap(new WeakHashMap<XMPPConnection, VersionManager>());
055
056    private Version own_version;
057
058    private VersionManager(final XMPPConnection connection) {
059        super(connection);
060        instances.put(connection, this);
061
062        ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
063        sdm.addFeature(Version.NAMESPACE);
064
065        connection.addPacketListener(new PacketListener() {
066            /**
067             * Sends a Version reply on request
068             * @throws NotConnectedException 
069             */
070            public void processPacket(Packet packet) throws NotConnectedException {
071                if (own_version == null)
072                    return;
073
074                Version reply = new Version(own_version);
075                reply.setPacketID(packet.getPacketID());
076                reply.setTo(packet.getFrom());
077                connection().sendPacket(reply);
078            }
079        }
080        , new AndFilter(new PacketTypeFilter(Version.class), new IQTypeFilter(Type.GET)));
081    }
082
083    public static synchronized VersionManager getInstanceFor(XMPPConnection connection) {
084        VersionManager versionManager = instances.get(connection);
085
086        if (versionManager == null) {
087            versionManager = new VersionManager(connection);
088        }
089
090        return versionManager;
091    }
092
093    public void setVersion(Version v) {
094        own_version = v;
095    }
096}