001 /* 002 * Copyright 2010 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package com.hs.mail.imap.mailbox; 017 018 import java.util.List; 019 020 import com.hs.mail.imap.dao.DaoFactory; 021 022 /** 023 * Convert Unique Identifier (UID) to Message Sequence Number (MSN) and vice 024 * versa. 025 * 026 * @author Won Chul Doh 027 * @since Mar 22, 2010 028 * 029 */ 030 public class UidToMsnMapper { 031 032 protected SelectedMailbox selected = null; 033 protected List<Long> uids; 034 protected boolean useUID = false; 035 036 public UidToMsnMapper(SelectedMailbox selected, List<Long> uids, boolean useUID) { 037 this.selected = selected; 038 this.uids = uids; 039 this.useUID = useUID; 040 } 041 042 public UidToMsnMapper(SelectedMailbox selected, boolean useUID) { 043 this(selected, selected.getCachedUids(), useUID); 044 } 045 046 public long getUID(int msgnum) { 047 long uid = selected.getUID(msgnum); 048 if (uid == -1) { 049 prepare(); 050 uid = (msgnum <= uids.size()) ? (Long) uids.get(msgnum - 1) : -1; 051 if (uid != -1) 052 selected.add(msgnum, uid); 053 } 054 return uid; 055 } 056 057 public int getMessageNumber(long uid) { 058 int msgnum = selected.getMessageNumber(uid); 059 if (msgnum == -1) { 060 prepare(); 061 if (uid == Long.MAX_VALUE) { // * 062 msgnum = (uids.size() > 0) ? uids.size() : -1; 063 } else { 064 int i = uids.indexOf(uid); 065 msgnum = (i >= 0) ? i + 1 : -1; 066 if (msgnum != -1) 067 selected.add(msgnum, uid); 068 } 069 } 070 return msgnum; 071 } 072 073 public List<Long> getUIDList() { 074 return uids; 075 } 076 077 /** 078 * Find the smallest message sequence number whose corresponding unique 079 * identifier is equal or greater than the given unique identifier. 080 * 081 * @param min 082 * the key UID to be searched for 083 * @return the smallest message sequence number if found; otherwise -1 084 */ 085 public long getMinMessageNumber(long min) { 086 if (useUID) { 087 int msgnum = getMessageNumber(min); 088 if (msgnum == -1) { 089 if ((msgnum = search(uids, min)) != -1) { 090 return (uids.get(msgnum) >= min) ? msgnum + 1 : msgnum + 2; 091 } 092 } 093 return msgnum; 094 } else { 095 return min; 096 } 097 } 098 099 /** 100 * Find the largest message sequence number whose corresponding unique 101 * identifier is equal or less than the given unique identifier. 102 * 103 * @param max 104 * the key UID to be searched for 105 * @return the largest message sequence number if found; otherwise -1 106 */ 107 public long getMaxMessageNumber(long max) { 108 if (useUID) { 109 int msgnum = getMessageNumber(max); 110 if (msgnum == -1) { 111 if ((msgnum = search(uids, max)) != -1) { 112 return (uids.get(msgnum) <= max) ? msgnum + 1: msgnum; 113 } 114 } 115 return msgnum; 116 } else { 117 return max; 118 } 119 } 120 121 protected int search(List<Long> v, long t) { 122 int low = 0; 123 int mid = -1; 124 int high = v.size() - 1; 125 while (low <= high) { 126 mid = (low + high) / 2; 127 long c = v.get(mid) - t; 128 if (c > 0) 129 high = mid - 1; 130 else if (c < 0) 131 low = mid + 1; 132 else 133 break; 134 } 135 return mid; 136 } 137 138 private void prepare() { 139 if (uids == null) 140 uids = DaoFactory.getMessageDao().getMessageIDList( 141 selected.getMailboxID()); 142 } 143 144 }