Search in sources :

Example 1 with DataSourceItem

use of com.zimbra.cs.db.DbDataSource.DataSourceItem in project zm-mailbox by Zimbra.

the class CalDavDataImport method getAllFolderMappings.

protected HashMap<String, DataSourceItem> getAllFolderMappings(DataSource ds) throws ServiceException {
    Collection<DataSourceItem> allFolders = DbDataSource.getAllMappingsInFolder(ds, getRootFolderId(ds));
    HashMap<String, DataSourceItem> folders = new HashMap<String, DataSourceItem>();
    for (DataSourceItem f : allFolders) if (f.remoteId != null)
        folders.put(f.remoteId, f);
    return folders;
}
Also used : HashMap(java.util.HashMap) DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem)

Example 2 with DataSourceItem

use of com.zimbra.cs.db.DbDataSource.DataSourceItem in project zm-mailbox by Zimbra.

the class ImapFolderSync method moveMessages.

private void moveMessages() throws IOException, ServiceException {
    Collection<DataSourceItem> mappings = tracker.getMappings();
    List<Integer> allIds = mailbox.listItemIds(mailbox.getOperationContext(), MailItem.Type.MESSAGE, tracker.getItemId());
    Integer[] sortedIds = allIds.toArray(new Integer[allIds.size()]);
    Arrays.sort(sortedIds);
    for (DataSourceItem mapping : mappings) {
        if (Arrays.binarySearch(sortedIds, mapping.itemId) < 0)
            moveMessage(new ImapMessage(ds, mapping));
    }
}
Also used : DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem)

Example 3 with DataSourceItem

use of com.zimbra.cs.db.DbDataSource.DataSourceItem in project zm-mailbox by Zimbra.

the class CalDavDataImport method syncFolders.

private ArrayList<CalendarFolder> syncFolders() throws ServiceException, IOException, DavException, HttpException {
    ArrayList<CalendarFolder> ret = new ArrayList<CalendarFolder>();
    DataSource ds = getDataSource();
    OperationContext octxt = new OperationContext(mbox);
    HashMap<String, DataSourceItem> allFolders = getAllFolderMappings(ds);
    Folder rootFolder = null;
    try {
        rootFolder = mbox.getFolderById(octxt, getRootFolderId(ds));
    } catch (NoSuchItemException e) {
        // folder may be deleted. delete the datasource
        ZimbraLog.datasource.info("Folder %d was deleted.  Deleting data source %s.", getRootFolderId(ds), ds.getName());
        mbox.getAccount().deleteDataSource(ds.getId());
        // return empty array
        return new ArrayList<CalendarFolder>(0);
    }
    List<Integer> deleted = new ArrayList<Integer>();
    int lastSync = (int) rootFolder.getLastSyncDate();
    if (lastSync > 0) {
        for (int itemId : mbox.getTombstones(lastSync).getAllIds()) deleted.add(itemId);
    }
    CalDavClient client = getClient();
    Map<String, DavObject> calendars = client.getCalendars();
    for (String name : calendars.keySet()) {
        DavObject obj = calendars.get(name);
        String ctag = obj.getPropertyText(DavElements.E_GETCTAG);
        String url = obj.getHref();
        DataSourceItem f = allFolders.get(url);
        if (f == null)
            f = new DataSourceItem(0, 0, url, null);
        CalendarFolder cf = new CalendarFolder(f.itemId);
        Folder folder = null;
        if (f.itemId != 0) {
            // check if the folder was deleted
            if (deleted.contains(f.itemId)) {
                allFolders.remove(url);
                DbDataSource.deleteMapping(ds, f.itemId);
                DbDataSource.deleteAllMappingsInFolder(ds, f.itemId);
                deleteRemoteFolder(url);
                continue;
            }
            // check if the folder is valid
            try {
                folder = mbox.getFolderById(octxt, f.itemId);
            } catch (ServiceException se) {
                if (se.getCode() != MailServiceException.NO_SUCH_FOLDER) {
                    throw se;
                }
                f.itemId = 0;
            }
        }
        if (f.itemId == 0) {
            try {
                // check if we can use the folder
                folder = mbox.getFolderByName(octxt, rootFolder.getId(), name);
                if (folder.getDefaultView() != MailItem.Type.APPOINTMENT) {
                    name = name + " (" + getDataSource().getName() + ")";
                    folder = null;
                }
            } catch (MailServiceException.NoSuchItemException e) {
            }
            if (folder == null) {
                Folder.FolderOptions fopt = new Folder.FolderOptions();
                fopt.setDefaultView(MailItem.Type.APPOINTMENT).setFlags(DEFAULT_FOLDER_FLAGS).setColor(getDefaultColor());
                folder = mbox.createFolder(octxt, name, rootFolder.getId(), fopt);
            }
            f.itemId = folder.getId();
            f.folderId = folder.getFolderId();
            f.md = new Metadata();
            f.md.put(METADATA_KEY_TYPE, METADATA_TYPE_FOLDER);
            if (ctag != null) {
                f.md.put(METADATA_KEY_CTAG, ctag);
            }
            f.remoteId = url;
            cf.id = f.itemId;
            mbox.setSyncDate(octxt, folder.getId(), mbox.getLastChangeID());
            DbDataSource.addMapping(ds, f);
        } else if (f.md == null) {
            ZimbraLog.datasource.warn("syncFolders: empty metadata for item %d", f.itemId);
            f.folderId = folder.getFolderId();
            f.remoteId = url;
            f.md = new Metadata();
            f.md.put(METADATA_KEY_TYPE, METADATA_TYPE_FOLDER);
            if (ctag != null)
                f.md.put(METADATA_KEY_CTAG, ctag);
            DbDataSource.addMapping(ds, f);
        } else if (ctag != null) {
            String oldctag = f.md.get(METADATA_KEY_CTAG, null);
            if (ctag.equals(oldctag)) {
                cf.ctagMatched = true;
            } else {
                f.md.put(METADATA_KEY_CTAG, ctag);
                DbDataSource.updateMapping(ds, f);
            }
        }
        String fname = folder.getName();
        if (!fname.equals(name)) {
            ZimbraLog.datasource.warn("renaming folder %s to %s", fname, name);
            try {
                mbox.rename(octxt, f.itemId, MailItem.Type.FOLDER, name, folder.getFolderId());
            } catch (ServiceException e) {
                ZimbraLog.datasource.warn("folder rename failed", e);
            }
        }
        allFolders.remove(url);
        ret.add(cf);
    }
    if (!allFolders.isEmpty()) {
        // handle deleted folders
        ArrayList<Integer> fids = new ArrayList<Integer>();
        int[] fidArray = new int[allFolders.size()];
        int i = 0;
        for (DataSourceItem f : allFolders.values()) {
            Folder folder = mbox.getFolderById(octxt, f.itemId);
            if (folder != null && folder.getDefaultView() != MailItem.Type.APPOINTMENT && folder.getDefaultView() != MailItem.Type.TASK) {
                continue;
            }
            fids.add(f.itemId);
            fidArray[i++] = f.itemId;
            DbDataSource.deleteAllMappingsInFolder(ds, f.itemId);
        }
        if (!fids.isEmpty()) {
            DbDataSource.deleteMappings(ds, fids);
            try {
                mbox.delete(octxt, fidArray, MailItem.Type.FOLDER, null);
            } catch (ServiceException e) {
                ZimbraLog.datasource.warn("folder delete failed", e);
            }
        }
    }
    mbox.setSyncDate(octxt, rootFolder.getId(), mbox.getLastChangeID());
    return ret;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) ArrayList(java.util.ArrayList) Metadata(com.zimbra.cs.mailbox.Metadata) Folder(com.zimbra.cs.mailbox.Folder) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) CalDavClient(com.zimbra.cs.dav.client.CalDavClient) DbDataSource(com.zimbra.cs.db.DbDataSource) DataSource(com.zimbra.cs.account.DataSource) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) DavObject(com.zimbra.cs.dav.client.DavObject)

Example 4 with DataSourceItem

use of com.zimbra.cs.db.DbDataSource.DataSourceItem in project zm-mailbox by Zimbra.

the class GalImport method importGal.

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 (// non-folder items
        dsItem.md == null || dsItem.md.get(TYPE, null) == null)
            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);
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) HashMap(java.util.HashMap) Metadata(com.zimbra.cs.mailbox.Metadata) ArrayList(java.util.ArrayList) SearchGalResult(com.zimbra.cs.account.Provisioning.SearchGalResult) ServiceException(com.zimbra.common.service.ServiceException) JSONException(org.json.JSONException) DbDataSource(com.zimbra.cs.db.DbDataSource) DataSource(com.zimbra.cs.account.DataSource) ServiceException(com.zimbra.common.service.ServiceException) DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem)

Example 5 with DataSourceItem

use of com.zimbra.cs.db.DbDataSource.DataSourceItem in project zm-mailbox by Zimbra.

the class GalSearchControl method doLocalGalAccountSync.

private void doLocalGalAccountSync(Account galAcct) throws ServiceException {
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(galAcct);
    OperationContext octxt = new OperationContext(mbox);
    GalSearchResultCallback callback = mParams.getResultCallback();
    Domain domain = mParams.getDomain();
    GalMode galMode = domain.getGalMode();
    int changeId = mParams.getGalSyncToken().getChangeId(galAcct.getId());
    // bug 46608
    // sync local resources from first datasource if galMode is ldap
    // and zimbraGalAlwaysIncludeLocalCalendarResources is set for the domain
    boolean syncLocalResources = (galMode == GalMode.ldap && domain.isGalAlwaysIncludeLocalCalendarResources());
    Set<Integer> folderIds = new HashSet<Integer>();
    String syncToken = null;
    for (DataSource ds : galAcct.getAllDataSources()) {
        if (ds.getType() != DataSourceType.gal) {
            ZimbraLog.gal.trace("skipping datasource %s: wrong type %s expected %s", ds.getName(), ds.getType(), DataSourceType.gal);
            continue;
        }
        if (galMode != null) {
            if (!(galMode.isBoth() || galMode.toString().equals(ds.getAttr(Provisioning.A_zimbraGalType)))) {
                ZimbraLog.gal.debug("skipping datasource %s: wrong zimbraGalType %s expected %s", ds.getName(), ds.getAttr(Provisioning.A_zimbraGalType), galMode.toString());
                continue;
            }
        }
        int fid = ds.getFolderId();
        DataSourceItem folderMapping = DbDataSource.getMapping(ds, fid);
        if (folderMapping.md == null) {
            ZimbraLog.gal.debug("skipping datasource %s: no folder mapping", ds.getName());
            continue;
        }
        folderIds.add(fid);
        syncToken = LdapUtil.getEarlierTimestamp(syncToken, folderMapping.md.get(GalImport.SYNCTOKEN));
        if (syncLocalResources) {
            doLocalGalAccountSync(callback, mbox, octxt, changeId, folderIds, syncToken, mParams.getLimit(), Provisioning.A_zimbraAccountCalendarUserType, "RESOURCE", mParams.isGetCount());
            syncLocalResources = false;
        }
    }
    if (folderIds.isEmpty()) {
        throw ServiceException.FAILURE("no gal datasource with mapped folder found", null);
    }
    if (syncToken == null) {
        throw ServiceException.FAILURE("no gal datasource with sync token found", null);
    }
    doLocalGalAccountSync(callback, mbox, octxt, changeId, folderIds, syncToken, mParams.getLimit(), mParams.isGetCount());
    List<Integer> deleted = null;
    if (callback.getResponse() != null && !callback.getResponse().getAttributeBool(MailConstants.A_QUERY_MORE) && changeId > 0) {
        try {
            TypedIdList tIdList = mbox.getTombstones(changeId);
            deleted = tIdList.getAllIds();
            int deletedChangeId = tIdList.getMaxModSequence();
            ZimbraLog.gal.debug("deleted change id = %s", deletedChangeId);
            if (deletedChangeId > changeId) {
                GalSyncToken newToken = new GalSyncToken(syncToken, mbox.getAccountId(), deletedChangeId);
                ZimbraLog.gal.debug("computing new sync token for %s:%s", mbox.getAccountId(), newToken);
                callback.setNewToken(newToken);
            }
        } catch (MailServiceException e) {
            if (MailServiceException.MUST_RESYNC == e.getCode()) {
                ZimbraLog.gal.warn("sync token too old, deleted items will not be handled", e);
            } else {
                throw e;
            }
        }
    }
    if (deleted != null) {
        for (int itemId : deleted) {
            callback.handleDeleted(new ItemId(galAcct.getId(), itemId));
        }
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) GalMode(com.zimbra.common.account.ZAttrProvisioning.GalMode) TypedIdList(com.zimbra.cs.mailbox.util.TypedIdList) ItemId(com.zimbra.cs.service.util.ItemId) DbDataSource(com.zimbra.cs.db.DbDataSource) DataSource(com.zimbra.cs.account.DataSource) Mailbox(com.zimbra.cs.mailbox.Mailbox) DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Domain(com.zimbra.cs.account.Domain) HashSet(java.util.HashSet)

Aggregations

DataSourceItem (com.zimbra.cs.db.DbDataSource.DataSourceItem)13 DataSource (com.zimbra.cs.account.DataSource)6 DbDataSource (com.zimbra.cs.db.DbDataSource)6 ArrayList (java.util.ArrayList)5 ServiceException (com.zimbra.common.service.ServiceException)4 Metadata (com.zimbra.cs.mailbox.Metadata)4 OperationContext (com.zimbra.cs.mailbox.OperationContext)4 CalDavClient (com.zimbra.cs.dav.client.CalDavClient)3 Appointment (com.zimbra.cs.dav.client.CalDavClient.Appointment)3 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)3 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 HashMap (java.util.HashMap)3 DbImapMessage (com.zimbra.cs.db.DbImapMessage)2 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)2 NoSuchItemException (com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)2 HashSet (java.util.HashSet)2 GalMode (com.zimbra.common.account.ZAttrProvisioning.GalMode)1 Domain (com.zimbra.cs.account.Domain)1 SearchGalResult (com.zimbra.cs.account.Provisioning.SearchGalResult)1 DavException (com.zimbra.cs.dav.DavException)1