Cleanup of PrivacyList API

Use Type enum instead of String for PrivacyItem's constructor. Add
getName() to PrivacyList. Remove PrivacyRule, as it just adds unnecessary
complexity spliting PrivacyItem and PrivacyRule, they belong
together. Don't mix camel-case and c-style method names. Some minor
improvements. Add parser test.
This commit is contained in:
Florian Schmaus 2014-03-10 14:45:17 +01:00
parent b489828027
commit 6110872062
7 changed files with 230 additions and 330 deletions

View File

@ -63,23 +63,20 @@ Now the client is able to show every <tt>PrivacyItem</tt> of the server and also
String groupName = <font color="green">"enemies"</font>; String groupName = <font color="green">"enemies"</font>;
ArrayList privacyItems = new ArrayList(); ArrayList privacyItems = new ArrayList();
PrivacyItem item = new PrivacyItem(PrivacyRule.<font color="navy"><i>JID</i></font>, <font color="navy">true</font>, 1); PrivacyItem item = new PrivacyItem(PrivacyItem.Type.jid, user, <font color="navy">true</font>, 1);
item.setValue(user);
privacyItems.add(item); privacyItems.add(item);
item = new PrivacyItem(PrivacyRule.<font color="navy"><i>SUBSCRIPTION</i></font>, <font color="navy">true</font>, 2); item = new PrivacyItem(PrivacyItem.Type.subscription, PrivacyItem.SUBSCRIPTION_BOTH, <font color="navy">true</font>, 2);
item.setValue(PrivacyRule.<font color="navy"><i>SUBSCRIPTION_BOTH</i></font>);
privacyItems.add(item); privacyItems.add(item);
item = new PrivacyItem(PrivacyRule.<font color="navy"><i>GROUP</i></font>, <font color="navy">false</font>, 3); item = new PrivacyItem(PrivacyItem.Type.group, groupName, <font color="navy">false</font>, 3);
item.setValue(groupName);
item.setFilterMessage(<font color="navy">true</font>); item.setFilterMessage(<font color="navy">true</font>);
privacyItems.add(item); privacyItems.add(item);
<font color="gray"><i>// Get the privacy manager for the current connection.</i></font> <font color="gray"><i>// Get the privacy manager for the current connection.</i></font>
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection); PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
<font color="gray"><i>// Create the new list.</i></font> <font color="gray"><i>// Create the new list.</i></font>
privacyManager.createPrivacyList(listName, Arrays.<i>asList</i>(privacyItems)); privacyManager.createPrivacyList(listName, privacyItems);
</pre> </pre>
</div> </div>

View File

@ -37,13 +37,13 @@ import java.util.List;
public class PrivacyList { public class PrivacyList {
/** Holds if it is an active list or not **/ /** Holds if it is an active list or not **/
private boolean isActiveList; private final boolean isActiveList;
/** Holds if it is an default list or not **/ /** Holds if it is an default list or not **/
private boolean isDefaultList; private final boolean isDefaultList;
/** Holds the list name used to print **/ /** Holds the list name used to print **/
private String listName; private final String listName;
/** Holds the list of {@see PrivacyItem} **/ /** Holds the list of {@see PrivacyItem} **/
private List<PrivacyItem> items; private final List<PrivacyItem> items;
protected PrivacyList(boolean isActiveList, boolean isDefaultList, protected PrivacyList(boolean isActiveList, boolean isDefaultList,
String listName, List<PrivacyItem> privacyItems) { String listName, List<PrivacyItem> privacyItems) {
@ -54,6 +54,10 @@ public class PrivacyList {
this.items = privacyItems; this.items = privacyItems;
} }
public String getName() {
return listName;
}
public boolean isActiveList() { public boolean isActiveList() {
return isActiveList; return isActiveList;
} }
@ -66,8 +70,4 @@ public class PrivacyList {
return items; return items;
} }
public String toString() {
return listName;
}
} }

View File

@ -28,9 +28,13 @@ import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.*; import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.IQTypeFilter;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.privacy.packet.Privacy; import org.jivesoftware.smackx.privacy.packet.Privacy;
import org.jivesoftware.smackx.privacy.packet.PrivacyItem; import org.jivesoftware.smackx.privacy.packet.PrivacyItem;
@ -46,27 +50,29 @@ import org.jivesoftware.smackx.privacy.packet.PrivacyItem;
* subscription type or globally (@see PrivacyItem). * subscription type or globally (@see PrivacyItem).
* *
* @author Francisco Vives * @author Francisco Vives
* @see <a href="http://xmpp.org/extensions/xep-0016.html">XEP-16: Privacy Lists</a>
*/ */
public class PrivacyListManager extends Manager { public class PrivacyListManager extends Manager {
public static final String NAMESPACE = "jabber:iq:privacy";
private static final PacketFilter PACKET_FILTER = new AndFilter(new IQTypeFilter(IQ.Type.SET),
new PacketExtensionFilter("query", "jabber:iq:privacy"));
// Keep the list of instances of this class. // Keep the list of instances of this class.
private static Map<XMPPConnection, PrivacyListManager> instances = Collections private static final Map<XMPPConnection, PrivacyListManager> instances = Collections
.synchronizedMap(new WeakHashMap<XMPPConnection, PrivacyListManager>()); .synchronizedMap(new WeakHashMap<XMPPConnection, PrivacyListManager>());
private final List<PrivacyListListener> listeners = new ArrayList<PrivacyListListener>(); private final List<PrivacyListListener> listeners = new ArrayList<PrivacyListListener>();
PacketFilter packetFilter = new AndFilter(new IQTypeFilter(IQ.Type.SET),
new PacketExtensionFilter("query", "jabber:iq:privacy"));
static { static {
// Create a new PrivacyListManager on every established connection. In the init() // Create a new PrivacyListManager on every established connection.
// method of PrivacyListManager, we'll add a listener that will delete the
// instance when the connection is closed.
XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener() { XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener() {
public void connectionCreated(XMPPConnection connection) { public void connectionCreated(XMPPConnection connection) {
getInstanceFor(connection); getInstanceFor(connection);
} }
}); });
} }
/** /**
* Creates a new privacy manager to maintain the communication privacy. Note: no * 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 * information is sent to or received from the server until you attempt to
@ -80,14 +86,10 @@ public class PrivacyListManager extends Manager {
instances.put(connection, this); instances.put(connection, this);
connection.addPacketListener(new PacketListener() { connection.addPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) { public void processPacket(Packet packet) {
if (packet == null || packet.getError() != null) {
return;
}
// The packet is correct.
Privacy privacy = (Privacy) packet; Privacy privacy = (Privacy) packet;
// Notifies the event to the listeners. // Notifies the event to the listeners.
synchronized (listeners) { synchronized (listeners) {
for (PrivacyListListener listener : listeners) { for (PrivacyListListener listener : listeners) {
@ -103,23 +105,13 @@ public class PrivacyListManager extends Manager {
} }
} }
} }
// 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. // Send a result package acknowledging the reception of a privacy package.
IQ iq = IQ.createResultIQ(privacy);
connection.sendPacket(iq); connection.sendPacket(iq);
} }
}, packetFilter); } }, PACKET_FILTER);
}
/** Answer the connection userJID that owns the privacy. /** Answer the connection userJID that owns the privacy.
* @return the userJID that owns the privacy * @return the userJID that owns the privacy
@ -139,7 +131,7 @@ public class PrivacyListManager extends Manager {
if (plm == null) plm = new PrivacyListManager(connection); if (plm == null) plm = new PrivacyListManager(connection);
return plm; return plm;
} }
/** /**
* Send the {@link Privacy} packet to the server in order to know some privacy content and then * Send the {@link Privacy} packet to the server in order to know some privacy content and then
* waits for the answer. * waits for the answer.
@ -176,20 +168,19 @@ public class PrivacyListManager extends Manager {
} }
/** /**
* Answer a privacy containing the list structre without {@link PrivacyItem}. * Answer a privacy containing the list structure without {@link PrivacyItem}.
* *
* @return a Privacy with the list names. * @return a Privacy with the list names.
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
private Privacy getPrivacyWithListNames() throws XMPPException { private Privacy getPrivacyWithListNames() throws XMPPException {
// The request of the list is an empty privacy message // The request of the list is an empty privacy message
Privacy request = new Privacy(); Privacy request = new Privacy();
// Send the package to the server and get the answer // Send the package to the server and get the answer
return getRequest(request); return getRequest(request);
} }
/** /**
* Answer the active privacy list. * Answer the active privacy list.
* *
@ -205,7 +196,7 @@ public class PrivacyListManager extends Manager {
privacyAnswer.getDefaultName()); privacyAnswer.getDefaultName());
return new PrivacyList(true, isDefaultAndActive, listName, getPrivacyListItems(listName)); return new PrivacyList(true, isDefaultAndActive, listName, getPrivacyListItems(listName));
} }
/** /**
* Answer the default privacy list. * Answer the default privacy list.
* *
@ -221,7 +212,7 @@ public class PrivacyListManager extends Manager {
privacyAnswer.getDefaultName()); privacyAnswer.getDefaultName());
return new PrivacyList(isDefaultAndActive, true, listName, getPrivacyListItems(listName)); return new PrivacyList(isDefaultAndActive, true, listName, getPrivacyListItems(listName));
} }
/** /**
* Answer the privacy list items under listName with the allowed and blocked permissions. * Answer the privacy list items under listName with the allowed and blocked permissions.
* *
@ -230,7 +221,6 @@ public class PrivacyListManager extends Manager {
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
private List<PrivacyItem> getPrivacyListItems(String listName) throws XMPPException { private List<PrivacyItem> getPrivacyListItems(String listName) throws XMPPException {
// The request of the list is an privacy message with an empty list // The request of the list is an privacy message with an empty list
Privacy request = new Privacy(); Privacy request = new Privacy();
request.setPrivacyList(listName, new ArrayList<PrivacyItem>()); request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
@ -240,7 +230,7 @@ public class PrivacyListManager extends Manager {
return privacyAnswer.getPrivacyList(listName); return privacyAnswer.getPrivacyList(listName);
} }
/** /**
* Answer the privacy list items under listName with the allowed and blocked permissions. * Answer the privacy list items under listName with the allowed and blocked permissions.
* *
@ -249,10 +239,9 @@ public class PrivacyListManager extends Manager {
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
public PrivacyList getPrivacyList(String listName) throws XMPPException { public PrivacyList getPrivacyList(String listName) throws XMPPException {
return new PrivacyList(false, false, listName, getPrivacyListItems(listName)); return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
} }
/** /**
* Answer every privacy list with the allowed and blocked permissions. * Answer every privacy list with the allowed and blocked permissions.
* *
@ -276,7 +265,6 @@ public class PrivacyListManager extends Manager {
return lists; return lists;
} }
/** /**
* Set or change the active list to listName. * Set or change the active list to listName.
* *
@ -284,7 +272,6 @@ public class PrivacyListManager extends Manager {
* @exception XMPPException if the request or the answer failed, it raises an exception. * @exception XMPPException if the request or the answer failed, it raises an exception.
*/ */
public void setActiveListName(String listName) throws XMPPException { public void setActiveListName(String listName) throws XMPPException {
// The request of the list is an privacy message with an empty list // The request of the list is an privacy message with an empty list
Privacy request = new Privacy(); Privacy request = new Privacy();
request.setActiveName(listName); request.setActiveName(listName);
@ -299,7 +286,6 @@ public class PrivacyListManager extends Manager {
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
public void declineActiveList() throws XMPPException { public void declineActiveList() throws XMPPException {
// The request of the list is an privacy message with an empty list // The request of the list is an privacy message with an empty list
Privacy request = new Privacy(); Privacy request = new Privacy();
request.setDeclineActiveList(true); request.setDeclineActiveList(true);
@ -315,7 +301,6 @@ public class PrivacyListManager extends Manager {
* @exception XMPPException if the request or the answer failed, it raises an exception. * @exception XMPPException if the request or the answer failed, it raises an exception.
*/ */
public void setDefaultListName(String listName) throws XMPPException { public void setDefaultListName(String listName) throws XMPPException {
// The request of the list is an privacy message with an empty list // The request of the list is an privacy message with an empty list
Privacy request = new Privacy(); Privacy request = new Privacy();
request.setDefaultName(listName); request.setDefaultName(listName);
@ -323,14 +308,13 @@ public class PrivacyListManager extends Manager {
// Send the package to the server // Send the package to the server
setRequest(request); setRequest(request);
} }
/** /**
* Client declines the use of default lists. * Client declines the use of default lists.
* *
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
public void declineDefaultList() throws XMPPException { public void declineDefaultList() throws XMPPException {
// The request of the list is an privacy message with an empty list // The request of the list is an privacy message with an empty list
Privacy request = new Privacy(); Privacy request = new Privacy();
request.setDeclineDefaultList(true); request.setDeclineDefaultList(true);
@ -338,7 +322,7 @@ public class PrivacyListManager extends Manager {
// Send the package to the server // Send the package to the server
setRequest(request); setRequest(request);
} }
/** /**
* The client has created a new list. It send the new one to the server. * The client has created a new list. It send the new one to the server.
* *
@ -347,7 +331,6 @@ public class PrivacyListManager extends Manager {
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException { public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
this.updatePrivacyList(listName, privacyItems); this.updatePrivacyList(listName, privacyItems);
} }
@ -361,7 +344,6 @@ public class PrivacyListManager extends Manager {
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
public void updatePrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException { public void updatePrivacyList(String listName, List<PrivacyItem> privacyItems) throws XMPPException {
// Build the privacy package to add or update the new list // Build the privacy package to add or update the new list
Privacy request = new Privacy(); Privacy request = new Privacy();
request.setPrivacyList(listName, privacyItems); request.setPrivacyList(listName, privacyItems);
@ -369,7 +351,7 @@ public class PrivacyListManager extends Manager {
// Send the package to the server // Send the package to the server
setRequest(request); setRequest(request);
} }
/** /**
* Remove a privacy list. * Remove a privacy list.
* *
@ -377,7 +359,6 @@ public class PrivacyListManager extends Manager {
* @throws XMPPException if an error occurs. * @throws XMPPException if an error occurs.
*/ */
public void deletePrivacyList(String listName) throws XMPPException { public void deletePrivacyList(String listName) throws XMPPException {
// The request of the list is an privacy message with an empty list // The request of the list is an privacy message with an empty list
Privacy request = new Privacy(); Privacy request = new Privacy();
request.setPrivacyList(listName, new ArrayList<PrivacyItem>()); request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
@ -385,7 +366,7 @@ public class PrivacyListManager extends Manager {
// Send the package to the server // Send the package to the server
setRequest(request); setRequest(request);
} }
/** /**
* Adds a packet listener that will be notified of any new update in the user * Adds a packet listener that will be notified of any new update in the user
* privacy communication. * privacy communication.
@ -398,5 +379,16 @@ public class PrivacyListManager extends Manager {
synchronized (listeners) { synchronized (listeners) {
listeners.add(listener); listeners.add(listener);
} }
} }
/**
* Check if the user's server supports privacy lists.
*
* @return true, if the server supports privacy lists, false otherwise.
* @throws XMPPException
*/
public boolean isSupported() throws XMPPException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(
connection().getServiceName(), NAMESPACE);
}
} }

View File

@ -19,6 +19,7 @@ package org.jivesoftware.smackx.privacy.packet;
import java.util.*; import java.util.*;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.privacy.PrivacyListManager;
/** /**
* A Privacy IQ Packet, is used by the {@link org.jivesoftware.smackx.privacy.PrivacyListManager} * A Privacy IQ Packet, is used by the {@link org.jivesoftware.smackx.privacy.PrivacyListManager}
@ -274,8 +275,8 @@ public class Privacy extends IQ {
public String getChildElementXML() { public String getChildElementXML() {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
buf.append("<query xmlns=\"jabber:iq:privacy\">"); buf.append("<query xmlns=\"" + PrivacyListManager.NAMESPACE + "\">");
// Add the active tag // Add the active tag
if (this.isDeclineActiveList()) { if (this.isDeclineActiveList()) {
buf.append("<active/>"); buf.append("<active/>");

View File

@ -30,37 +30,74 @@ package org.jivesoftware.smackx.privacy.packet;
* @author Francisco Vives * @author Francisco Vives
*/ */
public class PrivacyItem { public class PrivacyItem {
/** allow is the action associated with the item, it can allow or deny the communication. */ /**
private boolean allow; * Value for subscription type rules.
/** order is a non-negative integer that is unique among all items in the list. */ */
private int order; public static final String SUBSCRIPTION_BOTH = "both";
/** rule hold the kind of communication ([jid|group|subscription]) it will allow or block and public static final String SUBSCRIPTION_TO = "to";
* identifier to apply the action. public static final String SUBSCRIPTION_FROM = "from";
* If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID. public static final String SUBSCRIPTION_NONE = "none";
* If the type is "group", then the 'value' attribute SHOULD contain the name of a group
* in the user's roster. /** allow is the action associated with the item, it can allow or deny the communication. */
* If the type is "subscription", then the 'value' attribute MUST be one of "both", "to", private final boolean allow;
* "from", or "none". */ /** order is a non-negative integer that is unique among all items in the list. */
private PrivacyRule rule; private final int order;
/**
* Type defines if the rule is based on JIDs, roster groups or presence subscription types.
* Available values are: [jid|group|subscription]
*/
private final Type type;
/**
* The value hold the element identifier to apply the action. If the type is "jid", then the
* 'value' attribute MUST contain a valid Jabber ID. If the type is "group", then the
* 'value' attribute SHOULD contain the name of a group in the user's roster. If the type is
* "subscription", then the 'value' attribute MUST be one of "both", "to", "from", or
* "none".
*/
private final String value;
/** blocks incoming IQ stanzas. */ /** blocks incoming IQ stanzas. */
private boolean filterIQ = false; private boolean filterIQ = false;
/** filterMessage blocks incoming message stanzas. */ /** filterMessage blocks incoming message stanzas. */
private boolean filterMessage = false; private boolean filterMessage = false;
/** blocks incoming presence notifications. */ /** blocks incoming presence notifications. */
private boolean filterPresence_in = false; private boolean filterPresenceIn = false;
/** blocks outgoing presence notifications. */ /** blocks outgoing presence notifications. */
private boolean filterPresence_out = false; private boolean filterPresenceOut = false;
/**
* Creates a new fall-through privacy item.
*
* This is usually the last item in a privacy list and has no 'type' attribute.
*
* @param allow true if this is an allow item
* @param order the order of this privacy item
*/
public PrivacyItem(boolean allow, int order) {
this(null, null, allow, order);
}
/** /**
* Creates a new privacy item. * Creates a new privacy item.
* *
* If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
* If the type is "group", then the 'value' attribute SHOULD contain the name of a group
* in the user's roster.
* If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
* "from", or "none".
*
* @param type the type. * @param type the type.
* @param value the value of the privacy item
* @param allow true if this is an allow item
* @param order the order of this privacy item
*/ */
public PrivacyItem(String type, boolean allow, int order) { public PrivacyItem(Type type, String value, boolean allow, int order) {
this.setRule(PrivacyRule.fromString(type)); this.type = type;
this.setAllow(allow); this.value = value;
this.setOrder(order); this.allow = allow;
this.order = order;
} }
/** /**
@ -73,16 +110,6 @@ public class PrivacyItem {
return allow; return allow;
} }
/**
* Sets the action associated with the item, it can allow or deny the communication.
*
* @param allow indicates if the receiver allow or deny the communication.
*/
private void setAllow(boolean allow) {
this.allow = allow;
}
/** /**
* Returns whether the receiver allow or deny incoming IQ stanzas or not. * Returns whether the receiver allow or deny incoming IQ stanzas or not.
* *
@ -92,7 +119,6 @@ public class PrivacyItem {
return filterIQ; return filterIQ;
} }
/** /**
* Sets whether the receiver allows or denies incoming IQ stanzas or not. * Sets whether the receiver allows or denies incoming IQ stanzas or not.
* *
@ -102,7 +128,6 @@ public class PrivacyItem {
this.filterIQ = filterIQ; this.filterIQ = filterIQ;
} }
/** /**
* Returns whether the receiver allows or denies incoming messages or not. * Returns whether the receiver allows or denies incoming messages or not.
* *
@ -112,7 +137,6 @@ public class PrivacyItem {
return filterMessage; return filterMessage;
} }
/** /**
* Sets wheather the receiver allows or denies incoming messages or not. * Sets wheather the receiver allows or denies incoming messages or not.
* *
@ -122,47 +146,42 @@ public class PrivacyItem {
this.filterMessage = filterMessage; this.filterMessage = filterMessage;
} }
/** /**
* Returns whether the receiver allows or denies incoming presence or not. * Returns whether the receiver allows or denies incoming presence or not.
* *
* @return the iq filtering incoming presence status. * @return the iq filtering incoming presence status.
*/ */
public boolean isFilterPresence_in() { public boolean isFilterPresenceIn() {
return filterPresence_in; return filterPresenceIn;
} }
/** /**
* Sets whether the receiver allows or denies incoming presence or not. * Sets whether the receiver allows or denies incoming presence or not.
* *
* @param filterPresence_in indicates if the receiver allows or denies filtering incoming presence. * @param filterPresenceIn indicates if the receiver allows or denies filtering incoming presence.
*/ */
public void setFilterPresence_in(boolean filterPresence_in) { public void setFilterPresenceIn(boolean filterPresenceIn) {
this.filterPresence_in = filterPresence_in; this.filterPresenceIn = filterPresenceIn;
} }
/** /**
* Returns whether the receiver allows or denies incoming presence or not. * Returns whether the receiver allows or denies incoming presence or not.
* *
* @return the iq filtering incoming presence status. * @return the iq filtering incoming presence status.
*/ */
public boolean isFilterPresence_out() { public boolean isFilterPresenceOut() {
return filterPresence_out; return filterPresenceOut;
} }
/** /**
* Sets whether the receiver allows or denies outgoing presence or not. * Sets whether the receiver allows or denies outgoing presence or not.
* *
* @param filterPresence_out indicates if the receiver allows or denies filtering outgoing presence * @param filterPresenceOut indicates if the receiver allows or denies filtering outgoing presence
*/ */
public void setFilterPresence_out(boolean filterPresence_out) { public void setFilterPresenceOut(boolean filterPresenceOut) {
this.filterPresence_out = filterPresence_out; this.filterPresenceOut = filterPresenceOut;
} }
/** /**
* Returns the order where the receiver is processed. List items are processed in * Returns the order where the receiver is processed. List items are processed in
* ascending order. * ascending order.
@ -176,36 +195,6 @@ public class PrivacyItem {
return order; return order;
} }
/**
* Sets the order where the receiver is processed.
*
* The order MUST be filled and its value MUST be a non-negative integer
* that is unique among all items in the list.
*
* @param order indicates the order in the list.
*/
public void setOrder(int order) {
this.order = order;
}
/**
* Sets the element identifier to apply the action.
*
* If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
* If the type is "group", then the 'value' attribute SHOULD contain the name of a group
* in the user's roster.
* If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
* "from", or "none".
*
* @param value is the identifier to apply the action.
*/
public void setValue(String value) {
if (!(this.getRule() == null && value == null)) {
this.getRule().setValue(value);
}
}
/** /**
* Returns the type hold the kind of communication it will allow or block. * Returns the type hold the kind of communication it will allow or block.
* It MUST be filled with one of these values: jid, group or subscription. * It MUST be filled with one of these values: jid, group or subscription.
@ -213,11 +202,7 @@ public class PrivacyItem {
* @return the type of communication it represent. * @return the type of communication it represent.
*/ */
public Type getType() { public Type getType() {
if (this.getRule() == null) { return type;
return null;
} else {
return this.getRule().getType();
}
} }
/** /**
@ -232,35 +217,22 @@ public class PrivacyItem {
* @return the identifier to apply the action. * @return the identifier to apply the action.
*/ */
public String getValue() { public String getValue() {
if (this.getRule() == null) { return value;
return null;
} else {
return this.getRule().getValue();
}
} }
/** /**
* Returns whether the receiver allows or denies every kind of communication. * Returns whether the receiver allows or denies every kind of communication.
* *
* When filterIQ, filterMessage, filterPresence_in and filterPresence_out are not set * When filterIQ, filterMessage, filterPresenceIn and filterPresenceOut are not set
* the receiver will block all communications. * the receiver will block all communications.
* *
* @return the all communications status. * @return the all communications status.
*/ */
public boolean isFilterEverything() { public boolean isFilterEverything() {
return !(this.isFilterIQ() || this.isFilterMessage() || this.isFilterPresence_in() return !(this.isFilterIQ() || this.isFilterMessage() || this.isFilterPresenceIn()
|| this.isFilterPresence_out()); || this.isFilterPresenceOut());
} }
private PrivacyRule getRule() {
return rule;
}
private void setRule(PrivacyRule rule) {
this.rule = rule;
}
/** /**
* Answer an xml representation of the receiver according to the RFC 3921. * Answer an xml representation of the receiver according to the RFC 3921.
* *
@ -291,10 +263,10 @@ public class PrivacyItem {
if (this.isFilterMessage()) { if (this.isFilterMessage()) {
buf.append("<message/>"); buf.append("<message/>");
} }
if (this.isFilterPresence_in()) { if (this.isFilterPresenceIn()) {
buf.append("<presence-in/>"); buf.append("<presence-in/>");
} }
if (this.isFilterPresence_out()) { if (this.isFilterPresenceOut()) {
buf.append("<presence-out/>"); buf.append("<presence-out/>");
} }
buf.append("</item>"); buf.append("</item>");
@ -302,144 +274,6 @@ public class PrivacyItem {
return buf.toString(); return buf.toString();
} }
/**
* Privacy Rule represents the kind of action to apply.
* It holds the kind of communication ([jid|group|subscription]) it will allow or block and
* identifier to apply the action.
*/
public static class PrivacyRule {
/**
* Type defines if the rule is based on JIDs, roster groups or presence subscription types.
* Available values are: [jid|group|subscription]
*/
private Type type;
/**
* The value hold the element identifier to apply the action.
* If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
* If the type is "group", then the 'value' attribute SHOULD contain the name of a group
* in the user's roster.
* If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
* "from", or "none".
*/
private String value;
/**
* If the type is "subscription", then the 'value' attribute MUST be one of "both",
* "to", "from", or "none"
*/
public static final String SUBSCRIPTION_BOTH = "both";
public static final String SUBSCRIPTION_TO = "to";
public static final String SUBSCRIPTION_FROM = "from";
public static final String SUBSCRIPTION_NONE = "none";
/**
* Returns the type constant associated with the String value.
*/
protected static PrivacyRule fromString(String value) {
if (value == null) {
return null;
}
PrivacyRule rule = new PrivacyRule();
rule.setType(Type.valueOf(value.toLowerCase()));
return rule;
}
/**
* Returns the type hold the kind of communication it will allow or block.
* It MUST be filled with one of these values: jid, group or subscription.
*
* @return the type of communication it represent.
*/
public Type getType() {
return type;
}
/**
* Sets the action associated with the item, it can allow or deny the communication.
*
* @param type indicates if the receiver allows or denies the communication.
*/
private void setType(Type type) {
this.type = type;
}
/**
* Returns the element identifier to apply the action.
*
* If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
* If the type is "group", then the 'value' attribute SHOULD contain the name of a group
* in the user's roster.
* If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
* "from", or "none".
*
* @return the identifier to apply the action.
*/
public String getValue() {
return value;
}
/**
* Sets the element identifier to apply the action.
*
* If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
* If the type is "group", then the 'value' attribute SHOULD contain the name of a group
* in the user's roster.
* If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
* "from", or "none".
*
* @param value is the identifier to apply the action.
*/
protected void setValue(String value) {
if (this.isSuscription()) {
setSuscriptionValue(value);
} else {
this.value = value;
}
}
/**
* Sets the element identifier to apply the action.
*
* The 'value' attribute MUST be one of "both", "to", "from", or "none".
*
* @param value is the identifier to apply the action.
*/
private void setSuscriptionValue(String value) {
String setValue;
if (value == null) {
// Do nothing
}
if (SUBSCRIPTION_BOTH.equalsIgnoreCase(value)) {
setValue = SUBSCRIPTION_BOTH;
}
else if (SUBSCRIPTION_TO.equalsIgnoreCase(value)) {
setValue = SUBSCRIPTION_TO;
}
else if (SUBSCRIPTION_FROM.equalsIgnoreCase(value)) {
setValue = SUBSCRIPTION_FROM;
}
else if (SUBSCRIPTION_NONE.equalsIgnoreCase(value)) {
setValue = SUBSCRIPTION_NONE;
}
// Default to available.
else {
setValue = null;
}
this.value = setValue;
}
/**
* Returns if the receiver represents a subscription rule.
*
* @return if the receiver represents a subscription rule.
*/
public boolean isSuscription () {
return this.getType() == Type.subscription;
}
}
/** /**
* Type defines if the rule is based on JIDs, roster groups or presence subscription types. * Type defines if the rule is based on JIDs, roster groups or presence subscription types.
*/ */
@ -453,8 +287,8 @@ public class PrivacyItem {
*/ */
jid, jid,
/** /**
* JID being analyzed should belong to a contact present in the owner's roster with * JID being analyzed should belong to a contact present in the owner's roster with the
* the specified subscription status. * specified subscription status.
*/ */
subscription subscription
} }

View File

@ -29,7 +29,7 @@ import java.util.ArrayList;
* The PrivacyProvider parses {@link Privacy} packets. {@link Privacy} * The PrivacyProvider parses {@link Privacy} packets. {@link Privacy}
* Parses the <tt>query</tt> sub-document and creates an instance of {@link Privacy}. * Parses the <tt>query</tt> sub-document and creates an instance of {@link Privacy}.
* For each <tt>item</tt> in the <tt>list</tt> element, it creates an instance * For each <tt>item</tt> in the <tt>list</tt> element, it creates an instance
* of {@link PrivacyItem} and {@link org.jivesoftware.smackx.privacy.packet.PrivacyItem.PrivacyRule}. * of {@link PrivacyItem}.
* *
* @author Francisco Vives * @author Francisco Vives
*/ */
@ -106,7 +106,7 @@ public class PrivacyProvider implements IQProvider {
String actionValue = parser.getAttributeValue("", "action"); String actionValue = parser.getAttributeValue("", "action");
String orderValue = parser.getAttributeValue("", "order"); String orderValue = parser.getAttributeValue("", "order");
String type = parser.getAttributeValue("", "type"); String type = parser.getAttributeValue("", "type");
/* /*
* According the action value it sets the allow status. The fall-through action is assumed * According the action value it sets the allow status. The fall-through action is assumed
* to be "allow" * to be "allow"
@ -120,32 +120,39 @@ public class PrivacyProvider implements IQProvider {
// Set the order number // Set the order number
int order = Integer.parseInt(orderValue); int order = Integer.parseInt(orderValue);
// Create the privacy item PrivacyItem item;
PrivacyItem item = new PrivacyItem(type, allow, order); if (type != null) {
item.setValue(parser.getAttributeValue("", "value")); // If the type is not null, then we are dealing with a standard privacy item
String value = parser.getAttributeValue("", "value");
item = new PrivacyItem(PrivacyItem.Type.valueOf(type), value, allow, order);
while (!done) { while (!done) {
int eventType = parser.next(); int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) { if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("iq")) { if (parser.getName().equals("iq")) {
item.setFilterIQ(true); item.setFilterIQ(true);
}
if (parser.getName().equals("message")) {
item.setFilterMessage(true);
}
if (parser.getName().equals("presence-in")) {
item.setFilterPresenceIn(true);
}
if (parser.getName().equals("presence-out")) {
item.setFilterPresenceOut(true);
}
} }
if (parser.getName().equals("message")) { else if (eventType == XmlPullParser.END_TAG) {
item.setFilterMessage(true); if (parser.getName().equals("item")) {
} done = true;
if (parser.getName().equals("presence-in")) { }
item.setFilterPresence_in(true);
}
if (parser.getName().equals("presence-out")) {
item.setFilterPresence_out(true);
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
} }
} }
} }
else {
// If the type is null, then we are dealing with the fall-through privacy item.
item = new PrivacyItem(allow, order);
}
return item; return item;
} }
} }

View File

@ -0,0 +1,69 @@
/**
*
* Copyright 2012 Florian Schmaus
*
* 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.smackx.privacy.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.jivesoftware.smack.DummyConnection;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smackx.InitExtensions;
import org.jivesoftware.smackx.privacy.packet.Privacy;
import org.jivesoftware.smackx.privacy.packet.PrivacyItem;
import org.junit.Test;
public class PrivacyProviderTest extends InitExtensions {
@Test
public void parsePrivacyList() throws Exception {
DummyConnection connection = new DummyConnection();
// @formatter:off
final String xmlPrivacyList =
"<iq type='result' id='getlist2' to='romeo@example.net/orchard'>"
+ "<query xmlns='jabber:iq:privacy'>"
+ "<list name='public'>"
+ "<item type='jid'"
+ "value='tybalt@example.com'"
+ "action='deny'"
+ "order='1'/>"
+ "<item action='allow' order='2'/>"
+ "</list>"
+ "</query>"
+ "</iq>";
// @formatter:on
IQ iqPrivacyList = PacketParserUtils.parseIQ(TestUtils.getIQParser(xmlPrivacyList), connection);
assertTrue(iqPrivacyList instanceof Privacy);
Privacy privacyList = (Privacy) iqPrivacyList;
List<PrivacyItem> pl = privacyList.getPrivacyList("public");
PrivacyItem first = pl.get(0);
assertEquals(PrivacyItem.Type.jid, first.getType());
assertEquals("tybalt@example.com", first.getValue());
assertEquals(false, first.isAllow());
assertEquals(1, first.getOrder());
PrivacyItem second = pl.get(1);
assertEquals(true, second.isAllow());
assertEquals(2, second.getOrder());
}
}