diff options
author | Damian Minkov <damencho@jitsi.org> | 2013-11-22 16:52:57 +0200 |
---|---|---|
committer | Damian Minkov <damencho@jitsi.org> | 2013-11-22 19:58:04 +0200 |
commit | 5a4cf2e8271e79afe3aa5d99f58cf9402e947a52 (patch) | |
tree | f1d6f11cd4303cbf1f43741e0fe9f0045db0ad63 | |
parent | 2c7c656afc3ca986719eb9b613ca7e8923783e17 (diff) | |
download | jitsi-5a4cf2e8271e79afe3aa5d99f58cf9402e947a52.zip jitsi-5a4cf2e8271e79afe3aa5d99f58cf9402e947a52.tar.gz jitsi-5a4cf2e8271e79afe3aa5d99f58cf9402e947a52.tar.bz2 |
Adds operation set and its implementation to handle contactlist group modification permissions.
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";
|