@Override public void visit(GalContact contact) throws ServiceException { Map<String, Object> attrs = contact.getAttrs(); String id = contact.getId(); mappings.remove(id); attrs.put(ContactConstants.A_dn, id); ZimbraLog.gal.debug("processing gal contact " + id); DataSourceItem dsItem = DbDataSource.getReverseMapping(getDataSource(), id); addFileAsStr(attrs); if (dsItem.itemId == 0) { ZimbraLog.gal.debug("creating new contact " + id); dsItem.remoteId = id; ParsedContact pc = new ParsedContact(attrs); dsItem.itemId = mbox.createContact(octxt, pc, fid, null).getId(); DbDataSource.addMapping(getDataSource(), dsItem); } else { Contact mboxContact = mbox.getContactById(octxt, dsItem.itemId); // check for update conditions String syncDate = mboxContact.get(MODIFY_TIMESTAMP); String modifiedDate = (String) contact.getAttrs().get(MODIFY_TIMESTAMP); if (!force && syncDate != null && syncDate.equals(modifiedDate)) { ZimbraLog.gal.debug("gal contact %s has not been modified", id); return; } if (!force && allFieldsMatch(attrs, mboxContact.getAllFields())) { ZimbraLog.gal.debug("no field has changed in gal contact %s", id); return; } ZimbraLog.gal.debug("modifying contact " + id); ParsedContact pc = new ParsedContact(attrs); mbox.modifyContact(octxt, dsItem.itemId, pc); } }
public void importGal(int fid, boolean fullSync, boolean force) throws ServiceException { mbox.beginTrackingSync(); DataSource ds = getDataSource(); DataSourceItem folderMapping = DbDataSource.getMapping(ds, fid); if (folderMapping.md == null) { folderMapping.itemId = fid; folderMapping.md = new Metadata(); folderMapping.md.put(TYPE, FOLDER); DbDataSource.addMapping(ds, folderMapping); } String syncToken = fullSync ? "" : folderMapping.md.get(SYNCTOKEN, ""); HashMap<String, DataSourceItem> allMappings = new HashMap<String, DataSourceItem>(); if (fullSync || force) for (DataSourceItem dsItem : DbDataSource.getAllMappings(ds)) if (dsItem.md == null || dsItem.md.get(TYPE, null) == null) // non-folder items allMappings.put(dsItem.remoteId, dsItem); OperationContext octxt = new OperationContext(mbox); SearchGalResult result = SearchGalResult.newSearchGalResult(new GalSearchVisitor(mbox, allMappings, fid, force)); try { searchGal(syncToken, result, true); } catch (Exception e) { setStatus(false); ZimbraLog.gal.error("Error executing gal search", e); return; } folderMapping.md.put(SYNCTOKEN, result.getToken()); DbDataSource.updateMapping(ds, folderMapping); if (allMappings.size() == 0 || !fullSync) { setStatus(true); return; } ArrayList<Integer> deleted = new ArrayList<Integer>(); int[] deletedIds = new int[allMappings.size()]; int i = 0; for (DataSourceItem dsItem : allMappings.values()) { deleted.add(dsItem.itemId); deletedIds[i++] = dsItem.itemId; } try { mbox.delete(octxt, deletedIds, MailItem.Type.CONTACT, null); } catch (ServiceException e) { ZimbraLog.gal.warn("Ignoring error deleting gal contacts", e); } DbDataSource.deleteMappings(getDataSource(), deleted); mbox.index.optimize(); setStatus(true); }