/** * Remove mapping for a given localId * * @throws ServiceException */ public void removeTagMapping(int tagId) throws ServiceException { // delete the mapping if it was needed and exists if (mappingRequired) { try { DataSourceMapping mapping = new DataSourceMapping(tagDs, tagId); mapping.delete(); localIdFromRemote.remove(Integer.valueOf(mapping.getRemoteId())); remoteIdFromLocal.remove(tagId); if (localIdsByName.containsValue(tagId)) { Set<String> keysToRemove = new HashSet< String>(); // should only be one, but naming conflicts might end up with more.. for (Entry<String, Integer> entry : localIdsByName.entrySet()) { if (entry.getValue().equals(tagId)) { keysToRemove.add(entry.getKey()); } } for (String key : keysToRemove) { localIdsByName.remove(key); } } OfflineLog.offline.debug("removed tag mapping for localId %d", tagId); // TODO: consider the case where we have > 63 tags. // we can move one of the overflow tags into a free slot, but we also have to apply the tag // to existing messages } catch (ServiceException se) { if (!MailServiceException.NO_SUCH_ITEM.equals(se.getCode())) { throw se; } } } }
/** * Translate a delimted list of tag names to a delimited list of correponding local tagIds * * @throws ServiceException */ public String localTagsFromNames(String tagNames, String inDelim, String outDelim) throws ServiceException { if (tagNames != null && tagNames.length() > 0) { StringBuilder sb = new StringBuilder(); String[] names = tagNames.split(inDelim); for (String name : names) { if (name.trim().length() <= 0) { continue; } Integer tagId = localIdsByName.get(name); if (tagId == null) { try { Tag tag = mbox.getTagByName(null, name); tagId = tag.getId(); localIdsByName.put(name, tagId); } catch (MailServiceException mse) { if (MailServiceException.NO_SUCH_TAG.equals(mse.getCode())) { OfflineLog.offline.debug( "message has tag [" + name + "] which is not visible locally"); continue; } else { throw mse; } } } sb.append(tagId).append(outDelim); } if (sb.length() >= outDelim.length()) { sb.setLength(sb.length() - outDelim.length()); } return sb.toString(); } else { return tagNames; } }
private void mapTagInternal(int remote, int id) throws ServiceException { DataSourceMapping mapping = new DataSourceMapping(tagDs, Mailbox.ID_FOLDER_TAGS, id, remote + ""); mapping.add(); localIdFromRemote.put(remote, id); remoteIdFromLocal.put(id, remote); OfflineLog.offline.debug("added mapping from remote %s to local %d", remote, id); }
/** * Return true if a mapping already exists for a given remoteId * * @throws ServiceException */ public boolean mappingExists(int remoteId) throws ServiceException { if (localIdFromRemote.get(remoteId) != null) { return true; } try { DataSourceMapping mapping = new DataSourceMapping(tagDs, remoteId + ""); localIdFromRemote.put(remoteId, mapping.getItemId()); return true; } catch (NoSuchItemException e) { return false; } }
/** * Map a tag in the overflow range (i.e. > 127). These tags will never be visible in ZD but are * tracked internally * * @throws ServiceException */ public void mapOverflowTag(int remote) throws ServiceException { int max = TAG_ID_OFFSET; Collection<DataSourceItem> items = DataSourceDbMapping.getInstance().getAllMappingsInFolder(tagDs, Mailbox.ID_FOLDER_TAGS); for (DataSourceItem item : items) { if (item.itemId > max) { max = item.itemId; } } int overflowId = max + 1; mapTagInternal(remote, overflowId); localIdFromRemote.put(remote, overflowId); remoteIdFromLocal.put(overflowId, remote); OfflineLog.offline.debug( "added mapping from remote %s to (hidden) local %d", remote, overflowId); }
/** * Get the local ID corresponding to remote tagId * * @throws ServiceException */ public int localTagId(int id) throws ServiceException { if (!isMappingRequired(id)) { return id; } try { if (localIdFromRemote.containsKey(id)) { return localIdFromRemote.get(id); } DataSourceMapping mapping = new DataSourceMapping(tagDs, id + ""); OfflineLog.offline.debug("got localId %d from remote %d", mapping.getItemId(), id); localIdFromRemote.put(id, mapping.getItemId()); return mapping.getItemId(); } catch (ServiceException se) { if (MailServiceException.NO_SUCH_ITEM.equals(se.getCode())) { return -1; } throw se; } }
/** * Get the remoteId corresponding to local tagId * * @throws ServiceException */ public int remoteTagId(int id) throws ServiceException { if (mappingRequired) { if (remoteIdFromLocal.containsKey(id)) { return remoteIdFromLocal.get(id); } try { DataSourceMapping mapping = new DataSourceMapping(tagDs, id); int remoteId = Integer.valueOf(mapping.getRemoteId()); OfflineLog.offline.debug("got remoteId %d from localId %d", remoteId, id); remoteIdFromLocal.put(id, remoteId); return remoteId; } catch (ServiceException se) { if (MailServiceException.NO_SUCH_ITEM.equals(se.getCode())) { return -1; } throw se; } } else { return id; } }