1/**
2 * $RCSfile: PEPManager.java,v $
3 * $Revision: 1.4 $
4 * $Date: 2007/11/06 21:43:40 $
5 *
6 * Copyright 2003-2007 Jive Software.
7 *
8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package org.jivesoftware.smackx;
22
23import java.util.ArrayList;
24import java.util.List;
25
26import org.jivesoftware.smack.PacketListener;
27import org.jivesoftware.smack.Connection;
28import org.jivesoftware.smack.filter.PacketExtensionFilter;
29import org.jivesoftware.smack.filter.PacketFilter;
30import org.jivesoftware.smack.packet.Message;
31import org.jivesoftware.smack.packet.Packet;
32import org.jivesoftware.smack.packet.IQ.Type;
33import org.jivesoftware.smackx.packet.PEPEvent;
34import org.jivesoftware.smackx.packet.PEPItem;
35import org.jivesoftware.smackx.packet.PEPPubSub;
36
37/**
38 *
39 * Manages Personal Event Publishing (XEP-163). A PEPManager provides a high level access to
40 * pubsub personal events. It also provides an easy way
41 * to hook up custom logic when events are received from another XMPP client through PEPListeners.
42 *
43 * Use example:
44 *
45 * <pre>
46 *   PEPManager pepManager = new PEPManager(smackConnection);
47 *   pepManager.addPEPListener(new PEPListener() {
48 *       public void eventReceived(String inFrom, PEPEvent inEvent) {
49 *           LOGGER.debug("Event received: " + inEvent);
50 *       }
51 *   });
52 *
53 *   PEPProvider pepProvider = new PEPProvider();
54 *   pepProvider.registerPEPParserExtension("http://jabber.org/protocol/tune", new TuneProvider());
55 *   ProviderManager.getInstance().addExtensionProvider("event", "http://jabber.org/protocol/pubsub#event", pepProvider);
56 *
57 *   Tune tune = new Tune("jeff", "1", "CD", "My Title", "My Track");
58 *   pepManager.publish(tune);
59 * </pre>
60 *
61 * @author Jeff Williams
62 */
63public class PEPManager {
64
65    private List<PEPListener> pepListeners = new ArrayList<PEPListener>();
66
67    private Connection connection;
68
69    private PacketFilter packetFilter = new PacketExtensionFilter("event", "http://jabber.org/protocol/pubsub#event");
70    private PacketListener packetListener;
71
72    /**
73     * Creates a new PEP exchange manager.
74     *
75     * @param connection a Connection which is used to send and receive messages.
76     */
77    public PEPManager(Connection connection) {
78        this.connection = connection;
79        init();
80    }
81
82    /**
83     * Adds a listener to PEPs. The listener will be fired anytime PEP events
84     * are received from remote XMPP clients.
85     *
86     * @param pepListener a roster exchange listener.
87     */
88    public void addPEPListener(PEPListener pepListener) {
89        synchronized (pepListeners) {
90            if (!pepListeners.contains(pepListener)) {
91                pepListeners.add(pepListener);
92            }
93        }
94    }
95
96    /**
97     * Removes a listener from PEP events.
98     *
99     * @param pepListener a roster exchange listener.
100     */
101    public void removePEPListener(PEPListener pepListener) {
102        synchronized (pepListeners) {
103            pepListeners.remove(pepListener);
104        }
105    }
106
107    /**
108     * Publish an event.
109     *
110     * @param item the item to publish.
111     */
112    public void publish(PEPItem item) {
113        // Create a new message to publish the event.
114        PEPPubSub pubSub = new PEPPubSub(item);
115        pubSub.setType(Type.SET);
116        //pubSub.setFrom(connection.getUser());
117
118        // Send the message that contains the roster
119        connection.sendPacket(pubSub);
120    }
121
122    /**
123     * Fires roster exchange listeners.
124     */
125    private void firePEPListeners(String from, PEPEvent event) {
126        PEPListener[] listeners = null;
127        synchronized (pepListeners) {
128            listeners = new PEPListener[pepListeners.size()];
129            pepListeners.toArray(listeners);
130        }
131        for (int i = 0; i < listeners.length; i++) {
132            listeners[i].eventReceived(from, event);
133        }
134    }
135
136    private void init() {
137        // Listens for all roster exchange packets and fire the roster exchange listeners.
138        packetListener = new PacketListener() {
139            public void processPacket(Packet packet) {
140                Message message = (Message) packet;
141                PEPEvent event = (PEPEvent) message.getExtension("event", "http://jabber.org/protocol/pubsub#event");
142                // Fire event for roster exchange listeners
143                firePEPListeners(message.getFrom(), event);
144            };
145
146        };
147        connection.addPacketListener(packetListener, packetFilter);
148    }
149
150    public void destroy() {
151        if (connection != null)
152            connection.removePacketListener(packetListener);
153
154    }
155
156    protected void finalize() throws Throwable {
157        destroy();
158        super.finalize();
159    }
160}
161