aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamian Minkov <damencho@jitsi.org>2013-11-22 16:52:57 +0200
committerDamian Minkov <damencho@jitsi.org>2013-11-22 19:58:04 +0200
commit5a4cf2e8271e79afe3aa5d99f58cf9402e947a52 (patch)
treef1d6f11cd4303cbf1f43741e0fe9f0045db0ad63
parent2c7c656afc3ca986719eb9b613ca7e8923783e17 (diff)
downloadjitsi-5a4cf2e8271e79afe3aa5d99f58cf9402e947a52.zip
jitsi-5a4cf2e8271e79afe3aa5d99f58cf9402e947a52.tar.gz
jitsi-5a4cf2e8271e79afe3aa5d99f58cf9402e947a52.tar.bz2
Adds operation set and its implementation to handle contactlist group modification permissions.
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java115
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java26
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java92
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIGroup.java25
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresencePermissionsJabberImpl.java122
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java9
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetPersistentPresencePermissions.java42
-rw-r--r--src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java7
8 files changed, 396 insertions, 42 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java
index 773b428..43675bd 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java
@@ -329,6 +329,16 @@ public class AddContactDialog
if (opSet == null)
continue;
+ OperationSetPersistentPresencePermissions opSetPermissions
+ = provider.getOperationSet(
+ OperationSetPersistentPresencePermissions.class);
+ if(opSetPermissions != null)
+ {
+ // let's check whether we can edit something
+ if(opSetPermissions.isReadOnly())
+ continue;
+ }
+
accountCombo.addItem(provider);
if (provider.getAccountID().isPreferredProvider())
@@ -350,34 +360,17 @@ public class AddContactDialog
groupCombo.setRenderer(new GroupComboRenderer());
- groupCombo.addItem(GuiActivator.getContactListService().getRoot());
-
- Iterator<MetaContactGroup> groupList
- = GuiActivator.getContactListService().getRoot().getSubgroups();
-
- while (groupList.hasNext())
- {
- MetaContactGroup group = groupList.next();
-
- if (!group.isPersistent())
- continue;
-
- groupCombo.addItem(group);
- }
+ updateGroupItems(groupCombo, null);
final String newGroupString = GuiActivator.getResources()
.getI18NString("service.gui.CREATE_GROUP");
- if (!ConfigurationUtils.isCreateGroupDisabled())
- {
- groupCombo.addItem(newGroupString);
- }
-
groupCombo.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
- if (groupCombo.getSelectedItem().equals(newGroupString))
+ if (groupCombo.getSelectedItem() != null
+ && groupCombo.getSelectedItem().equals(newGroupString))
{
CreateGroupDialog dialog
= new CreateGroupDialog(parentDialog, false);
@@ -402,6 +395,80 @@ public class AddContactDialog
}
/**
+ * Update the group items in the combo supplied, by checking
+ * and the edit permissions
+ */
+ private static void updateGroupItems(JComboBox groupCombo,
+ ProtocolProviderService provider)
+ {
+ OperationSetPersistentPresencePermissions opsetPermissions = null;
+ OperationSetPersistentPresence opsetPresence = null;
+
+ boolean isRootReadOnly = false;
+
+ if(provider != null)
+ {
+ groupCombo.removeAllItems();
+
+ opsetPermissions = provider.getOperationSet(
+ OperationSetPersistentPresencePermissions.class);
+ opsetPresence = provider.getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ if(opsetPermissions != null
+ && opsetPresence != null)
+ isRootReadOnly = opsetPermissions.isReadOnly(
+ opsetPresence.getServerStoredContactListRoot());
+ }
+
+ if(!isRootReadOnly)
+ {
+ groupCombo.addItem(GuiActivator.getContactListService().getRoot());
+ }
+
+ Iterator<MetaContactGroup> groupList
+ = GuiActivator.getContactListService().getRoot().getSubgroups();
+
+ while (groupList.hasNext())
+ {
+ MetaContactGroup group = groupList.next();
+
+ if (!group.isPersistent())
+ continue;
+
+ if(provider != null && opsetPermissions != null)
+ {
+ Iterator<ContactGroup> protoGroupsIter =
+ group.getContactGroupsForProvider(provider);
+ boolean foundWritableGroup = false;
+ while(protoGroupsIter.hasNext())
+ {
+ ContactGroup gr = protoGroupsIter.next();
+ if(!opsetPermissions.isReadOnly(gr))
+ {
+ foundWritableGroup = true;
+ break;
+ }
+ }
+
+ if(!foundWritableGroup)
+ continue;
+ }
+
+ groupCombo.addItem(group);
+ }
+
+ final String newGroupString = GuiActivator.getResources()
+ .getI18NString("service.gui.CREATE_GROUP");
+
+ if (!ConfigurationUtils.isCreateGroupDisabled()
+ && !isRootReadOnly)
+ {
+ groupCombo.addItem(newGroupString);
+ }
+ }
+
+ /**
* Indicates that the "Add" buttons has been pressed.
* @param e the <tt>ActionEvent</tt> that notified us
*/
@@ -692,12 +759,16 @@ public class AddContactDialog
{
String contactAddress = contactAddressField.getText();
- if (accountCombo.getSelectedItem()
- instanceof ProtocolProviderService
+ Object selectedItem = accountCombo.getSelectedItem();
+ if (selectedItem instanceof ProtocolProviderService
&& contactAddress != null && contactAddress.length() > 0)
addButton.setEnabled(true);
else
addButton.setEnabled(false);
+
+ if(selectedItem instanceof ProtocolProviderService)
+ updateGroupItems(groupCombo,
+ (ProtocolProviderService)accountCombo.getSelectedItem());
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java
index 8711e35..98ec645 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java
@@ -224,6 +224,32 @@ public class ContactListTransferHandler
if (transferredContact == null)
return false;
+ if(transferredContact.getDescriptor() instanceof MetaContact)
+ {
+ // check if underlying account is readonly
+ MetaContact metaContact =
+ (MetaContact)transferredContact.getDescriptor();
+ boolean onlyReadonlyContacts = true;
+ Iterator<Contact> iter = metaContact.getContacts();
+ while(iter.hasNext())
+ {
+ Contact c = iter.next();
+ ProtocolProviderService pp = c.getProtocolProvider();
+ OperationSetPersistentPresencePermissions
+ opsetPermissions = pp.getOperationSet(
+ OperationSetPersistentPresencePermissions.class);
+
+ if( opsetPermissions == null
+ || !opsetPermissions.isReadOnly(c))
+ {
+ onlyReadonlyContacts = false;
+ break;
+ }
+ }
+ if(onlyReadonlyContacts)
+ return false;
+ }
+
if (dest instanceof ContactNode)
{
UIContact destContact
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java
index cf7ab1a..072c2ea 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java
@@ -366,6 +366,30 @@ public class MetaContactRightButtonMenu
this.moveToMenu.add(menuItem);
}
+ boolean hasOnlyReadonlyContacts = true;
+ boolean hasAnyReadonlyContact = false;
+ Iterator<Contact> iter = metaContact.getContacts();
+ while(iter.hasNext())
+ {
+ Contact c = iter.next();
+ OperationSetPersistentPresencePermissions opsetPermissions =
+ c.getProtocolProvider()
+ .getOperationSet(
+ OperationSetPersistentPresencePermissions.class);
+
+ if( opsetPermissions == null
+ || !opsetPermissions.isReadOnly(c))
+ {
+ hasOnlyReadonlyContacts = false;
+ }
+
+ if(opsetPermissions != null
+ && opsetPermissions.isReadOnly(c))
+ {
+ hasAnyReadonlyContact = true;
+ }
+ }
+
//Initialize removeContact menu.
Iterator<Contact> contacts = metaContact.getContacts();
@@ -383,10 +407,13 @@ public class MetaContactRightButtonMenu
allItem1.setName(moveSubcontactPrefix + "allContacts");
- this.removeContactMenu.add(allItem);
- this.moveSubcontactMenu.add(allItem1);
- this.removeContactMenu.addSeparator();
- this.moveSubcontactMenu.addSeparator();
+ if(!hasAnyReadonlyContact)
+ {
+ this.removeContactMenu.add(allItem);
+ this.moveSubcontactMenu.add(allItem1);
+ this.removeContactMenu.addSeparator();
+ this.moveSubcontactMenu.addSeparator();
+ }
}
contactPhoneUtil = MetaContactPhoneUtil.getPhoneUtil(metaContact);
@@ -405,20 +432,33 @@ public class MetaContactRightButtonMenu
Icon protocolIcon = new ImageIcon(
createContactStatusImage(contact));
- this.removeContactMenu.add(
- new ContactMenuItem(contact,
- contactAddress,
- removeContactPrefix,
- protocolIcon));
+ boolean isContactReadonly = false;
+
+ OperationSetPersistentPresencePermissions opsetPermissions =
+ protocolProvider
+ .getOperationSet(
+ OperationSetPersistentPresencePermissions.class);
+ if(opsetPermissions != null
+ && opsetPermissions.isReadOnly(contact))
+ isContactReadonly = true;
+
+ if(!isContactReadonly)
+ this.removeContactMenu.add(
+ new ContactMenuItem(contact,
+ contactAddress,
+ removeContactPrefix,
+ protocolIcon));
if(contactPersistableAddress != null)
{
hasPersistableAddress = true;
- this.moveSubcontactMenu.add(
- new ContactMenuItem(contact,
- contactPersistableAddress,
- moveSubcontactPrefix,
- protocolIcon));
+
+ if(!isContactReadonly)
+ this.moveSubcontactMenu.add(
+ new ContactMenuItem(contact,
+ contactPersistableAddress,
+ moveSubcontactPrefix,
+ protocolIcon));
}
List<String> phones = contactPhoneUtil.getPhones(contact);
@@ -590,15 +630,27 @@ public class MetaContactRightButtonMenu
!ConfigurationUtils.isCreateGroupDisabled() &&
hasPersistableAddress)
{
+ boolean addSeparator = false;
+
+ if(!hasAnyReadonlyContact)
+ {
+ add(moveToMenu);
+ addSeparator = true;
+ }
- add(moveToMenu);
- add(moveSubcontactMenu);
+ if(moveSubcontactMenu.getItemCount() > 0)
+ {
+ add(moveSubcontactMenu);
+ addSeparator = true;
+ }
- addSeparator();
+ if(addSeparator)
+ addSeparator();
}
- if (!ConfigurationUtils.isAddContactDisabled() &&
- !ConfigurationUtils.isMergeContactDisabled())
+ if (!ConfigurationUtils.isAddContactDisabled()
+ && !ConfigurationUtils.isMergeContactDisabled()
+ && !hasAnyReadonlyContact)
{
add(addContactItem);
addSeparator();
@@ -612,7 +664,7 @@ public class MetaContactRightButtonMenu
add(removeContactMenu);
separator = true;
}
- else
+ else if(!hasOnlyReadonlyContacts)
{
// There is only one contact, so a submenu is unnecessary -
// just add a single menu item. It masquerades as an item to
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIGroup.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIGroup.java
index 12aaf83..77a9b52 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIGroup.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIGroup.java
@@ -12,8 +12,11 @@ import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
+import java.util.*;
+
/**
* The <tt>MetaUIGroup</tt> is the implementation of the UIGroup for the
* <tt>MetaContactListService</tt>. This implementation is based on the
@@ -170,6 +173,28 @@ public class MetaUIGroup
@Override
public JPopupMenu getRightButtonMenu()
{
+ // check if group has readonly proto group then skip menu
+ boolean hasReadonlyGroup = false;
+ Iterator<ContactGroup> groupsIterator =
+ metaGroup.getContactGroups();
+ while(groupsIterator.hasNext())
+ {
+ ContactGroup group = groupsIterator.next();
+ OperationSetPersistentPresencePermissions opsetPermissions =
+ group.getProtocolProvider().getOperationSet(
+ OperationSetPersistentPresencePermissions.class);
+
+ if(opsetPermissions != null
+ && opsetPermissions.isReadOnly(group))
+ {
+ hasReadonlyGroup = true;
+ break;
+ }
+ }
+
+ if(hasReadonlyGroup)
+ return null;
+
return new GroupRightButtonMenu(
GuiActivator.getUIService().getMainFrame(), metaGroup);
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresencePermissionsJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresencePermissionsJabberImpl.java
new file mode 100644
index 0000000..ba8b8b1
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresencePermissionsJabberImpl.java
@@ -0,0 +1,122 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import net.java.sip.communicator.service.protocol.*;
+
+import java.util.*;
+
+/**
+ * Implements group edit permissions.
+ *
+ * @author Damian Minkov
+ */
+public class OperationSetPersistentPresencePermissionsJabberImpl
+ implements OperationSetPersistentPresencePermissions
+{
+ /**
+ * Will indicate everything is readonly.
+ */
+ private static final String ALL_GROUPS_STR = "all";
+
+ /**
+ * Can be added to mark root group as readonly.
+ */
+ private static final String ROOT_GROUP_STR = "root";
+
+ /**
+ * List of group names to be considered as readonly.
+ */
+ private List<String> readonlyGroups = new ArrayList<String>();
+
+ /**
+ * The parent provider.
+ */
+ private final ProtocolProviderServiceJabberImpl provider;
+
+ OperationSetPersistentPresencePermissionsJabberImpl(
+ ProtocolProviderServiceJabberImpl provider)
+ {
+ this.provider = provider;
+
+ String readOnlyGroupsStr = provider.getAccountID()
+ .getAccountPropertyString(
+ ProtocolProviderFactory.ACCOUNT_READ_ONLY_GROUPS);
+
+ if(readOnlyGroupsStr == null)
+ return;
+
+ StringTokenizer tokenizer = new StringTokenizer(readOnlyGroupsStr, ",");
+ while(tokenizer.hasMoreTokens())
+ {
+ readonlyGroups.add(tokenizer.nextToken().trim());
+ }
+ }
+
+ /**
+ * Is the whole contact list for the current provider readonly.
+ * @return <tt>true</tt> if the whole contact list is readonly, otherwise
+ * <tt>false</tt>.
+ */
+ @Override
+ public boolean isReadOnly()
+ {
+ if(readonlyGroups.contains(ALL_GROUPS_STR))
+ return true;
+
+ List<String> groupsList = new ArrayList<String>();
+ groupsList.add(ROOT_GROUP_STR);
+ Iterator<ContactGroup> groupsIter = provider
+ .getOperationSet(OperationSetPersistentPresence.class)
+ .getServerStoredContactListRoot().subgroups();
+ while(groupsIter.hasNext())
+ {
+ groupsList.add(groupsIter.next().getGroupName());
+ }
+
+ if(groupsList.size() > readonlyGroups.size())
+ return false;
+
+ groupsList.removeAll(readonlyGroups);
+
+ if(groupsList.size() > 0)
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Checks whether the <tt>contact</tt> can be edited, removed, moved. If
+ * the parent group is readonly.
+ * @param contact the contact to check.
+ * @return <tt>true</tt> if the contact is readonly, otherwise
+ * <tt>false</tt>.
+ */
+ @Override
+ public boolean isReadOnly(Contact contact)
+ {
+ return isReadOnly(contact.getParentContactGroup());
+ }
+
+ /**
+ * Checks whether the <tt>group</tt> is readonly.
+ * @param group the group to check.
+ * @return <tt>true</tt> if the group is readonly, otherwise
+ * <tt>false</tt>.
+ */
+ @Override
+ public boolean isReadOnly(ContactGroup group)
+ {
+ if(isReadOnly())
+ return true;
+
+ if(group instanceof RootContactGroupJabberImpl)
+ return readonlyGroups.contains(ROOT_GROUP_STR);
+ else
+ return readonlyGroups.contains(group.getGroupName());
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
index cadcdd2..f103697 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -1563,6 +1563,15 @@ public class ProtocolProviderServiceJabberImpl
OperationSetPresence.class,
persistentPresence);
+ if(accountID.getAccountPropertyString(
+ ProtocolProviderFactory.ACCOUNT_READ_ONLY_GROUPS) != null)
+ {
+ addSupportedOperationSet(
+ OperationSetPersistentPresencePermissions.class,
+ new OperationSetPersistentPresencePermissionsJabberImpl(
+ this));
+ }
+
//initialize the IM operation set
OperationSetBasicInstantMessagingJabberImpl basicInstantMessaging =
new OperationSetBasicInstantMessagingJabberImpl(this);
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetPersistentPresencePermissions.java b/src/net/java/sip/communicator/service/protocol/OperationSetPersistentPresencePermissions.java
new file mode 100644
index 0000000..7022e7e
--- /dev/null
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetPersistentPresencePermissions.java
@@ -0,0 +1,42 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.protocol;
+
+/**
+ * This interface is addition to the persistence presence operation set, meant
+ * to provide per group permissions for modification of the contacts and groups.
+ * Can make the contact list read only or only some groups in it.
+ *
+ * @author Damian Minkov
+ */
+public interface OperationSetPersistentPresencePermissions
+ extends OperationSet
+{
+ /**
+ * Is the whole contact list for the current provider readonly.
+ * @return <tt>true</tt> if the whole contact list is readonly, otherwise
+ * <tt>false</tt>.
+ */
+ public boolean isReadOnly();
+
+ /**
+ * Checks whether the <tt>contact</tt> can be edited, removed, moved. If
+ * the parent group is readonly.
+ * @param contact the contact to check.
+ * @return <tt>true</tt> if the contact is readonly, otherwise
+ * <tt>false</tt>.
+ */
+ public boolean isReadOnly(Contact contact);
+
+ /**
+ * Checks whether the <tt>group</tt> is readonly.
+ * @param group the group to check.
+ * @return <tt>true</tt> if the group is readonly, otherwise
+ * <tt>false</tt>.
+ */
+ public boolean isReadOnly(ContactGroup group);
+}
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
index 66b50fa..ec7167c 100644
--- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
+++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
@@ -314,6 +314,13 @@ public abstract class ProtocolProviderFactory
public static final String IS_ACCOUNT_CONFIG_HIDDEN = "IS_CONFIG_HIDDEN";
/**
+ * The name of the property that would indicate if a given account
+ * groups are readonly, values can be all or a comma separated
+ * group names including root.
+ */
+ public static final String ACCOUNT_READ_ONLY_GROUPS = "READ_ONLY_GROUPS";
+
+ /**
* Indicates if ICE should be used.
*/
public static final String IS_USE_ICE = "ICE_ENABLED";