/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * 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 net.java.sip.communicator.impl.protocol.jabber; import java.util.*; import net.java.sip.communicator.service.protocol.*; /** * A dummy ContactGroup implementation representing the ContactList root for * Jabber contact lists. * @author Damian Minkov * @author Emil Ivov */ public class RootContactGroupJabberImpl extends AbstractContactGroupJabberImpl { private String ROOT_CONTACT_GROUP_NAME = "ContactListRoot"; /** * Maps all JIDs in our roster to the actual contacts so that we could * easily search the set of existing contacts. Note that we only store * lower case strings in the left column because JIDs in XMPP are not case * sensitive. */ private List subGroups = new LinkedList(); private boolean isResolved = false; /** * An empty list that we use when returning an iterator. */ private Map contacts = new Hashtable(); /** * The provider. */ private final ProtocolProviderServiceJabberImpl protocolProvider; /** * Creates a ContactGroup instance. */ RootContactGroupJabberImpl( ProtocolProviderServiceJabberImpl protocolProvider) { this.protocolProvider = protocolProvider; } /** * The ContactListRoot is the only group that can contain subgroups. * * @return true (always) */ public boolean canContainSubgroups() { return true; } /** * Returns the name of this group which is always * ROOT_CONTACT_GROUP_NAME. * * @return a String containing the name of this group. */ public String getGroupName() { return ROOT_CONTACT_GROUP_NAME; } /** * Removes the specified contact from this contact group * @param contact the contact to remove. */ void removeContact(ContactJabberImpl contact) { contacts.remove(contact.getAddress().toLowerCase()); } /** * Adds the specified contact to the end of this group. * @param contact the new contact to add to this group */ public void addContact(ContactJabberImpl contact) { contacts.put(contact.getAddress(), contact); } /** * Adds the specified group to the end of the list of sub groups. * @param group the group to add. */ void addSubGroup(ContactGroupJabberImpl group) { subGroups.add(group); } /** * Removes the specified from the list of sub groups * @param group the group to remove. */ void removeSubGroup(ContactGroupJabberImpl group) { removeSubGroup(subGroups.indexOf(group)); } /** * Removes the sub group with the specified index. * @param index the index of the group to remove */ void removeSubGroup(int index) { subGroups.remove(index); } /** * Returns the number of subgroups contained by this * RootContactGroupImpl. * * @return an int indicating the number of subgroups that this * ContactGroup contains. */ public int countSubgroups() { return subGroups.size(); } /** * Returns null as this is the root contact group. * @return null as this is the root contact group. */ public ContactGroup getParentContactGroup() { return null; } /** * Returns the subgroup with the specified index. * * @param index the index of the ContactGroup to retrieve. * @return the ContactGroup with the specified index. */ public ContactGroup getGroup(int index) { return subGroups.get(index); } /** * Returns the subgroup with the specified name. * @param groupName the name of the ContactGroup to retrieve. * @return the ContactGroup with the specified index. */ public ContactGroup getGroup(String groupName) { Iterator subgroups = subgroups(); while (subgroups.hasNext()) { ContactGroup grp = subgroups.next(); if (grp.getGroupName().equals(groupName)) return grp; } return null; } /** * Returns the Contact with the specified address or * identifier. * @param id the addres or identifier of the Contact we are * looking for. * @return the Contact with the specified id or address. */ public Contact getContact(String id) { return findContact(id); } /** * Returns the contact encapsulating with the spcieified name or * null if no such contact was found. * * @param id the id for the contact we're looking for. * @return the ContactJabberImpl corresponding to the specified * jid or null if no such contact existed. */ ContactJabberImpl findContact(String id) { if(id == null) return null; return (ContactJabberImpl)contacts.get(id.toLowerCase()); } /** * Returns an iterator over the sub groups that this * ContactGroup contains. * * @return a java.util.Iterator over the ContactGroup * children of this group (i.e. subgroups). */ public Iterator subgroups() { return new ArrayList(subGroups).iterator(); } /** * Returns the number, which is always 0, of Contact members * of this ContactGroup * @return an int indicating the number of Contacts, members * of this ContactGroup. */ public int countContacts() { return contacts.size(); } /** * Returns an Iterator over all contacts, member of this * ContactGroup. * @return a java.util.Iterator over all contacts inside this * ContactGroup */ public Iterator contacts() { return contacts.values().iterator(); } /** * Returns a string representation of the root contact group that contains * all subgroups and subcontacts of this group. * * @return a string representation of this root contact group. */ @Override public String toString() { StringBuffer buff = new StringBuffer(getGroupName()); buff.append(".subGroups="+countSubgroups()+":\n"); Iterator subGroups = subgroups(); while (subGroups.hasNext()) { ContactGroup group = subGroups.next(); buff.append(group.toString()); if(subGroups.hasNext()) buff.append("\n"); } buff.append(".rootContacts="+countContacts()+":\n"); Iterator contactsIter = contacts(); while (contactsIter.hasNext()) { buff.append(contactsIter.next()); if(contactsIter.hasNext()) buff.append("\n"); } return buff.toString(); } /** * Returns the protocol provider that this group belongs to. * @return a reference to the ProtocolProviderService instance that this * ContactGroup belongs to. */ public ProtocolProviderService getProtocolProvider() { return protocolProvider; } /** * Determines whether or not this contact group is being stored by the * server. Non persistent contact groups exist for the sole purpose of * containing non persistent contacts. * @return true if the contact group is persistent and false otherwise. */ public boolean isPersistent() { return true; } /** * Returns null as no persistent data is required and the group name is * sufficient for restoring the contact. *

* @return null as no such data is needed. */ public String getPersistentData() { return null; } /** * Determines whether or not this group has been resolved against the * server. Unresolved groups are used when initially loading a contact * list that has been stored in a local file until the presence operation * set has managed to retrieve all the contact list from the server and has * properly mapped groups to their on-line buddies. * @return true if the group has been resolved (mapped against a buddy) * and false otherwise. */ public boolean isResolved() { return isResolved; } /** * Returns a String that uniquely represnets the group. In this we * use the name of the group as an identifier. This may cause problems * though, in clase the name is changed by some other application between * consecutive runs of the sip-communicator. * * @return a String representing this group in a unique and persistent * way. */ public String getUID() { return getGroupName(); } }