1 /* ***** BEGIN LICENSE BLOCK *****
  2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3  *
  4  * The contents of this file are subject to the Mozilla Public License Version
  5  * 1.1 (the "License"); you may not use this file except in compliance with
  6  * the License. You may obtain a copy of the License at
  7  * http://www.mozilla.org/MPL/
  8  *
  9  * Software distributed under the License is distributed on an "AS IS" basis,
 10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 11  * for the specific language governing rights and limitations under the
 12  * License.
 13  *
 14  * The Original Code is gContactSync.
 15  *
 16  * The Initial Developer of the Original Code is
 17  * Josh Geenen <gcontactsync@pirules.org>.
 18  * Portions created by the Initial Developer are Copyright (C) 2008-2009
 19  * the Initial Developer. All Rights Reserved.
 20  *
 21  * Contributor(s):
 22  *
 23  * Alternatively, the contents of this file may be used under the terms of
 24  * either the GNU General Public License Version 2 or later (the "GPL"), or
 25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 26  * in which case the provisions of the GPL or the LGPL are applicable instead
 27  * of those above. If you wish to allow use of your version of this file only
 28  * under the terms of either the GPL or the LGPL, and not to allow others to
 29  * use your version of this file under the terms of the MPL, indicate your
 30  * decision by deleting the provisions above and replace them with the notice
 31  * and other provisions required by the GPL or the LGPL. If you do not delete
 32  * the provisions above, a recipient may use your version of this file under
 33  * the terms of any one of the MPL, the GPL or the LGPL.
 34  *
 35  * ***** END LICENSE BLOCK ***** */
 36 
 37 if (!com) var com = {}; // A generic wrapper variable
 38 // A wrapper for all GCS functions and variables
 39 if (!com.gContactSync) com.gContactSync = {};
 40 
 41 /**
 42  * AbListener is a listener for the Address Book that is currently only used to
 43  * update the last modified date of mailing lists and cards contained within
 44  * them.
 45  * @class
 46  */
 47 com.gContactSync.AbListener = {
 48   /**
 49    * Unused.
 50    * @param aParentDir The parent directory to which an item was added.
 51    * @param aItem      The item added to the directory.
 52    */
 53   onItemAdded: function AbListener_onItemAdded(aParentDir, aItem) {},
 54   /**
 55    * Unused.
 56    * @param aItem     The item whose property was changed.
 57    * @param aProperty The property changed.
 58    * @param aOldValue The former value of the property.
 59    * @param aNewValue The new value of the property.
 60    */
 61   onItemPropertyChanged: function AbListener_onItemPropertyChanged(aItem,
 62                                                                    aProperty,
 63                                                                    aOldValue,
 64                                                                    aNewValue) {},
 65   /**
 66    * Used just to update the lastModifiedDate of cards removed from a mail list.
 67    * If a mail list is removed nothing needs to be done since the Group will be
 68    * deleted in Gmail.
 69    * @param aParentDir {nsIAbDirectory} The directory from which an item was
 70    *                                    removed.  Ignored unless it is a list.
 71    * @param aItem      The item removed from a directory.  Ignored unless it is
 72    *                   an Address Book card removed from a mail list.
 73    */
 74   onItemRemoved: function AbListener_onItemRemoved(aParentDir, aItem) {
 75     aParentDir.QueryInterface(Components.interfaces.nsIAbDirectory);
 76 
 77     // if a contact was removed and there is not an ongoing synchronization
 78     if (aItem instanceof Components.interfaces.nsIAbCard &&
 79         !com.gContactSync.Preferences.mSyncPrefs.synchronizing.value) {
 80       // if a contact was removed from just a mailing list, update the contact's
 81       // last modified date in the parent address book
 82       if (aParentDir.isMailList) {
 83         try {
 84           aItem.QueryInterface(Components.interfaces.nsIAbCard);
 85           var now     = (new Date()).getTime() / 1000,
 86               uri     = this.getURI(aParentDir),
 87               // the parent of aParentDir (aParentDir is a mailing list, dir is the
 88               // directory in which aParentDir is stored)
 89               dir     = new com.gContactSync.GAddressBook(com.gContactSync.AbManager.getAbByURI(uri)),
 90               contact = new com.gContactSync.TBContact(aItem, dir);
 91           // the URI of the list's parent
 92           uri = uri.substring(0, uri.lastIndexOf("/"));
 93           // set the last modified date and update the card
 94           contact.setValue("LastModifiedDate", now);
 95           contact.update();
 96         }
 97         catch (e) {
 98           com.gContactSync.LOGGER.LOG_WARNING("Error updating card after being removed: " + 
 99                              aItem + " " + uri + " " + now, e);
100         }
101       }
102     }
103   },
104   /**
105    * Gets the Uniform Resource Identifier (URI) of the specified directory.
106    * @param aDirectory {nsIAbDirectory} The directory whose URI is returned.
107    * @returns {string} The URI of aDirectory.
108    */
109   getURI: function AbListener_getURI(aDirectory) {
110     var error;
111     try {
112       if (aDirectory && (aDirectory instanceof Components.interfaces.nsIAbDirectory)) {
113         if (aDirectory.URI) // Thunderbird 3
114           return aDirectory.URI;
115         aDirectory.QueryInterface(Components.interfaces.nsIAbMDBDirectory); // Thunderbird 2
116         if (aDirectory.getDirUri)
117           return aDirectory.getDirUri();
118      } 
119     } catch (e) { error = e; }
120     com.gContactSync.LOGGER.LOG_WARNING("AbListener could not get a URI for: " + aDirectory,
121                        error);
122     return "";
123   },
124   /**
125    * Adds this listener to be alerted whenever a directory item is removed.
126    * It will be called whenever an item (card or mail list) is removed from a
127    * directory (address book or mail list).
128    */
129   add: function AbListener_add() {
130     var flags;
131     if (Components.classes["@mozilla.org/abmanager;1"]) { // Thunderbird 3
132       flags = Components.interfaces.nsIAbListener.directoryItemRemoved;
133       Components.classes["@mozilla.org/abmanager;1"]
134                 .getService(Components.interfaces.nsIAbManager)
135                 .addAddressBookListener(com.gContactSync.AbListener, flags);
136     }
137     else { // Thunderbird 2
138       flags = Components.interfaces.nsIAddrBookSession.directoryItemRemoved;
139       Components.classes["@mozilla.org/addressbook/services/session;1"]
140                 .getService(Components.interfaces.nsIAddrBookSession)
141                 .addAddressBookListener(com.gContactSync.AbListener, flags);
142     }
143   },
144   /**
145    * Removes this listener.
146    */
147   remove: function AbListener_remove() {
148     if (Components.classes["@mozilla.org/abmanager;1"]) // Thunderbird 3
149       Components.classes["@mozilla.org/abmanager;1"]
150                 .getService(Components.interfaces.nsIAbManager)
151                 .removeAddressBookListener(com.gContactSync.AbListener);
152     else // Thunderbird 2
153       Components.classes["@mozilla.org/addressbook/services/session;1"]
154                 .getService(Components.interfaces.nsIAddrBookSession)
155                 .removeAddressBookListener(com.gContactSync.AbListener);
156   }
157 };
158