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;
}
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));
}
}
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;
}
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);
}
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));
}
}
}
Aggregations