ContactListManager.java
上传用户:szyujian
上传日期:2016-09-20
资源大小:320k
文件大小:19k
源码类别:

android开发

开发平台:

C/C++

  1. /*
  2.  * Copyright (C) 2007-2008 Esmertec AG.
  3.  * Copyright (C) 2007-2008 The Android Open Source Project
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package com.android.im.engine;
  18. import java.util.Collection;
  19. import java.util.Collections;
  20. import java.util.List;
  21. import java.util.Vector;
  22. import java.util.concurrent.CopyOnWriteArrayList;
  23. /**
  24.  * ContactListManager manages the creating, removing and retrieving contact
  25.  * lists.
  26.  */
  27. public abstract class ContactListManager {
  28.     /**
  29.      * ContactListManager state that indicates the contact list(s) has not been loaded.
  30.      */
  31.     public static final int LISTS_NOT_LOADED = 0;
  32.     /**
  33.      * ContactListManager state that indicates the contact list(s) is loading.
  34.      */
  35.     public static final int LISTS_LOADING = 1;
  36.     /**
  37.      * ContactListManager state that indicates the blocked list has been loaded.
  38.      */
  39.     public static final int BLOCKED_LIST_LOADED = 2;
  40.     /**
  41.      * ContactListManager state that indicates the contact list(s) has been loaded.
  42.      */
  43.     public static final int LISTS_LOADED = 3;
  44.     protected ContactList mDefaultContactList;
  45.     protected Vector<ContactList> mContactLists;
  46.     protected CopyOnWriteArrayList<ContactListListener> mContactListListeners;
  47.     protected SubscriptionRequestListener mSubscriptionRequestListener;
  48.     protected Vector<Contact> mBlockedList;
  49.     private int mState;
  50.     /**
  51.      * Creates a new ContactListManager.
  52.      *
  53.      * @param conn The underlying protocol connection.
  54.      */
  55.     protected ContactListManager() {
  56.         mContactLists = new Vector<ContactList>();
  57.         mContactListListeners = new CopyOnWriteArrayList<ContactListListener>();
  58.         mBlockedList = new Vector<Contact>();
  59.         mState = LISTS_NOT_LOADED;
  60.     }
  61.     /**
  62.      * Set the state of the ContactListManager
  63.      *
  64.      * @param state the new state
  65.      */
  66.     protected synchronized void setState(int state) {
  67.         if (state < LISTS_NOT_LOADED || state > LISTS_LOADED) {
  68.             throw new IllegalArgumentException();
  69.         }
  70.         mState = state;
  71.     }
  72.     /**
  73.      * Get the state of the ContactListManager
  74.      *
  75.      * @return the current state of the manager
  76.      */
  77.     public synchronized int getState() {
  78.         return mState;
  79.     }
  80.     /**
  81.      * Adds a listener to the manager so that it will be notified for contact
  82.      * list changed.
  83.      *
  84.      * @param listener the listener to add.
  85.      */
  86.     public synchronized void addContactListListener(ContactListListener listener) {
  87.         if ((listener != null) && !mContactListListeners.contains(listener)) {
  88.             mContactListListeners.add(listener);
  89.         }
  90.     }
  91.     /**
  92.      * Removes a listener from this manager.
  93.      *
  94.      * @param listener the listener to remove.
  95.      */
  96.     public synchronized void removeContactListListener(ContactListListener listener) {
  97.         mContactListListeners.remove(listener);
  98.     }
  99.     /**
  100.      * Sets the SubscriptionRequestListener to the manager so that it will be notified
  101.      * when a subscription request from another user is received.
  102.      *
  103.      * @param listener the ContactInvitationListener.
  104.      */
  105.     public synchronized void setSubscriptionRequestListener(
  106.             SubscriptionRequestListener listener) {
  107.         mSubscriptionRequestListener = listener;
  108.     }
  109.     public synchronized SubscriptionRequestListener getSubscriptionRequestListener() {
  110.         return mSubscriptionRequestListener;
  111.     }
  112.     /**
  113.      * Gets a collection of the contact lists.
  114.      *
  115.      * @return a collection of the contact lists.
  116.      */
  117.     public Collection<ContactList> getContactLists() {
  118.         return Collections.unmodifiableCollection(mContactLists);
  119.     }
  120.     /**
  121.      * Gets a contact by address.
  122.      *
  123.      * @param address the address of the Contact.
  124.      * @return the Contact or null if the Contact doesn't exist in any list.
  125.      */
  126.     public Contact getContact(Address address) {
  127.         return getContact(address.getFullName());
  128.     }
  129.     public Contact getContact(String address) {
  130.         for (ContactList list : mContactLists) {
  131.             Contact c = list.getContact(address);
  132.             if( c != null) {
  133.                 return c;
  134.             }
  135.         }
  136.         return null;
  137.     }
  138.     public abstract String normalizeAddress(String address);
  139.     /**
  140.      * Creates a temporary contact. It's usually used when we want to create
  141.      * a chat with someone not in the list.
  142.      *
  143.      * @param address the address of the temporary contact.
  144.      * @return the created temporary contact
  145.      */
  146.     public abstract Contact createTemporaryContact(String address);
  147.     /**
  148.      * Tell whether the manager contains the specified contact
  149.      *
  150.      * @param contact the specified contact
  151.      * @return true if the contact is contained in the lists of the manager,
  152.      *          otherwise, return false
  153.      */
  154.     public boolean containsContact(Contact contact) {
  155.         for (ContactList list : mContactLists) {
  156.             if (list.containsContact(contact)) {
  157.                 return true;
  158.             }
  159.         }
  160.         return false;
  161.     }
  162.     /**
  163.      * Gets a contact list by name.
  164.      *
  165.      * @param name the name of the contact list.
  166.      * @return the ContactList or null if the contact list doesn't exist.
  167.      */
  168.     public ContactList getContactList(String name) {
  169.         for (ContactList list : mContactLists) {
  170.             if (list.getName() != null && list.getName().equals(name)) {
  171.                 return list;
  172.             }
  173.         }
  174.         return null;
  175.     }
  176.     /**
  177.      * Get the contact list by the address
  178.      *
  179.      * @param address the address of the contact list
  180.      * @return the <code>ContactList</code> or null if the list doesn't exist
  181.      */
  182.     public ContactList getContactList(Address address) {
  183.         for (ContactList list : mContactLists) {
  184.             if (list.getAddress().equals(address)) {
  185.                 return list;
  186.             }
  187.         }
  188.         return null;
  189.     }
  190.     /**
  191.      * Gets the default contact list.
  192.      *
  193.      * @return the default contact list.
  194.      * @throws ImException
  195.      */
  196.     public ContactList getDefaultContactList() throws ImException {
  197.         checkState();
  198.         return mDefaultContactList;
  199.     }
  200.     /**
  201.      * Create a contact list with the specified name asynchronously.
  202.      *
  203.      * @param name the specific name of the contact list
  204.      * @throws ImException
  205.      */
  206.     public void createContactListAsync(String name) throws ImException {
  207.         createContactListAsync(name, null, false);
  208.     }
  209.     /**
  210.      * Create a contact list with specified name and whether it is to be
  211.      * created as the default list.
  212.      *
  213.      * @param name the specific name of the contact list
  214.      * @param isDefault whether the contact list is to be created as the
  215.      *                  default list
  216.      * @throws ImException
  217.      */
  218.     public void createContactListAsync(String name, boolean isDefault) throws ImException {
  219.         createContactListAsync(name, null, isDefault);
  220.     }
  221.     /**
  222.      * Create a contact list with specified name and contacts asynchronously.
  223.      *
  224.      * @param name the specific name of the contact list
  225.      * @param contacts the initial contacts of the contact list
  226.      * @throws ImException
  227.      */
  228.     public void createContactListAsync(String name,
  229.             Collection<Contact> contacts) throws ImException {
  230.         createContactListAsync(name, contacts, false);
  231.     }
  232.     /**
  233.      * Create a contact list with specified name and contacts asynchronously,
  234.      * and whether it is to be created as the default contact list.
  235.      *
  236.      * @param name the name of the contact list
  237.      * @param contacts the initial contacts of the list
  238.      * @param isDefault whether the contact list is the default list
  239.      * @throws ImException
  240.      */
  241.     public synchronized void createContactListAsync(String name,
  242.             Collection<Contact> contacts, boolean isDefault) throws ImException {
  243.         checkState();
  244.         if (getContactList(name) != null) {
  245.             throw new ImException(ImErrorInfo.CONTACT_LIST_EXISTS,
  246.                     "Contact list already exists");
  247.         }
  248.         if (mContactLists.isEmpty()) {
  249.             isDefault = true;
  250.         }
  251.         doCreateContactListAsync(name, contacts, isDefault);
  252.     }
  253.     /**
  254.      * Delete a contact list of the specified name asynchronously
  255.      * @param name the specific name of the contact list
  256.      * @throws ImException
  257.      */
  258.     public void deleteContactListAsync(String name) throws ImException {
  259.         deleteContactListAsync(getContactList(name));
  260.     }
  261.     /**
  262.      * Delete a specified contact list asynchronously
  263.      * @param list the contact list to be deleted
  264.      * @throws ImException if any error raised
  265.      */
  266.     public synchronized void deleteContactListAsync(ContactList list) throws ImException {
  267.         checkState();
  268.         if (null == list) {
  269.             throw new ImException(ImErrorInfo.CONTACT_LIST_NOT_FOUND,
  270.                     "Contact list doesn't exist");
  271.         }
  272.         doDeleteContactListAsync(list);
  273.     }
  274.     public void blockContactAsync(Contact contact) throws ImException {
  275.         blockContactAsync(contact.getAddress().getFullName());
  276.     }
  277.     /**
  278.      * Blocks a certain Contact. The contact will be removed from any
  279.      * ContactList after be blocked. If the contact has already been blocked,
  280.      * the method does nothing.
  281.      *
  282.      * @param address the address of the contact to block.
  283.      * @throws ImException if an error occurs
  284.      */
  285.     public void blockContactAsync(String address) throws ImException {
  286.         checkState();
  287.         if(isBlocked(address)){
  288.             return;
  289.         }
  290.         doBlockContactAsync(address, true);
  291.     }
  292.     public void unblockContactAsync(Contact contact) throws ImException {
  293.         unblockContactAsync(contact.getAddress().getFullName());
  294.     }
  295.     /**
  296.      * Unblock a certain contact. It will removes the contact from the blocked
  297.      * list and allows the contact to send message or invitation to the client
  298.      * again. If the contact is not blocked on the client, this method does
  299.      * nothing. Whether the unblocked contact will be added to the ContactList
  300.      * it belongs before blocked or not depends on the underlying protocol
  301.      * implementation.
  302.      *
  303.      * @param address the address of the contact to unblock.
  304.      * @throws ImException if the current state is illegal
  305.      */
  306.     public void unblockContactAsync(String address) throws ImException {
  307.         checkState();
  308.         if(!isBlocked(address)) {
  309.             return;
  310.         }
  311.         doBlockContactAsync(address, false);
  312.     }
  313.     protected void addContactToListAsync(String address, ContactList list)
  314.             throws ImException {
  315.         checkState();
  316.         doAddContactToListAsync(address, list);
  317.     }
  318.     protected void removeContactFromListAsync(Contact contact, ContactList list)
  319.             throws ImException {
  320.         checkState();
  321.         doRemoveContactFromListAsync(contact, list);
  322.     }
  323.     /**
  324.      * Gets a unmodifiable list of blocked contacts.
  325.      *
  326.      * @return a unmodifiable list of blocked contacts.
  327.      * @throws ImException
  328.      */
  329.     public List<Contact> getBlockedList() throws ImException {
  330.         checkState();
  331.         return Collections.unmodifiableList(mBlockedList);
  332.     }
  333.     /**
  334.      * Checks if a contact is blocked.
  335.      *
  336.      * @param contact the contact.
  337.      * @return true if it's blocked, false otherwise.
  338.      * @throws ImException if contacts has not been loaded.
  339.      */
  340.     public boolean isBlocked(Contact contact) throws ImException {
  341.         return isBlocked(contact.getAddress().getFullName());
  342.     }
  343.     /**
  344.      * Checks if a contact is blocked.
  345.      *
  346.      * @param address the address of the contact.
  347.      * @return true if it's blocked, false otherwise.
  348.      * @throws ImException if contacts has not been loaded.
  349.      */
  350.     public synchronized boolean isBlocked(String address) throws ImException {
  351.         if(mState < BLOCKED_LIST_LOADED) {
  352.             throw new ImException(ImErrorInfo.ILLEGAL_CONTACT_LIST_MANAGER_STATE,
  353.                 "Blocked list hasn't been loaded");
  354.         }
  355.         for(Contact c : mBlockedList) {
  356.             if(c.getAddress().getFullName().equals(address)){
  357.                 return true;
  358.             }
  359.         }
  360.         return false;
  361.     }
  362.     /**
  363.      * Check the state of the ContactListManager. Only the LIST_LOADED state
  364.      * is permitted.
  365.      *
  366.      * @throws ImException if the current state is not LIST_LOADED
  367.      */
  368.     protected void checkState() throws ImException {
  369.         if (getConnection().getState() != ImConnection.LOGGED_IN) {
  370.             throw new ImException(ImErrorInfo.CANT_CONNECT_TO_SERVER,
  371.                     "Can't connect to server");
  372.         }
  373.         if (getState() != LISTS_LOADED) {
  374.             throw new ImException(ImErrorInfo.ILLEGAL_CONTACT_LIST_MANAGER_STATE,
  375.                     "Illegal contact list manager state");
  376.         }
  377.     }
  378.     /**
  379.      * Load the contact lists from the server. This method will normally called
  380.      * after the user logged in to get the initial/saved contact lists from
  381.      * server. After called once, this method should not be called again.
  382.      */
  383.     public abstract void loadContactListsAsync();
  384.     public abstract void approveSubscriptionRequest(String contact);
  385.     public abstract void declineSubscriptionRequest(String contact);
  386.     protected abstract ImConnection getConnection();
  387.     /**
  388.      * Block or unblock a contact.
  389.      *
  390.      * @param address
  391.      *            the address of the contact to block or unblock.
  392.      * @param block
  393.      *            <code>true</code> to block the contact; <code>false</code>
  394.      *            to unblock the contact.
  395.      */
  396.     protected abstract void doBlockContactAsync(String address, boolean block);
  397.     protected abstract void doCreateContactListAsync(String name,
  398.             Collection<Contact> contacts, boolean isDefault);
  399.     protected abstract void doDeleteContactListAsync(ContactList list);
  400.     /**
  401.      * Notify that the presence of the contact has been updated
  402.      *
  403.      * @param contacts the contacts who have updated presence information
  404.      */
  405.     protected void notifyContactsPresenceUpdated(Contact[] contacts) {
  406.         for (ContactListListener listener : mContactListListeners) {
  407.             listener.onContactsPresenceUpdate(contacts);
  408.         }
  409.     }
  410.     /**
  411.      * Notify that a contact list related error has been raised.
  412.      *
  413.      * @param type the type of the error
  414.      * @param error the raised error
  415.      * @param listName the list name, if any, associated with the error
  416.      * @param contact the contact, if any, associated with the error
  417.      */
  418.     protected void notifyContactError(int type, ImErrorInfo error,
  419.             String listName, Contact contact) {
  420.         for (ContactListListener listener : mContactListListeners) {
  421.             listener.onContactError(type, error, listName, contact);
  422.         }
  423.     }
  424.     /**
  425.      * Notify that a contact list has been loaded
  426.      *
  427.      * @param list the loaded list
  428.      */
  429.     protected void notifyContactListLoaded(ContactList list) {
  430.         for (ContactListListener listener : mContactListListeners) {
  431.             listener.onContactChange(ContactListListener.LIST_LOADED,
  432.                     list, null);
  433.         }
  434.     }
  435.     /**
  436.      * Notify that all contact lists has been loaded
  437.      */
  438.     protected void notifyContactListsLoaded() {
  439.         setState(LISTS_LOADED);
  440.         for (ContactListListener listener : mContactListListeners) {
  441.             listener.onAllContactListsLoaded();
  442.         }
  443.     }
  444.     /**
  445.      * Notify that a contact has been added to or removed from a list.
  446.      *
  447.      * @param list the updated contact list
  448.      * @param type the type of the update
  449.      * @param contact the involved contact, null if no contact involved.
  450.      */
  451.     protected void notifyContactListUpdated(ContactList list, int type,
  452.             Contact contact) {
  453.         synchronized (this) {
  454.             if (type == ContactListListener.LIST_CONTACT_ADDED) {
  455.                 list.insertToCache(contact);
  456.             } else if (type == ContactListListener.LIST_CONTACT_REMOVED) {
  457.                 list.removeFromCache(contact);
  458.             }
  459.         }
  460.         for (ContactListListener listener : mContactListListeners) {
  461.             listener.onContactChange(type, list, contact);
  462.         }
  463.     }
  464.     /**
  465.      * Notify that the name of the specified contact list has been updated.
  466.      *
  467.      * @param list
  468.      * @param name the new name of the list
  469.      */
  470.     protected void notifyContactListNameUpdated(ContactList list, String name) {
  471.         list.mName = name;
  472.         for (ContactListListener listener : mContactListListeners) {
  473.             listener.onContactChange(ContactListListener.LIST_RENAMED,
  474.                     list, null);
  475.         }
  476.     }
  477.     /**
  478.      * Notify that a contact list has been created.
  479.      *
  480.      * @param list the created list
  481.      */
  482.     protected void notifyContactListCreated(ContactList list) {
  483.         synchronized (this) {
  484.             if (list.isDefault()) {
  485.                 for (ContactList l : mContactLists) {
  486.                     l.setDefault(false);
  487.                 }
  488.                 mDefaultContactList = list;
  489.             }
  490.             mContactLists.add(list);
  491.         }
  492.         for (ContactListListener listener : mContactListListeners) {
  493.             listener.onContactChange(ContactListListener.LIST_CREATED,
  494.                     list, null);
  495.         }
  496.     }
  497.     /**
  498.      * Notify that a contact list has been deleted
  499.      *
  500.      * @param list the deleted list
  501.      */
  502.     protected void notifyContactListDeleted(ContactList list) {
  503.         synchronized(this) {
  504.             mContactLists.remove(list);
  505.             if (list.isDefault() && mContactLists.size() > 0) {
  506.                 mContactLists.get(0).setDefault(true);
  507.             }
  508.         }
  509.         for (ContactListListener listener : mContactListListeners) {
  510.             listener.onContactChange(ContactListListener.LIST_DELETED,
  511.                     list, null);
  512.         }
  513.     }
  514.     /**
  515.      * Notify that a contact has been blocked/unblocked.
  516.      *
  517.      * @param contact the blocked/unblocked contact
  518.      */
  519.     protected void notifyBlockContact(Contact contact, boolean blocked) {
  520.         synchronized (this) {
  521.             if (blocked) {
  522.                 mBlockedList.add(contact);
  523.             } else {
  524.                 mBlockedList.remove(contact);
  525.             }
  526.         }
  527.         for (ContactListListener listener : mContactListListeners) {
  528.             listener.onContactChange(blocked ? ContactListListener.CONTACT_BLOCKED
  529.                     : ContactListListener.CONTACT_UNBLOCKED, null, contact);
  530.         }
  531.     }
  532.     protected abstract void doAddContactToListAsync(String address,
  533.             ContactList list) throws ImException;
  534.     protected abstract void doRemoveContactFromListAsync(Contact contact, ContactList list);
  535.     protected abstract void setListNameAsync(String name, ContactList list);
  536. }