private void processCategories(List<Category> categories) throws ServiceException { Stats stats = new Stats(); // Get all existing contact groups Map<Integer, ContactGroup> groups = new HashMap<Integer, ContactGroup>(); for (Category cat : categories) { groups.put(cat.getId(), new ContactGroup(cat.getName())); } // Get all contact mappings and update contact group dlist information Collection<DataSourceItem> mappings = localData.getAllContactMappings(); for (DataSourceItem dsi : mappings) { if (dsi.remoteId != null) { RemoteId rid = RemoteId.parse(dsi.remoteId); if (rid.isContact()) { Contact contact = getContact(dsi); if (contact != null) { List<Category> cats = contact.getCategories(); if (!cats.isEmpty()) { List<String> emails = getEmailAddresses(contact); if (!emails.isEmpty()) { for (Category cat : cats) { ContactGroup group = groups.get(cat.getId()); if (group != null) { group.addEmail(emails.get(0)); } } } } } } } } // Remove contact groups deleted remotely for (DataSourceItem dsi : mappings) { if (dsi.remoteId != null) { RemoteId rid = RemoteId.parse(dsi.remoteId); if (rid.isCategory() && !groups.containsKey(rid.getId())) { localData.deleteContactGroup(dsi.itemId); groups.remove(rid.getId()); stats.deleted++; } } } // Create new or update existring contact groups for (Map.Entry<Integer, ContactGroup> me : groups.entrySet()) { RemoteId rid = RemoteId.categoryId(me.getKey()); updateGroup(rid.toString(), me.getValue(), stats); } LOG.debug("Processed remote category changes: %s", stats); }
private void processContactResult(SyncRequestEvent event, int itemId, Stats stats) throws ServiceException { Contact contact = pushedContacts.get(itemId); if (event.isAddContact()) { SuccessResult result = (SuccessResult) event.getResult(); contact.setId(result.getContactId()); updateContactMapping(itemId, contact); stats.added++; } else if (event.isUpdateContact()) { updateContactMapping(itemId, contact); stats.updated++; } else if (event.isRemoveContact()) { deleteContact(itemId, stats); } }
private void processEvent(SyncResponseEvent event, Stats stats) throws ServiceException { Contact contact = event.getContact(); RemoteId rid = RemoteId.contactId(contact.getId()); DataSourceItem dsi = localData.getReverseMapping(rid.toString()); if (event.isAddContact() || event.isUpdateContact()) { if (dsi.itemId > 0) { // Don't update contact if it has been modified locally since // sync request was sent. Wait until we send the new changes // before updating the local contact. if (!contactChanges.containsKey(dsi.itemId)) { updateContact(contact, dsi, stats); } } else { addContact(contact, stats); } } else if (event.isRemoveContact()) { if (dsi.itemId > 0) { deleteContact(dsi.itemId, stats); } } }
private List<String> getEmailAddresses(Contact contact) { List<String> emails = new ArrayList<String>(); for (Field field : contact.getFields()) { if (field.isSimple()) { SimpleField simple = (SimpleField) field; if (simple.isEmail()) { emails.add(simple.getValue()); } } } return emails; }
private void addContact(Contact contact, Stats stats) throws ServiceException { int cid = contact.getId(); ContactData cd = new ContactData(contact); if (!cd.isEmpty()) { ParsedContact pc = cd.getParsedContact(); int itemId = localData.createContact(pc).getId(); updateContactMapping(itemId, contact); stats.added++; LOG.debug("Created new local contact: itemId=%d, cid=%d", itemId, cid); } else { LOG.debug( "Not adding contact with cid %d since it would " + "result in an empty contact", cid); } }
private void updateContact(Contact contact, DataSourceItem dsi, Stats stats) throws ServiceException { int cid = contact.getId(); ContactData cd = new ContactData(contact); if (!cd.isEmpty()) { ParsedContact pc = new ParsedContact(localData.getContact(dsi.itemId)); cd.modifyParsedContact(pc); localData.modifyContact(dsi.itemId, pc); updateContactMapping(dsi.itemId, contact); stats.updated++; LOG.debug("Modified local contact: itemId=%d, cid=%d", dsi.itemId, cid); } else { LOG.debug( "Removing contact with cid %d since changes would " + "result in an empty contact", cid); deleteContact(dsi.itemId, stats); } }
private SyncRequestEvent getContactEvent(Change change) throws ServiceException { int itemId = change.getItemId(); if (change.isAdd() || change.isUpdate()) { com.zimbra.cs.mailbox.Contact zcontact = localData.getContact(itemId); if (ContactGroup.isContactGroup(zcontact)) { // Delete mapping so contact group will no longer be sync'd localData.deleteMapping(itemId); } else { ContactData cd = new ContactData(zcontact); if (change.isAdd()) { Contact contact = cd.getContact(); pushedContacts.put(itemId, contact); return SyncRequestEvent.addContact(contact); } else { // LOG.debug("count = " + cd.getCategories().size()); Contact newContact = cd.getContact(); Contact oldContact = getContact(localData.getMapping(itemId)); // LOG.debug("oldContact: " + oldContact); // LOG.debug("newContact: " + newContact); newContact.setId(oldContact.getId()); // Add categories so we can track updates for (Category category : oldContact.getCategories()) { newContact.addCategory(category); } pushedContacts.put(itemId, newContact); ContactChange cc = cd.getContactChange(oldContact); return cc.isEmpty() ? null : SyncRequestEvent.updateContact(cc); } } } else if (change.isDelete()) { DataSourceItem dsi = localData.getMapping(itemId); RemoteId rid = RemoteId.parse(dsi.remoteId); if (rid.isContact()) { pushedContacts.put(itemId, new Contact(rid.getId())); return SyncRequestEvent.removeContact(rid.getId()); } else { // Remove mapping for deleted contact group localData.deleteMapping(rid.getId()); } } return null; }
private Contact getContact(DataSourceItem dsi) throws ServiceException { return Contact.fromXml(getDocument(dsi).getDocumentElement()); }
private void updateContactMapping(int itemId, Contact contact) throws ServiceException { RemoteId rid = RemoteId.contactId(contact.getId()); localData.updateMapping(itemId, rid.toString(), toXml(contact)); }