aboutsummaryrefslogtreecommitdiff
path: root/src/org/jivesoftware/smack/PrivacyListManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jivesoftware/smack/PrivacyListManager.java')
-rw-r--r--src/org/jivesoftware/smack/PrivacyListManager.java467
1 files changed, 467 insertions, 0 deletions
diff --git a/src/org/jivesoftware/smack/PrivacyListManager.java b/src/org/jivesoftware/smack/PrivacyListManager.java
new file mode 100644
index 0000000..4dcc9e1
--- /dev/null
+++ b/src/org/jivesoftware/smack/PrivacyListManager.java
@@ -0,0 +1,467 @@
+/**
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2006-2007 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.smack;
+
+import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.packet.Privacy;
+import org.jivesoftware.smack.packet.PrivacyItem;
+
+import java.util.*;
+
+/**
+ * A PrivacyListManager is used by XMPP clients to block or allow communications from other
+ * users. Use the manager to: <ul>
+ * <li>Retrieve privacy lists.
+ * <li>Add, remove, and edit privacy lists.
+ * <li>Set, change, or decline active lists.
+ * <li>Set, change, or decline the default list (i.e., the list that is active by default).
+ * </ul>
+ * Privacy Items can handle different kind of permission communications based on JID, group,
+ * subscription type or globally (@see PrivacyItem).
+ *
+ * @author Francisco Vives
+ */
+public class PrivacyListManager {
+
+ // Keep the list of instances of this class.
+ private static Map<Connection, PrivacyListManager> instances = Collections
+ .synchronizedMap(new WeakHashMap<Connection, PrivacyListManager>());
+
+ private Connection connection;
+ private final List<PrivacyListListener> listeners = new ArrayList<PrivacyListListener>();
+ PacketFilter packetFilter = new AndFilter(new IQTypeFilter(IQ.Type.SET),
+ new PacketExtensionFilter("query", "jabber:iq:privacy"));
+
+ static {
+ // Create a new PrivacyListManager on every established connection. In the init()
+ // method of PrivacyListManager, we'll add a listener that will delete the
+ // instance when the connection is closed.
+ Connection.addConnectionCreationListener(new ConnectionCreationListener() {
+ public void connectionCreated(Connection connection) {
+ new PrivacyListManager(connection);
+ }
+ });
+ }
+ /**
+ * Creates a new privacy manager to maintain the communication privacy. Note: no
+ * information is sent to or received from the server until you attempt to
+ * get or set the privacy communication.<p>
+ *
+ * @param connection the XMPP connection.
+ */
+ private PrivacyListManager(Connection connection) {
+ this.connection = connection;
+ this.init();
+ }
+
+ /** Answer the connection userJID that owns the privacy.
+ * @return the userJID that owns the privacy
+ */
+ private String getUser() {
+ return connection.getUser();
+ }
+
+ /**
+ * Initializes the packet listeners of the connection that will notify for any set privacy
+ * package.
+ */
+ private void init() {
+ // Register the new instance and associate it with the connection
+ instances.put(connection, this);
+ // Add a listener to the connection that removes the registered instance when
+ // the connection is closed
+ connection.addConnectionListener(new ConnectionListener() {
+ public void connectionClosed() {
+ // Unregister this instance since the connection has been closed
+ instances.remove(connection);
+ }
+
+ public void connectionClosedOnError(Exception e) {
+ // ignore
+ }
+
+ public void reconnectionFailed(Exception e) {
+ // ignore
+ }
+
+ public void reconnectingIn(int seconds) {
+ // ignore
+ }
+
+ public void reconnectionSuccessful() {
+ // ignore
+ }
+ });
+
+ connection.addPacketListener(new PacketListener() {
+ public void processPacket(Packet packet) {
+
+ if (packet == null || packet.getError() != null) {
+ return;
+ }
+ // The packet is correct.
+ Privacy privacy = (Privacy) packet;
+
+ // Notifies the event to the listeners.
+ synchronized (listeners) {
+ for (PrivacyListListener listener : listeners) {
+ // Notifies the created or updated privacy lists
+ for (Map.Entry<String,List<PrivacyItem>> entry : privacy.getItemLists().entrySet()) {
+ String listName = entry.getKey();
+ List<PrivacyItem> items = entry.getValue();
+ if (items.isEmpty()) {
+ listener.updatedPrivacyList(listName);
+ } else {
+ listener.setPrivacyList(listName, items);
+ }
+ }
+ }
+ }
+
+ // Send a result package acknowledging the reception of a privacy package.
+
+ // Prepare the IQ packet to send
+ IQ iq = new IQ() {
+ public String getChildElementXML() {
+ return "";
+ }
+ };
+ iq.setType(IQ.Type.RESULT);
+ iq.setFrom(packet.getFrom());
+ iq.setPacketID(packet.getPacketID());
+
+ // Send create & join packet.
+ connection.sendPacket(iq);
+ }
+ }, packetFilter);
+ }
+
+ /**
+ * Returns the PrivacyListManager instance associated with a given Connection.
+ *
+ * @param connection the connection used to look for the proper PrivacyListManager.
+ * @return the PrivacyListManager associated with a given Connection.
+ */
+ public static PrivacyListManager getInstanceFor(Connection connection) {
+ return instances.get(connection);
+ }
+
+ /**
+ * Send the {@link Privacy} packet to the server in order to know some privacy content and then
+ * waits for the answer.
+ *
+ * @param requestPrivacy is the {@link Privacy} packet configured properly whose XML
+ * will be sent to the server.
+ * @return a new {@link Privacy} with the data received from the server.
+ * @exception XMPPException if the request or the answer failed, it raises an exception.
+ */
+ private Privacy getRequest(Privacy requestPrivacy) throws XMPPException {
+ // The request is a get iq type
+ requestPrivacy.setType(Privacy.Type.GET);
+ requestPrivacy.setFrom(this.getUser());
+
+ // Filter packets looking for an answer from the server.
+ PacketFilter responseFilter = new PacketIDFilter(requestPrivacy.getPacketID());
+ PacketCollector response = connection.createPacketCollector(responseFilter);
+
+ // Send create & join packet.
+ connection.sendPacket(requestPrivacy);
+
+ // Wait up to a certain number of seconds for a reply.
+ Privacy privacyAnswer =
+ (Privacy) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+ // Stop queuing results
+ response.cancel();
+
+ // Interprete the result and answer the privacy only if it is valid
+ if (privacyAnswer == null) {
+ throw new XMPPException("No response from server.");
+ }
+ else if (privacyAnswer.getError() != null) {
+ throw new XMPPException(privacyAnswer.getError());
+ }
+ return privacyAnswer;
+ }
+
+ /**
+ * Send the {@link Privacy} packet to the server in order to modify the server privacy and
+ * waits for the answer.
+ *
+ * @param requestPrivacy is the {@link Privacy} packet configured properly whose xml will be sent
+ * to the server.
+ * @return a new {@link Privacy} with the data received from the server.
+ * @exception XMPPException if the request or the answer failed, it raises an exception.
+ */
+ private Packet setRequest(Privacy requestPrivacy) throws XMPPException {
+
+ // The request is a get iq type
+ requestPrivacy.setType(Privacy.Type.SET);
+ requestPrivacy.setFrom(this.getUser());
+
+ // Filter packets looking for an answer from the server.
+ PacketFilter responseFilter = new PacketIDFilter(requestPrivacy.getPacketID());
+ PacketCollector response = connection.createPacketCollector(responseFilter);
+
+ // Send create & join packet.
+ connection.sendPacket(requestPrivacy);
+
+ // Wait up to a certain number of seconds for a reply.
+ Packet privacyAnswer = response.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+ // Stop queuing results
+ response.cancel();
+
+ // Interprete the result and answer the privacy only if it is valid
+ if (privacyAnswer == null) {
+ throw new XMPPException("No response from server.");
+ } else if (privacyAnswer.getError() != null) {
+ throw new XMPPException(privacyAnswer.getError());
+ }
+ return privacyAnswer;
+ }
+
+ /**
+ * Answer a privacy containing the list structre without {@link PrivacyItem}.
+ *
+ * @return a Privacy with the list names.
+ * @throws XMPPException if an error occurs.
+ */
+ private Privacy getPrivacyWithListNames() throws XMPPException {
+
+ // The request of the list is an empty privacy message
+ Privacy request = new Privacy();
+
+ // Send the package to the server and get the answer
+ return getRequest(request);
+ }
+
+ /**
+ * Answer the active privacy list.
+ *
+ * @return the privacy list of the active list.
+ * @throws XMPPException if an error occurs.
+ */
+ public PrivacyList getActiveList() throws XMPPException {
+ Privacy privacyAnswer = this.getPrivacyWithListNames();
+ String listName = privacyAnswer.getActiveName();
+ boolean isDefaultAndActive = privacyAnswer.getActiveName() != null
+ && privacyAnswer.getDefaultName() != null
+ && privacyAnswer.getActiveName().equals(
+ privacyAnswer.getDefaultName());
+ return new PrivacyList(true, isDefaultAndActive, listName, getPrivacyListItems(listName));
+ }
+
+ /**
+ * Answer the default privacy list.
+ *
+ * @return the privacy list of the default list.
+ * @throws XMPPException if an error occurs.
+ */
+ public PrivacyList getDefaultList() throws XMPPException {
+ Privacy privacyAnswer = this.getPrivacyWithListNames();
+ String listName = privacyAnswer.getDefaultName();
+ boolean isDefaultAndActive = privacyAnswer.getActiveName() != null
+ && privacyAnswer.getDefaultName() != null
+ && privacyAnswer.getActiveName().equals(
+ privacyAnswer.getDefaultName());
+ return new PrivacyList(isDefaultAndActive, true, listName, getPrivacyListItems(listName));
+ }
+
+ /**
+ * Answer the privacy list items under listName with the allowed and blocked permissions.
+ *
+ * @param listName the name of the list to get the allowed and blocked permissions.
+ * @return a list of privacy items under the list listName.
+ * @throws XMPPException if an error occurs.
+ */
+ private List<PrivacyItem> getPrivacyListItems(String listName) throws XMPPException {
+
+ // The request of the list is an privacy message with an empty list
+ Privacy request = new Privacy();
+ request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
+
+ // Send the package to the server and get the answer
+ Privacy privacyAnswer = getRequest(request);
+
+ return privacyAnswer.getPrivacyList(listName);
+ }
+
+ /**
+ * Answer the privacy list items under listName with the allowed and blocked permissions.
+ *
+ * @param listName the name of the list to get the allowed and blocked permissions.
+ * @return a privacy list under the list listName.
+ * @throws XMPPException if an error occurs.
+ */
+ public PrivacyList getPrivacyList(String listName) throws XMPPException {
+
+ return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
+ }
+
+ /**
+ * Answer every privacy list with the allowed and blocked permissions.
+ *
+ * @return an array of privacy lists.
+ * @throws XMPPException if an error occurs.
+ */
+ public PrivacyList[] getPrivacyLists() throws XMPPException {
+ Privacy privacyAnswer = this.getPrivacyWithListNames();
+ Set<String> names = privacyAnswer.getPrivacyListNames();
+ PrivacyList[] lists = new PrivacyList[names.size()];
+ boolean isActiveList;
+ boolean isDefaultList;
+ int index=0;
+ for (String listName : names) {
+ isActiveList = listName.equals(privacyAnswer.getActiveName());
+ isDefaultList = listName.equals(privacyAnswer.getDefaultName());
+ lists[index] = new PrivacyList(isActiveList, isDefaultList,
+ listName, getPrivacyListItems(listName));
+ index = index + 1;
+ }
+ return lists;
+ }
+
+
+ /**
+ * Set or change the active list to listName.
+ *
+ * @param listName the list name to set as the active one.
+ * @exception XMPPException if the request or the answer failed, it raises an exception.
+ */
+ public void setActiveListName(String listName) throws XMPPException {
+
+ // The request of the list is an privacy message with an empty list
+ Privacy request = new Privacy();
+ request.setActiveName(listName);
+
+ // Send the package to the server
+ setRequest(request);
+ }
+
+ /**
+ * Client declines the use of active lists.
+ *
+ * @throws XMPPException if an error occurs.
+ */
+ public void declineActiveList() throws XMPPException {
+
+ // The request of the list is an privacy message with an empty list
+ Privacy request = new Privacy();
+ request.setDeclineActiveList(true);
+
+ // Send the package to the server
+ setRequest(request);
+ }
+
+ /**
+ * Set or change the default list to listName.
+ *
+ * @param listName the list name to set as the default one.
+ * @exception XMPPException if the request or the answer failed, it raises an exception.
+ */
+ public void setDefaultListName(String listName) throws XMPPException {
+
+ // The request of the list is an privacy message with an empty list
+ Privacy request = new Privacy();
+ request.setDefaultName(listName);
+
+ // Send the package to the server
+ setRequest(request);
+ }
+
+ /**
+ * Client declines the use of default lists.
+ *
+ * @throws XMPPException if an error occurs.
+ */
+ public void declineDefaultList() throws XMPPException {
+
+ // The request of the list is an privacy message with an empty list
+ Privacy request = new Privacy();
+ request.setDeclineDefaultList(true);
+
+ // Send the package to the server
+ setRequest(request);
+ }
+
+ /**
+ * The client has created a new list. It send the new one to the server.
+ *
+ * @param listName the list that has changed its content.
+ * @param privacyItems a List with every privacy item in the list.
+ * @throws XMPPException if an error occurs.
+ */
+ public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
+
+ this.updatePrivacyList(listName, privacyItems);
+ }
+
+ /**
+ * The client has edited an existing list. It updates the server content with the resulting
+ * list of privacy items. The {@link PrivacyItem} list MUST contain all elements in the
+ * list (not the "delta").
+ *
+ * @param listName the list that has changed its content.
+ * @param privacyItems a List with every privacy item in the list.
+ * @throws XMPPException if an error occurs.
+ */
+ public void updatePrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
+
+ // Build the privacy package to add or update the new list
+ Privacy request = new Privacy();
+ request.setPrivacyList(listName, privacyItems);
+
+ // Send the package to the server
+ setRequest(request);
+ }
+
+ /**
+ * Remove a privacy list.
+ *
+ * @param listName the list that has changed its content.
+ * @throws XMPPException if an error occurs.
+ */
+ public void deletePrivacyList(String listName) throws XMPPException {
+
+ // The request of the list is an privacy message with an empty list
+ Privacy request = new Privacy();
+ request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
+
+ // Send the package to the server
+ setRequest(request);
+ }
+
+ /**
+ * Adds a packet listener that will be notified of any new update in the user
+ * privacy communication.
+ *
+ * @param listener a packet listener.
+ */
+ public void addListener(PrivacyListListener listener) {
+ // Keep track of the listener so that we can manually deliver extra
+ // messages to it later if needed.
+ synchronized (listeners) {
+ listeners.add(listener);
+ }
+ }
+}